Skip to content

Commit 2b0093d

Browse files
committed
refactor(language-core): resolve component ranges in parseScriptRanges, parseScriptSetupRanges
1 parent d245142 commit 2b0093d

File tree

5 files changed

+61
-68
lines changed

5 files changed

+61
-68
lines changed

packages/language-core/lib/parsers/scriptRanges.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import type * as ts from 'typescript';
2-
import type { TextRange } from '../types';
2+
import type { TextRange, VueCompilerOptions } from '../types';
33
import { getNodeText, getStartEnd } from '../utils/shared';
44
import { getClosestMultiLineCommentRange, parseBindingRanges } from './utils';
55

66
export interface ScriptRanges extends ReturnType<typeof parseScriptRanges> {}
77

8-
export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.SourceFile, hasScriptSetup: boolean) {
8+
export function parseScriptRanges(
9+
ts: typeof import('typescript'),
10+
ast: ts.SourceFile,
11+
vueCompilerOptions: VueCompilerOptions,
12+
) {
913
let exportDefault:
1014
| TextRange & {
1115
expression: TextRange;
@@ -24,7 +28,7 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc
2428
}
2529
| undefined;
2630

27-
const bindings = hasScriptSetup ? parseBindingRanges(ts, ast) : [];
31+
const { bindings, components } = parseBindingRanges(ts, ast, vueCompilerOptions.extensions);
2832

2933
ts.forEachChild(ast, raw => {
3034
if (ts.isExportAssignment(raw)) {
@@ -92,6 +96,7 @@ export function parseScriptRanges(ts: typeof import('typescript'), ast: ts.Sourc
9296
exportDefault,
9397
componentOptions,
9498
bindings,
99+
components,
95100
};
96101

97102
function _getStartEnd(node: ts.Node) {

packages/language-core/lib/parsers/scriptSetupRanges.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export function parseScriptSetupRanges(
9393
range => tsCheckReg.test(text.slice(range.pos, range.end)),
9494
)?.end ?? 0;
9595

96-
let bindings = parseBindingRanges(ts, ast);
96+
let { bindings, components } = parseBindingRanges(ts, ast, vueCompilerOptions.extensions);
9797
let foundNonImportExportNode = false;
9898
let importSectionEndOffset = 0;
9999

@@ -129,7 +129,7 @@ export function parseScriptSetupRanges(
129129
ts.forEachChild(ast, node => visitNode(node, [ast]));
130130

131131
const templateRefNames = new Set(useTemplateRef.map(ref => ref.name));
132-
bindings = bindings.filter(({ range }) => {
132+
bindings = bindings.filter(range => {
133133
const name = text.slice(range.start, range.end);
134134
return !templateRefNames.has(name);
135135
});
@@ -138,6 +138,7 @@ export function parseScriptSetupRanges(
138138
leadingCommentEndOffset,
139139
importSectionEndOffset,
140140
bindings,
141+
components,
141142
defineModel,
142143
defineProps,
143144
withDefaults,

packages/language-core/lib/parsers/utils.ts

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,33 @@ import type { TextRange } from '../types';
33
import { collectBindingRanges } from '../utils/collectBindings';
44
import { getNodeText, getStartEnd } from '../utils/shared';
55

6-
export function parseBindingRanges(ts: typeof import('typescript'), ast: ts.SourceFile) {
7-
const bindings: {
8-
range: TextRange;
9-
moduleName?: string;
10-
isDefaultImport?: boolean;
11-
isNamespace?: boolean;
12-
}[] = [];
6+
export function parseBindingRanges(
7+
ts: typeof import('typescript'),
8+
ast: ts.SourceFile,
9+
componentExtsensions: string[],
10+
) {
11+
const bindings: TextRange[] = [];
12+
const components: TextRange[] = [];
1313

1414
ts.forEachChild(ast, node => {
1515
if (ts.isVariableStatement(node)) {
1616
for (const decl of node.declarationList.declarations) {
1717
const ranges = collectBindingRanges(ts, decl.name, ast);
18-
bindings.push(...ranges.map(range => ({ range })));
18+
bindings.push(...ranges);
1919
}
2020
}
2121
else if (ts.isFunctionDeclaration(node)) {
2222
if (node.name && ts.isIdentifier(node.name)) {
23-
bindings.push({
24-
range: _getStartEnd(node.name),
25-
});
23+
bindings.push(_getStartEnd(node.name));
2624
}
2725
}
2826
else if (ts.isClassDeclaration(node)) {
2927
if (node.name) {
30-
bindings.push({
31-
range: _getStartEnd(node.name),
32-
});
28+
bindings.push(_getStartEnd(node.name));
3329
}
3430
}
3531
else if (ts.isEnumDeclaration(node)) {
36-
bindings.push({
37-
range: _getStartEnd(node.name),
38-
});
32+
bindings.push(_getStartEnd(node.name));
3933
}
4034

4135
if (ts.isImportDeclaration(node)) {
@@ -45,38 +39,40 @@ export function parseBindingRanges(ts: typeof import('typescript'), ast: ts.Sour
4539
const { name, namedBindings } = node.importClause;
4640

4741
if (name) {
48-
bindings.push({
49-
range: _getStartEnd(name),
50-
moduleName,
51-
isDefaultImport: true,
52-
});
42+
if (componentExtsensions.some(ext => moduleName.endsWith(ext))) {
43+
components.push(_getStartEnd(name));
44+
}
5345
}
5446
if (namedBindings) {
5547
if (ts.isNamedImports(namedBindings)) {
5648
for (const element of namedBindings.elements) {
5749
if (element.isTypeOnly) {
5850
continue;
5951
}
60-
bindings.push({
61-
range: _getStartEnd(element.name),
62-
moduleName,
63-
isDefaultImport: element.propertyName?.text === 'default',
64-
});
52+
if (
53+
element.propertyName
54+
&& _getNodeText(element.propertyName) === 'default'
55+
&& componentExtsensions.some(ext => moduleName.endsWith(ext))
56+
) {
57+
components.push(_getStartEnd(element.name));
58+
}
59+
else {
60+
bindings.push(_getStartEnd(element.name));
61+
}
6562
}
6663
}
6764
else {
68-
bindings.push({
69-
range: _getStartEnd(namedBindings.name),
70-
moduleName,
71-
isNamespace: true,
72-
});
65+
bindings.push(_getStartEnd(namedBindings.name));
7366
}
7467
}
7568
}
7669
}
7770
});
7871

79-
return bindings;
72+
return {
73+
bindings,
74+
components,
75+
};
8076

8177
function _getStartEnd(node: ts.Node) {
8278
return getStartEnd(ts, node, ast);

packages/language-core/lib/plugins/vue-tsx.ts

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function useCodegen(
7474

7575
const getScriptRanges = computed(() =>
7676
sfc.script && validLangs.has(sfc.script.lang)
77-
? parseScriptRanges(ts, sfc.script.ast, !!sfc.scriptSetup)
77+
? parseScriptRanges(ts, sfc.script.ast, getResolvedOptions())
7878
: undefined
7979
);
8080

@@ -88,27 +88,13 @@ function useCodegen(
8888
const names = new Set<string>();
8989
const scriptSetupRanges = getScriptSetupRanges();
9090
if (sfc.scriptSetup && scriptSetupRanges) {
91-
for (const { range, moduleName, isDefaultImport, isNamespace } of scriptSetupRanges.bindings) {
92-
if (
93-
moduleName
94-
&& isDefaultImport
95-
&& !isNamespace
96-
&& ctx.vueCompilerOptions.extensions.some(ext => moduleName.endsWith(ext))
97-
) {
98-
names.add(sfc.scriptSetup.content.slice(range.start, range.end));
99-
}
91+
for (const range of scriptSetupRanges.components) {
92+
names.add(sfc.scriptSetup.content.slice(range.start, range.end));
10093
}
10194
const scriptRange = getScriptRanges();
10295
if (sfc.script && scriptRange) {
103-
for (const { range, moduleName, isDefaultImport, isNamespace } of scriptRange.bindings) {
104-
if (
105-
moduleName
106-
&& isDefaultImport
107-
&& !isNamespace
108-
&& ctx.vueCompilerOptions.extensions.some(ext => moduleName.endsWith(ext))
109-
) {
110-
names.add(sfc.script.content.slice(range.start, range.end));
111-
}
96+
for (const range of scriptRange.components) {
97+
names.add(sfc.script.content.slice(range.start, range.end));
11298
}
11399
}
114100
}
@@ -214,13 +200,13 @@ function useCodegen(
214200
if (!sfc.scriptSetup || !scriptSetupRanges) {
215201
return allVars;
216202
}
217-
for (const { range } of scriptSetupRanges.bindings) {
203+
for (const range of scriptSetupRanges.bindings) {
218204
const name = sfc.scriptSetup.content.slice(range.start, range.end);
219205
allVars.add(name);
220206
}
221207
const scriptRanges = getScriptRanges();
222208
if (sfc.script && scriptRanges) {
223-
for (const { range } of scriptRanges.bindings) {
209+
for (const range of scriptRanges.bindings) {
224210
const name = sfc.script.content.slice(range.start, range.end);
225211
allVars.add(name);
226212
}
@@ -276,6 +262,5 @@ function useCodegen(
276262
getGeneratedTemplate,
277263
getImportComponentNames,
278264
getSetupExposed,
279-
getSetupConsts,
280265
};
281266
}

packages/language-service/lib/plugins/vue-template.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ export function create(
685685
version++;
686686
})());
687687
}
688-
const scriptSetupRanges = tsCodegen.get(root.sfc)?.getScriptSetupRanges();
688+
const codegen = tsCodegen.get(root.sfc);
689689
const names = new Set<string>();
690690
const tags: html.ITagData[] = [];
691691

@@ -698,13 +698,19 @@ export function create(
698698
}
699699
}
700700

701-
for (const binding of scriptSetupRanges?.bindings ?? []) {
702-
const name = root.sfc.scriptSetup!.content.slice(binding.range.start, binding.range.end);
703-
if (tagNameCasing === TagNameCasing.Kebab) {
704-
names.add(hyphenateTag(name));
705-
}
706-
else {
707-
names.add(name);
701+
if (codegen) {
702+
for (
703+
const name of [
704+
...codegen.getImportComponentNames(),
705+
...codegen.getSetupExposed(),
706+
]
707+
) {
708+
if (tagNameCasing === TagNameCasing.Kebab) {
709+
names.add(hyphenateTag(name));
710+
}
711+
else {
712+
names.add(name);
713+
}
708714
}
709715
}
710716

0 commit comments

Comments
 (0)