@vue/language-core 2.0.29 → 2.1.0

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 (72) hide show
  1. package/index.d.ts +4 -3
  2. package/index.js +4 -3
  3. package/lib/codegen/common.d.ts +2 -1
  4. package/lib/codegen/common.js +16 -5
  5. package/lib/codegen/globalTypes.d.ts +1 -0
  6. package/lib/codegen/globalTypes.js +123 -0
  7. package/lib/codegen/localTypes.d.ts +14 -0
  8. package/lib/codegen/localTypes.js +120 -0
  9. package/lib/codegen/script/component.d.ts +1 -4
  10. package/lib/codegen/script/component.js +112 -63
  11. package/lib/codegen/script/context.d.ts +14 -10
  12. package/lib/codegen/script/context.js +5 -107
  13. package/lib/codegen/script/index.d.ts +3 -2
  14. package/lib/codegen/script/index.js +37 -53
  15. package/lib/codegen/script/internalComponent.d.ts +1 -1
  16. package/lib/codegen/script/internalComponent.js +13 -5
  17. package/lib/codegen/script/scriptSetup.js +144 -62
  18. package/lib/codegen/script/template.d.ts +3 -0
  19. package/lib/codegen/script/template.js +80 -79
  20. package/lib/codegen/template/context.d.ts +6 -1
  21. package/lib/codegen/template/context.js +9 -2
  22. package/lib/codegen/template/element.d.ts +1 -1
  23. package/lib/codegen/template/element.js +214 -92
  24. package/lib/codegen/template/elementChildren.js +1 -0
  25. package/lib/codegen/template/elementDirectives.js +8 -4
  26. package/lib/codegen/template/elementEvents.js +13 -14
  27. package/lib/codegen/template/elementProps.js +43 -22
  28. package/lib/codegen/template/index.d.ts +3 -0
  29. package/lib/codegen/template/index.js +29 -41
  30. package/lib/codegen/template/interpolation.d.ts +1 -1
  31. package/lib/codegen/template/interpolation.js +24 -15
  32. package/lib/codegen/template/objectProperty.d.ts +1 -1
  33. package/lib/codegen/template/objectProperty.js +7 -2
  34. package/lib/codegen/template/styleScopedClasses.d.ts +3 -0
  35. package/lib/codegen/template/styleScopedClasses.js +72 -0
  36. package/lib/codegen/template/templateChild.js +5 -1
  37. package/lib/codegen/types.d.ts +9 -0
  38. package/lib/codegen/types.js +3 -0
  39. package/lib/languagePlugin.d.ts +2 -4
  40. package/lib/languagePlugin.js +4 -57
  41. package/lib/parsers/scriptRanges.d.ts +1 -0
  42. package/lib/parsers/scriptRanges.js +5 -0
  43. package/lib/parsers/scriptSetupRanges.d.ts +17 -3
  44. package/lib/parsers/scriptSetupRanges.js +127 -44
  45. package/lib/plugins/file-md.js +9 -6
  46. package/lib/plugins/vue-root-tags.js +51 -0
  47. package/lib/plugins/vue-tsx.d.ts +40 -3
  48. package/lib/plugins/vue-tsx.js +17 -4
  49. package/lib/plugins.js +2 -0
  50. package/lib/types.d.ts +14 -10
  51. package/lib/utils/findDestructuredProps.js +3 -0
  52. package/lib/utils/parseCssClassNames.js +4 -6
  53. package/lib/utils/parseCssVars.js +5 -7
  54. package/lib/utils/parseSfc.js +4 -1
  55. package/lib/utils/ts.js +8 -2
  56. package/lib/virtualFile/{computedFiles.d.ts → computedEmbeddedCodes.d.ts} +1 -1
  57. package/lib/virtualFile/{computedFiles.js → computedEmbeddedCodes.js} +3 -3
  58. package/lib/virtualFile/computedSfc.d.ts +1 -1
  59. package/lib/virtualFile/computedSfc.js +14 -3
  60. package/lib/virtualFile/vueFile.d.ts +13 -3
  61. package/lib/virtualFile/vueFile.js +17 -9
  62. package/package.json +4 -4
  63. package/lib/codegen/script/globalTypes.d.ts +0 -2
  64. package/lib/codegen/script/globalTypes.js +0 -134
  65. package/lib/codegen/template/objectKey.js +0 -34
  66. package/lib/languageModule.d.ts +0 -5
  67. package/lib/languageModule.js +0 -159
  68. package/lib/plugins/file-dot-setup.js +0 -34
  69. package/lib/virtualFile/computedMappings.d.ts +0 -4
  70. package/lib/virtualFile/computedMappings.js +0 -65
  71. /package/lib/plugins/{file-dot-setup.d.ts → vue-root-tags.d.ts} +0 -0
  72. /package/lib/{codegen/template/objectKey.d.ts → utils/findDestructuredProps.d.ts} +0 -0
@@ -17,11 +17,12 @@ const interpolation_1 = require("./interpolation");
17
17
  const propertyAccess_1 = require("./propertyAccess");
18
18
  const templateChild_1 = require("./templateChild");
19
19
  const objectProperty_1 = require("./objectProperty");
20
+ const scriptSetupRanges_1 = require("../../parsers/scriptSetupRanges");
20
21
  const colonReg = /:/g;
21
- function* generateComponent(options, ctx, node, currentComponent, componentCtxVar) {
22
+ function* generateComponent(options, ctx, node, currentComponent) {
22
23
  const startTagOffset = node.loc.start.offset + options.template.content.substring(node.loc.start.offset).indexOf(node.tag);
23
24
  const endTagOffset = !node.isSelfClosing && options.template.lang === 'html' ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) : undefined;
24
- const tagOffsets = endTagOffset !== undefined
25
+ const tagOffsets = endTagOffset !== undefined && endTagOffset > startTagOffset
25
26
  ? [startTagOffset, endTagOffset]
26
27
  : [startTagOffset];
27
28
  const propsFailedExps = [];
@@ -41,7 +42,7 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
41
42
  if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) {
42
43
  dynamicTagInfo = {
43
44
  exp: prop.exp.loc.source,
44
- offset: prop.exp.loc.start.offset,
45
+ offsets: [prop.exp.loc.start.offset, undefined],
45
46
  astHolder: prop.exp.loc,
46
47
  };
47
48
  props = props.filter(p => p !== prop);
@@ -54,7 +55,7 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
54
55
  dynamicTagInfo = {
55
56
  exp: node.tag,
56
57
  astHolder: node.loc,
57
- offset: startTagOffset,
58
+ offsets: [startTagOffset, endTagOffset],
58
59
  };
59
60
  }
60
61
  if (matchImportName) {
@@ -84,57 +85,54 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
84
85
  yield `]${common_1.endOfLine}`;
85
86
  }
86
87
  else if (dynamicTagInfo) {
87
- yield `const ${var_originalComponent} = `;
88
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offset, ctx.codeFeatures.all, '(', ')');
89
- yield common_1.endOfLine;
88
+ yield `const ${var_originalComponent} = (`;
89
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[0], ctx.codeFeatures.all, '(', ')');
90
+ if (dynamicTagInfo.offsets[1] !== undefined) {
91
+ yield `,`;
92
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[1], {
93
+ ...ctx.codeFeatures.all,
94
+ completion: false,
95
+ }, '(', ')');
96
+ }
97
+ yield `)${common_1.endOfLine}`;
90
98
  }
91
99
  else if (!isComponentTag) {
92
- yield `// @ts-ignore${common_1.newLine}`;
93
- yield `const ${var_originalComponent} = ({} as `;
94
- for (const componentName of possibleOriginalNames) {
95
- yield `'${componentName}' extends keyof typeof __VLS_ctx ? { '${getCanonicalComponentName(node.tag)}': typeof __VLS_ctx`;
96
- yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, componentName);
97
- yield ` }: `;
98
- }
99
- yield `typeof __VLS_resolvedLocalAndGlobalComponents)${common_1.newLine}`;
100
- yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, getCanonicalComponentName(node.tag), startTagOffset, ctx.codeFeatures.verification);
101
- yield common_1.endOfLine;
102
- // hover support
103
- for (const offset of tagOffsets) {
104
- yield `({} as { ${getCanonicalComponentName(node.tag)}: typeof ${var_originalComponent} }).`;
105
- yield* generateCanonicalComponentName(node.tag, offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation);
106
- yield common_1.endOfLine;
107
- }
100
+ yield `const ${var_originalComponent} = __VLS_resolvedLocalAndGlobalComponents.`;
101
+ yield* generateCanonicalComponentName(node.tag, startTagOffset, {
102
+ // with hover support
103
+ ...ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation,
104
+ ...ctx.codeFeatures.verification,
105
+ });
106
+ yield `${common_1.endOfLine}`;
108
107
  const camelizedTag = (0, shared_1.camelize)(node.tag);
109
108
  if (common_1.variableNameRegex.test(camelizedTag)) {
110
109
  // renaming / find references support
110
+ yield `/** @type { [`;
111
111
  for (const tagOffset of tagOffsets) {
112
112
  for (const shouldCapitalize of (node.tag[0] === node.tag[0].toUpperCase() ? [false] : [true, false])) {
113
113
  const expectName = shouldCapitalize ? (0, shared_1.capitalize)(camelizedTag) : camelizedTag;
114
- yield `__VLS_components.`;
114
+ yield `typeof __VLS_components.`;
115
115
  yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(node.tag) : node.tag, tagOffset, {
116
116
  navigation: {
117
117
  resolveRenameNewName: node.tag !== expectName ? camelizeComponentName : undefined,
118
118
  resolveRenameEditText: getTagRenameApply(node.tag),
119
119
  },
120
120
  });
121
- yield `;`;
121
+ yield `, `;
122
122
  }
123
123
  }
124
- yield `${common_1.newLine}`;
124
+ yield `] } */${common_1.newLine}`;
125
125
  // auto import support
126
- yield `// @ts-ignore${common_1.newLine}`; // #2304
127
- yield `[`;
128
- for (const tagOffset of tagOffsets) {
129
- yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), tagOffset, {
126
+ if (options.edited) {
127
+ yield `// @ts-ignore${common_1.newLine}`; // #2304
128
+ yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), startTagOffset, {
130
129
  completion: {
131
130
  isAdditional: true,
132
131
  onlyImport: true,
133
132
  },
134
133
  });
135
- yield `,`;
134
+ yield `${common_1.endOfLine}`;
136
135
  }
137
- yield `]${common_1.endOfLine}`;
138
136
  }
139
137
  }
140
138
  else {
@@ -144,44 +142,52 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
144
142
  yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`;
145
143
  yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, false);
146
144
  yield `}))${common_1.endOfLine}`;
147
- if (options.vueCompilerOptions.strictTemplates) {
148
- // with strictTemplates, generate once for props type-checking + instance type
149
- yield `const ${var_componentInstance} = ${var_functionalComponent}(`;
150
- yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
151
- yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
152
- }
153
- else {
154
- // without strictTemplates, this only for instacne type
155
- yield `const ${var_componentInstance} = ${var_functionalComponent}({`;
156
- yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, false);
157
- yield `}, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
158
- // and this for props type-checking
159
- yield `({} as (props: __VLS_FunctionalComponentProps<typeof ${var_originalComponent}, typeof ${var_componentInstance}> & Record<string, unknown>) => void)(`;
160
- yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
161
- yield `)${common_1.endOfLine}`;
162
- }
163
- componentCtxVar = var_defineComponentCtx;
145
+ yield `const ${var_componentInstance} = ${var_functionalComponent}(`;
146
+ yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
147
+ yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
164
148
  currentComponent = node;
165
149
  for (const failedExp of propsFailedExps) {
166
150
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, failedExp.node.loc.source, failedExp.node.loc, failedExp.node.loc.start.offset, ctx.codeFeatures.all, failedExp.prefix, failedExp.suffix);
167
151
  yield common_1.endOfLine;
168
152
  }
169
- yield* generateVScope(options, ctx, node, props);
170
- ctx.usedComponentCtxVars.add(componentCtxVar);
171
- const usedComponentEventsVar = yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents);
172
- if (var_defineComponentCtx && ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
173
- yield `const ${componentCtxVar} = __VLS_nonNullable(__VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance}))${common_1.endOfLine}`;
153
+ const refName = yield* generateVScope(options, ctx, node, props);
154
+ if (refName) {
155
+ ctx.usedComponentCtxVars.add(var_defineComponentCtx);
174
156
  }
157
+ const usedComponentEventsVar = yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents);
175
158
  if (usedComponentEventsVar) {
176
- yield `let ${var_componentEmit}!: typeof ${componentCtxVar}.emit${common_1.endOfLine}`;
159
+ ctx.usedComponentCtxVars.add(var_defineComponentCtx);
160
+ yield `let ${var_componentEmit}!: typeof ${var_defineComponentCtx}.emit${common_1.endOfLine}`;
177
161
  yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${var_componentEmit}>${common_1.endOfLine}`;
178
162
  }
163
+ if (options.vueCompilerOptions.fallthroughAttributes
164
+ && (node.props.some(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.exp?.loc.source === '$attrs')
165
+ || node === ctx.singleRootNode)) {
166
+ const varAttrs = ctx.getInternalVariable();
167
+ ctx.inheritedAttrVars.add(varAttrs);
168
+ yield `var ${varAttrs}!: Parameters<typeof ${var_functionalComponent}>[0];\n`;
169
+ }
179
170
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
180
171
  if (slotDir) {
181
- yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
172
+ yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, var_defineComponentCtx);
182
173
  }
183
174
  else {
184
- yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, componentCtxVar);
175
+ yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, var_defineComponentCtx);
176
+ }
177
+ if (ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
178
+ yield `const ${var_defineComponentCtx} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})${common_1.endOfLine}`;
179
+ if (refName) {
180
+ yield `// @ts-ignore${common_1.newLine}`;
181
+ if (node.codegenNode?.type === CompilerDOM.NodeTypes.VNODE_CALL
182
+ && node.codegenNode.props?.type === CompilerDOM.NodeTypes.JS_OBJECT_EXPRESSION
183
+ && node.codegenNode.props.properties.find(({ key }) => key.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && key.content === 'ref_for')) {
184
+ yield `(${refName} ??= []).push(${var_defineComponentCtx})`;
185
+ }
186
+ else {
187
+ yield `${refName} = ${var_defineComponentCtx}`;
188
+ }
189
+ yield common_1.endOfLine;
190
+ }
185
191
  }
186
192
  }
187
193
  function* generateElement(options, ctx, node, currentComponent, componentCtxVar) {
@@ -203,7 +209,13 @@ function* generateElement(options, ctx, node, currentComponent, componentCtxVar)
203
209
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, failedExp.node.loc.source, failedExp.node.loc, failedExp.node.loc.start.offset, ctx.codeFeatures.all, failedExp.prefix, failedExp.suffix);
204
210
  yield common_1.endOfLine;
205
211
  }
206
- yield* generateVScope(options, ctx, node, node.props);
212
+ const refName = yield* generateVScope(options, ctx, node, node.props);
213
+ if (refName) {
214
+ yield `// @ts-ignore${common_1.newLine}`;
215
+ yield `${refName} = __VLS_intrinsicElements`;
216
+ yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, node.tag);
217
+ yield common_1.endOfLine;
218
+ }
207
219
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
208
220
  if (slotDir && componentCtxVar) {
209
221
  yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
@@ -211,6 +223,11 @@ function* generateElement(options, ctx, node, currentComponent, componentCtxVar)
211
223
  else {
212
224
  yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, componentCtxVar);
213
225
  }
226
+ if (options.vueCompilerOptions.fallthroughAttributes
227
+ && (node.props.some(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.exp?.loc.source === '$attrs')
228
+ || node === ctx.singleRootNode)) {
229
+ ctx.inheritedAttrVars.add(`__VLS_intrinsicElements.${node.tag}`);
230
+ }
214
231
  }
215
232
  function* generateVScope(options, ctx, node, props) {
216
233
  const vScope = props.find(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && (prop.name === 'scope' || prop.name === 'data'));
@@ -232,12 +249,13 @@ function* generateVScope(options, ctx, node, props) {
232
249
  inScope = true;
233
250
  }
234
251
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
235
- yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
236
- yield* generateReferencesForScopedCssClasses(ctx, node);
252
+ const refName = yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
253
+ yield* generateReferencesForScopedCssClasses(options, ctx, node);
237
254
  if (inScope) {
238
255
  yield `}${common_1.newLine}`;
239
256
  ctx.blockConditions.length = originalConditionsNum;
240
257
  }
258
+ return refName;
241
259
  }
242
260
  function getCanonicalComponentName(tagText) {
243
261
  return common_1.variableNameRegex.test(tagText)
@@ -274,7 +292,7 @@ function* generateComponentSlot(options, ctx, node, slotDir, currentComponent, c
274
292
  const slotBlockVars = [];
275
293
  yield `const {`;
276
294
  if (slotDir?.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && slotDir.arg.content) {
277
- yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slotDir.arg.loc.source, slotDir.arg.loc.start.offset, slotDir.arg.isStatic ? ctx.codeFeatures.withoutHighlight : ctx.codeFeatures.all, slotDir.arg.loc);
295
+ yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slotDir.arg.loc.source, slotDir.arg.loc.start.offset, slotDir.arg.isStatic ? ctx.codeFeatures.withoutHighlight : ctx.codeFeatures.all, slotDir.arg.loc, false, true);
278
296
  yield ': __VLS_thisSlot';
279
297
  }
280
298
  else {
@@ -347,56 +365,123 @@ function* generateReferencesForElements(options, ctx, node) {
347
365
  if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
348
366
  && prop.name === 'ref'
349
367
  && prop.value) {
368
+ const [content, startOffset] = normalizeAttributeValue(prop.value);
350
369
  yield `// @ts-ignore${common_1.newLine}`;
351
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, prop.value.content, prop.value.loc, prop.value.loc.start.offset + 1, ctx.codeFeatures.navigation, '(', ')');
370
+ yield `__VLS_ctx`;
371
+ yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, content, startOffset, ctx.codeFeatures.navigation, prop.value.loc);
352
372
  yield common_1.endOfLine;
373
+ if (common_1.variableNameRegex.test(content)) {
374
+ ctx.accessExternalVariable(content, startOffset);
375
+ }
376
+ const refName = CompilerDOM.toValidAssetId(prop.value.content, '_VLS_refs');
377
+ options.templateRefNames.set(prop.value.content, refName);
378
+ return refName;
353
379
  }
354
380
  }
355
381
  }
356
- function* generateReferencesForScopedCssClasses(ctx, node) {
382
+ function* generateReferencesForScopedCssClasses(options, ctx, node) {
357
383
  for (const prop of node.props) {
358
384
  if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
359
385
  && prop.name === 'class'
360
386
  && prop.value) {
361
- let startOffset = prop.value.loc.start.offset;
362
- let content = prop.value.loc.source;
363
- if ((content.startsWith(`'`) && content.endsWith(`'`))
364
- || (content.startsWith(`"`) && content.endsWith(`"`))) {
365
- startOffset++;
366
- content = content.slice(1, -1);
367
- }
368
- if (content) {
369
- let currentClassName = '';
370
- for (const char of (content + ' ')) {
371
- if (char.trim() === '') {
372
- if (currentClassName !== '') {
373
- ctx.scopedClasses.push({ className: currentClassName, offset: startOffset });
374
- startOffset += currentClassName.length;
375
- currentClassName = '';
376
- }
377
- startOffset += char.length;
378
- }
379
- else {
380
- currentClassName += char;
387
+ if (options.template.lang === 'pug') {
388
+ const getClassOffset = Reflect.get(prop.value.loc.start, 'getClassOffset');
389
+ const content = prop.value.loc.source.slice(1, -1);
390
+ let startOffset = 1;
391
+ for (const className of content.split(' ')) {
392
+ if (className) {
393
+ ctx.scopedClasses.push({
394
+ source: 'template',
395
+ className,
396
+ offset: getClassOffset(startOffset),
397
+ });
381
398
  }
399
+ startOffset += className.length + 1;
382
400
  }
383
401
  }
384
402
  else {
385
- ctx.emptyClassOffsets.push(startOffset);
403
+ let isWrapped = false;
404
+ const [content, startOffset] = normalizeAttributeValue(prop.value);
405
+ if (content) {
406
+ const classes = collectClasses(content, startOffset + (isWrapped ? 1 : 0));
407
+ ctx.scopedClasses.push(...classes);
408
+ }
409
+ else {
410
+ ctx.emptyClassOffsets.push(startOffset);
411
+ }
386
412
  }
387
413
  }
388
414
  else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
389
415
  && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
390
416
  && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
391
417
  && prop.arg.content === 'class') {
392
- yield `__VLS_styleScopedClasses = (`;
393
- yield [
394
- prop.exp.content,
395
- 'template',
396
- prop.exp.loc.start.offset,
397
- ctx.codeFeatures.navigationAndCompletion,
398
- ];
399
- yield `)${common_1.endOfLine}`;
418
+ const content = '`${' + prop.exp.content + '}`';
419
+ const startOffset = prop.exp.loc.start.offset - 3;
420
+ const { ts } = options;
421
+ const ast = ts.createSourceFile('', content, 99);
422
+ const literals = [];
423
+ ts.forEachChild(ast, node => {
424
+ if (!ts.isExpressionStatement(node) ||
425
+ !isTemplateExpression(node.expression)) {
426
+ return;
427
+ }
428
+ const expression = node.expression.templateSpans[0].expression;
429
+ if (ts.isStringLiteralLike(expression)) {
430
+ literals.push(expression);
431
+ }
432
+ if (ts.isArrayLiteralExpression(expression)) {
433
+ walkArrayLiteral(expression);
434
+ }
435
+ if (ts.isObjectLiteralExpression(expression)) {
436
+ walkObjectLiteral(expression);
437
+ }
438
+ });
439
+ for (const literal of literals) {
440
+ const classes = collectClasses(literal.text, literal.end - literal.text.length - 1 + startOffset);
441
+ ctx.scopedClasses.push(...classes);
442
+ }
443
+ function walkArrayLiteral(node) {
444
+ const { elements } = node;
445
+ for (const element of elements) {
446
+ if (ts.isStringLiteralLike(element)) {
447
+ literals.push(element);
448
+ }
449
+ else if (ts.isObjectLiteralExpression(element)) {
450
+ walkObjectLiteral(element);
451
+ }
452
+ }
453
+ }
454
+ function walkObjectLiteral(node) {
455
+ const { properties } = node;
456
+ for (const property of properties) {
457
+ if (ts.isPropertyAssignment(property)) {
458
+ const { name } = property;
459
+ if (ts.isIdentifier(name)) {
460
+ walkIdentifier(name);
461
+ }
462
+ else if (ts.isStringLiteral(name)) {
463
+ literals.push(name);
464
+ }
465
+ else if (ts.isComputedPropertyName(name)) {
466
+ const { expression } = name;
467
+ if (ts.isStringLiteralLike(expression)) {
468
+ literals.push(expression);
469
+ }
470
+ }
471
+ }
472
+ else if (ts.isShorthandPropertyAssignment(property)) {
473
+ walkIdentifier(property.name);
474
+ }
475
+ }
476
+ }
477
+ function walkIdentifier(node) {
478
+ const text = (0, scriptSetupRanges_1.getNodeText)(ts, node, ast);
479
+ ctx.scopedClasses.push({
480
+ source: 'template',
481
+ className: text,
482
+ offset: node.end - text.length + startOffset
483
+ });
484
+ }
400
485
  }
401
486
  }
402
487
  }
@@ -406,4 +491,41 @@ function camelizeComponentName(newName) {
406
491
  function getTagRenameApply(oldName) {
407
492
  return oldName === (0, shared_2.hyphenateTag)(oldName) ? shared_2.hyphenateTag : undefined;
408
493
  }
494
+ function normalizeAttributeValue(node) {
495
+ let offset = node.loc.start.offset;
496
+ let content = node.loc.source;
497
+ if ((content.startsWith(`'`) && content.endsWith(`'`))
498
+ || (content.startsWith(`"`) && content.endsWith(`"`))) {
499
+ offset++;
500
+ content = content.slice(1, -1);
501
+ }
502
+ return [content, offset];
503
+ }
504
+ function collectClasses(content, startOffset = 0) {
505
+ const classes = [];
506
+ let currentClassName = '';
507
+ let offset = 0;
508
+ for (const char of (content + ' ')) {
509
+ if (char.trim() === '') {
510
+ if (currentClassName !== '') {
511
+ classes.push({
512
+ source: 'template',
513
+ className: currentClassName,
514
+ offset: offset + startOffset
515
+ });
516
+ offset += currentClassName.length;
517
+ currentClassName = '';
518
+ }
519
+ offset += char.length;
520
+ }
521
+ else {
522
+ currentClassName += char;
523
+ }
524
+ }
525
+ return classes;
526
+ }
527
+ // isTemplateExpression is missing in tsc
528
+ function isTemplateExpression(node) {
529
+ return node.kind === 228;
530
+ }
409
531
  //# sourceMappingURL=element.js.map
@@ -18,6 +18,7 @@ function* generateElementChildren(options, ctx, node, currentComponent, componen
18
18
  && node.children.length
19
19
  && node.tagType !== CompilerDOM.ElementTypes.ELEMENT
20
20
  && node.tagType !== CompilerDOM.ElementTypes.TEMPLATE) {
21
+ ctx.usedComponentCtxVars.add(componentCtxVar);
21
22
  yield `__VLS_nonNullable(${componentCtxVar}.slots).`;
22
23
  yield* (0, common_1.wrapWith)(node.children[0].loc.start.offset, node.children[node.children.length - 1].loc.end.offset, ctx.codeFeatures.navigation, `default`);
23
24
  yield common_1.endOfLine;
@@ -21,7 +21,7 @@ function* generateElementDirectives(options, ctx, node) {
21
21
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, prop.arg.content, prop.arg.loc, prop.arg.loc.start.offset + prop.arg.loc.source.indexOf(prop.arg.content), ctx.codeFeatures.all, '(', ')');
22
22
  yield common_1.endOfLine;
23
23
  }
24
- yield* (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, `__VLS_directiveFunction(__VLS_ctx.`, ...(0, camelized_1.generateCamelized)('v-' + prop.name, prop.loc.start.offset, {
24
+ yield* (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, `__VLS_directiveAsFunction(__VLS_ctx.`, ...(0, camelized_1.generateCamelized)('v-' + prop.name, prop.loc.start.offset, {
25
25
  ...ctx.codeFeatures.all,
26
26
  verification: false,
27
27
  completion: {
@@ -32,9 +32,13 @@ function* generateElementDirectives(options, ctx, node) {
32
32
  resolveRenameNewName: shared_1.camelize,
33
33
  resolveRenameEditText: getPropRenameApply(prop.name),
34
34
  },
35
- }), `)(`, ...(prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
36
- ? (0, common_1.wrapWith)(prop.exp.loc.start.offset, prop.exp.loc.end.offset, ctx.codeFeatures.verification, ...(0, interpolation_1.generateInterpolation)(options, ctx, prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, ctx.codeFeatures.all, '(', ')'))
37
- : [`undefined`]), `)`);
35
+ }), `)(null!, { ...__VLS_directiveBindingRestFields, `, ...(prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
36
+ ? [
37
+ ...(0, common_1.wrapWith)(prop.exp.loc.start.offset, prop.exp.loc.end.offset, ctx.codeFeatures.verification, 'value'),
38
+ ': ',
39
+ ...(0, common_1.wrapWith)(prop.exp.loc.start.offset, prop.exp.loc.end.offset, ctx.codeFeatures.verification, ...(0, interpolation_1.generateInterpolation)(options, ctx, prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, ctx.codeFeatures.all, '(', ')'))
40
+ ]
41
+ : [`undefined`]), `}, null!, null!)`);
38
42
  yield common_1.endOfLine;
39
43
  }
40
44
  }
@@ -105,22 +105,21 @@ function* generateEventExpression(options, ctx, prop) {
105
105
  prefix += `if (!(${blockCondition})) return${common_1.endOfLine}`;
106
106
  }
107
107
  }
108
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, () => {
108
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, offset => {
109
109
  if (_isCompoundExpression && isFirstMapping) {
110
110
  isFirstMapping = false;
111
- return {
112
- ...ctx.codeFeatures.all,
113
- __hint: {
114
- setting: 'vue.inlayHints.inlineHandlerLeading',
115
- label: '$event =>',
116
- tooltip: [
117
- '`$event` is a hidden parameter, you can use it in this callback.',
118
- 'To hide this hint, set `vue.inlayHints.inlineHandlerLeading` to `false` in IDE settings.',
119
- '[More info](https://github.com/vuejs/language-tools/issues/2445#issuecomment-1444771420)',
120
- ].join('\n\n'),
121
- paddingRight: true,
122
- },
123
- };
111
+ ctx.inlayHints.push({
112
+ blockName: 'template',
113
+ offset,
114
+ setting: 'vue.inlayHints.inlineHandlerLeading',
115
+ label: '$event =>',
116
+ paddingRight: true,
117
+ tooltip: [
118
+ '`$event` is a hidden parameter, you can use it in this callback.',
119
+ 'To hide this hint, set `vue.inlayHints.inlineHandlerLeading` to `false` in IDE settings.',
120
+ '[More info](https://github.com/vuejs/language-tools/issues/2445#issuecomment-1444771420)',
121
+ ].join('\n\n'),
122
+ });
124
123
  }
125
124
  return ctx.codeFeatures.all;
126
125
  }, prefix, suffix);
@@ -76,17 +76,30 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
76
76
  if (shouldSpread) {
77
77
  yield `...{ `;
78
78
  }
79
+ const codeInfo = ctx.codeFeatures.withoutHighlightAndCompletion;
79
80
  const codes = (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(prop.arg
80
81
  ? (0, objectProperty_1.generateObjectProperty)(options, ctx, propName, prop.arg.loc.start.offset, {
81
- ...ctx.codeFeatures.withoutHighlightAndCompletion,
82
- navigation: ctx.codeFeatures.withoutHighlightAndCompletion.navigation
82
+ ...codeInfo,
83
+ verification: options.vueCompilerOptions.strictTemplates
84
+ ? codeInfo.verification
85
+ : {
86
+ shouldReport(_source, code) {
87
+ if (String(code) === '2353' || String(code) === '2561') {
88
+ return false;
89
+ }
90
+ return typeof codeInfo.verification === 'object'
91
+ ? codeInfo.verification.shouldReport?.(_source, code) ?? true
92
+ : true;
93
+ },
94
+ },
95
+ navigation: codeInfo.navigation
83
96
  ? {
84
97
  resolveRenameNewName: shared_1.camelize,
85
98
  resolveRenameEditText: shouldCamelize ? shared_2.hyphenateAttr : undefined,
86
99
  }
87
100
  : false,
88
101
  }, prop.loc.name_2 ?? (prop.loc.name_2 = {}), shouldCamelize)
89
- : (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.start.offset + 'v-model'.length, ctx.codeFeatures.verification, propName)), `: (`, ...genereatePropExp(options, ctx, prop.exp, ctx.codeFeatures.all, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, enableCodeFeatures), `)`);
102
+ : (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.start.offset + 'v-model'.length, ctx.codeFeatures.verification, propName)), `: (`, ...genereatePropExp(options, ctx, prop, prop.exp, ctx.codeFeatures.all, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, enableCodeFeatures), `)`);
90
103
  if (!enableCodeFeatures) {
91
104
  yield (0, muggle_string_1.toString)([...codes]);
92
105
  }
@@ -113,9 +126,22 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
113
126
  if (shouldSpread) {
114
127
  yield `...{ `;
115
128
  }
129
+ const codeInfo = ctx.codeFeatures.withoutHighlightAndCompletion;
116
130
  const codes = (0, common_1.conditionWrapWith)(enableCodeFeatures, prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(0, objectProperty_1.generateObjectProperty)(options, ctx, prop.name, prop.loc.start.offset, shouldCamelize
117
131
  ? {
118
- ...ctx.codeFeatures.withoutHighlightAndCompletion,
132
+ ...codeInfo,
133
+ verification: options.vueCompilerOptions.strictTemplates
134
+ ? codeInfo.verification
135
+ : {
136
+ shouldReport(_source, code) {
137
+ if (String(code) === '2353' || String(code) === '2561') {
138
+ return false;
139
+ }
140
+ return typeof codeInfo.verification === 'object'
141
+ ? codeInfo.verification.shouldReport?.(_source, code) ?? true
142
+ : true;
143
+ },
144
+ },
119
145
  navigation: ctx.codeFeatures.withoutHighlightAndCompletion.navigation
120
146
  ? {
121
147
  resolveRenameNewName: shared_1.camelize,
@@ -156,7 +182,7 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
156
182
  }
157
183
  }
158
184
  }
159
- function* genereatePropExp(options, ctx, exp, features, isShorthand, inlayHints) {
185
+ function* genereatePropExp(options, ctx, prop, exp, features, isShorthand, enableCodeFeatures) {
160
186
  if (exp && exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) { // style='z-index: 2' will compile to {'z-index':'2'}
161
187
  if (!isShorthand) { // vue 3.4+
162
188
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, exp.loc.source, exp.loc, exp.loc.start.offset, features, '(', ')');
@@ -169,23 +195,18 @@ function* genereatePropExp(options, ctx, exp, features, isShorthand, inlayHints)
169
195
  yield `__VLS_ctx.`;
170
196
  }
171
197
  yield* (0, camelized_1.generateCamelized)(exp.loc.source, exp.loc.start.offset, features);
172
- if (inlayHints) {
173
- yield [
174
- '',
175
- 'template',
176
- exp.loc.end.offset,
177
- {
178
- __hint: {
179
- setting: 'vue.inlayHints.vBindShorthand',
180
- label: `="${propVariableName}"`,
181
- tooltip: [
182
- `This is a shorthand for \`${exp.loc.source}="${propVariableName}"\`.`,
183
- 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
184
- '[More info](https://github.com/vuejs/core/pull/9451)',
185
- ].join('\n\n'),
186
- },
187
- },
188
- ];
198
+ if (enableCodeFeatures) {
199
+ ctx.inlayHints.push({
200
+ blockName: 'template',
201
+ offset: prop.loc.end.offset,
202
+ setting: 'vue.inlayHints.vBindShorthand',
203
+ label: `="${propVariableName}"`,
204
+ tooltip: [
205
+ `This is a shorthand for \`${prop.loc.source}="${propVariableName}"\`.`,
206
+ 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
207
+ '[More info](https://github.com/vuejs/core/pull/9451)',
208
+ ].join('\n\n'),
209
+ });
189
210
  }
190
211
  }
191
212
  }
@@ -9,9 +9,12 @@ export interface TemplateCodegenOptions {
9
9
  template: NonNullable<Sfc['template']>;
10
10
  scriptSetupBindingNames: Set<string>;
11
11
  scriptSetupImportComponentNames: Set<string>;
12
+ edited: boolean;
13
+ templateRefNames: Map<string, string>;
12
14
  hasDefineSlots?: boolean;
13
15
  slotsAssignName?: string;
14
16
  propsAssignName?: string;
17
+ inheritAttrs: boolean;
15
18
  }
16
19
  export declare function generateTemplate(options: TemplateCodegenOptions): Generator<Code, TemplateCodegenContext>;
17
20
  export declare function forEachElementNode(node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode): Generator<CompilerDOM.ElementNode>;