@vue/language-core 3.1.5 → 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 (100) 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 +12 -18
  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 +7 -16
  28. package/lib/codegen/template/context.js +81 -93
  29. package/lib/codegen/template/element.js +151 -55
  30. package/lib/codegen/template/elementDirectives.js +32 -12
  31. package/lib/codegen/template/elementEvents.js +27 -28
  32. package/lib/codegen/template/elementProps.d.ts +2 -2
  33. package/lib/codegen/template/elementProps.js +49 -23
  34. package/lib/codegen/template/index.d.ts +8 -19
  35. package/lib/codegen/template/index.js +85 -80
  36. package/lib/codegen/template/interpolation.d.ts +3 -3
  37. package/lib/codegen/template/interpolation.js +90 -136
  38. package/lib/codegen/template/objectProperty.js +8 -4
  39. package/lib/codegen/template/propertyAccess.d.ts +1 -1
  40. package/lib/codegen/template/propertyAccess.js +5 -7
  41. package/lib/codegen/template/slotOutlet.js +25 -8
  42. package/lib/codegen/template/styleScopedClasses.d.ts +3 -6
  43. package/lib/codegen/template/styleScopedClasses.js +23 -149
  44. package/lib/codegen/template/templateChild.d.ts +0 -1
  45. package/lib/codegen/template/templateChild.js +11 -68
  46. package/lib/codegen/template/vFor.js +10 -13
  47. package/lib/codegen/template/vIf.js +5 -3
  48. package/lib/codegen/template/vSlot.js +20 -15
  49. package/lib/codegen/utils/boundary.d.ts +3 -0
  50. package/lib/codegen/utils/boundary.js +13 -0
  51. package/lib/codegen/utils/camelized.js +3 -3
  52. package/lib/codegen/utils/escaped.js +4 -2
  53. package/lib/codegen/utils/index.d.ts +3 -4
  54. package/lib/codegen/utils/index.js +42 -16
  55. package/lib/codegen/utils/merge.d.ts +2 -2
  56. package/lib/codegen/utils/merge.js +9 -9
  57. package/lib/codegen/utils/stringLiteralKey.js +6 -3
  58. package/lib/codegen/utils/transform.d.ts +8 -0
  59. package/lib/codegen/utils/transform.js +27 -0
  60. package/lib/codegen/utils/unicode.js +4 -2
  61. package/lib/compilerOptions.d.ts +5 -2
  62. package/lib/compilerOptions.js +67 -44
  63. package/lib/languagePlugin.d.ts +1 -1
  64. package/lib/languagePlugin.js +2 -2
  65. package/lib/plugins/vue-template-inline-css.js +2 -6
  66. package/lib/plugins/vue-template-inline-ts.js +12 -14
  67. package/lib/plugins/vue-tsx.d.ts +11 -20
  68. package/lib/plugins/vue-tsx.js +121 -68
  69. package/lib/plugins.js +1 -1
  70. package/lib/types.d.ts +5 -4
  71. package/lib/utils/parseSfc.js +7 -3
  72. package/lib/utils/shared.d.ts +1 -1
  73. package/lib/utils/shared.js +7 -6
  74. package/lib/utils/signals.d.ts +2 -2
  75. package/lib/utils/signals.js +8 -6
  76. package/lib/virtualCode/embeddedCodes.d.ts +12 -0
  77. package/lib/virtualCode/embeddedCodes.js +249 -0
  78. package/lib/{virtualFile/vueFile.d.ts → virtualCode/index.d.ts} +9 -9
  79. package/lib/virtualCode/index.js +81 -0
  80. package/lib/virtualCode/ir.d.ts +4 -0
  81. package/lib/{virtualFile/computedSfc.js → virtualCode/ir.js} +59 -94
  82. package/lib/virtualCode/normalize.d.ts +2 -0
  83. package/lib/virtualCode/normalize.js +170 -0
  84. package/package.json +4 -4
  85. package/lib/codegen/style/classProperty.d.ts +0 -2
  86. package/lib/codegen/style/classProperty.js +0 -18
  87. package/lib/codegen/style/imports.d.ts +0 -2
  88. package/lib/codegen/style/imports.js +0 -27
  89. package/lib/codegen/template/elementChildren.d.ts +0 -5
  90. package/lib/codegen/template/elementChildren.js +0 -12
  91. package/lib/codegen/utils/wrapWith.d.ts +0 -2
  92. package/lib/codegen/utils/wrapWith.js +0 -15
  93. package/lib/virtualFile/computedEmbeddedCodes.d.ts +0 -4
  94. package/lib/virtualFile/computedEmbeddedCodes.js +0 -262
  95. package/lib/virtualFile/computedSfc.d.ts +0 -6
  96. package/lib/virtualFile/computedVueSfc.d.ts +0 -4
  97. package/lib/virtualFile/computedVueSfc.js +0 -41
  98. package/lib/virtualFile/embeddedFile.d.ts +0 -11
  99. package/lib/virtualFile/embeddedFile.js +0 -14
  100. 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,72 +103,33 @@ 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,
@@ -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)('template', 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
@@ -8,24 +8,25 @@ const muggle_string_1 = require("muggle-string");
8
8
  const shared_2 = require("../../utils/shared");
9
9
  const codeFeatures_1 = require("../codeFeatures");
10
10
  const inlayHints_1 = require("../inlayHints");
11
+ const names = require("../names");
11
12
  const utils_1 = require("../utils");
13
+ const boundary_1 = require("../utils/boundary");
12
14
  const camelized_1 = require("../utils/camelized");
13
- const wrapWith_1 = require("../utils/wrapWith");
14
- const elementChildren_1 = require("./elementChildren");
15
15
  const elementDirectives_1 = require("./elementDirectives");
16
16
  const elementEvents_1 = require("./elementEvents");
17
17
  const elementProps_1 = require("./elementProps");
18
18
  const interpolation_1 = require("./interpolation");
19
19
  const propertyAccess_1 = require("./propertyAccess");
20
20
  const styleScopedClasses_1 = require("./styleScopedClasses");
21
+ const templateChild_1 = require("./templateChild");
21
22
  const vSlot_1 = require("./vSlot");
22
23
  const colonReg = /:/g;
23
24
  function* generateComponent(options, ctx, node) {
24
25
  const tagOffsets = (0, shared_2.getElementTagOffsets)(node, options.template);
25
- const failedPropExps = [];
26
+ const failGeneratedExpressions = [];
26
27
  const possibleOriginalNames = getPossibleOriginalComponentNames(node.tag, true);
27
- const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
28
- const componentOriginalVar = matchImportName ?? ctx.getInternalVariable();
28
+ const matchConst = possibleOriginalNames.find(name => options.setupConsts.has(name));
29
+ const componentOriginalVar = matchConst ?? ctx.getInternalVariable();
29
30
  const componentFunctionalVar = ctx.getInternalVariable();
30
31
  const componentVNodeVar = ctx.getInternalVariable();
31
32
  const componentCtxVar = ctx.getInternalVariable();
@@ -70,7 +71,7 @@ function* generateComponent(options, ctx, node) {
70
71
  offsets: tagOffsets,
71
72
  };
72
73
  }
73
- if (matchImportName) {
74
+ if (matchConst) {
74
75
  // navigation support
75
76
  yield `/** @type {[`;
76
77
  for (const tagOffset of tagOffsets) {
@@ -84,26 +85,30 @@ function* generateComponent(options, ctx, node) {
84
85
  ];
85
86
  }
86
87
  else {
87
- const shouldCapitalize = matchImportName[0].toUpperCase() === matchImportName[0];
88
+ const shouldCapitalize = matchConst[0].toUpperCase() === matchConst[0];
88
89
  yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(node.tag) : node.tag, 'template', tagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
89
90
  }
90
91
  yield `, `;
91
92
  }
92
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;
93
98
  }
94
99
  else if (dynamicTagInfo) {
95
100
  yield `const ${componentOriginalVar} = (`;
96
- 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], `(`, `)`);
97
102
  if (dynamicTagInfo.offsets[1] !== undefined) {
98
103
  yield `,`;
99
- 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], `(`, `)`);
100
105
  }
101
106
  yield `)${utils_1.endOfLine}`;
102
107
  }
103
108
  else {
104
109
  yield `const ${componentOriginalVar} = ({} as __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
105
110
  if (options.selfComponentName && possibleOriginalNames.includes(options.selfComponentName)) {
106
- yield `typeof __VLS_export, `;
111
+ yield `typeof ${names._export}, `;
107
112
  }
108
113
  else {
109
114
  yield `void, `;
@@ -125,7 +130,7 @@ function* generateComponent(options, ctx, node) {
125
130
  yield `/** @type {[`;
126
131
  for (const tagOffset of tagOffsets) {
127
132
  for (const shouldCapitalize of (node.tag[0] === node.tag[0].toUpperCase() ? [false] : [true, false])) {
128
- yield `typeof __VLS_components.`;
133
+ yield `typeof ${names.components}.`;
129
134
  yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(node.tag) : node.tag, 'template', tagOffset, codeFeatures_1.codeFeatures.navigation);
130
135
  yield `, `;
131
136
  }
@@ -133,35 +138,36 @@ function* generateComponent(options, ctx, node) {
133
138
  yield `]} */${utils_1.endOfLine}`;
134
139
  // auto import support
135
140
  yield `// @ts-ignore${utils_1.newLine}`; // #2304
136
- yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), 'template', tagOffsets[0], {
137
- completion: {
138
- isAdditional: true,
139
- onlyImport: true,
140
- },
141
- });
141
+ yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), 'template', tagOffsets[0], codeFeatures_1.codeFeatures.importCompletionOnly);
142
142
  yield utils_1.endOfLine;
143
143
  }
144
144
  }
145
- const propCodes = [...(0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, failedPropExps)];
145
+ const propCodes = [...(0, elementProps_1.generateElementProps)(options, ctx, node, props, options.vueCompilerOptions.checkUnknownProps, failGeneratedExpressions)];
146
146
  yield `// @ts-ignore${utils_1.newLine}`;
147
147
  yield `const ${componentFunctionalVar} = __VLS_asFunctionalComponent(${componentOriginalVar}, new ${componentOriginalVar}({${utils_1.newLine}`;
148
148
  yield* (0, muggle_string_1.toString)(propCodes);
149
149
  yield `}))${utils_1.endOfLine}`;
150
150
  yield `const `;
151
- yield* (0, wrapWith_1.wrapWith)('template', 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);
152
154
  yield ` = ${componentFunctionalVar}`;
153
155
  yield* generateComponentGeneric(ctx);
154
156
  yield `(`;
155
- yield* (0, wrapWith_1.wrapWith)('template', tagOffsets[0], tagOffsets[0] + node.tag.length, codeFeatures_1.codeFeatures.verification, `{${utils_1.newLine}`, ...propCodes, `}`);
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);
156
162
  yield `, ...__VLS_functionalComponentArgsRest(${componentFunctionalVar}))${utils_1.endOfLine}`;
157
- yield* generateFailedPropExps(options, ctx, failedPropExps);
163
+ yield* generateFailedExpressions(options, ctx, failGeneratedExpressions);
158
164
  yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, componentOriginalVar);
159
165
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
160
- const reference = yield* generateElementReference(options, ctx, node);
166
+ const templateRef = getTemplateRef(node);
161
167
  const tag = (0, shared_2.hyphenateTag)(node.tag);
162
168
  const isRootNode = ctx.singleRootNodes.has(node)
163
169
  && !options.vueCompilerOptions.fallthroughComponentNames.includes(tag);
164
- if (reference || isRootNode) {
170
+ if (templateRef || isRootNode) {
165
171
  const componentInstanceVar = ctx.getInternalVariable();
166
172
  isCtxVarUsed = true;
167
173
  yield `var ${componentInstanceVar} = {} as (Parameters<NonNullable<typeof ${componentCtxVar}['expose']>>[0] | null)`;
@@ -169,9 +175,9 @@ function* generateComponent(options, ctx, node) {
169
175
  yield `[]`;
170
176
  }
171
177
  yield utils_1.endOfLine;
172
- if (reference) {
178
+ if (templateRef) {
173
179
  const typeExp = `typeof ${ctx.getHoistVariable(componentInstanceVar)}`;
174
- ctx.addTemplateRef(reference.name, typeExp, reference.offset);
180
+ ctx.addTemplateRef(templateRef[0], typeExp, templateRef[1]);
175
181
  }
176
182
  if (isRootNode) {
177
183
  ctx.singleRootElTypes.add(`NonNullable<typeof ${componentInstanceVar}>['$el']`);
@@ -181,7 +187,7 @@ function* generateComponent(options, ctx, node) {
181
187
  ctx.inheritedAttrVars.add(componentPropsVar);
182
188
  isPropsVarUsed = true;
183
189
  }
184
- (0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
190
+ yield* generateStyleScopedClassReferences(options, node);
185
191
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
186
192
  yield* (0, vSlot_1.generateVSlot)(options, ctx, node, slotDir);
187
193
  if (isCtxVarUsed) {
@@ -194,24 +200,29 @@ function* generateComponent(options, ctx, node) {
194
200
  function* generateElement(options, ctx, node) {
195
201
  const [startTagOffset, endTagOffset] = (0, shared_2.getElementTagOffsets)(node, options.template);
196
202
  const failedPropExps = [];
197
- yield `__VLS_asFunctionalElement(__VLS_intrinsics`;
203
+ yield `__VLS_asFunctionalElement(${names.intrinsics}`;
198
204
  yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, node.tag, startTagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
199
205
  if (endTagOffset !== undefined) {
200
- yield `, __VLS_intrinsics`;
206
+ yield `, `;
207
+ yield names.intrinsics;
201
208
  yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, node.tag, endTagOffset, codeFeatures_1.codeFeatures.withoutHighlightAndCompletion);
202
209
  }
203
210
  yield `)(`;
204
- yield* (0, wrapWith_1.wrapWith)('template', startTagOffset, startTagOffset + node.tag.length, codeFeatures_1.codeFeatures.verification, `{${utils_1.newLine}`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, node.props, options.vueCompilerOptions.checkUnknownProps, 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);
205
216
  yield `)${utils_1.endOfLine}`;
206
- yield* generateFailedPropExps(options, ctx, failedPropExps);
217
+ yield* generateFailedExpressions(options, ctx, failedPropExps);
207
218
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
208
- const reference = yield* generateElementReference(options, ctx, node);
209
- if (reference) {
219
+ const templateRef = getTemplateRef(node);
220
+ if (templateRef) {
210
221
  let typeExp = `__VLS_Elements['${node.tag}']`;
211
222
  if (ctx.inVFor) {
212
223
  typeExp += `[]`;
213
224
  }
214
- ctx.addTemplateRef(reference.name, typeExp, reference.offset);
225
+ ctx.addTemplateRef(templateRef[0], typeExp, templateRef[1]);
215
226
  }
216
227
  if (ctx.singleRootNodes.has(node)) {
217
228
  ctx.singleRootElTypes.add(`__VLS_Elements['${node.tag}']`);
@@ -219,15 +230,110 @@ function* generateElement(options, ctx, node) {
219
230
  if (hasVBindAttrs(options, ctx, node)) {
220
231
  ctx.inheritedAttrVars.add(`__VLS_intrinsics.${node.tag}`);
221
232
  }
222
- (0, styleScopedClasses_1.collectStyleScopedClassReferences)(options, ctx, node);
233
+ yield* generateStyleScopedClassReferences(options, node);
223
234
  const { currentComponent } = ctx;
224
235
  ctx.currentComponent = undefined;
225
- 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
+ }
226
239
  ctx.currentComponent = currentComponent;
227
240
  }
228
- function* generateFailedPropExps(options, ctx, failedPropExps) {
229
- for (const failedExp of failedPropExps) {
230
- 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);
231
337
  yield utils_1.endOfLine;
232
338
  }
233
339
  }
@@ -260,29 +366,19 @@ function* generateCanonicalComponentName(tagText, offset, features) {
260
366
  function* generateComponentGeneric(ctx) {
261
367
  if (ctx.currentInfo.generic) {
262
368
  const { content, offset } = ctx.currentInfo.generic;
263
- yield* (0, wrapWith_1.wrapWith)('template', offset, offset + content.length, codeFeatures_1.codeFeatures.verification, `<`, [
264
- content,
265
- 'template',
266
- offset,
267
- codeFeatures_1.codeFeatures.all,
268
- ], `>`);
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);
269
374
  }
270
375
  }
271
- function* generateElementReference(options, ctx, node) {
376
+ function getTemplateRef(node) {
272
377
  for (const prop of node.props) {
273
378
  if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
274
379
  && prop.name === 'ref'
275
380
  && prop.value) {
276
- const name = prop.value.content;
277
- const offset = (0, shared_2.getAttributeValueOffset)(prop.value);
278
- // navigation support for `const foo = ref()`
279
- yield `/** @type {typeof __VLS_ctx`;
280
- yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, name, offset, codeFeatures_1.codeFeatures.navigation);
281
- yield `} */${utils_1.endOfLine}`;
282
- if (utils_1.identifierRegex.test(name) && !options.templateRefNames.has(name)) {
283
- ctx.accessExternalVariable(name, offset);
284
- }
285
- return { name, offset };
381
+ return (0, shared_2.normalizeAttributeValue)(prop.value);
286
382
  }
287
383
  }
288
384
  }