@vue/language-core 3.1.4 → 3.1.6

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.
Files changed (101) hide show
  1. package/index.d.ts +2 -1
  2. package/index.js +3 -2
  3. package/lib/codegen/codeFeatures.d.ts +5 -9
  4. package/lib/codegen/codeFeatures.js +5 -5
  5. package/lib/codegen/globalTypes.js +15 -20
  6. package/lib/codegen/localTypes.d.ts +1 -1
  7. package/lib/codegen/localTypes.js +6 -6
  8. package/lib/codegen/names.d.ts +30 -0
  9. package/lib/codegen/names.js +34 -0
  10. package/lib/codegen/script/component.js +45 -54
  11. package/lib/codegen/script/context.d.ts +2 -5
  12. package/lib/codegen/script/context.js +1 -7
  13. package/lib/codegen/script/index.d.ts +10 -12
  14. package/lib/codegen/script/index.js +74 -73
  15. package/lib/codegen/script/scriptSetup.d.ts +3 -2
  16. package/lib/codegen/script/scriptSetup.js +209 -283
  17. package/lib/codegen/script/src.js +9 -3
  18. package/lib/codegen/script/template.js +64 -108
  19. package/lib/codegen/style/common.d.ts +3 -0
  20. package/lib/codegen/style/common.js +43 -0
  21. package/lib/codegen/style/index.d.ts +63 -0
  22. package/lib/codegen/style/index.js +38 -0
  23. package/lib/codegen/style/modules.d.ts +3 -2
  24. package/lib/codegen/style/modules.js +12 -11
  25. package/lib/codegen/style/scopedClasses.d.ts +2 -3
  26. package/lib/codegen/style/scopedClasses.js +23 -21
  27. package/lib/codegen/template/context.d.ts +10 -19
  28. package/lib/codegen/template/context.js +82 -94
  29. package/lib/codegen/template/element.js +174 -65
  30. package/lib/codegen/template/elementDirectives.js +32 -12
  31. package/lib/codegen/template/elementEvents.d.ts +1 -1
  32. package/lib/codegen/template/elementEvents.js +30 -35
  33. package/lib/codegen/template/elementProps.d.ts +3 -3
  34. package/lib/codegen/template/elementProps.js +64 -83
  35. package/lib/codegen/template/index.d.ts +11 -22
  36. package/lib/codegen/template/index.js +85 -80
  37. package/lib/codegen/template/interpolation.d.ts +3 -3
  38. package/lib/codegen/template/interpolation.js +108 -155
  39. package/lib/codegen/template/objectProperty.js +8 -4
  40. package/lib/codegen/template/propertyAccess.d.ts +1 -1
  41. package/lib/codegen/template/propertyAccess.js +5 -7
  42. package/lib/codegen/template/slotOutlet.js +26 -14
  43. package/lib/codegen/template/styleScopedClasses.d.ts +3 -6
  44. package/lib/codegen/template/styleScopedClasses.js +23 -149
  45. package/lib/codegen/template/templateChild.d.ts +0 -1
  46. package/lib/codegen/template/templateChild.js +11 -68
  47. package/lib/codegen/template/vFor.js +10 -13
  48. package/lib/codegen/template/vIf.js +5 -3
  49. package/lib/codegen/template/vSlot.js +20 -16
  50. package/lib/codegen/utils/boundary.d.ts +3 -0
  51. package/lib/codegen/utils/boundary.js +13 -0
  52. package/lib/codegen/utils/camelized.js +3 -3
  53. package/lib/codegen/utils/escaped.js +4 -2
  54. package/lib/codegen/utils/index.d.ts +3 -6
  55. package/lib/codegen/utils/index.js +41 -26
  56. package/lib/codegen/utils/merge.d.ts +2 -2
  57. package/lib/codegen/utils/merge.js +9 -9
  58. package/lib/codegen/utils/stringLiteralKey.js +6 -3
  59. package/lib/codegen/utils/transform.d.ts +8 -0
  60. package/lib/codegen/utils/transform.js +27 -0
  61. package/lib/codegen/utils/unicode.js +4 -2
  62. package/lib/compilerOptions.js +4 -4
  63. package/lib/languagePlugin.d.ts +1 -1
  64. package/lib/languagePlugin.js +18 -25
  65. package/lib/plugins/vue-template-html.js +12 -9
  66. package/lib/plugins/vue-template-inline-css.js +8 -18
  67. package/lib/plugins/vue-template-inline-ts.js +12 -14
  68. package/lib/plugins/vue-tsx.d.ts +14 -23
  69. package/lib/plugins/vue-tsx.js +121 -69
  70. package/lib/plugins.js +1 -1
  71. package/lib/types.d.ts +5 -4
  72. package/lib/utils/parseSfc.js +10 -11
  73. package/lib/utils/shared.d.ts +1 -0
  74. package/lib/utils/shared.js +9 -0
  75. package/lib/utils/signals.d.ts +2 -2
  76. package/lib/utils/signals.js +8 -6
  77. package/lib/virtualCode/embeddedCodes.d.ts +12 -0
  78. package/lib/virtualCode/embeddedCodes.js +249 -0
  79. package/lib/{virtualFile/vueFile.d.ts → virtualCode/index.d.ts} +9 -9
  80. package/lib/virtualCode/index.js +81 -0
  81. package/lib/virtualCode/ir.d.ts +4 -0
  82. package/lib/{virtualFile/computedSfc.js → virtualCode/ir.js} +65 -96
  83. package/lib/virtualCode/normalize.d.ts +2 -0
  84. package/lib/virtualCode/normalize.js +170 -0
  85. package/package.json +4 -4
  86. package/lib/codegen/style/classProperty.d.ts +0 -2
  87. package/lib/codegen/style/classProperty.js +0 -18
  88. package/lib/codegen/style/imports.d.ts +0 -2
  89. package/lib/codegen/style/imports.js +0 -27
  90. package/lib/codegen/template/elementChildren.d.ts +0 -5
  91. package/lib/codegen/template/elementChildren.js +0 -12
  92. package/lib/codegen/utils/wrapWith.d.ts +0 -3
  93. package/lib/codegen/utils/wrapWith.js +0 -24
  94. package/lib/virtualFile/computedEmbeddedCodes.d.ts +0 -4
  95. package/lib/virtualFile/computedEmbeddedCodes.js +0 -262
  96. package/lib/virtualFile/computedSfc.d.ts +0 -6
  97. package/lib/virtualFile/computedVueSfc.d.ts +0 -4
  98. package/lib/virtualFile/computedVueSfc.js +0 -41
  99. package/lib/virtualFile/embeddedFile.d.ts +0 -11
  100. package/lib/virtualFile/embeddedFile.js +0 -14
  101. package/lib/virtualFile/vueFile.js +0 -49
@@ -2,10 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createTemplateCodegenContext = createTemplateCodegenContext;
4
4
  const CompilerDOM = require("@vue/compiler-dom");
5
- const computedSfc_1 = require("../../virtualFile/computedSfc");
6
5
  const codeFeatures_1 = require("../codeFeatures");
7
6
  const utils_1 = require("../utils");
8
- const wrapWith_1 = require("../utils/wrapWith");
7
+ const boundary_1 = require("../utils/boundary");
9
8
  const commentDirectiveRegex = /^<!--\s*@vue-(?<name>[-\w]+)\b(?<content>[\s\S]*)-->$/;
10
9
  /**
11
10
  * Creates and returns a Context object used for generating type-checkable TS code
@@ -104,76 +103,37 @@ const commentDirectiveRegex = /^<!--\s*@vue-(?<name>[-\w]+)\b(?<content>[\s\S]*)
104
103
  * an error/diagnostic was encountered for a region of code covered by a `@vue-expect-error` directive,
105
104
  * and additionally how we use that to determine whether to propagate diagnostics back upward.
106
105
  */
107
- function createTemplateCodegenContext(options, templateAst) {
106
+ function createTemplateCodegenContext() {
108
107
  let variableId = 0;
109
- function resolveCodeFeatures(features) {
110
- if (features.verification && stack.length) {
111
- const data = stack[stack.length - 1];
112
- if (data.ignoreError) {
113
- // We are currently in a region of code covered by a @vue-ignore directive, so don't
114
- // even bother performing any type-checking: set verification to false.
115
- return {
116
- ...features,
117
- verification: false,
118
- };
119
- }
120
- if (data.expectError !== undefined) {
121
- // We are currently in a region of code covered by a @vue-expect-error directive. We need to
122
- // keep track of the number of errors encountered within this region so that we can know whether
123
- // we will need to propagate an "unused ts-expect-error" diagnostic back to the original
124
- // .vue file or not.
125
- return {
126
- ...features,
127
- verification: {
128
- shouldReport: (source, code) => {
129
- if (typeof features.verification !== 'object'
130
- || !features.verification.shouldReport
131
- || features.verification.shouldReport(source, code) === true) {
132
- data.expectError.token++;
133
- }
134
- return false;
135
- },
136
- },
137
- };
138
- }
139
- }
140
- return features;
141
- }
108
+ const scopes = [];
142
109
  const hoistVars = new Map();
143
- const localVars = new Map();
144
110
  const dollarVars = new Set();
145
- const accessExternalVariables = new Map();
111
+ const componentAccessMap = new Map();
146
112
  const slots = [];
147
113
  const dynamicSlots = [];
148
114
  const blockConditions = [];
149
- const scopedClasses = [];
150
- const emptyClassOffsets = [];
151
115
  const inlayHints = [];
152
- const bindingAttrLocs = [];
153
116
  const inheritedAttrVars = new Set();
154
117
  const templateRefs = new Map();
155
118
  const stack = [];
156
119
  const commentBuffer = [];
157
120
  return {
121
+ generatedTypes: new Set(),
158
122
  get currentInfo() {
159
123
  return stack[stack.length - 1];
160
124
  },
161
125
  resolveCodeFeatures,
162
- inlineTsAsts: templateAst && computedSfc_1.templateInlineTsAsts.get(templateAst),
163
126
  inVFor: false,
164
127
  slots,
165
128
  dynamicSlots,
166
129
  dollarVars,
167
- accessExternalVariables,
130
+ componentAccessMap,
168
131
  blockConditions,
169
- scopedClasses,
170
- emptyClassOffsets,
171
132
  inlayHints,
172
- bindingAttrLocs,
173
133
  inheritedAttrVars,
174
134
  templateRefs,
175
135
  currentComponent: undefined,
176
- singleRootElTypes: [],
136
+ singleRootElTypes: new Set(),
177
137
  singleRootNodes: new Set(),
178
138
  addTemplateRef(name, typeExp, offset) {
179
139
  let refs = templateRefs.get(name);
@@ -182,23 +142,33 @@ function createTemplateCodegenContext(options, templateAst) {
182
142
  }
183
143
  refs.push({ typeExp, offset });
184
144
  },
185
- accessExternalVariable(name, offset) {
186
- let arr = accessExternalVariables.get(name);
145
+ recordComponentAccess(source, name, offset) {
146
+ let map = componentAccessMap.get(name);
147
+ if (!map) {
148
+ componentAccessMap.set(name, map = new Map());
149
+ }
150
+ let arr = map.get(source);
187
151
  if (!arr) {
188
- accessExternalVariables.set(name, arr = new Set());
152
+ map.set(source, arr = new Set());
189
153
  }
190
154
  if (offset !== undefined) {
191
155
  arr.add(offset);
192
156
  }
193
157
  },
194
- hasLocalVariable(name) {
195
- return !!localVars.get(name);
196
- },
197
- addLocalVariable(name) {
198
- localVars.set(name, (localVars.get(name) ?? 0) + 1);
158
+ scopes,
159
+ declare(...varNames) {
160
+ const scope = scopes.at(-1);
161
+ for (const varName of varNames) {
162
+ scope.add(varName);
163
+ }
199
164
  },
200
- removeLocalVariable(name) {
201
- localVars.set(name, localVars.get(name) - 1);
165
+ startScope() {
166
+ const scope = new Set();
167
+ scopes.push(scope);
168
+ return () => {
169
+ scopes.pop();
170
+ return generateAutoImport();
171
+ };
202
172
  },
203
173
  getInternalVariable() {
204
174
  return `__VLS_${variableId++}`;
@@ -226,41 +196,6 @@ function createTemplateCodegenContext(options, templateAst) {
226
196
  yield `if (!${condition}) return${utils_1.endOfLine}`;
227
197
  }
228
198
  },
229
- *generateAutoImportCompletion() {
230
- const all = [...accessExternalVariables.entries()];
231
- if (!all.some(([, offsets]) => offsets.size)) {
232
- return;
233
- }
234
- yield `// @ts-ignore${utils_1.newLine}`; // #2304
235
- yield `[`;
236
- for (const [varName, offsets] of all) {
237
- for (const offset of offsets) {
238
- if (options.scriptSetupBindingNames.has(varName)) {
239
- // #3409
240
- yield [
241
- varName,
242
- 'template',
243
- offset,
244
- {
245
- ...codeFeatures_1.codeFeatures.additionalCompletion,
246
- ...codeFeatures_1.codeFeatures.semanticWithoutHighlight,
247
- },
248
- ];
249
- }
250
- else {
251
- yield [
252
- varName,
253
- 'template',
254
- offset,
255
- codeFeatures_1.codeFeatures.additionalCompletion,
256
- ];
257
- }
258
- yield `,`;
259
- }
260
- offsets.clear();
261
- }
262
- yield `]${utils_1.endOfLine}`;
263
- },
264
199
  enter(node) {
265
200
  if (node.type === CompilerDOM.NodeTypes.COMMENT) {
266
201
  commentBuffer.push(node);
@@ -308,17 +243,70 @@ function createTemplateCodegenContext(options, templateAst) {
308
243
  const data = stack.pop();
309
244
  commentBuffer.length = 0;
310
245
  if (data.expectError !== undefined) {
311
- yield* (0, wrapWith_1.wrapWith)(data.expectError.node.loc.start.offset, data.expectError.node.loc.end.offset, {
246
+ const token = yield* (0, boundary_1.startBoundary)('template', data.expectError.node.loc.start.offset, {
312
247
  verification: {
313
248
  // If no errors/warnings/diagnostics were reported within the region of code covered
314
249
  // by the @vue-expect-error directive, then we should allow any `unused @ts-expect-error`
315
250
  // diagnostics to be reported upward.
316
251
  shouldReport: () => data.expectError.token === 0,
317
252
  },
318
- }, `// @ts-expect-error`);
253
+ });
254
+ yield `// @ts-expect-error`;
255
+ yield (0, boundary_1.endBoundary)(token, data.expectError.node.loc.end.offset);
319
256
  yield `${utils_1.newLine}${utils_1.endOfLine}`;
320
257
  }
321
258
  },
322
259
  };
260
+ function* generateAutoImport() {
261
+ const all = [...componentAccessMap.entries()];
262
+ if (!all.some(([, offsets]) => offsets.size)) {
263
+ return;
264
+ }
265
+ yield `// @ts-ignore${utils_1.newLine}`; // #2304
266
+ yield `[`;
267
+ for (const [varName, map] of all) {
268
+ for (const [source, offsets] of map) {
269
+ for (const offset of offsets) {
270
+ yield [varName, source, offset, codeFeatures_1.codeFeatures.importCompletionOnly];
271
+ yield `,`;
272
+ }
273
+ offsets.clear();
274
+ }
275
+ }
276
+ yield `]${utils_1.endOfLine}`;
277
+ }
278
+ function resolveCodeFeatures(features) {
279
+ if (features.verification && stack.length) {
280
+ const data = stack[stack.length - 1];
281
+ if (data.ignoreError) {
282
+ // We are currently in a region of code covered by a @vue-ignore directive, so don't
283
+ // even bother performing any type-checking: set verification to false.
284
+ return {
285
+ ...features,
286
+ verification: false,
287
+ };
288
+ }
289
+ if (data.expectError !== undefined) {
290
+ // We are currently in a region of code covered by a @vue-expect-error directive. We need to
291
+ // keep track of the number of errors encountered within this region so that we can know whether
292
+ // we will need to propagate an "unused ts-expect-error" diagnostic back to the original
293
+ // .vue file or not.
294
+ return {
295
+ ...features,
296
+ verification: {
297
+ shouldReport: (source, code) => {
298
+ if (typeof features.verification !== 'object'
299
+ || !features.verification.shouldReport
300
+ || features.verification.shouldReport(source, code) === true) {
301
+ data.expectError.token++;
302
+ }
303
+ return false;
304
+ },
305
+ },
306
+ };
307
+ }
308
+ }
309
+ return features;
310
+ }
323
311
  }
324
312
  //# sourceMappingURL=context.js.map
@@ -4,34 +4,45 @@ exports.generateComponent = generateComponent;
4
4
  exports.generateElement = generateElement;
5
5
  const CompilerDOM = require("@vue/compiler-dom");
6
6
  const shared_1 = require("@vue/shared");
7
+ const muggle_string_1 = require("muggle-string");
7
8
  const shared_2 = require("../../utils/shared");
8
9
  const codeFeatures_1 = require("../codeFeatures");
9
10
  const inlayHints_1 = require("../inlayHints");
11
+ const names = require("../names");
10
12
  const utils_1 = require("../utils");
13
+ const boundary_1 = require("../utils/boundary");
11
14
  const camelized_1 = require("../utils/camelized");
12
- const wrapWith_1 = require("../utils/wrapWith");
13
- const elementChildren_1 = require("./elementChildren");
14
15
  const elementDirectives_1 = require("./elementDirectives");
15
16
  const elementEvents_1 = require("./elementEvents");
16
17
  const elementProps_1 = require("./elementProps");
17
18
  const interpolation_1 = require("./interpolation");
18
19
  const propertyAccess_1 = require("./propertyAccess");
19
20
  const styleScopedClasses_1 = require("./styleScopedClasses");
21
+ const templateChild_1 = require("./templateChild");
20
22
  const vSlot_1 = require("./vSlot");
21
23
  const colonReg = /:/g;
22
24
  function* generateComponent(options, ctx, node) {
23
25
  const tagOffsets = (0, shared_2.getElementTagOffsets)(node, options.template);
24
- const failedPropExps = [];
26
+ const failGeneratedExpressions = [];
25
27
  const possibleOriginalNames = getPossibleOriginalComponentNames(node.tag, true);
26
- const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
27
- const componentOriginalVar = matchImportName ?? ctx.getInternalVariable();
28
+ const matchConst = possibleOriginalNames.find(name => options.setupConsts.has(name));
29
+ const componentOriginalVar = matchConst ?? ctx.getInternalVariable();
28
30
  const componentFunctionalVar = ctx.getInternalVariable();
29
31
  const componentVNodeVar = ctx.getInternalVariable();
30
32
  const componentCtxVar = ctx.getInternalVariable();
33
+ const componentPropsVar = ctx.getInternalVariable();
31
34
  const isComponentTag = node.tag.toLowerCase() === 'component';
35
+ let isCtxVarUsed = false;
36
+ let isPropsVarUsed = false;
32
37
  ctx.currentComponent = {
33
- ctxVar: componentCtxVar,
34
- used: false,
38
+ get ctxVar() {
39
+ isCtxVarUsed = true;
40
+ return componentCtxVar;
41
+ },
42
+ get propsVar() {
43
+ isPropsVarUsed = true;
44
+ return componentPropsVar;
45
+ },
35
46
  };
36
47
  let props = node.props;
37
48
  let dynamicTagInfo;
@@ -60,7 +71,7 @@ function* generateComponent(options, ctx, node) {
60
71
  offsets: tagOffsets,
61
72
  };
62
73
  }
63
- if (matchImportName) {
74
+ if (matchConst) {
64
75
  // navigation support
65
76
  yield `/** @type {[`;
66
77
  for (const tagOffset of tagOffsets) {
@@ -74,26 +85,30 @@ function* generateComponent(options, ctx, node) {
74
85
  ];
75
86
  }
76
87
  else {
77
- const shouldCapitalize = matchImportName[0].toUpperCase() === matchImportName[0];
88
+ const shouldCapitalize = matchConst[0].toUpperCase() === matchConst[0];
78
89
  yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(node.tag) : node.tag, 'template', tagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
79
90
  }
80
91
  yield `, `;
81
92
  }
82
93
  yield `]} */${utils_1.endOfLine}`;
94
+ // auto import support
95
+ yield `// @ts-ignore${utils_1.newLine}`; // #2304
96
+ yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), 'template', tagOffsets[0], codeFeatures_1.codeFeatures.importCompletionOnly);
97
+ yield utils_1.endOfLine;
83
98
  }
84
99
  else if (dynamicTagInfo) {
85
100
  yield `const ${componentOriginalVar} = (`;
86
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', codeFeatures_1.codeFeatures.all, dynamicTagInfo.tag, dynamicTagInfo.offsets[0], `(`, `)`);
101
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.all, dynamicTagInfo.tag, dynamicTagInfo.offsets[0], `(`, `)`);
87
102
  if (dynamicTagInfo.offsets[1] !== undefined) {
88
103
  yield `,`;
89
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', codeFeatures_1.codeFeatures.withoutCompletion, dynamicTagInfo.tag, dynamicTagInfo.offsets[1], `(`, `)`);
104
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.withoutCompletion, dynamicTagInfo.tag, dynamicTagInfo.offsets[1], `(`, `)`);
90
105
  }
91
106
  yield `)${utils_1.endOfLine}`;
92
107
  }
93
108
  else {
94
109
  yield `const ${componentOriginalVar} = ({} as __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
95
110
  if (options.selfComponentName && possibleOriginalNames.includes(options.selfComponentName)) {
96
- yield `typeof __VLS_export, `;
111
+ yield `typeof ${names._export}, `;
97
112
  }
98
113
  else {
99
114
  yield `void, `;
@@ -115,7 +130,7 @@ function* generateComponent(options, ctx, node) {
115
130
  yield `/** @type {[`;
116
131
  for (const tagOffset of tagOffsets) {
117
132
  for (const shouldCapitalize of (node.tag[0] === node.tag[0].toUpperCase() ? [false] : [true, false])) {
118
- yield `typeof __VLS_components.`;
133
+ yield `typeof ${names.components}.`;
119
134
  yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(node.tag) : node.tag, 'template', tagOffset, codeFeatures_1.codeFeatures.navigation);
120
135
  yield `, `;
121
136
  }
@@ -123,99 +138,202 @@ function* generateComponent(options, ctx, node) {
123
138
  yield `]} */${utils_1.endOfLine}`;
124
139
  // auto import support
125
140
  yield `// @ts-ignore${utils_1.newLine}`; // #2304
126
- yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), 'template', tagOffsets[0], {
127
- completion: {
128
- isAdditional: true,
129
- onlyImport: true,
130
- },
131
- });
141
+ yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), 'template', tagOffsets[0], codeFeatures_1.codeFeatures.importCompletionOnly);
132
142
  yield utils_1.endOfLine;
133
143
  }
134
144
  }
145
+ const propCodes = [...(0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, failGeneratedExpressions)];
135
146
  yield `// @ts-ignore${utils_1.newLine}`;
136
147
  yield `const ${componentFunctionalVar} = __VLS_asFunctionalComponent(${componentOriginalVar}, new ${componentOriginalVar}({${utils_1.newLine}`;
137
- yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, false);
148
+ yield* (0, muggle_string_1.toString)(propCodes);
138
149
  yield `}))${utils_1.endOfLine}`;
139
150
  yield `const `;
140
- yield* (0, wrapWith_1.wrapWith)(node.loc.start.offset, node.loc.end.offset, codeFeatures_1.codeFeatures.doNotReportTs6133, componentVNodeVar);
151
+ const token = yield* (0, boundary_1.startBoundary)('template', node.loc.start.offset, codeFeatures_1.codeFeatures.doNotReportTs6133);
152
+ yield componentVNodeVar;
153
+ yield (0, boundary_1.endBoundary)(token, node.loc.end.offset);
141
154
  yield ` = ${componentFunctionalVar}`;
142
155
  yield* generateComponentGeneric(ctx);
143
156
  yield `(`;
144
- yield* (0, wrapWith_1.wrapWith)(tagOffsets[0], tagOffsets[0] + node.tag.length, codeFeatures_1.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, true, failedPropExps), `}`);
157
+ const token2 = yield* (0, boundary_1.startBoundary)('template', tagOffsets[0], codeFeatures_1.codeFeatures.verification);
158
+ yield `{${utils_1.newLine}`;
159
+ yield* propCodes;
160
+ yield `}`;
161
+ yield (0, boundary_1.endBoundary)(token2, tagOffsets[0] + node.tag.length);
145
162
  yield `, ...__VLS_functionalComponentArgsRest(${componentFunctionalVar}))${utils_1.endOfLine}`;
146
- yield* generateFailedPropExps(options, ctx, failedPropExps);
147
- yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, componentOriginalVar, componentFunctionalVar, componentVNodeVar, componentCtxVar);
163
+ yield* generateFailedExpressions(options, ctx, failGeneratedExpressions);
164
+ yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, componentOriginalVar);
148
165
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
149
- const reference = yield* generateElementReference(options, ctx, node);
166
+ const templateRef = getTemplateRef(node);
150
167
  const tag = (0, shared_2.hyphenateTag)(node.tag);
151
168
  const isRootNode = ctx.singleRootNodes.has(node)
152
169
  && !options.vueCompilerOptions.fallthroughComponentNames.includes(tag);
153
- if (reference || isRootNode) {
170
+ if (templateRef || isRootNode) {
154
171
  const componentInstanceVar = ctx.getInternalVariable();
155
- ctx.currentComponent.used = true;
172
+ isCtxVarUsed = true;
156
173
  yield `var ${componentInstanceVar} = {} as (Parameters<NonNullable<typeof ${componentCtxVar}['expose']>>[0] | null)`;
157
174
  if (ctx.inVFor) {
158
175
  yield `[]`;
159
176
  }
160
177
  yield utils_1.endOfLine;
161
- if (reference) {
178
+ if (templateRef) {
162
179
  const typeExp = `typeof ${ctx.getHoistVariable(componentInstanceVar)}`;
163
- ctx.addTemplateRef(reference.name, typeExp, reference.offset);
180
+ ctx.addTemplateRef(templateRef[0], typeExp, templateRef[1]);
164
181
  }
165
182
  if (isRootNode) {
166
- ctx.singleRootElTypes.push(`NonNullable<typeof ${componentInstanceVar}>['$el']`);
183
+ ctx.singleRootElTypes.add(`NonNullable<typeof ${componentInstanceVar}>['$el']`);
167
184
  }
168
185
  }
169
186
  if (hasVBindAttrs(options, ctx, node)) {
170
- const attrsVar = ctx.getInternalVariable();
171
- ctx.currentComponent.used = true;
172
- yield `var ${attrsVar}!: NonNullable<typeof ${componentCtxVar}['props']>${utils_1.endOfLine}`;
173
- ctx.inheritedAttrVars.add(attrsVar);
187
+ ctx.inheritedAttrVars.add(componentPropsVar);
188
+ isPropsVarUsed = true;
174
189
  }
175
- (0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
190
+ yield* generateStyleScopedClassReferences(options, node);
176
191
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
177
192
  yield* (0, vSlot_1.generateVSlot)(options, ctx, node, slotDir);
178
- if (ctx.currentComponent.used) {
193
+ if (isCtxVarUsed) {
179
194
  yield `var ${componentCtxVar}!: __VLS_FunctionalComponentCtx<typeof ${componentOriginalVar}, typeof ${componentVNodeVar}>${utils_1.endOfLine}`;
180
195
  }
196
+ if (isPropsVarUsed) {
197
+ yield `var ${componentPropsVar}!: __VLS_FunctionalComponentProps<typeof ${componentOriginalVar}, typeof ${componentVNodeVar}>${utils_1.endOfLine}`;
198
+ }
181
199
  }
182
200
  function* generateElement(options, ctx, node) {
183
201
  const [startTagOffset, endTagOffset] = (0, shared_2.getElementTagOffsets)(node, options.template);
184
202
  const failedPropExps = [];
185
- yield `__VLS_asFunctionalElement(__VLS_intrinsics`;
203
+ yield `__VLS_asFunctionalElement(${names.intrinsics}`;
186
204
  yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, node.tag, startTagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
187
205
  if (endTagOffset !== undefined) {
188
- yield `, __VLS_intrinsics`;
206
+ yield `, `;
207
+ yield names.intrinsics;
189
208
  yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, node.tag, endTagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
190
209
  }
191
210
  yield `)(`;
192
- yield* (0, wrapWith_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, codeFeatures_1.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, node.props, options.vueCompilerOptions.checkUnknownProps, true, failedPropExps), `}`);
211
+ const token = yield* (0, boundary_1.startBoundary)('template', startTagOffset, codeFeatures_1.codeFeatures.verification);
212
+ yield `{${utils_1.newLine}`;
213
+ yield* (0, elementProps_1.generateElementProps)(options, ctx, node, node.props, options.vueCompilerOptions.checkUnknownProps, failedPropExps);
214
+ yield `}`;
215
+ yield (0, boundary_1.endBoundary)(token, startTagOffset + node.tag.length);
193
216
  yield `)${utils_1.endOfLine}`;
194
- yield* generateFailedPropExps(options, ctx, failedPropExps);
217
+ yield* generateFailedExpressions(options, ctx, failedPropExps);
195
218
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
196
- const reference = yield* generateElementReference(options, ctx, node);
197
- if (reference) {
219
+ const templateRef = getTemplateRef(node);
220
+ if (templateRef) {
198
221
  let typeExp = `__VLS_Elements['${node.tag}']`;
199
222
  if (ctx.inVFor) {
200
223
  typeExp += `[]`;
201
224
  }
202
- ctx.addTemplateRef(reference.name, typeExp, reference.offset);
225
+ ctx.addTemplateRef(templateRef[0], typeExp, templateRef[1]);
203
226
  }
204
227
  if (ctx.singleRootNodes.has(node)) {
205
- ctx.singleRootElTypes.push(`__VLS_Elements['${node.tag}']`);
228
+ ctx.singleRootElTypes.add(`__VLS_Elements['${node.tag}']`);
206
229
  }
207
230
  if (hasVBindAttrs(options, ctx, node)) {
208
231
  ctx.inheritedAttrVars.add(`__VLS_intrinsics.${node.tag}`);
209
232
  }
210
- (0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
233
+ yield* generateStyleScopedClassReferences(options, node);
211
234
  const { currentComponent } = ctx;
212
235
  ctx.currentComponent = undefined;
213
- yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node.children);
236
+ for (const child of node.children) {
237
+ yield* (0, templateChild_1.generateTemplateChild)(options, ctx, child);
238
+ }
214
239
  ctx.currentComponent = currentComponent;
215
240
  }
216
- function* generateFailedPropExps(options, ctx, failedPropExps) {
217
- for (const failedExp of failedPropExps) {
218
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, 'template', codeFeatures_1.codeFeatures.all, failedExp.node.loc.source, failedExp.node.loc.start.offset, failedExp.prefix, failedExp.suffix);
241
+ function* generateStyleScopedClassReferences({ template, ts }, node) {
242
+ for (const prop of node.props) {
243
+ if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
244
+ && prop.name === 'class'
245
+ && prop.value) {
246
+ if (template.lang === 'pug') {
247
+ const getClassOffset = Reflect.get(prop.value.loc.start, 'getClassOffset');
248
+ const content = prop.value.loc.source.slice(1, -1);
249
+ for (const [className, pos] of forEachClassName(content)) {
250
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, getClassOffset(pos + 1));
251
+ }
252
+ }
253
+ else {
254
+ const [text, start] = (0, shared_2.normalizeAttributeValue)(prop.value);
255
+ for (const [className, offset] of forEachClassName(text)) {
256
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, start + offset);
257
+ }
258
+ }
259
+ }
260
+ else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
261
+ && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
262
+ && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
263
+ && prop.arg.content === 'class') {
264
+ const content = '(' + prop.exp.content + ')';
265
+ const startOffset = prop.exp.loc.start.offset - 1;
266
+ const ast = (0, utils_1.getTypeScriptAST)(ts, template, content);
267
+ const literals = [];
268
+ for (const node of (0, utils_1.forEachNode)(ts, ast)) {
269
+ if (!ts.isExpressionStatement(node)
270
+ || !ts.isParenthesizedExpression(node.expression)) {
271
+ continue;
272
+ }
273
+ const { expression } = node.expression;
274
+ if (ts.isStringLiteralLike(expression)) {
275
+ literals.push(expression);
276
+ }
277
+ else if (ts.isArrayLiteralExpression(expression)) {
278
+ yield* walkArrayLiteral(expression);
279
+ }
280
+ else if (ts.isObjectLiteralExpression(expression)) {
281
+ yield* walkObjectLiteral(expression);
282
+ }
283
+ }
284
+ for (const literal of literals) {
285
+ const start = literal.end - literal.text.length - 1 + startOffset;
286
+ for (const [className, offset] of forEachClassName(literal.text)) {
287
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, className, start + offset);
288
+ }
289
+ }
290
+ function* walkArrayLiteral(node) {
291
+ const { elements } = node;
292
+ for (const element of elements) {
293
+ if (ts.isStringLiteralLike(element)) {
294
+ literals.push(element);
295
+ }
296
+ else if (ts.isObjectLiteralExpression(element)) {
297
+ yield* walkObjectLiteral(element);
298
+ }
299
+ }
300
+ }
301
+ function* walkObjectLiteral(node) {
302
+ const { properties } = node;
303
+ for (const property of properties) {
304
+ if (ts.isPropertyAssignment(property)) {
305
+ const { name } = property;
306
+ if (ts.isIdentifier(name)) {
307
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, name.text, name.end - name.text.length + startOffset);
308
+ }
309
+ else if (ts.isStringLiteral(name)) {
310
+ literals.push(name);
311
+ }
312
+ else if (ts.isComputedPropertyName(name)) {
313
+ const { expression } = name;
314
+ if (ts.isStringLiteralLike(expression)) {
315
+ literals.push(expression);
316
+ }
317
+ }
318
+ }
319
+ else if (ts.isShorthandPropertyAssignment(property)) {
320
+ yield* (0, styleScopedClasses_1.generateStyleScopedClassReference)(template, property.name.text, property.name.end - property.name.text.length + startOffset);
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+ function* forEachClassName(content) {
328
+ let offset = 0;
329
+ for (const className of content.split(' ')) {
330
+ yield [className, offset];
331
+ offset += className.length + 1;
332
+ }
333
+ }
334
+ function* generateFailedExpressions(options, ctx, failGeneratedExpressions) {
335
+ for (const failedExp of failGeneratedExpressions) {
336
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, options.template, codeFeatures_1.codeFeatures.all, failedExp.node.loc.source, failedExp.node.loc.start.offset, failedExp.prefix, failedExp.suffix);
219
337
  yield utils_1.endOfLine;
220
338
  }
221
339
  }
@@ -248,28 +366,19 @@ function* generateCanonicalComponentName(tagText, offset, features) {
248
366
  function* generateComponentGeneric(ctx) {
249
367
  if (ctx.currentInfo.generic) {
250
368
  const { content, offset } = ctx.currentInfo.generic;
251
- yield* (0, wrapWith_1.wrapWith)(offset, offset + content.length, codeFeatures_1.codeFeatures.verification, `<`, [
252
- content,
253
- 'template',
254
- offset,
255
- codeFeatures_1.codeFeatures.all,
256
- ], `>`);
369
+ const token = yield* (0, boundary_1.startBoundary)('template', offset, codeFeatures_1.codeFeatures.verification);
370
+ yield `<`;
371
+ yield [content, 'template', offset, codeFeatures_1.codeFeatures.all];
372
+ yield `>`;
373
+ yield (0, boundary_1.endBoundary)(token, offset + content.length);
257
374
  }
258
375
  }
259
- function* generateElementReference(options, ctx, node) {
376
+ function getTemplateRef(node) {
260
377
  for (const prop of node.props) {
261
378
  if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
262
379
  && prop.name === 'ref'
263
380
  && prop.value) {
264
- const [name, offset] = (0, utils_1.normalizeAttributeValue)(prop.value);
265
- // navigation support for `const foo = ref()`
266
- yield `/** @type {typeof __VLS_ctx`;
267
- yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, name, offset, codeFeatures_1.codeFeatures.navigation);
268
- yield `} */${utils_1.endOfLine}`;
269
- if (utils_1.identifierRegex.test(name) && !options.templateRefNames.has(name)) {
270
- ctx.accessExternalVariable(name, offset);
271
- }
272
- return { name, offset };
381
+ return (0, shared_2.normalizeAttributeValue)(prop.value);
273
382
  }
274
383
  }
275
384
  }