@vue/language-core 2.0.7 → 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 +26 -129
- package/lib/generators/template.d.ts +13 -3
- package/lib/generators/template.js +112 -157
- 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/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 +3 -73
- package/lib/plugins.js +4 -0
- package/lib/virtualFile/computedFiles.js +1 -10
- 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
|
}
|
|
@@ -352,24 +341,8 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
352
341
|
}
|
|
353
342
|
else if (node.type === CompilerDOM.NodeTypes.INTERPOLATION) {
|
|
354
343
|
// {{ ... }}
|
|
355
|
-
|
|
356
|
-
let start = node.content.loc.start.offset;
|
|
357
|
-
let leftCharacter;
|
|
358
|
-
let rightCharacter;
|
|
359
|
-
// fix https://github.com/vuejs/language-tools/issues/1787
|
|
360
|
-
while ((leftCharacter = template.content.substring(start - 1, start)).trim() === '' && leftCharacter.length) {
|
|
361
|
-
start--;
|
|
362
|
-
content = leftCharacter + content;
|
|
363
|
-
}
|
|
364
|
-
while ((rightCharacter = template.content.substring(start + content.length, start + content.length + 1)).trim() === '' && rightCharacter.length) {
|
|
365
|
-
content = content + rightCharacter;
|
|
366
|
-
}
|
|
344
|
+
const [content, start] = parseInterpolationNode(node, template.content);
|
|
367
345
|
yield* generateInterpolation(content, node.content.loc, start, presetInfos.all, '(', ');\n');
|
|
368
|
-
const lines = content.split('\n');
|
|
369
|
-
yield* generateTsFormat(content, start, lines.length <= 1 ? formatBrackets.curly : [
|
|
370
|
-
lines[0].trim() === '' ? '(' : formatBrackets.curly[0],
|
|
371
|
-
lines[lines.length - 1].trim() === '' ? ')' : formatBrackets.curly[1],
|
|
372
|
-
]);
|
|
373
346
|
}
|
|
374
347
|
else if (node.type === CompilerDOM.NodeTypes.IF) {
|
|
375
348
|
// v-if / v-else-if / v-else
|
|
@@ -403,7 +376,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
403
376
|
blockConditions.push((0, language_core_1.toString)([...generateInterpolation(branch.condition.content, branch.condition.loc, undefined, undefined, '(', ')')]
|
|
404
377
|
.map(code => code[1])));
|
|
405
378
|
addedBlockCondition = true;
|
|
406
|
-
yield* generateTsFormat(branch.condition.content, branch.condition.loc.start.offset, formatBrackets.normal);
|
|
407
379
|
}
|
|
408
380
|
yield _ts(` {\n`);
|
|
409
381
|
let prev;
|
|
@@ -421,19 +393,17 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
421
393
|
blockConditions.length = originalBlockConditionsLength;
|
|
422
394
|
}
|
|
423
395
|
function* generateVFor(node, parentEl, componentCtxVar) {
|
|
424
|
-
const { source
|
|
425
|
-
const
|
|
426
|
-
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);
|
|
427
398
|
const forBlockVars = [];
|
|
428
399
|
yield _ts(`for (const [`);
|
|
429
400
|
if (leftExpressionRange && leftExpressionText) {
|
|
430
|
-
const collectAst = createTsAst(node.parseResult, `const [${leftExpressionText}]`);
|
|
401
|
+
const collectAst = createTsAst(ts, node.parseResult, `const [${leftExpressionText}]`);
|
|
431
402
|
(0, transform_1.collectVars)(ts, collectAst, collectAst, forBlockVars);
|
|
432
403
|
for (const varName of forBlockVars) {
|
|
433
404
|
localVars.set(varName, (localVars.get(varName) ?? 0) + 1);
|
|
434
405
|
}
|
|
435
406
|
yield _ts([leftExpressionText, 'template', leftExpressionRange.start, presetInfos.all]);
|
|
436
|
-
yield* generateTsFormat(leftExpressionText, leftExpressionRange.start, formatBrackets.normal);
|
|
437
407
|
}
|
|
438
408
|
yield _ts(`] of __VLS_getVForSourceType`);
|
|
439
409
|
if (source.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
@@ -449,7 +419,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
449
419
|
yield* generateExpectErrorComment();
|
|
450
420
|
yield* generateExtraAutoImport();
|
|
451
421
|
yield _ts('}\n');
|
|
452
|
-
yield* generateTsFormat(source.content, source.loc.start.offset, formatBrackets.normal);
|
|
453
422
|
}
|
|
454
423
|
for (const varName of forBlockVars) {
|
|
455
424
|
localVars.set(varName, localVars.get(varName) - 1);
|
|
@@ -595,12 +564,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
595
564
|
for (const failedExp of propsFailedExps) {
|
|
596
565
|
yield* generateInterpolation(failedExp.loc.source, failedExp.loc, failedExp.loc.start.offset, presetInfos.all, '(', ')');
|
|
597
566
|
yield _ts(';\n');
|
|
598
|
-
const fb = formatBrackets.normal;
|
|
599
|
-
if (fb) {
|
|
600
|
-
yield* generateTsFormat(failedExp.loc.source, failedExp.loc.start.offset, fb);
|
|
601
|
-
}
|
|
602
567
|
}
|
|
603
|
-
yield* generateInlineCss(props);
|
|
604
568
|
const vScope = props.find(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && (prop.name === 'scope' || prop.name === 'data'));
|
|
605
569
|
let inScope = false;
|
|
606
570
|
let originalConditionsNum = blockConditions.length;
|
|
@@ -646,8 +610,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
646
610
|
yield _ts(`{\n`);
|
|
647
611
|
let hasProps = false;
|
|
648
612
|
if (slotDir?.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
649
|
-
|
|
650
|
-
const slotAst = createTsAst(slotDir, `(${slotDir.exp.content}) => {}`);
|
|
613
|
+
const slotAst = createTsAst(ts, slotDir, `(${slotDir.exp.content}) => {}`);
|
|
651
614
|
(0, transform_1.collectVars)(ts, slotAst, slotAst, slotBlockVars);
|
|
652
615
|
hasProps = true;
|
|
653
616
|
if (slotDir.exp.content.indexOf(':') === -1) {
|
|
@@ -813,35 +776,17 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
813
776
|
// https://github.com/johnsoncodehk/vue-tsc/issues/67
|
|
814
777
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, presetInfos.all, '$event => {(', ')}');
|
|
815
778
|
yield _ts(';\n');
|
|
816
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
817
779
|
}
|
|
818
780
|
}
|
|
819
781
|
}
|
|
820
782
|
function* appendExpressionNode(prop) {
|
|
821
783
|
if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
822
|
-
const ast = createTsAst(prop.exp, prop.exp.content);
|
|
823
|
-
let isCompoundExpression = true;
|
|
824
|
-
if (ast.statements.length === 1) {
|
|
825
|
-
ts.forEachChild(ast, child_1 => {
|
|
826
|
-
if (ts.isExpressionStatement(child_1)) {
|
|
827
|
-
ts.forEachChild(child_1, child_2 => {
|
|
828
|
-
if (ts.isArrowFunction(child_2)) {
|
|
829
|
-
isCompoundExpression = false;
|
|
830
|
-
}
|
|
831
|
-
else if (ts.isIdentifier(child_2)) {
|
|
832
|
-
isCompoundExpression = false;
|
|
833
|
-
}
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
else if (ts.isFunctionDeclaration(child_1)) {
|
|
837
|
-
isCompoundExpression = false;
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
784
|
let prefix = '(';
|
|
842
785
|
let suffix = ')';
|
|
843
786
|
let isFirstMapping = true;
|
|
844
|
-
|
|
787
|
+
const ast = createTsAst(ts, prop.exp, prop.exp.content);
|
|
788
|
+
const _isCompoundExpression = isCompoundExpression(ts, ast);
|
|
789
|
+
if (_isCompoundExpression) {
|
|
845
790
|
yield _ts('$event => {\n');
|
|
846
791
|
localVars.set('$event', (localVars.get('$event') ?? 0) + 1);
|
|
847
792
|
prefix = '';
|
|
@@ -851,19 +796,18 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
851
796
|
}
|
|
852
797
|
}
|
|
853
798
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, () => {
|
|
854
|
-
if (
|
|
799
|
+
if (_isCompoundExpression && isFirstMapping) {
|
|
855
800
|
isFirstMapping = false;
|
|
856
801
|
return presetInfos.allWithHiddenParam;
|
|
857
802
|
}
|
|
858
803
|
return presetInfos.all;
|
|
859
804
|
}, prefix, suffix);
|
|
860
|
-
if (
|
|
805
|
+
if (_isCompoundExpression) {
|
|
861
806
|
localVars.set('$event', localVars.get('$event') - 1);
|
|
862
807
|
yield _ts(';\n');
|
|
863
808
|
yield* generateExtraAutoImport();
|
|
864
809
|
yield _ts('}\n');
|
|
865
810
|
}
|
|
866
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, isCompoundExpression ? formatBrackets.event : formatBrackets.normal);
|
|
867
811
|
}
|
|
868
812
|
else {
|
|
869
813
|
yield _ts(`() => {}`);
|
|
@@ -942,9 +886,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
942
886
|
const isShorthand = prop.arg?.loc.start.offset === prop.exp?.loc.start.offset; // vue 3.4+
|
|
943
887
|
if (!isShorthand) {
|
|
944
888
|
yield* generateInterpolation(prop.exp.loc.source, prop.exp.loc, prop.exp.loc.start.offset, caps_all, '(', ')');
|
|
945
|
-
if (mode === 'normal') {
|
|
946
|
-
yield* generateTsFormat(prop.exp.loc.source, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
947
|
-
}
|
|
948
889
|
}
|
|
949
890
|
else {
|
|
950
891
|
const propVariableName = (0, shared_1.camelize)(prop.exp.loc.source);
|
|
@@ -1033,9 +974,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1033
974
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, caps_all, '(', ')');
|
|
1034
975
|
yield _ts(['', 'template', prop.exp.loc.end.offset, presetInfos.diagnosticOnly]);
|
|
1035
976
|
yield _ts(', ');
|
|
1036
|
-
if (mode === 'normal') {
|
|
1037
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
1038
|
-
}
|
|
1039
977
|
}
|
|
1040
978
|
else {
|
|
1041
979
|
// comment this line to avoid affecting comments in prop expressions
|
|
@@ -1043,32 +981,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1043
981
|
}
|
|
1044
982
|
}
|
|
1045
983
|
}
|
|
1046
|
-
function* generateInlineCss(props) {
|
|
1047
|
-
for (const prop of props) {
|
|
1048
|
-
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
1049
|
-
&& prop.name === 'bind'
|
|
1050
|
-
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
|
|
1051
|
-
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
|
|
1052
|
-
&& prop.arg.content === 'style'
|
|
1053
|
-
&& prop.exp.constType === CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
|
|
1054
|
-
const endCrt = prop.arg.loc.source[prop.arg.loc.source.length - 1]; // " | '
|
|
1055
|
-
const start = prop.arg.loc.source.indexOf(endCrt) + 1;
|
|
1056
|
-
const end = prop.arg.loc.source.lastIndexOf(endCrt);
|
|
1057
|
-
const content = prop.arg.loc.source.substring(start, end);
|
|
1058
|
-
yield _inlineCss(`x { `);
|
|
1059
|
-
yield _inlineCss([
|
|
1060
|
-
content,
|
|
1061
|
-
'template',
|
|
1062
|
-
prop.arg.loc.start.offset + start,
|
|
1063
|
-
(0, utils_1.enableAllFeatures)({
|
|
1064
|
-
format: false,
|
|
1065
|
-
structure: false,
|
|
1066
|
-
}),
|
|
1067
|
-
]);
|
|
1068
|
-
yield _inlineCss(` }\n`);
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
984
|
function* generateDirectives(node) {
|
|
1073
985
|
for (const prop of node.props) {
|
|
1074
986
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
@@ -1081,7 +993,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1081
993
|
if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && !prop.arg.isStatic) {
|
|
1082
994
|
yield* generateInterpolation(prop.arg.content, prop.arg.loc, prop.arg.loc.start.offset + prop.arg.loc.source.indexOf(prop.arg.content), presetInfos.all, '(', ')');
|
|
1083
995
|
yield _ts(';\n');
|
|
1084
|
-
yield* generateTsFormat(prop.arg.content, prop.arg.loc.start.offset, formatBrackets.normal);
|
|
1085
996
|
}
|
|
1086
997
|
yield _ts(['', 'template', prop.loc.start.offset, presetInfos.diagnosticOnly]);
|
|
1087
998
|
yield _ts(`__VLS_directiveFunction(__VLS_ctx.`);
|
|
@@ -1101,7 +1012,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1101
1012
|
yield _ts(['', 'template', prop.exp.loc.start.offset, presetInfos.diagnosticOnly]);
|
|
1102
1013
|
yield* generateInterpolation(prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, presetInfos.all, '(', ')');
|
|
1103
1014
|
yield _ts(['', 'template', prop.exp.loc.end.offset, presetInfos.diagnosticOnly]);
|
|
1104
|
-
yield* generateTsFormat(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
|
|
1105
1015
|
}
|
|
1106
1016
|
else {
|
|
1107
1017
|
yield _ts('undefined');
|
|
@@ -1332,20 +1242,6 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1332
1242
|
offset += part.length + 1;
|
|
1333
1243
|
}
|
|
1334
1244
|
}
|
|
1335
|
-
function* generateTsFormat(code, offset, formatWrapper) {
|
|
1336
|
-
yield _tsFormat(formatWrapper[0]);
|
|
1337
|
-
yield _tsFormat([
|
|
1338
|
-
code,
|
|
1339
|
-
'template',
|
|
1340
|
-
offset,
|
|
1341
|
-
(0, utils_1.mergeFeatureSettings)(presetInfos.disabledAll, {
|
|
1342
|
-
format: true,
|
|
1343
|
-
// autoInserts: true, // TODO: support vue-autoinsert-parentheses
|
|
1344
|
-
}),
|
|
1345
|
-
]);
|
|
1346
|
-
yield _tsFormat(formatWrapper[1]);
|
|
1347
|
-
yield _tsFormat('\n');
|
|
1348
|
-
}
|
|
1349
1245
|
function* generateObjectProperty(code, offset, info, astHolder, shouldCamelize = false) {
|
|
1350
1246
|
if (code.startsWith('[') && code.endsWith(']') && astHolder) {
|
|
1351
1247
|
yield* generateInterpolation(code, astHolder, offset, info, '', '');
|
|
@@ -1373,7 +1269,7 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1373
1269
|
}
|
|
1374
1270
|
function* generateInterpolation(_code, astHolder, start, data, prefix, suffix) {
|
|
1375
1271
|
const code = prefix + _code + suffix;
|
|
1376
|
-
const ast = createTsAst(astHolder, code);
|
|
1272
|
+
const ast = createTsAst(ts, astHolder, code);
|
|
1377
1273
|
const vars = [];
|
|
1378
1274
|
for (let [section, offset, onlyError] of (0, transform_1.eachInterpolationSegment)(ts, code, ast, localVars, accessedGlobalVariables, vueCompilerOptions, vars)) {
|
|
1379
1275
|
if (offset === undefined) {
|
|
@@ -1445,15 +1341,74 @@ function* generate(ts, compilerOptions, vueCompilerOptions, template, shouldGene
|
|
|
1445
1341
|
yield _ts(['', 'template', offset + code.length, (0, utils_1.disableAllFeatures)({ __combineLastMapping: true })]);
|
|
1446
1342
|
}
|
|
1447
1343
|
}
|
|
1448
|
-
function createTsAst(astHolder, text) {
|
|
1449
|
-
if (astHolder.__volar_ast_text !== text) {
|
|
1450
|
-
astHolder.__volar_ast_text = text;
|
|
1451
|
-
astHolder.__volar_ast = ts.createSourceFile('/a.ts', text, 99);
|
|
1452
|
-
}
|
|
1453
|
-
return astHolder.__volar_ast;
|
|
1454
|
-
}
|
|
1455
1344
|
}
|
|
1456
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;
|
|
1457
1412
|
function getCanonicalComponentName(tagText) {
|
|
1458
1413
|
return validTsVarReg.test(tagText)
|
|
1459
1414
|
? tagText
|
|
@@ -1467,21 +1422,21 @@ function getPossibleOriginalComponentNames(tagText) {
|
|
|
1467
1422
|
tagText,
|
|
1468
1423
|
])];
|
|
1469
1424
|
}
|
|
1470
|
-
function*
|
|
1425
|
+
function* forEachElementNode(node) {
|
|
1471
1426
|
if (node.type === CompilerDOM.NodeTypes.ROOT) {
|
|
1472
1427
|
for (const child of node.children) {
|
|
1473
|
-
yield*
|
|
1428
|
+
yield* forEachElementNode(child);
|
|
1474
1429
|
}
|
|
1475
1430
|
}
|
|
1476
1431
|
else if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
|
|
1477
1432
|
const patchForNode = getVForNode(node);
|
|
1478
1433
|
if (patchForNode) {
|
|
1479
|
-
yield*
|
|
1434
|
+
yield* forEachElementNode(patchForNode);
|
|
1480
1435
|
}
|
|
1481
1436
|
else {
|
|
1482
1437
|
yield node;
|
|
1483
1438
|
for (const child of node.children) {
|
|
1484
|
-
yield*
|
|
1439
|
+
yield* forEachElementNode(child);
|
|
1485
1440
|
}
|
|
1486
1441
|
}
|
|
1487
1442
|
}
|
|
@@ -1490,18 +1445,18 @@ function* eachElementNode(node) {
|
|
|
1490
1445
|
for (let i = 0; i < node.branches.length; i++) {
|
|
1491
1446
|
const branch = node.branches[i];
|
|
1492
1447
|
for (const childNode of branch.children) {
|
|
1493
|
-
yield*
|
|
1448
|
+
yield* forEachElementNode(childNode);
|
|
1494
1449
|
}
|
|
1495
1450
|
}
|
|
1496
1451
|
}
|
|
1497
1452
|
else if (node.type === CompilerDOM.NodeTypes.FOR) {
|
|
1498
1453
|
// v-for
|
|
1499
1454
|
for (const child of node.children) {
|
|
1500
|
-
yield*
|
|
1455
|
+
yield* forEachElementNode(child);
|
|
1501
1456
|
}
|
|
1502
1457
|
}
|
|
1503
1458
|
}
|
|
1504
|
-
exports.
|
|
1459
|
+
exports.forEachElementNode = forEachElementNode;
|
|
1505
1460
|
function needToUnicode(str) {
|
|
1506
1461
|
return str.indexOf('\\') >= 0 || str.indexOf('\n') >= 0;
|
|
1507
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 {
|
|
@@ -43,6 +43,7 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript'),
|
|
|
43
43
|
name: TextRange | undefined;
|
|
44
44
|
nameIsString: boolean;
|
|
45
45
|
type: TextRange | undefined;
|
|
46
|
+
modifierType?: TextRange | undefined;
|
|
46
47
|
defaultValue: TextRange | undefined;
|
|
47
48
|
required: boolean;
|
|
48
49
|
isModel?: boolean | undefined;
|
|
@@ -87,6 +87,7 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
|
|
|
87
87
|
name,
|
|
88
88
|
nameIsString: true,
|
|
89
89
|
type: node.typeArguments?.length ? _getStartEnd(node.typeArguments[0]) : undefined,
|
|
90
|
+
modifierType: node.typeArguments && node.typeArguments?.length >= 2 ? _getStartEnd(node.typeArguments[1]) : undefined,
|
|
90
91
|
defaultValue: undefined,
|
|
91
92
|
required,
|
|
92
93
|
isModel: true,
|