@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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.eachElementNode = exports.generate = void 0;
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 (ignoreError && typeof code !== 'string') {
68
- const data = code[3];
69
- if (data.verification) {
70
- code[3] = {
71
- ...data,
72
- verification: false,
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
- if (expectErrorToken && typeof code !== 'string') {
77
- const token = expectErrorToken;
78
- const data = code[3];
79
- if (data.verification) {
80
- code[3] = {
81
- ...data,
82
- verification: {
83
- shouldReport: () => {
84
- token.errors++;
85
- return false;
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) => ['ts', processDirectiveComment(code), (0, utils_1.getStack)()]
95
- : (code) => ['ts', processDirectiveComment(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 eachElementNode(template.ast)) {
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
- let content = node.content.loc.source;
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
- else if (branch.condition)
365
+ }
366
+ else if (branch.condition) {
391
367
  yield _ts('else if');
392
- else
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, value, key, index } = node.parseResult;
420
- const leftExpressionRange = value ? { start: (value ?? key ?? index).loc.start.offset, end: (index ?? key ?? value).loc.end.offset } : undefined;
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
- yield* generateTsFormat(slotDir.exp.content, slotDir.exp.loc.start.offset, formatBrackets.params);
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
- if (isCompoundExpression) {
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 (isCompoundExpression && isFirstMapping) {
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 (isCompoundExpression) {
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* eachElementNode(node) {
1425
+ function* forEachElementNode(node) {
1462
1426
  if (node.type === CompilerDOM.NodeTypes.ROOT) {
1463
1427
  for (const child of node.children) {
1464
- yield* eachElementNode(child);
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* eachElementNode(patchForNode);
1434
+ yield* forEachElementNode(patchForNode);
1471
1435
  }
1472
1436
  else {
1473
1437
  yield node;
1474
1438
  for (const child of node.children) {
1475
- yield* eachElementNode(child);
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* eachElementNode(childNode);
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* eachElementNode(child);
1455
+ yield* forEachElementNode(child);
1492
1456
  }
1493
1457
  }
1494
1458
  }
1495
- exports.eachElementNode = eachElementNode;
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 { Code, CodeAndStack, VueCodeInformation } from '../types';
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;
@@ -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 = exports.withStack = void 0;
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;
@@ -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
- export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (fileId: string) => string, isValidGlobalTypesHolder: (fileName: string) => boolean, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, codegenStack?: boolean): LanguagePlugin<VueGeneratedCode>;
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 {};
@@ -35,7 +35,7 @@ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
35
35
  ];
36
36
  return JSON.stringify(values);
37
37
  }
38
- function createVueLanguagePlugin(ts, getFileName, isValidGlobalTypesHolder, compilerOptions, vueCompilerOptions, codegenStack = false) {
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
- if (!pluginContext.globalTypesHolder && isValidGlobalTypesHolder(fileName)) {
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
- disposeVirtualCode(fileId, code, files) {
87
- const isGlobalTypesHolder = code.fileName === pluginContext.globalTypesHolder;
88
- const fileRegistry = getFileRegistry(isGlobalTypesHolder);
89
- fileRegistry.delete(fileId);
90
- if (isGlobalTypesHolder) {
91
- pluginContext.globalTypesHolder = undefined;
92
- const fileRegistry2 = getFileRegistry(false);
93
- for (const [fileId, code] of fileRegistry2) {
94
- if (isValidGlobalTypesHolder(code.fileName)) {
95
- pluginContext.globalTypesHolder = code.fileName;
96
- fileRegistry2.delete(fileId);
97
- // force dirty
98
- files?.delete(fileId);
99
- files?.set(fileId, code.languageId, code.snapshot);
100
- break;
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
- getScript(rootVirtualCode) {
112
- for (const code of (0, language_core_1.forEachEmbeddedCode)(rootVirtualCode)) {
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 {