Skip to content

Commit 60f1409

Browse files
committed
fix(tooling): incorrect mappings after replace
1 parent 88231cd commit 60f1409

File tree

4 files changed

+55
-31
lines changed

4 files changed

+55
-31
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@vitejs/plugin-vue": "^4.1.0",
3838
"@vitest/coverage-c8": "^0.29.7",
3939
"@volar/vue-language-core": "^1.6.3",
40+
"@vue/shared": "^3.2.47",
4041
"changelogen": "^0.5.1",
4142
"eslint": "^8.36.0",
4243
"eslint-config-unjs": "^0.1.0",

pnpm-lock.yaml

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/utils.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import {
22
parseVueRequest as _parseVueRequest,
33
VueQuery,
44
} from "@vitejs/plugin-vue";
5+
import { capitalize, camelize } from "@vue/shared";
56

67
export function pascalCase(str: string) {
7-
return str
8-
.replace(/(?:\b|_)[a-z]/g, (c) => c.toUpperCase())
9-
.replace(/[\W_]+/g, "");
8+
return capitalize(camelize(str));
109
}
1110

1211
export function parseVueRequest(id: string) {

tooling/index.ts

+50-28
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import {
33
VueFile,
44
getDefaultVueLanguagePlugins,
55
replace,
6+
getLength,
67
} from "@volar/vue-language-core";
8+
import { capitalize, camelize } from "@vue/shared";
79

810
function pascalCase(str: string) {
9-
return str
10-
.replace(/(?:\b|_)[a-z]/g, (c) => c.toUpperCase())
11-
.replace(/[\W_]+/g, "");
11+
return capitalize(camelize(str));
1212
}
1313

1414
const plugin: VueLanguagePlugin = (ctx) => {
@@ -88,29 +88,33 @@ const plugin: VueLanguagePlugin = (ctx) => {
8888
if (typeof segment === "string") {
8989
newContent.push(segment);
9090
} else {
91-
let base = 0;
91+
let base: number | undefined = 0;
9292
// eslint-disable-next-line unicorn/prefer-switch
9393
if (segment[1] === "template") {
94-
base = vueFile.sfc.template!.startTagEnd;
94+
base = vueFile.sfc.template?.startTagEnd;
9595
} else if (segment[1] === "script") {
96-
base = vueFile.sfc.script!.startTagEnd;
96+
base = vueFile.sfc.script?.startTagEnd;
9797
} else if (segment[1] === "scriptSetup") {
98-
base = vueFile.sfc.scriptSetup!.startTagEnd;
98+
base = vueFile.sfc.scriptSetup?.startTagEnd;
9999
} else if (segment[1]?.startsWith("style_")) {
100100
const index = Number(segment[1].slice("style_".length));
101-
base = vueFile.sfc.styles[index]!.startTagEnd;
101+
base = vueFile.sfc.styles[index]?.startTagEnd;
102102
} else if (segment[1]?.startsWith("customBlock_")) {
103103
const index = Number(segment[1].slice("customBlock_".length));
104-
base = vueFile.sfc.customBlocks[index]!.startTagEnd;
104+
base = vueFile.sfc.customBlocks[index]?.startTagEnd;
105+
}
106+
if (base !== undefined) {
107+
newContent.push([
108+
segment[0],
109+
componentBlock.name,
110+
typeof segment[2] === "number"
111+
? segment[2] + base
112+
: [segment[2][0] + base, segment[2][1] + base],
113+
segment[3],
114+
]);
115+
} else {
116+
newContent.push(segment[0]);
105117
}
106-
newContent.push([
107-
segment[0],
108-
componentBlock.name,
109-
typeof segment[2] === "number"
110-
? segment[2] + base
111-
: [segment[2][0] + base, segment[2][1] + base],
112-
segment[3],
113-
]);
114118
}
115119
}
116120
embeddedFile.content = newContent;
@@ -135,38 +139,56 @@ const plugin: VueLanguagePlugin = (ctx) => {
135139
`${fileName}__VLS_NSFC_${b.name.slice(
136140
"customBlock_".length
137141
)}.vue`
138-
)};\n`
142+
)};`
139143
)
140144
);
141145

146+
// export components
147+
embeddedFile.content.push(
148+
`\nexport { ${componentBlocks
149+
.map((b) => pascalCase(b.attrs.name as string))
150+
.join(", ")} };\n`
151+
);
152+
153+
const codeLength = getLength(embeddedFile.content);
154+
142155
// register components
143156
if (sfc.scriptSetup) {
144157
replace(
145158
embeddedFile.content,
146-
/setup\(\) {\nreturn {\n/,
147-
"setup() {",
148-
"return {",
159+
new RegExp(
160+
`const __VLS_internalComponent = \\(await import\\('${ctx.vueCompilerOptions.lib}'\\)\\)\\.defineComponent\\({\nsetup\\(\\) {\nreturn {\n`
161+
),
162+
`const __VLS_internalComponent = (await import('${ctx.vueCompilerOptions.lib}')).defineComponent({\nsetup() {\nreturn {\n`,
149163
...componentBlocks.map(
150164
(b) => `${pascalCase(b.attrs.name as string)},\n`
151165
)
152166
);
153167
} else {
154168
replace(
155169
embeddedFile.content,
156-
/const __VLS_componentsOption = {/,
170+
"const __VLS_componentsOption = {",
157171
"const __VLS_componentsOption = {\n",
158172
...componentBlocks.map(
159173
(b) => `${pascalCase(b.attrs.name as string)},\n`
160174
)
161175
);
162176
}
163177

164-
// export components
165-
embeddedFile.content.push(
166-
`\nexport { ${componentBlocks
167-
.map((b) => pascalCase(b.attrs.name as string))
168-
.join(", ")} };\n`
169-
);
178+
// mappings have to be shifted because of the added code when replacing
179+
const lengthShift = getLength(embeddedFile.content) - codeLength;
180+
embeddedFile.mirrorBehaviorMappings =
181+
embeddedFile.mirrorBehaviorMappings.map((mapping) => ({
182+
...mapping,
183+
sourceRange: [
184+
mapping.sourceRange[0] + lengthShift,
185+
mapping.sourceRange[1] + lengthShift,
186+
],
187+
generatedRange: [
188+
mapping.generatedRange[0] + lengthShift,
189+
mapping.generatedRange[1] + lengthShift,
190+
],
191+
}));
170192
}
171193
},
172194
};

0 commit comments

Comments
 (0)