@vue/language-core 2.0.6 → 2.0.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/generators/globalTypes.d.ts +2 -0
- package/lib/generators/globalTypes.js +135 -0
- package/lib/generators/inlineCss.d.ts +3 -0
- package/lib/generators/inlineCss.js +37 -0
- package/lib/generators/script.js +65 -144
- package/lib/generators/template.d.ts +13 -3
- package/lib/generators/template.js +130 -166
- package/lib/generators/utils.d.ts +1 -2
- package/lib/generators/utils.js +1 -5
- package/lib/languageModule.d.ts +7 -2
- package/lib/languageModule.js +40 -23
- package/lib/parsers/scriptSetupRanges.d.ts +1 -0
- package/lib/parsers/scriptSetupRanges.js +1 -0
- package/lib/plugins/file-vue.js +1 -1
- package/lib/plugins/vue-sfc-styles.js +37 -11
- package/lib/plugins/vue-template-inline-css.d.ts +3 -0
- package/lib/plugins/vue-template-inline-css.js +23 -0
- package/lib/plugins/vue-template-inline-ts.d.ts +3 -0
- package/lib/plugins/vue-template-inline-ts.js +151 -0
- package/lib/plugins/vue-tsx.d.ts +1 -4
- package/lib/plugins/vue-tsx.js +6 -75
- package/lib/plugins.js +9 -3
- package/lib/utils/transform.js +6 -3
- package/lib/utils/ts.d.ts +1 -1
- package/lib/utils/ts.js +9 -5
- package/lib/utils/vue2TemplateCompiler.js +2 -2
- package/lib/virtualFile/computedFiles.js +1 -10
- package/lib/virtualFile/computedMappings.js +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.forEachElementNode = exports.parseVForNode = exports.parseInterpolationNode = exports.isCompoundExpression = exports.createTsAst = exports.generate = void 0;
|
|
4
4
|
const language_core_1 = require("@volar/language-core");
|
|
5
5
|
const CompilerDOM = require("@vue/compiler-dom");
|
|
6
6
|
const shared_1 = require("@vue/shared");
|
|
@@ -36,15 +36,6 @@ const presetInfos = {
|
|
|
36
36
|
slotNameExport: (0, utils_1.disableAllFeatures)({ semantic: { shouldHighlight: () => false }, verification: true, navigation: true, /* __navigationCodeLens: true */ }),
|
|
37
37
|
refAttr: (0, utils_1.disableAllFeatures)({ navigation: true }),
|
|
38
38
|
};
|
|
39
|
-
const formatBrackets = {
|
|
40
|
-
normal: ['`${', '}`;'],
|
|
41
|
-
// fix https://github.com/vuejs/language-tools/issues/3572
|
|
42
|
-
params: ['(', ') => {}'],
|
|
43
|
-
// fix https://github.com/vuejs/language-tools/issues/1210
|
|
44
|
-
// fix https://github.com/vuejs/language-tools/issues/2305
|
|
45
|
-
curly: ['0 +', '+ 0;'],
|
|
46
|
-
event: ['() => ', ';'],
|
|
47
|
-
};
|
|
48
39
|
const validTsVarReg = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
|
|
49
40
|
const colonReg = /:/g;
|
|
50
41
|
// @ts-ignore
|
|
@@ -64,41 +55,39 @@ const transformContext = {
|
|
|
64
55
|
};
|
|
65
56
|
function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGenerateScopedClasses, stylesScopedClasses, hasScriptSetupSlots, slotsAssignName, propsAssignName, codegenStack) {
|
|
66
57
|
const processDirectiveComment = (code) => {
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
58
|
+
if (typeof code !== 'string') {
|
|
59
|
+
if (ignoreError) {
|
|
60
|
+
const data = code[3];
|
|
61
|
+
if (data.verification) {
|
|
62
|
+
code[3] = {
|
|
63
|
+
...data,
|
|
64
|
+
verification: false,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
74
67
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
if (expectErrorToken) {
|
|
69
|
+
const token = expectErrorToken;
|
|
70
|
+
const data = code[3];
|
|
71
|
+
if (data.verification) {
|
|
72
|
+
code[3] = {
|
|
73
|
+
...data,
|
|
74
|
+
verification: {
|
|
75
|
+
shouldReport: () => {
|
|
76
|
+
token.errors++;
|
|
77
|
+
return false;
|
|
78
|
+
},
|
|
86
79
|
},
|
|
87
|
-
}
|
|
88
|
-
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
89
82
|
}
|
|
83
|
+
code[3].structure = false;
|
|
84
|
+
code[3].format = false;
|
|
90
85
|
}
|
|
91
86
|
return code;
|
|
92
87
|
};
|
|
93
88
|
const _ts = codegenStack
|
|
94
|
-
? (code) => [
|
|
95
|
-
: (code) => [
|
|
96
|
-
const _tsFormat = codegenStack
|
|
97
|
-
? (code) => ['tsFormat', code, (0, utils_1.getStack)()]
|
|
98
|
-
: (code) => ['tsFormat', code, ''];
|
|
99
|
-
const _inlineCss = codegenStack
|
|
100
|
-
? (code) => ['inlineCss', code, (0, utils_1.getStack)()]
|
|
101
|
-
: (code) => ['inlineCss', code, ''];
|
|
89
|
+
? (code) => [processDirectiveComment(code), (0, utils_1.getStack)()]
|
|
90
|
+
: (code) => [processDirectiveComment(code), ''];
|
|
102
91
|
const nativeTags = new Set(vueCompilerOptions.nativeTags);
|
|
103
92
|
const slots = new Map();
|
|
104
93
|
const slotExps = new Map();
|
|
@@ -142,7 +131,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
142
131
|
if (!template.ast) {
|
|
143
132
|
return tagOffsetsMap;
|
|
144
133
|
}
|
|
145
|
-
for (const node of
|
|
134
|
+
for (const node of forEachElementNode(template.ast)) {
|
|
146
135
|
if (node.tag === 'slot') {
|
|
147
136
|
// ignore
|
|
148
137
|
}
|
|
@@ -243,11 +232,13 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
243
232
|
function* generatePreResolveComponents() {
|
|
244
233
|
yield _ts(`let __VLS_resolvedLocalAndGlobalComponents!: {}\n`);
|
|
245
234
|
for (const [tagName] of tagOffsetsMap) {
|
|
246
|
-
if (nativeTags.has(tagName))
|
|
235
|
+
if (nativeTags.has(tagName)) {
|
|
247
236
|
continue;
|
|
237
|
+
}
|
|
248
238
|
const isNamespacedTag = tagName.indexOf('.') >= 0;
|
|
249
|
-
if (isNamespacedTag)
|
|
239
|
+
if (isNamespacedTag) {
|
|
250
240
|
continue;
|
|
241
|
+
}
|
|
251
242
|
yield _ts(`& __VLS_WithComponent<'${getCanonicalComponentName(tagName)}', typeof __VLS_localComponents, `);
|
|
252
243
|
// order is important: https://github.com/vuejs/language-tools/issues/2010
|
|
253
244
|
yield _ts(`"${(0, shared_1.capitalize)((0, shared_1.camelize)(tagName))}", `);
|
|
@@ -350,24 +341,8 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
350
341
|
}
|
|
351
342
|
else if (node.type === CompilerDOM.NodeTypes.INTERPOLATION) {
|
|
352
343
|
// {{ ... }}
|
|
353
|
-
|
|
354
|
-
let start = node.content.loc.start.offset;
|
|
355
|
-
let leftCharacter;
|
|
356
|
-
let rightCharacter;
|
|
357
|
-
// fix https://github.com/vuejs/language-tools/issues/1787
|
|
358
|
-
while ((leftCharacter = template.content.substring(start - 1, start)).trim() === '' && leftCharacter.length) {
|
|
359
|
-
start--;
|
|
360
|
-
content = leftCharacter + content;
|
|
361
|
-
}
|
|
362
|
-
while ((rightCharacter = template.content.substring(start + content.length, start + content.length + 1)).trim() === '' && rightCharacter.length) {
|
|
363
|
-
content = content + rightCharacter;
|
|
364
|
-
}
|
|
344
|
+
const [content, start] = parseInterpolationNode(node, template.content);
|
|
365
345
|
yield* generateInterpolation(content, node.content.loc, start, presetInfos.all, '(', ');\n');
|
|
366
|
-
const lines = content.split('\n');
|
|
367
|
-
yield* generateTsFormat(content, start, lines.length <= 1 ? formatBrackets.curly : [
|
|
368
|
-
lines[0].trim() === '' ? '(' : formatBrackets.curly[0],
|
|
369
|
-
lines[lines.length - 1].trim() === '' ? ')' : formatBrackets.curly[1],
|
|
370
|
-
]);
|
|
371
346
|
}
|
|
372
347
|
else if (node.type === CompilerDOM.NodeTypes.IF) {
|
|
373
348
|
// v-if / v-else-if / v-else
|
|
@@ -385,12 +360,15 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
385
360
|
let originalBlockConditionsLength = blockConditions.length;
|
|
386
361
|
for (let i = 0; i < node.branches.length; i++) {
|
|
387
362
|
const branch = node.branches[i];
|
|
388
|
-
if (i === 0)
|
|
363
|
+
if (i === 0) {
|
|
389
364
|
yield _ts('if');
|
|
390
|
-
|
|
365
|
+
}
|
|
366
|
+
else if (branch.condition) {
|
|
391
367
|
yield _ts('else if');
|
|
392
|
-
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
393
370
|
yield _ts('else');
|
|
371
|
+
}
|
|
394
372
|
let addedBlockCondition = false;
|
|
395
373
|
if (branch.condition?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
396
374
|
yield _ts(` `);
|
|
@@ -398,7 +376,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
398
376
|
blockConditions.push((0, language_core_1.toString)([...generateInterpolation(branch.condition.content, branch.condition.loc, undefined, undefined, '(', ')')]
|
|
399
377
|
.map(code => code[1])));
|
|
400
378
|
addedBlockCondition = true;
|
|
401
|
-
yield* generateTsFormat(branch.condition.content, branch.condition.loc.start.offset, formatBrackets.normal);
|
|
402
379
|
}
|
|
403
380
|
yield _ts(` {\n`);
|
|
404
381
|
let prev;
|
|
@@ -416,18 +393,17 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
416
393
|
blockConditions.length = originalBlockConditionsLength;
|
|
417
394
|
}
|
|
418
395
|
function* generateVFor(node, parentEl, componentCtxVar) {
|
|
419
|
-
const { source
|
|
420
|
-
const
|
|
421
|
-
const leftExpressionText = leftExpressionRange ? node.loc.source.substring(leftExpressionRange.start - node.loc.start.offset, leftExpressionRange.end - node.loc.start.offset) : undefined;
|
|
396
|
+
const { source } = node.parseResult;
|
|
397
|
+
const { leftExpressionRange, leftExpressionText } = parseVForNode(node);
|
|
422
398
|
const forBlockVars = [];
|
|
423
399
|
yield _ts(`for (const [`);
|
|
424
400
|
if (leftExpressionRange && leftExpressionText) {
|
|
425
|
-
const collectAst = createTsAst(node.parseResult, `const [${leftExpressionText}]`);
|
|
401
|
+
const collectAst = createTsAst(ts, node.parseResult, `const [${leftExpressionText}]`);
|
|
426
402
|
(0, transform_1.collectVars)(ts, collectAst, collectAst, forBlockVars);
|
|
427
|
-
for (const varName of forBlockVars)
|
|
403
|
+
for (const varName of forBlockVars) {
|
|
428
404
|
localVars.set(varName, (localVars.get(varName) ?? 0) + 1);
|
|
405
|
+
}
|
|
429
406
|
yield _ts([leftExpressionText, 'template', leftExpressionRange.start, presetInfos.all]);
|
|
430
|
-
yield* generateTsFormat(leftExpressionText, leftExpressionRange.start, formatBrackets.normal);
|
|
431
407
|
}
|
|
432
408
|
yield _ts(`] of __VLS_getVForSourceType`);
|
|
433
409
|
if (source.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
@@ -443,10 +419,10 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
443
419
|
yield* generateExpectErrorComment();
|
|
444
420
|
yield* generateExtraAutoImport();
|
|
445
421
|
yield _ts('}\n');
|
|
446
|
-
yield* generateTsFormat(source.content, source.loc.start.offset, formatBrackets.normal);
|
|
447
422
|
}
|
|
448
|
-
for (const varName of forBlockVars)
|
|
423
|
+
for (const varName of forBlockVars) {
|
|
449
424
|
localVars.set(varName, localVars.get(varName) - 1);
|
|
425
|
+
}
|
|
450
426
|
}
|
|
451
427
|
function* generateElement(node, parentEl, componentCtxVar) {
|
|
452
428
|
yield _ts(`{\n`);
|
|
@@ -588,12 +564,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
588
564
|
for (const failedExp of propsFailedExps) {
|
|
589
565
|
yield* generateInterpolation(failedExp.loc.source, failedExp.loc, failedExp.loc.start.offset, presetInfos.all, '(', ')');
|
|
590
566
|
yield _ts(';\n');
|
|
591
|
-
const fb = formatBrackets.normal;
|
|
592
|
-
if (fb) {
|
|
593
|
-
yield* generateTsFormat(failedExp.loc.source, failedExp.loc.start.offset, fb);
|
|
594
|
-
}
|
|
595
567
|
}
|
|
596
|
-
yield* generateInlineCss(props);
|
|
597
568
|
const vScope = props.find(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && (prop.name === 'scope' || prop.name === 'data'));
|
|
598
569
|
let inScope = false;
|
|
599
570
|
let originalConditionsNum = blockConditions.length;
|
|
@@ -639,8 +610,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
639
610
|
yield _ts(`{\n`);
|
|
640
611
|
let hasProps = false;
|
|
641
612
|
if (slotDir?.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
642
|
-
|
|
643
|
-
const slotAst = createTsAst(slotDir, `(${slotDir.exp.content}) => {}`);
|
|
613
|
+
const slotAst = createTsAst(ts, slotDir, `(${slotDir.exp.content}) => {}`);
|
|
644
614
|
(0, transform_1.collectVars)(ts, slotAst, slotAst, slotBlockVars);
|
|
645
615
|
hasProps = true;
|
|
646
616
|
if (slotDir.exp.content.indexOf(':') === -1) {
|
|
@@ -806,35 +776,17 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
806
776
|
// https://github.com/johnsoncodehk/vue-tsc/issues/67
|
|
807
777
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, presetInfos.all, '$event => {(', ')}');
|
|
808
778
|
yield _ts(';\n');
|
|
809
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
810
779
|
}
|
|
811
780
|
}
|
|
812
781
|
}
|
|
813
782
|
function* appendExpressionNode(prop) {
|
|
814
783
|
if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
815
|
-
const ast = createTsAst(prop.exp, prop.exp.content);
|
|
816
|
-
let isCompoundExpression = true;
|
|
817
|
-
if (ast.statements.length === 1) {
|
|
818
|
-
ts.forEachChild(ast, child_1 => {
|
|
819
|
-
if (ts.isExpressionStatement(child_1)) {
|
|
820
|
-
ts.forEachChild(child_1, child_2 => {
|
|
821
|
-
if (ts.isArrowFunction(child_2)) {
|
|
822
|
-
isCompoundExpression = false;
|
|
823
|
-
}
|
|
824
|
-
else if (ts.isIdentifier(child_2)) {
|
|
825
|
-
isCompoundExpression = false;
|
|
826
|
-
}
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
else if (ts.isFunctionDeclaration(child_1)) {
|
|
830
|
-
isCompoundExpression = false;
|
|
831
|
-
}
|
|
832
|
-
});
|
|
833
|
-
}
|
|
834
784
|
let prefix = '(';
|
|
835
785
|
let suffix = ')';
|
|
836
786
|
let isFirstMapping = true;
|
|
837
|
-
|
|
787
|
+
const ast = createTsAst(ts, prop.exp, prop.exp.content);
|
|
788
|
+
const _isCompoundExpression = isCompoundExpression(ts, ast);
|
|
789
|
+
if (_isCompoundExpression) {
|
|
838
790
|
yield _ts('$event => {\n');
|
|
839
791
|
localVars.set('$event', (localVars.get('$event') ?? 0) + 1);
|
|
840
792
|
prefix = '';
|
|
@@ -844,19 +796,18 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
844
796
|
}
|
|
845
797
|
}
|
|
846
798
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, () => {
|
|
847
|
-
if (
|
|
799
|
+
if (_isCompoundExpression && isFirstMapping) {
|
|
848
800
|
isFirstMapping = false;
|
|
849
801
|
return presetInfos.allWithHiddenParam;
|
|
850
802
|
}
|
|
851
803
|
return presetInfos.all;
|
|
852
804
|
}, prefix, suffix);
|
|
853
|
-
if (
|
|
805
|
+
if (_isCompoundExpression) {
|
|
854
806
|
localVars.set('$event', localVars.get('$event') - 1);
|
|
855
807
|
yield _ts(';\n');
|
|
856
808
|
yield* generateExtraAutoImport();
|
|
857
809
|
yield _ts('}\n');
|
|
858
810
|
}
|
|
859
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, isCompoundExpression ? formatBrackets.event : formatBrackets.normal);
|
|
860
811
|
}
|
|
861
812
|
else {
|
|
862
813
|
yield _ts(`() => {}`);
|
|
@@ -935,9 +886,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
935
886
|
const isShorthand = prop.arg?.loc.start.offset === prop.exp?.loc.start.offset; // vue 3.4+
|
|
936
887
|
if (!isShorthand) {
|
|
937
888
|
yield* generateInterpolation(prop.exp.loc.source, prop.exp.loc, prop.exp.loc.start.offset, caps_all, '(', ')');
|
|
938
|
-
if (mode === 'normal') {
|
|
939
|
-
yield* generateTsFormat(prop.exp.loc.source, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
940
|
-
}
|
|
941
889
|
}
|
|
942
890
|
else {
|
|
943
891
|
const propVariableName = (0, shared_1.camelize)(prop.exp.loc.source);
|
|
@@ -985,8 +933,9 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
985
933
|
|| (prop.name === 'style' && ++styleAttrNum >= 2)
|
|
986
934
|
|| (prop.name === 'class' && ++classAttrNum >= 2)
|
|
987
935
|
|| (prop.name === 'name' && node.tag === 'slot') // #2308
|
|
988
|
-
)
|
|
936
|
+
) {
|
|
989
937
|
continue;
|
|
938
|
+
}
|
|
990
939
|
if (vueCompilerOptions.target < 3
|
|
991
940
|
&& (node.tag === 'transition' || node.tag === 'Transition')
|
|
992
941
|
&& prop.name === 'persisted') {
|
|
@@ -1025,9 +974,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1025
974
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, caps_all, '(', ')');
|
|
1026
975
|
yield _ts(['', 'template', prop.exp.loc.end.offset, presetInfos.diagnosticOnly]);
|
|
1027
976
|
yield _ts(', ');
|
|
1028
|
-
if (mode === 'normal') {
|
|
1029
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
1030
|
-
}
|
|
1031
977
|
}
|
|
1032
978
|
else {
|
|
1033
979
|
// comment this line to avoid affecting comments in prop expressions
|
|
@@ -1035,32 +981,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1035
981
|
}
|
|
1036
982
|
}
|
|
1037
983
|
}
|
|
1038
|
-
function* generateInlineCss(props) {
|
|
1039
|
-
for (const prop of props) {
|
|
1040
|
-
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
1041
|
-
&& prop.name === 'bind'
|
|
1042
|
-
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
|
|
1043
|
-
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
|
|
1044
|
-
&& prop.arg.content === 'style'
|
|
1045
|
-
&& prop.exp.constType === CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
|
|
1046
|
-
const endCrt = prop.arg.loc.source[prop.arg.loc.source.length - 1]; // " | '
|
|
1047
|
-
const start = prop.arg.loc.source.indexOf(endCrt) + 1;
|
|
1048
|
-
const end = prop.arg.loc.source.lastIndexOf(endCrt);
|
|
1049
|
-
const content = prop.arg.loc.source.substring(start, end);
|
|
1050
|
-
yield _inlineCss(`x { `);
|
|
1051
|
-
yield _inlineCss([
|
|
1052
|
-
content,
|
|
1053
|
-
'template',
|
|
1054
|
-
prop.arg.loc.start.offset + start,
|
|
1055
|
-
(0, utils_1.enableAllFeatures)({
|
|
1056
|
-
format: false,
|
|
1057
|
-
structure: false,
|
|
1058
|
-
}),
|
|
1059
|
-
]);
|
|
1060
|
-
yield _inlineCss(` }\n`);
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
984
|
function* generateDirectives(node) {
|
|
1065
985
|
for (const prop of node.props) {
|
|
1066
986
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
@@ -1073,7 +993,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1073
993
|
if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && !prop.arg.isStatic) {
|
|
1074
994
|
yield* generateInterpolation(prop.arg.content, prop.arg.loc, prop.arg.loc.start.offset + prop.arg.loc.source.indexOf(prop.arg.content), presetInfos.all, '(', ')');
|
|
1075
995
|
yield _ts(';\n');
|
|
1076
|
-
yield* generateTsFormat(prop.arg.content, prop.arg.loc.start.offset, formatBrackets.normal);
|
|
1077
996
|
}
|
|
1078
997
|
yield _ts(['', 'template', prop.loc.start.offset, presetInfos.diagnosticOnly]);
|
|
1079
998
|
yield _ts(`__VLS_directiveFunction(__VLS_ctx.`);
|
|
@@ -1093,7 +1012,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1093
1012
|
yield _ts(['', 'template', prop.exp.loc.start.offset, presetInfos.diagnosticOnly]);
|
|
1094
1013
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, presetInfos.all, '(', ')');
|
|
1095
1014
|
yield _ts(['', 'template', prop.exp.loc.end.offset, presetInfos.diagnosticOnly]);
|
|
1096
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
1097
1015
|
}
|
|
1098
1016
|
else {
|
|
1099
1017
|
yield _ts('undefined');
|
|
@@ -1264,8 +1182,9 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1264
1182
|
}
|
|
1265
1183
|
}
|
|
1266
1184
|
function* generateExtraAutoImport() {
|
|
1267
|
-
if (!tempVars.length)
|
|
1185
|
+
if (!tempVars.length) {
|
|
1268
1186
|
return;
|
|
1187
|
+
}
|
|
1269
1188
|
yield _ts('// @ts-ignore\n'); // #2304
|
|
1270
1189
|
yield _ts('[');
|
|
1271
1190
|
for (const _vars of tempVars) {
|
|
@@ -1323,20 +1242,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1323
1242
|
offset += part.length + 1;
|
|
1324
1243
|
}
|
|
1325
1244
|
}
|
|
1326
|
-
function* generateTsFormat(code, offset, formatWrapper) {
|
|
1327
|
-
yield _tsFormat(formatWrapper[0]);
|
|
1328
|
-
yield _tsFormat([
|
|
1329
|
-
code,
|
|
1330
|
-
'template',
|
|
1331
|
-
offset,
|
|
1332
|
-
(0, utils_1.mergeFeatureSettings)(presetInfos.disabledAll, {
|
|
1333
|
-
format: true,
|
|
1334
|
-
// autoInserts: true, // TODO: support vue-autoinsert-parentheses
|
|
1335
|
-
}),
|
|
1336
|
-
]);
|
|
1337
|
-
yield _tsFormat(formatWrapper[1]);
|
|
1338
|
-
yield _tsFormat('\n');
|
|
1339
|
-
}
|
|
1340
1245
|
function* generateObjectProperty(code, offset, info, astHolder, shouldCamelize = false) {
|
|
1341
1246
|
if (code.startsWith('[') && code.endsWith(']') && astHolder) {
|
|
1342
1247
|
yield* generateInterpolation(code, astHolder, offset, info, '', '');
|
|
@@ -1364,7 +1269,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1364
1269
|
}
|
|
1365
1270
|
function* generateInterpolation(_code, astHolder, start, data, prefix, suffix) {
|
|
1366
1271
|
const code = prefix + _code + suffix;
|
|
1367
|
-
const ast = createTsAst(astHolder, code);
|
|
1272
|
+
const ast = createTsAst(ts, astHolder, code);
|
|
1368
1273
|
const vars = [];
|
|
1369
1274
|
for (let [section, offset, onlyError] of (0, transform_1.eachInterpolationSegment)(ts, code, ast, localVars, accessedGlobalVariables, vueCompilerOptions, vars)) {
|
|
1370
1275
|
if (offset === undefined) {
|
|
@@ -1436,15 +1341,74 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1436
1341
|
yield _ts(['', 'template', offset + code.length, (0, utils_1.disableAllFeatures)({ __combineLastMapping: true })]);
|
|
1437
1342
|
}
|
|
1438
1343
|
}
|
|
1439
|
-
function createTsAst(astHolder, text) {
|
|
1440
|
-
if (astHolder.__volar_ast_text !== text) {
|
|
1441
|
-
astHolder.__volar_ast_text = text;
|
|
1442
|
-
astHolder.__volar_ast = ts.createSourceFile('/a.ts', text, 99);
|
|
1443
|
-
}
|
|
1444
|
-
return astHolder.__volar_ast;
|
|
1445
|
-
}
|
|
1446
1344
|
}
|
|
1447
1345
|
exports.generate = generate;
|
|
1346
|
+
function createTsAst(ts, astHolder, text) {
|
|
1347
|
+
if (astHolder.__volar_ast_text !== text) {
|
|
1348
|
+
astHolder.__volar_ast_text = text;
|
|
1349
|
+
astHolder.__volar_ast = ts.createSourceFile('/a.ts', text, 99);
|
|
1350
|
+
}
|
|
1351
|
+
return astHolder.__volar_ast;
|
|
1352
|
+
}
|
|
1353
|
+
exports.createTsAst = createTsAst;
|
|
1354
|
+
function isCompoundExpression(ts, ast) {
|
|
1355
|
+
let result = true;
|
|
1356
|
+
if (ast.statements.length === 1) {
|
|
1357
|
+
ts.forEachChild(ast, child_1 => {
|
|
1358
|
+
if (ts.isExpressionStatement(child_1)) {
|
|
1359
|
+
ts.forEachChild(child_1, child_2 => {
|
|
1360
|
+
if (ts.isArrowFunction(child_2)) {
|
|
1361
|
+
result = false;
|
|
1362
|
+
}
|
|
1363
|
+
else if (ts.isIdentifier(child_2)) {
|
|
1364
|
+
result = false;
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1368
|
+
else if (ts.isFunctionDeclaration(child_1)) {
|
|
1369
|
+
result = false;
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
return result;
|
|
1374
|
+
}
|
|
1375
|
+
exports.isCompoundExpression = isCompoundExpression;
|
|
1376
|
+
function parseInterpolationNode(node, template) {
|
|
1377
|
+
let content = node.content.loc.source;
|
|
1378
|
+
let start = node.content.loc.start.offset;
|
|
1379
|
+
let leftCharacter;
|
|
1380
|
+
let rightCharacter;
|
|
1381
|
+
// fix https://github.com/vuejs/language-tools/issues/1787
|
|
1382
|
+
while ((leftCharacter = template.substring(start - 1, start)).trim() === '' && leftCharacter.length) {
|
|
1383
|
+
start--;
|
|
1384
|
+
content = leftCharacter + content;
|
|
1385
|
+
}
|
|
1386
|
+
while ((rightCharacter = template.substring(start + content.length, start + content.length + 1)).trim() === '' && rightCharacter.length) {
|
|
1387
|
+
content = content + rightCharacter;
|
|
1388
|
+
}
|
|
1389
|
+
return [
|
|
1390
|
+
content,
|
|
1391
|
+
start,
|
|
1392
|
+
];
|
|
1393
|
+
}
|
|
1394
|
+
exports.parseInterpolationNode = parseInterpolationNode;
|
|
1395
|
+
function parseVForNode(node) {
|
|
1396
|
+
const { value, key, index } = node.parseResult;
|
|
1397
|
+
const leftExpressionRange = (value || key || index)
|
|
1398
|
+
? {
|
|
1399
|
+
start: (value ?? key ?? index).loc.start.offset,
|
|
1400
|
+
end: (index ?? key ?? value).loc.end.offset,
|
|
1401
|
+
}
|
|
1402
|
+
: undefined;
|
|
1403
|
+
const leftExpressionText = leftExpressionRange
|
|
1404
|
+
? node.loc.source.substring(leftExpressionRange.start - node.loc.start.offset, leftExpressionRange.end - node.loc.start.offset)
|
|
1405
|
+
: undefined;
|
|
1406
|
+
return {
|
|
1407
|
+
leftExpressionRange,
|
|
1408
|
+
leftExpressionText,
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
exports.parseVForNode = parseVForNode;
|
|
1448
1412
|
function getCanonicalComponentName(tagText) {
|
|
1449
1413
|
return validTsVarReg.test(tagText)
|
|
1450
1414
|
? tagText
|
|
@@ -1458,21 +1422,21 @@ function getPossibleOriginalComponentNames(tagText) {
|
|
|
1458
1422
|
tagText,
|
|
1459
1423
|
])];
|
|
1460
1424
|
}
|
|
1461
|
-
function*
|
|
1425
|
+
function* forEachElementNode(node) {
|
|
1462
1426
|
if (node.type === CompilerDOM.NodeTypes.ROOT) {
|
|
1463
1427
|
for (const child of node.children) {
|
|
1464
|
-
yield*
|
|
1428
|
+
yield* forEachElementNode(child);
|
|
1465
1429
|
}
|
|
1466
1430
|
}
|
|
1467
1431
|
else if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
|
|
1468
1432
|
const patchForNode = getVForNode(node);
|
|
1469
1433
|
if (patchForNode) {
|
|
1470
|
-
yield*
|
|
1434
|
+
yield* forEachElementNode(patchForNode);
|
|
1471
1435
|
}
|
|
1472
1436
|
else {
|
|
1473
1437
|
yield node;
|
|
1474
1438
|
for (const child of node.children) {
|
|
1475
|
-
yield*
|
|
1439
|
+
yield* forEachElementNode(child);
|
|
1476
1440
|
}
|
|
1477
1441
|
}
|
|
1478
1442
|
}
|
|
@@ -1481,18 +1445,18 @@ function* eachElementNode(node) {
|
|
|
1481
1445
|
for (let i = 0; i < node.branches.length; i++) {
|
|
1482
1446
|
const branch = node.branches[i];
|
|
1483
1447
|
for (const childNode of branch.children) {
|
|
1484
|
-
yield*
|
|
1448
|
+
yield* forEachElementNode(childNode);
|
|
1485
1449
|
}
|
|
1486
1450
|
}
|
|
1487
1451
|
}
|
|
1488
1452
|
else if (node.type === CompilerDOM.NodeTypes.FOR) {
|
|
1489
1453
|
// v-for
|
|
1490
1454
|
for (const child of node.children) {
|
|
1491
|
-
yield*
|
|
1455
|
+
yield* forEachElementNode(child);
|
|
1492
1456
|
}
|
|
1493
1457
|
}
|
|
1494
1458
|
}
|
|
1495
|
-
exports.
|
|
1459
|
+
exports.forEachElementNode = forEachElementNode;
|
|
1496
1460
|
function needToUnicode(str) {
|
|
1497
1461
|
return str.indexOf('\\') >= 0 || str.indexOf('\n') >= 0;
|
|
1498
1462
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function withStack(code: Code): CodeAndStack;
|
|
1
|
+
import type { VueCodeInformation } from '../types';
|
|
3
2
|
export declare function getStack(): string;
|
|
4
3
|
export declare function disableAllFeatures(override: Partial<VueCodeInformation>): VueCodeInformation;
|
|
5
4
|
export declare function enableAllFeatures(override: Partial<VueCodeInformation>): VueCodeInformation;
|
package/lib/generators/utils.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mergeFeatureSettings = exports.enableAllFeatures = exports.disableAllFeatures = exports.getStack =
|
|
4
|
-
function withStack(code) {
|
|
5
|
-
return [code, getStack()];
|
|
6
|
-
}
|
|
7
|
-
exports.withStack = withStack;
|
|
3
|
+
exports.mergeFeatureSettings = exports.enableAllFeatures = exports.disableAllFeatures = exports.getStack = void 0;
|
|
8
4
|
// TODO: import from muggle-string
|
|
9
5
|
function getStack() {
|
|
10
6
|
const stack = new Error().stack;
|
package/lib/languageModule.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type LanguagePlugin } from '@volar/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
import type { VueCompilerOptions } from './types';
|
|
3
|
+
import type { VueCompilerOptions, VueLanguagePlugin } from './types';
|
|
4
4
|
import { VueGeneratedCode } from './virtualFile/vueFile';
|
|
5
|
-
|
|
5
|
+
interface _Plugin extends LanguagePlugin<VueGeneratedCode> {
|
|
6
|
+
getCanonicalFileName: (fileName: string) => string;
|
|
7
|
+
pluginContext: Parameters<VueLanguagePlugin>[0];
|
|
8
|
+
}
|
|
9
|
+
export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (fileId: string) => string, useCaseSensitiveFileNames: boolean, getProjectVersion: () => string, getScriptFileNames: () => string[] | Set<string>, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, codegenStack?: boolean): _Plugin;
|
|
10
|
+
export {};
|
package/lib/languageModule.js
CHANGED
|
@@ -35,7 +35,7 @@ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
|
|
|
35
35
|
];
|
|
36
36
|
return JSON.stringify(values);
|
|
37
37
|
}
|
|
38
|
-
function createVueLanguagePlugin(ts, getFileName,
|
|
38
|
+
function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, getProjectVersion, getScriptFileNames, compilerOptions, vueCompilerOptions, codegenStack = false) {
|
|
39
39
|
const allowLanguageIds = new Set(['vue']);
|
|
40
40
|
const pluginContext = {
|
|
41
41
|
modules: {
|
|
@@ -59,11 +59,23 @@ function createVueLanguagePlugin(ts, getFileName, isValidGlobalTypesHolder, comp
|
|
|
59
59
|
if (vueCompilerOptions.extensions.includes('.html')) {
|
|
60
60
|
allowLanguageIds.add('html');
|
|
61
61
|
}
|
|
62
|
+
const getCanonicalFileName = useCaseSensitiveFileNames
|
|
63
|
+
? (fileName) => fileName
|
|
64
|
+
: (fileName) => fileName.toLowerCase();
|
|
65
|
+
let canonicalRootFileNames = new Set();
|
|
66
|
+
let canonicalRootFileNamesVersion;
|
|
62
67
|
return {
|
|
68
|
+
getCanonicalFileName,
|
|
69
|
+
pluginContext,
|
|
63
70
|
createVirtualCode(fileId, languageId, snapshot) {
|
|
64
71
|
if (allowLanguageIds.has(languageId)) {
|
|
65
72
|
const fileName = getFileName(fileId);
|
|
66
|
-
|
|
73
|
+
const projectVersion = getProjectVersion();
|
|
74
|
+
if (projectVersion !== canonicalRootFileNamesVersion) {
|
|
75
|
+
canonicalRootFileNames = new Set([...getScriptFileNames()].map(getCanonicalFileName));
|
|
76
|
+
canonicalRootFileNamesVersion = projectVersion;
|
|
77
|
+
}
|
|
78
|
+
if (!pluginContext.globalTypesHolder && canonicalRootFileNames.has(getCanonicalFileName(fileName))) {
|
|
67
79
|
pluginContext.globalTypesHolder = fileName;
|
|
68
80
|
}
|
|
69
81
|
const fileRegistry = getFileRegistry(pluginContext.globalTypesHolder === fileName);
|
|
@@ -83,33 +95,38 @@ function createVueLanguagePlugin(ts, getFileName, isValidGlobalTypesHolder, comp
|
|
|
83
95
|
code.update(snapshot);
|
|
84
96
|
return code;
|
|
85
97
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
// TODO: when global types holder deleted, move global types to another file
|
|
99
|
+
// disposeVirtualCode(fileId, code) {
|
|
100
|
+
// const isGlobalTypesHolder = code.fileName === pluginContext.globalTypesHolder;
|
|
101
|
+
// const fileRegistry = getFileRegistry(isGlobalTypesHolder);
|
|
102
|
+
// fileRegistry.delete(fileId);
|
|
103
|
+
// if (isGlobalTypesHolder) {
|
|
104
|
+
// pluginContext.globalTypesHolder = undefined;
|
|
105
|
+
// const fileRegistry2 = getFileRegistry(false);
|
|
106
|
+
// for (const [fileId, code] of fileRegistry2) {
|
|
107
|
+
// if (isValidGlobalTypesHolder(code.fileName)) {
|
|
108
|
+
// pluginContext.globalTypesHolder = code.fileName;
|
|
109
|
+
// fileRegistry2.delete(fileId);
|
|
110
|
+
// // force dirty
|
|
111
|
+
// files?.delete(fileId);
|
|
112
|
+
// files?.set(
|
|
113
|
+
// fileId,
|
|
114
|
+
// code.languageId,
|
|
115
|
+
// code.snapshot,
|
|
116
|
+
// );
|
|
117
|
+
// break;
|
|
118
|
+
// }
|
|
119
|
+
// }
|
|
120
|
+
// }
|
|
121
|
+
// },
|
|
105
122
|
typescript: {
|
|
106
123
|
extraFileExtensions: vueCompilerOptions.extensions.map(ext => ({
|
|
107
124
|
extension: ext.slice(1),
|
|
108
125
|
isMixedContent: true,
|
|
109
126
|
scriptKind: 7,
|
|
110
127
|
})),
|
|
111
|
-
|
|
112
|
-
for (const code of (0, language_core_1.forEachEmbeddedCode)(
|
|
128
|
+
getServiceScript(root) {
|
|
129
|
+
for (const code of (0, language_core_1.forEachEmbeddedCode)(root)) {
|
|
113
130
|
if (code.id.startsWith('script_')) {
|
|
114
131
|
const lang = code.id.substring('script_'.length);
|
|
115
132
|
return {
|