@vue/language-core 3.0.0-alpha.0 → 3.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/codegen/codeFeatures.d.ts +5 -0
- package/lib/codegen/codeFeatures.js +5 -0
- package/lib/codegen/globalTypes.js +44 -30
- package/lib/codegen/localTypes.d.ts +2 -3
- package/lib/codegen/localTypes.js +5 -15
- package/lib/codegen/script/component.js +21 -9
- package/lib/codegen/script/context.d.ts +1 -1
- package/lib/codegen/script/context.js +1 -1
- package/lib/codegen/script/index.d.ts +1 -1
- package/lib/codegen/script/index.js +2 -15
- package/lib/codegen/script/scriptSetup.js +5 -16
- package/lib/codegen/script/src.js +4 -3
- package/lib/codegen/script/template.js +3 -5
- package/lib/codegen/template/context.d.ts +28 -18
- package/lib/codegen/template/context.js +87 -53
- package/lib/codegen/template/element.d.ts +2 -2
- package/lib/codegen/template/element.js +20 -30
- package/lib/codegen/template/elementChildren.d.ts +2 -2
- package/lib/codegen/template/elementChildren.js +4 -6
- package/lib/codegen/template/elementDirectives.js +3 -7
- package/lib/codegen/template/elementEvents.d.ts +3 -3
- package/lib/codegen/template/elementEvents.js +25 -18
- package/lib/codegen/template/elementProps.d.ts +2 -2
- package/lib/codegen/template/elementProps.js +8 -15
- package/lib/codegen/template/index.d.ts +1 -1
- package/lib/codegen/template/index.js +22 -11
- package/lib/codegen/template/interpolation.d.ts +1 -1
- package/lib/codegen/template/interpolation.js +52 -50
- package/lib/codegen/template/slotOutlet.js +2 -3
- package/lib/codegen/template/templateChild.d.ts +1 -1
- package/lib/codegen/template/templateChild.js +12 -46
- package/lib/codegen/template/vFor.js +5 -10
- package/lib/codegen/template/vIf.js +2 -10
- package/lib/codegen/template/vSlot.d.ts +1 -2
- package/lib/codegen/template/vSlot.js +111 -59
- package/lib/codegen/utils/index.d.ts +2 -3
- package/lib/codegen/utils/index.js +0 -16
- package/lib/languagePlugin.d.ts +1 -1
- package/lib/languagePlugin.js +1 -7
- package/lib/parsers/scriptRanges.d.ts +2 -3
- package/lib/parsers/scriptRanges.js +3 -10
- package/lib/parsers/scriptSetupRanges.js +27 -22
- package/lib/plugins/file-md.js +3 -0
- package/lib/plugins/vue-style-css.d.ts +3 -0
- package/lib/plugins/vue-style-css.js +18 -0
- package/lib/plugins/vue-template-inline-css.js +1 -1
- package/lib/plugins/vue-template-inline-ts.js +5 -2
- package/lib/plugins/vue-tsx.d.ts +27 -18
- package/lib/plugins/vue-tsx.js +32 -20
- package/lib/plugins.d.ts +1 -1
- package/lib/types.d.ts +2 -1
- package/lib/utils/shared.d.ts +0 -1
- package/lib/utils/shared.js +0 -4
- package/lib/utils/signals.d.ts +1 -0
- package/lib/utils/signals.js +11 -0
- package/lib/utils/ts.js +3 -4
- package/lib/virtualFile/computedSfc.js +6 -6
- package/package.json +6 -8
- package/lib/utils/vue2TemplateCompiler.d.ts +0 -2
- package/lib/utils/vue2TemplateCompiler.js +0 -89
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as CompilerDOM from '@vue/compiler-dom';
|
|
1
|
+
import type * as CompilerDOM from '@vue/compiler-dom';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
import type { Code, SfcBlock,
|
|
3
|
+
import type { Code, SfcBlock, VueCodeInformation } from '../../types';
|
|
4
4
|
export declare const newLine = "\n";
|
|
5
5
|
export declare const endOfLine = ";\n";
|
|
6
6
|
export declare const combineLastMapping: VueCodeInformation;
|
|
@@ -18,4 +18,3 @@ export declare function collectIdentifiers(ts: typeof import('typescript'), node
|
|
|
18
18
|
export declare function normalizeAttributeValue(node: CompilerDOM.TextNode): [string, number];
|
|
19
19
|
export declare function createTsAst(ts: typeof import('typescript'), astHolder: any, text: string): ts.SourceFile;
|
|
20
20
|
export declare function generateSfcBlockSection(block: SfcBlock, start: number, end: number, features: VueCodeInformation): Code;
|
|
21
|
-
export declare function generateSfcBlockAttrValue(src: SfcBlockAttr & object, text: string, features: VueCodeInformation): Generator<Code>;
|
|
@@ -6,7 +6,6 @@ exports.collectIdentifiers = collectIdentifiers;
|
|
|
6
6
|
exports.normalizeAttributeValue = normalizeAttributeValue;
|
|
7
7
|
exports.createTsAst = createTsAst;
|
|
8
8
|
exports.generateSfcBlockSection = generateSfcBlockSection;
|
|
9
|
-
exports.generateSfcBlockAttrValue = generateSfcBlockAttrValue;
|
|
10
9
|
const shared_1 = require("../../utils/shared");
|
|
11
10
|
exports.newLine = `\n`;
|
|
12
11
|
exports.endOfLine = `;${exports.newLine}`;
|
|
@@ -65,19 +64,4 @@ function generateSfcBlockSection(block, start, end, features) {
|
|
|
65
64
|
features,
|
|
66
65
|
];
|
|
67
66
|
}
|
|
68
|
-
function* generateSfcBlockAttrValue(src, text, features) {
|
|
69
|
-
const { offset, quotes } = src;
|
|
70
|
-
if (!quotes) {
|
|
71
|
-
yield [``, 'main', offset, { verification: true }];
|
|
72
|
-
}
|
|
73
|
-
yield [
|
|
74
|
-
`'${text}'`,
|
|
75
|
-
'main',
|
|
76
|
-
quotes ? offset - 1 : offset,
|
|
77
|
-
features
|
|
78
|
-
];
|
|
79
|
-
if (!quotes) {
|
|
80
|
-
yield [``, 'main', offset + text.length, { __combineOffset: 2 }];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
67
|
//# sourceMappingURL=index.js.map
|
package/lib/languagePlugin.d.ts
CHANGED
package/lib/languagePlugin.js
CHANGED
|
@@ -6,7 +6,6 @@ exports.getAllExtensions = getAllExtensions;
|
|
|
6
6
|
const language_core_1 = require("@volar/language-core");
|
|
7
7
|
const CompilerDOM = require("@vue/compiler-dom");
|
|
8
8
|
const plugins_1 = require("./plugins");
|
|
9
|
-
const CompilerVue2 = require("./utils/vue2TemplateCompiler");
|
|
10
9
|
const vueFile_1 = require("./virtualFile/vueFile");
|
|
11
10
|
const fileRegistries = [];
|
|
12
11
|
function getVueFileRegistry(key, plugins) {
|
|
@@ -38,12 +37,7 @@ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
|
|
|
38
37
|
function createVueLanguagePlugin(ts, compilerOptions, vueCompilerOptions, asFileName) {
|
|
39
38
|
const pluginContext = {
|
|
40
39
|
modules: {
|
|
41
|
-
'@vue/compiler-dom':
|
|
42
|
-
? {
|
|
43
|
-
...CompilerDOM,
|
|
44
|
-
compile: CompilerVue2.compile,
|
|
45
|
-
}
|
|
46
|
-
: CompilerDOM,
|
|
40
|
+
'@vue/compiler-dom': CompilerDOM,
|
|
47
41
|
typescript: ts,
|
|
48
42
|
},
|
|
49
43
|
compilerOptions,
|
|
@@ -2,18 +2,17 @@ import type * as ts from 'typescript';
|
|
|
2
2
|
import type { TextRange } from '../types';
|
|
3
3
|
export interface ScriptRanges extends ReturnType<typeof parseScriptRanges> {
|
|
4
4
|
}
|
|
5
|
-
export declare function parseScriptRanges(ts: typeof import('typescript'), ast: ts.SourceFile, hasScriptSetup: boolean
|
|
5
|
+
export declare function parseScriptRanges(ts: typeof import('typescript'), ast: ts.SourceFile, hasScriptSetup: boolean): {
|
|
6
6
|
exportDefault: (TextRange & {
|
|
7
7
|
expression: TextRange;
|
|
8
8
|
args: TextRange;
|
|
9
|
-
argsNode: ts.ObjectLiteralExpression
|
|
9
|
+
argsNode: ts.ObjectLiteralExpression;
|
|
10
10
|
componentsOption: TextRange | undefined;
|
|
11
11
|
componentsOptionNode: ts.ObjectLiteralExpression | undefined;
|
|
12
12
|
directivesOption: TextRange | undefined;
|
|
13
13
|
nameOption: TextRange | undefined;
|
|
14
14
|
inheritAttrsOption: string | undefined;
|
|
15
15
|
}) | undefined;
|
|
16
|
-
classBlockEnd: number | undefined;
|
|
17
16
|
bindings: {
|
|
18
17
|
range: TextRange;
|
|
19
18
|
moduleName?: string;
|
|
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseScriptRanges = parseScriptRanges;
|
|
4
4
|
const shared_1 = require("../utils/shared");
|
|
5
5
|
const scriptSetupRanges_1 = require("./scriptSetupRanges");
|
|
6
|
-
function parseScriptRanges(ts, ast, hasScriptSetup
|
|
6
|
+
function parseScriptRanges(ts, ast, hasScriptSetup) {
|
|
7
7
|
let exportDefault;
|
|
8
|
-
let classBlockEnd;
|
|
9
8
|
const bindings = hasScriptSetup ? (0, scriptSetupRanges_1.parseBindingRanges)(ts, ast) : [];
|
|
10
9
|
ts.forEachChild(ast, raw => {
|
|
11
10
|
if (ts.isExportAssignment(raw)) {
|
|
@@ -49,24 +48,18 @@ function parseScriptRanges(ts, ast, hasScriptSetup, withNode) {
|
|
|
49
48
|
..._getStartEnd(raw),
|
|
50
49
|
expression: _getStartEnd(node.expression),
|
|
51
50
|
args: _getStartEnd(obj),
|
|
52
|
-
argsNode:
|
|
51
|
+
argsNode: obj,
|
|
53
52
|
componentsOption: componentsOptionNode ? _getStartEnd(componentsOptionNode) : undefined,
|
|
54
|
-
componentsOptionNode
|
|
53
|
+
componentsOptionNode,
|
|
55
54
|
directivesOption: directivesOptionNode ? _getStartEnd(directivesOptionNode) : undefined,
|
|
56
55
|
nameOption: nameOptionNode ? _getStartEnd(nameOptionNode) : undefined,
|
|
57
56
|
inheritAttrsOption,
|
|
58
57
|
};
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
|
-
if (ts.isClassDeclaration(raw)
|
|
62
|
-
&& raw.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)
|
|
63
|
-
&& raw.modifiers?.some(mod => mod.kind === ts.SyntaxKind.DefaultKeyword)) {
|
|
64
|
-
classBlockEnd = raw.end - 1;
|
|
65
|
-
}
|
|
66
60
|
});
|
|
67
61
|
return {
|
|
68
62
|
exportDefault,
|
|
69
|
-
classBlockEnd,
|
|
70
63
|
bindings,
|
|
71
64
|
};
|
|
72
65
|
function _getStartEnd(node) {
|
|
@@ -26,24 +26,27 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
|
|
|
26
26
|
let foundNonImportExportNode = false;
|
|
27
27
|
let importSectionEndOffset = 0;
|
|
28
28
|
ts.forEachChild(ast, node => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
&& !isTypeExport
|
|
34
|
-
&& !ts.isEmptyStatement(node)
|
|
29
|
+
if (foundNonImportExportNode
|
|
30
|
+
|| ts.isImportDeclaration(node)
|
|
31
|
+
|| ts.isExportDeclaration(node)
|
|
32
|
+
|| ts.isEmptyStatement(node)
|
|
35
33
|
// fix https://github.com/vuejs/language-tools/issues/1223
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
|| ts.isImportEqualsDeclaration(node)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if ((ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node))
|
|
38
|
+
&& node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const commentRanges = ts.getLeadingCommentRanges(text, node.pos);
|
|
42
|
+
if (commentRanges?.length) {
|
|
43
|
+
const commentRange = commentRanges.sort((a, b) => a.pos - b.pos)[0];
|
|
44
|
+
importSectionEndOffset = commentRange.pos;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
importSectionEndOffset = (0, shared_1.getStartEnd)(ts, node, ast).start;
|
|
46
48
|
}
|
|
49
|
+
foundNonImportExportNode = true;
|
|
47
50
|
});
|
|
48
51
|
ts.forEachChild(ast, node => visitNode(node, [ast]));
|
|
49
52
|
const templateRefNames = new Set(useTemplateRef.map(ref => ref.name));
|
|
@@ -159,7 +162,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
|
|
|
159
162
|
defaultValue,
|
|
160
163
|
required,
|
|
161
164
|
isModel: isDefineModel,
|
|
162
|
-
comments:
|
|
165
|
+
comments: getClosestMultiLineCommentRange(ts, node, parents, ast),
|
|
163
166
|
argNode: options,
|
|
164
167
|
});
|
|
165
168
|
}
|
|
@@ -410,18 +413,20 @@ function getStatementRange(ts, parents, node, ast) {
|
|
|
410
413
|
}
|
|
411
414
|
return statementRange;
|
|
412
415
|
}
|
|
413
|
-
function
|
|
416
|
+
function getClosestMultiLineCommentRange(ts, node, parents, ast) {
|
|
414
417
|
for (let i = parents.length - 1; i >= 0; i--) {
|
|
415
418
|
if (ts.isStatement(node)) {
|
|
416
419
|
break;
|
|
417
420
|
}
|
|
418
421
|
node = parents[i];
|
|
419
422
|
}
|
|
420
|
-
const
|
|
421
|
-
|
|
423
|
+
const comment = ts.getLeadingCommentRanges(ast.text, node.pos)
|
|
424
|
+
?.reverse()
|
|
425
|
+
.find(range => range.kind === 3);
|
|
426
|
+
if (comment) {
|
|
422
427
|
return {
|
|
423
|
-
start:
|
|
424
|
-
end:
|
|
428
|
+
start: comment.pos,
|
|
429
|
+
end: comment.end,
|
|
425
430
|
};
|
|
426
431
|
}
|
|
427
432
|
}
|
package/lib/plugins/file-md.js
CHANGED
|
@@ -4,6 +4,7 @@ const language_core_1 = require("@volar/language-core");
|
|
|
4
4
|
const muggle_string_1 = require("muggle-string");
|
|
5
5
|
const buildMappings_1 = require("../utils/buildMappings");
|
|
6
6
|
const parseSfc_1 = require("../utils/parseSfc");
|
|
7
|
+
const frontmatterReg = /^---[\s\S]*?\n---(?:\r?\n|$)/;
|
|
7
8
|
const codeblockReg = /(`{3,})[\s\S]+?\1/g;
|
|
8
9
|
const inlineCodeblockReg = /`[^\n`]+?`/g;
|
|
9
10
|
const latexBlockReg = /(\${2,})[\s\S]+?\1/g;
|
|
@@ -28,6 +29,8 @@ const plugin = ({ vueCompilerOptions }) => {
|
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
content = content
|
|
32
|
+
// frontmatter
|
|
33
|
+
.replace(frontmatterReg, match => ' '.repeat(match.length))
|
|
31
34
|
// code block
|
|
32
35
|
.replace(codeblockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
|
|
33
36
|
// inline code block
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const css = require("css-tree");
|
|
4
|
+
const plugin = () => {
|
|
5
|
+
return {
|
|
6
|
+
version: 2.1,
|
|
7
|
+
compileSFCStyle(lang, style) {
|
|
8
|
+
if (lang === 'css' || lang === 'scss' || lang === 'sass' || lang === 'less') {
|
|
9
|
+
return css.parse(style, {
|
|
10
|
+
filename: 'test.' + lang,
|
|
11
|
+
positions: true,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.default = plugin;
|
|
18
|
+
//# sourceMappingURL=vue-style-css.js.map
|
|
@@ -21,7 +21,7 @@ const plugin = () => {
|
|
|
21
21
|
if (embeddedFile.id !== 'template_inline_css' || !sfc.template?.ast) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
embeddedFile.parentCodeId = 'template';
|
|
24
|
+
embeddedFile.parentCodeId = sfc.template.lang === 'md' ? 'root_tags' : 'template';
|
|
25
25
|
embeddedFile.content.push(...generate(sfc.template.ast));
|
|
26
26
|
},
|
|
27
27
|
};
|
|
@@ -37,14 +37,17 @@ const plugin = ctx => {
|
|
|
37
37
|
return result;
|
|
38
38
|
},
|
|
39
39
|
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
|
|
40
|
+
if (!embeddedFile.id.startsWith('template_inline_ts_')) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
40
43
|
// access template content to watch change
|
|
41
|
-
|
|
44
|
+
void sfc.template?.content;
|
|
42
45
|
const parsed = parseds.get(sfc);
|
|
43
46
|
if (parsed) {
|
|
44
47
|
const codes = parsed.get(embeddedFile.id);
|
|
45
48
|
if (codes) {
|
|
46
49
|
embeddedFile.content.push(...codes);
|
|
47
|
-
embeddedFile.parentCodeId = 'template';
|
|
50
|
+
embeddedFile.parentCodeId = sfc.template?.lang === 'md' ? 'root_tags' : 'template';
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
},
|
package/lib/plugins/vue-tsx.d.ts
CHANGED
|
@@ -4,14 +4,13 @@ export declare const tsCodegen: WeakMap<Sfc, {
|
|
|
4
4
|
exportDefault: (import("../types").TextRange & {
|
|
5
5
|
expression: import("../types").TextRange;
|
|
6
6
|
args: import("../types").TextRange;
|
|
7
|
-
argsNode: import("typescript").ObjectLiteralExpression
|
|
7
|
+
argsNode: import("typescript").ObjectLiteralExpression;
|
|
8
8
|
componentsOption: import("../types").TextRange | undefined;
|
|
9
9
|
componentsOptionNode: import("typescript").ObjectLiteralExpression | undefined;
|
|
10
10
|
directivesOption: import("../types").TextRange | undefined;
|
|
11
11
|
nameOption: import("../types").TextRange | undefined;
|
|
12
12
|
inheritAttrsOption: string | undefined;
|
|
13
13
|
}) | undefined;
|
|
14
|
-
classBlockEnd: number | undefined;
|
|
15
14
|
bindings: {
|
|
16
15
|
range: import("../types").TextRange;
|
|
17
16
|
moduleName?: string;
|
|
@@ -138,6 +137,17 @@ export declare const tsCodegen: WeakMap<Sfc, {
|
|
|
138
137
|
};
|
|
139
138
|
getGeneratedTemplate: () => {
|
|
140
139
|
codes: Code[];
|
|
140
|
+
currentInfo: {
|
|
141
|
+
ignoreError?: boolean;
|
|
142
|
+
expectError?: {
|
|
143
|
+
token: number;
|
|
144
|
+
node: import("@vue/compiler-dom").CommentNode;
|
|
145
|
+
};
|
|
146
|
+
generic?: {
|
|
147
|
+
content: string;
|
|
148
|
+
offset: number;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
141
151
|
codeFeatures: {
|
|
142
152
|
all: import("../types").VueCodeInformation;
|
|
143
153
|
none: import("../types").VueCodeInformation;
|
|
@@ -155,8 +165,10 @@ export declare const tsCodegen: WeakMap<Sfc, {
|
|
|
155
165
|
withoutHighlightAndNavigation: import("../types").VueCodeInformation;
|
|
156
166
|
withoutHighlightAndCompletion: import("../types").VueCodeInformation;
|
|
157
167
|
withoutHighlightAndCompletionAndNavigation: import("../types").VueCodeInformation;
|
|
168
|
+
withoutSemantic: import("../types").VueCodeInformation;
|
|
158
169
|
};
|
|
159
170
|
resolveCodeFeatures: (features: import("../types").VueCodeInformation) => import("../types").VueCodeInformation;
|
|
171
|
+
inVFor: boolean;
|
|
160
172
|
slots: {
|
|
161
173
|
name: string;
|
|
162
174
|
offset?: number;
|
|
@@ -170,10 +182,6 @@ export declare const tsCodegen: WeakMap<Sfc, {
|
|
|
170
182
|
}[];
|
|
171
183
|
dollarVars: Set<string>;
|
|
172
184
|
accessExternalVariables: Map<string, Set<number>>;
|
|
173
|
-
lastGenericComment: {
|
|
174
|
-
content: string;
|
|
175
|
-
offset: number;
|
|
176
|
-
} | undefined;
|
|
177
185
|
blockConditions: string[];
|
|
178
186
|
scopedClasses: {
|
|
179
187
|
source: string;
|
|
@@ -187,25 +195,26 @@ export declare const tsCodegen: WeakMap<Sfc, {
|
|
|
187
195
|
templateRefs: Map<string, {
|
|
188
196
|
typeExp: string;
|
|
189
197
|
offset: number;
|
|
190
|
-
}>;
|
|
198
|
+
}[]>;
|
|
191
199
|
currentComponent: {
|
|
192
200
|
ctxVar: string;
|
|
201
|
+
childTypes: string[];
|
|
193
202
|
used: boolean;
|
|
194
203
|
} | undefined;
|
|
195
204
|
singleRootElTypes: string[];
|
|
196
205
|
singleRootNodes: Set<import("@vue/compiler-dom").ElementNode | null>;
|
|
206
|
+
addTemplateRef(name: string, typeExp: string, offset: number): void;
|
|
197
207
|
accessExternalVariable(name: string, offset?: number): void;
|
|
198
|
-
hasLocalVariable
|
|
199
|
-
addLocalVariable
|
|
200
|
-
removeLocalVariable
|
|
201
|
-
getInternalVariable
|
|
202
|
-
getHoistVariable
|
|
203
|
-
generateHoistVariables
|
|
204
|
-
generateConditionGuards
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
generateAutoImportCompletion: () => Generator<Code>;
|
|
208
|
+
hasLocalVariable(name: string): boolean;
|
|
209
|
+
addLocalVariable(name: string): void;
|
|
210
|
+
removeLocalVariable(name: string): void;
|
|
211
|
+
getInternalVariable(): string;
|
|
212
|
+
getHoistVariable(originalVar: string): string;
|
|
213
|
+
generateHoistVariables(): Generator<string, void, unknown>;
|
|
214
|
+
generateConditionGuards(): Generator<string, void, unknown>;
|
|
215
|
+
generateAutoImportCompletion(): Generator<Code>;
|
|
216
|
+
enter(node: import("@vue/compiler-dom").RootNode | import("@vue/compiler-dom").TemplateChildNode | import("@vue/compiler-dom").SimpleExpressionNode): boolean;
|
|
217
|
+
exit(): Generator<Code>;
|
|
209
218
|
} | undefined;
|
|
210
219
|
}>;
|
|
211
220
|
declare const plugin: VueLanguagePlugin;
|
package/lib/plugins/vue-tsx.js
CHANGED
|
@@ -12,6 +12,7 @@ const vueCompilerOptions_1 = require("../parsers/vueCompilerOptions");
|
|
|
12
12
|
const signals_1 = require("../utils/signals");
|
|
13
13
|
const ts_1 = require("../utils/ts");
|
|
14
14
|
exports.tsCodegen = new WeakMap();
|
|
15
|
+
const validLangs = new Set(['js', 'jsx', 'ts', 'tsx']);
|
|
15
16
|
const plugin = ctx => {
|
|
16
17
|
let appendedGlobalTypes = false;
|
|
17
18
|
return {
|
|
@@ -22,11 +23,10 @@ const plugin = ctx => {
|
|
|
22
23
|
],
|
|
23
24
|
getEmbeddedCodes(fileName, sfc) {
|
|
24
25
|
const codegen = useCodegen(fileName, sfc);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return files;
|
|
26
|
+
return [{
|
|
27
|
+
id: 'script_' + codegen.getLang(),
|
|
28
|
+
lang: codegen.getLang(),
|
|
29
|
+
}];
|
|
30
30
|
},
|
|
31
31
|
resolveEmbeddedCode(fileName, sfc, embeddedFile) {
|
|
32
32
|
if (/script_(js|jsx|ts|tsx)/.test(embeddedFile.id)) {
|
|
@@ -53,11 +53,23 @@ const plugin = ctx => {
|
|
|
53
53
|
exports.default = plugin;
|
|
54
54
|
function createTsx(fileName, sfc, ctx, appendGlobalTypes) {
|
|
55
55
|
const ts = ctx.modules.typescript;
|
|
56
|
+
const getRawLang = (0, alien_signals_1.computed)(() => {
|
|
57
|
+
if (sfc.script && sfc.scriptSetup) {
|
|
58
|
+
if (sfc.scriptSetup.lang !== 'js') {
|
|
59
|
+
return sfc.scriptSetup.lang;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return sfc.script.lang;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return sfc.scriptSetup?.lang ?? sfc.script?.lang;
|
|
66
|
+
});
|
|
56
67
|
const getLang = (0, alien_signals_1.computed)(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
const rawLang = getRawLang();
|
|
69
|
+
if (rawLang && validLangs.has(rawLang)) {
|
|
70
|
+
return rawLang;
|
|
71
|
+
}
|
|
72
|
+
return 'ts';
|
|
61
73
|
});
|
|
62
74
|
const getResolvedOptions = (0, alien_signals_1.computed)(() => {
|
|
63
75
|
const options = (0, vueCompilerOptions_1.parseVueCompilerOptions)(sfc.comments);
|
|
@@ -68,13 +80,13 @@ function createTsx(fileName, sfc, ctx, appendGlobalTypes) {
|
|
|
68
80
|
}
|
|
69
81
|
return ctx.vueCompilerOptions;
|
|
70
82
|
});
|
|
71
|
-
const getScriptRanges = (0, alien_signals_1.computed)(() => sfc.script
|
|
72
|
-
? (0, scriptRanges_1.parseScriptRanges)(ts, sfc.script.ast, !!sfc.scriptSetup
|
|
83
|
+
const getScriptRanges = (0, alien_signals_1.computed)(() => sfc.script && validLangs.has(sfc.script.lang)
|
|
84
|
+
? (0, scriptRanges_1.parseScriptRanges)(ts, sfc.script.ast, !!sfc.scriptSetup)
|
|
73
85
|
: undefined);
|
|
74
|
-
const getScriptSetupRanges = (0, alien_signals_1.computed)(() => sfc.scriptSetup
|
|
86
|
+
const getScriptSetupRanges = (0, alien_signals_1.computed)(() => sfc.scriptSetup && validLangs.has(sfc.scriptSetup.lang)
|
|
75
87
|
? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, sfc.scriptSetup.ast, getResolvedOptions())
|
|
76
88
|
: undefined);
|
|
77
|
-
const getSetupBindingNames = (0, signals_1.computedSet)((
|
|
89
|
+
const getSetupBindingNames = (0, signals_1.computedSet)(() => {
|
|
78
90
|
const newNames = new Set();
|
|
79
91
|
const bindings = getScriptSetupRanges()?.bindings;
|
|
80
92
|
if (sfc.scriptSetup && bindings) {
|
|
@@ -83,8 +95,8 @@ function createTsx(fileName, sfc, ctx, appendGlobalTypes) {
|
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
return newNames;
|
|
86
|
-
})
|
|
87
|
-
const getSetupImportComponentNames = (0, signals_1.computedSet)((
|
|
98
|
+
});
|
|
99
|
+
const getSetupImportComponentNames = (0, signals_1.computedSet)(() => {
|
|
88
100
|
const newNames = new Set();
|
|
89
101
|
const bindings = getScriptSetupRanges()?.bindings;
|
|
90
102
|
if (sfc.scriptSetup && bindings) {
|
|
@@ -98,21 +110,21 @@ function createTsx(fileName, sfc, ctx, appendGlobalTypes) {
|
|
|
98
110
|
}
|
|
99
111
|
}
|
|
100
112
|
return newNames;
|
|
101
|
-
})
|
|
102
|
-
const getSetupDestructuredPropNames = (0, signals_1.computedSet)((
|
|
113
|
+
});
|
|
114
|
+
const getSetupDestructuredPropNames = (0, signals_1.computedSet)(() => {
|
|
103
115
|
const newNames = new Set(getScriptSetupRanges()?.defineProps?.destructured?.keys());
|
|
104
116
|
const rest = getScriptSetupRanges()?.defineProps?.destructuredRest;
|
|
105
117
|
if (rest) {
|
|
106
118
|
newNames.add(rest);
|
|
107
119
|
}
|
|
108
120
|
return newNames;
|
|
109
|
-
})
|
|
110
|
-
const getSetupTemplateRefNames = (0, signals_1.computedSet)((
|
|
121
|
+
});
|
|
122
|
+
const getSetupTemplateRefNames = (0, signals_1.computedSet)(() => {
|
|
111
123
|
const newNames = new Set(getScriptSetupRanges()?.useTemplateRef
|
|
112
124
|
.map(({ name }) => name)
|
|
113
125
|
.filter(name => name !== undefined));
|
|
114
126
|
return newNames;
|
|
115
|
-
})
|
|
127
|
+
});
|
|
116
128
|
const setupHasDefineSlots = (0, alien_signals_1.computed)(() => !!getScriptSetupRanges()?.defineSlots);
|
|
117
129
|
const getSetupSlotsAssignName = (0, alien_signals_1.computed)(() => getScriptSetupRanges()?.defineSlots?.name);
|
|
118
130
|
const getSetupPropsAssignName = (0, alien_signals_1.computed)(() => getScriptSetupRanges()?.defineProps?.name);
|
package/lib/plugins.d.ts
CHANGED
package/lib/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type { SFCParseResult } from '@vue/compiler-sfc';
|
|
|
8
8
|
export { VueEmbeddedCode };
|
|
9
9
|
export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' | 'plugins'>> & {
|
|
10
10
|
strictTemplates?: boolean;
|
|
11
|
-
target?: 'auto' |
|
|
11
|
+
target?: 'auto' | 3 | 3.3 | 3.5 | 3.6 | 99 | number;
|
|
12
12
|
plugins?: string[];
|
|
13
13
|
};
|
|
14
14
|
export interface VueCodeInformation extends CodeInformation {
|
|
@@ -23,6 +23,7 @@ export interface VueCompilerOptions {
|
|
|
23
23
|
vitePressExtensions: string[];
|
|
24
24
|
petiteVueExtensions: string[];
|
|
25
25
|
jsxSlots: boolean;
|
|
26
|
+
strictSlotChildren: boolean;
|
|
26
27
|
strictVModel: boolean;
|
|
27
28
|
checkUnknownProps: boolean;
|
|
28
29
|
checkUnknownEvents: boolean;
|
package/lib/utils/shared.d.ts
CHANGED
|
@@ -2,6 +2,5 @@ import type * as ts from 'typescript';
|
|
|
2
2
|
import type { TextRange } from '../types';
|
|
3
3
|
export { hyphenate as hyphenateTag } from '@vue/shared';
|
|
4
4
|
export declare function hyphenateAttr(str: string): string;
|
|
5
|
-
export declare function getSlotsPropertyName(vueVersion: number): "$scopedSlots" | "$slots";
|
|
6
5
|
export declare function getStartEnd(ts: typeof import('typescript'), node: ts.Node, ast: ts.SourceFile): TextRange;
|
|
7
6
|
export declare function getNodeText(ts: typeof import('typescript'), node: ts.Node, ast: ts.SourceFile): string;
|
package/lib/utils/shared.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hyphenateTag = void 0;
|
|
4
4
|
exports.hyphenateAttr = hyphenateAttr;
|
|
5
|
-
exports.getSlotsPropertyName = getSlotsPropertyName;
|
|
6
5
|
exports.getStartEnd = getStartEnd;
|
|
7
6
|
exports.getNodeText = getNodeText;
|
|
8
7
|
const shared_1 = require("@vue/shared");
|
|
@@ -16,9 +15,6 @@ function hyphenateAttr(str) {
|
|
|
16
15
|
}
|
|
17
16
|
return hyphencase;
|
|
18
17
|
}
|
|
19
|
-
function getSlotsPropertyName(vueVersion) {
|
|
20
|
-
return vueVersion < 3 ? '$scopedSlots' : '$slots';
|
|
21
|
-
}
|
|
22
18
|
function getStartEnd(ts, node, ast) {
|
|
23
19
|
return {
|
|
24
20
|
start: ts.getTokenPosOfNode(node, ast),
|
package/lib/utils/signals.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export declare function computedArray<I, O>(arr: () => I[], getGetter: (item: () => I, index: number) => () => O): readonly Readonly<O>[];
|
|
2
2
|
export declare function computedSet<T>(source: () => Set<T>): () => Set<T>;
|
|
3
|
+
export declare function computedItems<T>(source: () => T[], compareFn: (oldItem: T, newItem: T) => boolean): () => T[];
|
package/lib/utils/signals.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.computedArray = computedArray;
|
|
4
4
|
exports.computedSet = computedSet;
|
|
5
|
+
exports.computedItems = computedItems;
|
|
5
6
|
const alien_signals_1 = require("alien-signals");
|
|
6
7
|
function computedArray(arr, getGetter) {
|
|
7
8
|
const length = (0, alien_signals_1.computed)(() => arr().length);
|
|
@@ -51,4 +52,14 @@ function computedSet(source) {
|
|
|
51
52
|
return newValue;
|
|
52
53
|
});
|
|
53
54
|
}
|
|
55
|
+
function computedItems(source, compareFn) {
|
|
56
|
+
return (0, alien_signals_1.computed)(oldArr => {
|
|
57
|
+
oldArr ??= [];
|
|
58
|
+
const newArr = source();
|
|
59
|
+
if (oldArr.length === newArr.length && oldArr.every((item, index) => compareFn(item, newArr[index]))) {
|
|
60
|
+
return oldArr;
|
|
61
|
+
}
|
|
62
|
+
return newArr;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
54
65
|
//# sourceMappingURL=signals.js.map
|
package/lib/utils/ts.js
CHANGED
|
@@ -131,7 +131,7 @@ class CompilerOptionsResolver {
|
|
|
131
131
|
break;
|
|
132
132
|
case 'plugins':
|
|
133
133
|
this.plugins = (options.plugins ?? [])
|
|
134
|
-
.
|
|
134
|
+
.flatMap((pluginPath) => {
|
|
135
135
|
try {
|
|
136
136
|
const resolvedPath = resolvePath(pluginPath, rootDir);
|
|
137
137
|
if (resolvedPath) {
|
|
@@ -217,6 +217,7 @@ function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = f
|
|
|
217
217
|
vitePressExtensions: [],
|
|
218
218
|
petiteVueExtensions: [],
|
|
219
219
|
jsxSlots: false,
|
|
220
|
+
strictSlotChildren: strictTemplates,
|
|
220
221
|
strictVModel: strictTemplates,
|
|
221
222
|
checkUnknownProps: strictTemplates,
|
|
222
223
|
checkUnknownEvents: strictTemplates,
|
|
@@ -238,9 +239,7 @@ function getDefaultCompilerOptions(target = 99, lib = 'vue', strictTemplates = f
|
|
|
238
239
|
],
|
|
239
240
|
dataAttributes: [],
|
|
240
241
|
htmlAttributes: ['aria-*'],
|
|
241
|
-
optionsWrapper:
|
|
242
|
-
? [`(await import('${lib}')).defineComponent(`, `)`]
|
|
243
|
-
: [`(await import('${lib}')).default.extend(`, `)`],
|
|
242
|
+
optionsWrapper: [`(await import('${lib}')).defineComponent(`, `)`],
|
|
244
243
|
macros: {
|
|
245
244
|
defineProps: ['defineProps'],
|
|
246
245
|
defineSlots: ['defineSlots'],
|
|
@@ -7,9 +7,9 @@ const parseCssVars_1 = require("../utils/parseCssVars");
|
|
|
7
7
|
const signals_1 = require("../utils/signals");
|
|
8
8
|
function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
9
9
|
const getUntrackedSnapshot = () => {
|
|
10
|
-
(0, alien_signals_1.
|
|
10
|
+
const pausedSub = (0, alien_signals_1.setCurrentSub)(undefined);
|
|
11
11
|
const res = getSnapshot();
|
|
12
|
-
(0, alien_signals_1.
|
|
12
|
+
(0, alien_signals_1.setCurrentSub)(pausedSub);
|
|
13
13
|
return res;
|
|
14
14
|
};
|
|
15
15
|
const getContent = (0, alien_signals_1.computed)(() => {
|
|
@@ -88,8 +88,8 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
88
88
|
const base = computedSfcBlock('style_' + i, 'css', getBlock);
|
|
89
89
|
const getModule = computedAttrValue('__module', base, getBlock);
|
|
90
90
|
const getScoped = (0, alien_signals_1.computed)(() => !!getBlock().scoped);
|
|
91
|
-
const getCssVars = (0,
|
|
92
|
-
const getClassNames = (0,
|
|
91
|
+
const getCssVars = (0, signals_1.computedItems)(() => [...(0, parseCssVars_1.parseCssVars)(base.content)], (oldItem, newItem) => oldItem.text === newItem.text && oldItem.offset === newItem.offset);
|
|
92
|
+
const getClassNames = (0, signals_1.computedItems)(() => [...(0, parseCssClassNames_1.parseCssClassNames)(base.content)], (oldItem, newItem) => oldItem.text === newItem.text && oldItem.offset === newItem.offset);
|
|
93
93
|
return () => mergeObject(base, {
|
|
94
94
|
get module() { return getModule(); },
|
|
95
95
|
get scoped() { return getScoped(); },
|
|
@@ -127,9 +127,9 @@ function computedSfc(ts, plugins, fileName, getSnapshot, getParseResult) {
|
|
|
127
127
|
if (cache?.plugin.updateSFCTemplate) {
|
|
128
128
|
const change = getUntrackedSnapshot().getChangeRange(cache.snapshot);
|
|
129
129
|
if (change) {
|
|
130
|
-
(0, alien_signals_1.
|
|
130
|
+
const pausedSub = (0, alien_signals_1.setCurrentSub)(undefined);
|
|
131
131
|
const templateOffset = base.startTagEnd;
|
|
132
|
-
(0, alien_signals_1.
|
|
132
|
+
(0, alien_signals_1.setCurrentSub)(pausedSub);
|
|
133
133
|
const newText = getUntrackedSnapshot().getText(change.span.start, change.span.start + change.newLength);
|
|
134
134
|
const newResult = cache.plugin.updateSFCTemplate(cache.result, {
|
|
135
135
|
start: change.span.start - templateOffset,
|