@vue/language-core 2.1.6 → 2.1.8

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 (49) hide show
  1. package/lib/codegen/common.d.ts +2 -2
  2. package/lib/codegen/common.js +8 -10
  3. package/lib/codegen/globalTypes.js +13 -8
  4. package/lib/codegen/inlayHints.d.ts +11 -0
  5. package/lib/codegen/inlayHints.js +17 -0
  6. package/lib/codegen/script/component.d.ts +1 -1
  7. package/lib/codegen/script/component.js +8 -5
  8. package/lib/codegen/script/componentSelf.js +1 -1
  9. package/lib/codegen/script/context.d.ts +1 -1
  10. package/lib/codegen/script/index.d.ts +1 -0
  11. package/lib/codegen/script/index.js +23 -10
  12. package/lib/codegen/script/scriptSetup.js +103 -112
  13. package/lib/codegen/script/styleModulesType.js +3 -5
  14. package/lib/codegen/script/template.d.ts +1 -1
  15. package/lib/codegen/script/template.js +9 -12
  16. package/lib/codegen/template/context.d.ts +3 -2
  17. package/lib/codegen/template/context.js +1 -0
  18. package/lib/codegen/template/element.d.ts +1 -1
  19. package/lib/codegen/template/element.js +31 -11
  20. package/lib/codegen/template/elementDirectives.js +63 -31
  21. package/lib/codegen/template/elementProps.js +7 -17
  22. package/lib/codegen/template/index.d.ts +1 -0
  23. package/lib/codegen/template/index.js +63 -53
  24. package/lib/codegen/template/interpolation.d.ts +1 -1
  25. package/lib/codegen/template/interpolation.js +34 -28
  26. package/lib/codegen/template/slotOutlet.js +5 -0
  27. package/lib/codegen/template/templateChild.d.ts +1 -1
  28. package/lib/codegen/template/templateChild.js +6 -2
  29. package/lib/codegen/template/vFor.js +1 -1
  30. package/lib/parsers/scriptSetupRanges.d.ts +14 -4
  31. package/lib/parsers/scriptSetupRanges.js +39 -26
  32. package/lib/plugins/vue-tsx.d.ts +27 -16
  33. package/lib/plugins/vue-tsx.js +43 -31
  34. package/lib/types.d.ts +3 -1
  35. package/lib/utils/parseCssClassNames.d.ts +1 -1
  36. package/lib/utils/parseCssClassNames.js +5 -4
  37. package/lib/utils/parseCssVars.d.ts +3 -2
  38. package/lib/utils/parseCssVars.js +12 -11
  39. package/lib/utils/ts.d.ts +1 -1
  40. package/lib/utils/ts.js +3 -5
  41. package/lib/virtualFile/computedEmbeddedCodes.d.ts +2 -1
  42. package/lib/virtualFile/computedEmbeddedCodes.js +11 -11
  43. package/lib/virtualFile/computedSfc.d.ts +2 -1
  44. package/lib/virtualFile/computedSfc.js +77 -76
  45. package/lib/virtualFile/computedVueSfc.d.ts +2 -1
  46. package/lib/virtualFile/computedVueSfc.js +8 -8
  47. package/lib/virtualFile/vueFile.d.ts +6 -7
  48. package/lib/virtualFile/vueFile.js +13 -12
  49. package/package.json +9 -8
@@ -10,14 +10,9 @@ const context_1 = require("../template/context");
10
10
  const interpolation_1 = require("../template/interpolation");
11
11
  const styleScopedClasses_1 = require("../template/styleScopedClasses");
12
12
  const index_1 = require("./index");
13
- function* generateTemplateCtx(options, isClassComponent) {
13
+ function* generateTemplateCtx(options) {
14
14
  const exps = [];
15
- if (isClassComponent) {
16
- exps.push(`this`);
17
- }
18
- else {
19
- exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);
20
- }
15
+ exps.push(`{} as InstanceType<__VLS_PickNotAny<typeof __VLS_self, new () => {}>>`);
21
16
  if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) {
22
17
  exps.push(`globalThis`);
23
18
  }
@@ -99,13 +94,13 @@ function* generateTemplateDirectives(options) {
99
94
  yield `}${common_1.endOfLine}`;
100
95
  yield `let __VLS_directives!: typeof __VLS_localDirectives & __VLS_GlobalDirectives${common_1.endOfLine}`;
101
96
  }
102
- function* generateTemplate(options, ctx, isClassComponent) {
97
+ function* generateTemplate(options, ctx) {
103
98
  ctx.generatedTemplate = true;
104
99
  const templateCodegenCtx = (0, context_1.createTemplateCodegenContext)({
105
100
  scriptSetupBindingNames: new Set(),
106
101
  edited: options.edited,
107
102
  });
108
- yield* generateTemplateCtx(options, isClassComponent);
103
+ yield* generateTemplateCtx(options);
109
104
  yield* generateTemplateComponents(options);
110
105
  yield* generateTemplateDirectives(options);
111
106
  yield* generateTemplateBody(options, templateCodegenCtx);
@@ -145,13 +140,15 @@ function* generateTemplateBody(options, templateCodegenCtx) {
145
140
  if (!options.scriptSetupRanges?.slots.define) {
146
141
  yield `const __VLS_slots = {}${common_1.endOfLine}`;
147
142
  }
148
- yield `const $refs = {}${common_1.endOfLine}`;
149
143
  yield `const __VLS_inheritedAttrs = {}${common_1.endOfLine}`;
144
+ yield `const $refs = {}${common_1.endOfLine}`;
145
+ yield `const $el = {} as any${common_1.endOfLine}`;
150
146
  }
151
147
  yield `return {${common_1.newLine}`;
148
+ yield ` attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${common_1.newLine}`;
152
149
  yield ` slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${common_1.newLine}`;
153
150
  yield ` refs: $refs,${common_1.newLine}`;
154
- yield ` attrs: {} as Partial<typeof __VLS_inheritedAttrs>,${common_1.newLine}`;
151
+ yield ` rootEl: $el,${common_1.newLine}`;
155
152
  yield `}${common_1.endOfLine}`;
156
153
  }
157
154
  function* generateCssClassProperty(styleIndex, classNameWithDot, offset, propertyType, optional) {
@@ -186,7 +183,7 @@ function* generateCssVars(options, ctx) {
186
183
  yield `// CSS variable injection ${common_1.newLine}`;
187
184
  for (const style of options.sfc.styles) {
188
185
  for (const cssBind of style.cssVars) {
189
- for (const [segment, offset, onlyError] of (0, interpolation_1.forEachInterpolationSegment)(options.ts, undefined, ctx, cssBind.text, cssBind.offset, options.ts.createSourceFile('/a.txt', cssBind.text, 99))) {
186
+ for (const [segment, offset, onlyError] of (0, interpolation_1.forEachInterpolationSegment)(options.ts, undefined, undefined, ctx, cssBind.text, cssBind.offset, options.ts.createSourceFile('/a.txt', cssBind.text, 99))) {
190
187
  if (offset === undefined) {
191
188
  yield segment;
192
189
  }
@@ -1,7 +1,7 @@
1
1
  import type * as CompilerDOM from '@vue/compiler-dom';
2
2
  import type { Code, VueCodeInformation } from '../../types';
3
3
  import type { TemplateCodegenOptions } from './index';
4
- import { InlayHintInfo } from '../types';
4
+ import { InlayHintInfo } from '../inlayHints';
5
5
  export type TemplateCodegenContext = ReturnType<typeof createTemplateCodegenContext>;
6
6
  export declare function createTemplateCodegenContext(options: Pick<TemplateCodegenOptions, 'scriptSetupBindingNames' | 'edited'>): {
7
7
  slots: {
@@ -41,7 +41,8 @@ export declare function createTemplateCodegenContext(options: Pick<TemplateCodeg
41
41
  inlayHints: InlayHintInfo[];
42
42
  hasSlot: boolean;
43
43
  inheritedAttrVars: Set<unknown>;
44
- templateRefs: Map<string, [string, number]>;
44
+ templateRefs: Map<string, [varName: string, offset: number]>;
45
+ singleRootElType: string | undefined;
45
46
  singleRootNode: CompilerDOM.ElementNode | undefined;
46
47
  accessExternalVariable(name: string, offset?: number): void;
47
48
  hasLocalVariable: (name: string) => boolean;
@@ -110,6 +110,7 @@ function createTemplateCodegenContext(options) {
110
110
  hasSlot: false,
111
111
  inheritedAttrVars: new Set(),
112
112
  templateRefs,
113
+ singleRootElType: undefined,
113
114
  singleRootNode: undefined,
114
115
  accessExternalVariable(name, offset) {
115
116
  let arr = accessExternalVariables.get(name);
@@ -3,6 +3,6 @@ import type { Code } from '../../types';
3
3
  import type { TemplateCodegenContext } from './context';
4
4
  import type { TemplateCodegenOptions } from './index';
5
5
  export declare function generateComponent(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, currentComponent: CompilerDOM.ElementNode | undefined): Generator<Code>;
6
- export declare function generateElement(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, currentComponent: CompilerDOM.ElementNode | undefined, componentCtxVar: string | undefined): Generator<Code>;
6
+ export declare function generateElement(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, currentComponent: CompilerDOM.ElementNode | undefined, componentCtxVar: string | undefined, isVForChild: boolean): Generator<Code>;
7
7
  export declare function getCanonicalComponentName(tagText: string): string;
8
8
  export declare function getPossibleOriginalComponentNames(tagText: string, deduplicate: boolean): string[];
@@ -17,6 +17,7 @@ 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 inlayHints_1 = require("../inlayHints");
20
21
  const scriptSetupRanges_1 = require("../../parsers/scriptSetupRanges");
21
22
  const colonReg = /:/g;
22
23
  function* generateComponent(options, ctx, node, currentComponent) {
@@ -39,9 +40,15 @@ function* generateComponent(options, ctx, node, currentComponent) {
39
40
  let dynamicTagInfo;
40
41
  if (isComponentTag) {
41
42
  for (const prop of node.props) {
42
- if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) {
43
+ if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
44
+ && prop.name === 'bind'
45
+ && prop.arg?.loc.source === 'is'
46
+ && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
47
+ if (prop.arg.loc.end.offset === prop.exp.loc.end.offset) {
48
+ ctx.inlayHints.push((0, inlayHints_1.createVBindShorthandInlayHintInfo)(prop.exp.loc, 'is'));
49
+ }
43
50
  dynamicTagInfo = {
44
- exp: prop.exp.loc.source,
51
+ tag: prop.exp.content,
45
52
  offsets: [prop.exp.loc.start.offset, undefined],
46
53
  astHolder: prop.exp.loc,
47
54
  };
@@ -53,9 +60,9 @@ function* generateComponent(options, ctx, node, currentComponent) {
53
60
  else if (node.tag.includes('.')) {
54
61
  // namespace tag
55
62
  dynamicTagInfo = {
56
- exp: node.tag,
57
- astHolder: node.loc,
63
+ tag: node.tag,
58
64
  offsets: [startTagOffset, endTagOffset],
65
+ astHolder: node.loc,
59
66
  };
60
67
  }
61
68
  if (matchImportName) {
@@ -86,10 +93,10 @@ function* generateComponent(options, ctx, node, currentComponent) {
86
93
  }
87
94
  else if (dynamicTagInfo) {
88
95
  yield `const ${var_originalComponent} = (`;
89
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[0], ctx.codeFeatures.all, '(', ')');
96
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.tag, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[0], ctx.codeFeatures.all, '(', ')');
90
97
  if (dynamicTagInfo.offsets[1] !== undefined) {
91
98
  yield `,`;
92
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[1], {
99
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.tag, dynamicTagInfo.astHolder, dynamicTagInfo.offsets[1], {
93
100
  ...ctx.codeFeatures.all,
94
101
  completion: false,
95
102
  }, '(', ')');
@@ -151,9 +158,9 @@ function* generateComponent(options, ctx, node, currentComponent) {
151
158
  yield common_1.endOfLine;
152
159
  }
153
160
  const [refName, offset] = yield* generateVScope(options, ctx, node, props);
154
- if (refName) {
161
+ const isRootNode = node === ctx.singleRootNode;
162
+ if (refName || isRootNode) {
155
163
  const varName = ctx.getInternalVariable();
156
- ctx.templateRefs.set(refName, [varName, offset]);
157
164
  ctx.usedComponentCtxVars.add(var_defineComponentCtx);
158
165
  yield `var ${varName} = {} as (Parameters<NonNullable<typeof ${var_defineComponentCtx}['expose']>>[0] | null)`;
159
166
  if (node.codegenNode?.type === CompilerDOM.NodeTypes.VNODE_CALL
@@ -162,6 +169,12 @@ function* generateComponent(options, ctx, node, currentComponent) {
162
169
  yield `[]`;
163
170
  }
164
171
  yield `${common_1.endOfLine}`;
172
+ if (refName) {
173
+ ctx.templateRefs.set(refName, [varName, offset]);
174
+ }
175
+ if (isRootNode) {
176
+ ctx.singleRootElType = `NonNullable<typeof ${varName}>['$el']`;
177
+ }
165
178
  }
166
179
  const usedComponentEventsVar = yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents);
167
180
  if (usedComponentEventsVar) {
@@ -184,10 +197,10 @@ function* generateComponent(options, ctx, node, currentComponent) {
184
197
  yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, var_defineComponentCtx);
185
198
  }
186
199
  if (ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
187
- yield `const ${var_defineComponentCtx} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})${common_1.endOfLine}`;
200
+ yield `var ${var_defineComponentCtx}!: __VLS_PickFunctionalComponentCtx<typeof ${var_originalComponent}, typeof ${var_componentInstance}>${common_1.endOfLine}`;
188
201
  }
189
202
  }
190
- function* generateElement(options, ctx, node, currentComponent, componentCtxVar) {
203
+ function* generateElement(options, ctx, node, currentComponent, componentCtxVar, isVForChild) {
191
204
  const startTagOffset = node.loc.start.offset + options.template.content.substring(node.loc.start.offset).indexOf(node.tag);
192
205
  const endTagOffset = !node.isSelfClosing && options.template.lang === 'html'
193
206
  ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag)
@@ -208,7 +221,14 @@ function* generateElement(options, ctx, node, currentComponent, componentCtxVar)
208
221
  }
209
222
  const [refName, offset] = yield* generateVScope(options, ctx, node, node.props);
210
223
  if (refName) {
211
- ctx.templateRefs.set(refName, [`__VLS_nativeElements['${node.tag}']`, offset]);
224
+ let refValue = `__VLS_nativeElements['${node.tag}']`;
225
+ if (isVForChild) {
226
+ refValue = `[${refValue}]`;
227
+ }
228
+ ctx.templateRefs.set(refName, [refValue, offset]);
229
+ }
230
+ if (ctx.singleRootNode === node) {
231
+ ctx.singleRootElType = `typeof __VLS_nativeElements['${node.tag}']`;
212
232
  }
213
233
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
214
234
  if (slotDir && componentCtxVar) {
@@ -7,42 +7,74 @@ const shared_2 = require("../../utils/shared");
7
7
  const common_1 = require("../common");
8
8
  const camelized_1 = require("./camelized");
9
9
  const interpolation_1 = require("./interpolation");
10
+ const objectProperty_1 = require("./objectProperty");
11
+ const stringLiteralKey_1 = require("./stringLiteralKey");
10
12
  function* generateElementDirectives(options, ctx, node) {
11
13
  for (const prop of node.props) {
12
- if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
13
- && prop.name !== 'slot'
14
- && prop.name !== 'on'
15
- && prop.name !== 'model'
16
- && prop.name !== 'bind'
17
- && prop.name !== 'scope'
18
- && prop.name !== 'data') {
19
- ctx.accessExternalVariable((0, shared_1.camelize)('v-' + prop.name), prop.loc.start.offset);
20
- if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && !prop.arg.isStatic) {
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
- yield common_1.endOfLine;
23
- }
24
- yield* (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, `__VLS_directiveAsFunction(__VLS_directives.`, ...(0, camelized_1.generateCamelized)('v-' + prop.name, prop.loc.start.offset, {
25
- ...ctx.codeFeatures.all,
26
- verification: false,
27
- completion: {
28
- // fix https://github.com/vuejs/language-tools/issues/1905
29
- isAdditional: true,
30
- },
31
- navigation: {
32
- resolveRenameNewName: shared_1.camelize,
33
- resolveRenameEditText: getPropRenameApply(prop.name),
34
- },
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!)`);
42
- yield common_1.endOfLine;
14
+ if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE
15
+ || prop.name === 'slot'
16
+ || prop.name === 'on'
17
+ || prop.name === 'model'
18
+ || prop.name === 'bind'
19
+ || prop.name === 'scope'
20
+ || prop.name === 'data') {
21
+ continue;
43
22
  }
23
+ ctx.accessExternalVariable((0, shared_1.camelize)('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_asFunctionalDirective(`, ...generateIdentifier(ctx, prop), `)(null!, { ...__VLS_directiveBindingRestFields, `, ...generateArg(options, ctx, prop), ...generateModifiers(options, ctx, prop), ...generateValue(options, ctx, prop), `}, null!, null!)`);
25
+ yield common_1.endOfLine;
44
26
  }
45
27
  }
28
+ function* generateIdentifier(ctx, prop) {
29
+ const rawName = 'v-' + prop.name;
30
+ yield* (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.start.offset + rawName.length, ctx.codeFeatures.verification, `__VLS_directives.`, ...(0, camelized_1.generateCamelized)(rawName, prop.loc.start.offset, {
31
+ ...ctx.codeFeatures.all,
32
+ verification: false,
33
+ completion: {
34
+ // fix https://github.com/vuejs/language-tools/issues/1905
35
+ isAdditional: true,
36
+ },
37
+ navigation: {
38
+ resolveRenameNewName: shared_1.camelize,
39
+ resolveRenameEditText: getPropRenameApply(prop.name),
40
+ },
41
+ }));
42
+ }
43
+ function* generateArg(options, ctx, prop) {
44
+ const { arg } = prop;
45
+ if (arg?.type !== CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
46
+ return;
47
+ }
48
+ const startOffset = arg.loc.start.offset + arg.loc.source.indexOf(arg.content);
49
+ yield* (0, common_1.wrapWith)(startOffset, startOffset + arg.content.length, ctx.codeFeatures.verification, 'arg');
50
+ yield ': ';
51
+ if (arg.isStatic) {
52
+ yield* (0, stringLiteralKey_1.generateStringLiteralKey)(arg.content, startOffset, ctx.codeFeatures.withoutHighlight);
53
+ }
54
+ else {
55
+ yield* (0, interpolation_1.generateInterpolation)(options, ctx, arg.content, arg.loc, startOffset, ctx.codeFeatures.all, '(', ')');
56
+ }
57
+ yield ', ';
58
+ }
59
+ function* generateModifiers(options, ctx, prop) {
60
+ if (options.vueCompilerOptions.target < 3.5) {
61
+ return;
62
+ }
63
+ yield 'modifiers: { ';
64
+ for (const mod of prop.modifiers) {
65
+ yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, mod.content, mod.loc.start.offset, ctx.codeFeatures.withoutHighlight);
66
+ yield ': true, ';
67
+ }
68
+ yield '}, ';
69
+ }
70
+ function* generateValue(options, ctx, prop) {
71
+ if (prop.exp?.type !== CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
72
+ return;
73
+ }
74
+ yield* (0, common_1.wrapWith)(prop.exp.loc.start.offset, prop.exp.loc.end.offset, ctx.codeFeatures.verification, 'value');
75
+ yield ': ';
76
+ yield* (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, '(', ')'));
77
+ }
46
78
  function getPropRenameApply(oldName) {
47
79
  return oldName === (0, shared_2.hyphenateAttr)(oldName) ? shared_2.hyphenateAttr : undefined;
48
80
  }
@@ -11,16 +11,16 @@ const camelized_1 = require("./camelized");
11
11
  const elementEvents_1 = require("./elementEvents");
12
12
  const interpolation_1 = require("./interpolation");
13
13
  const objectProperty_1 = require("./objectProperty");
14
+ const inlayHints_1 = require("../inlayHints");
14
15
  function* generateElementProps(options, ctx, node, props, enableCodeFeatures, propsFailedExps) {
15
- const isIntrinsicElement = node.tagType === CompilerDOM.ElementTypes.ELEMENT || node.tagType === CompilerDOM.ElementTypes.TEMPLATE;
16
- const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
16
+ const isComponent = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
17
17
  for (const prop of props) {
18
18
  if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
19
19
  && prop.name === 'on') {
20
20
  if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
21
21
  && !prop.arg.loc.source.startsWith('[')
22
22
  && !prop.arg.loc.source.endsWith(']')) {
23
- if (isIntrinsicElement) {
23
+ if (!isComponent) {
24
24
  yield `...{ `;
25
25
  yield* (0, elementEvents_1.generateEventArg)(ctx, prop.arg, true);
26
26
  yield `: `;
@@ -65,11 +65,11 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
65
65
  }
66
66
  continue;
67
67
  }
68
- if (prop.modifiers.some(m => m === 'prop' || m === 'attr')) {
68
+ if (prop.modifiers.some(m => m.content === 'prop' || m.content === 'attr')) {
69
69
  propName = propName.substring(1);
70
70
  }
71
71
  const shouldSpread = propName === 'style' || propName === 'class';
72
- const shouldCamelize = canCamelize
72
+ const shouldCamelize = isComponent
73
73
  && (!prop.arg || (prop.arg.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && prop.arg.isStatic)) // isStatic
74
74
  && (0, shared_2.hyphenateAttr)(propName) === propName
75
75
  && !options.vueCompilerOptions.htmlAttributes.some(pattern => (0, minimatch_1.minimatch)(propName, pattern));
@@ -120,7 +120,7 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
120
120
  continue;
121
121
  }
122
122
  const shouldSpread = prop.name === 'style' || prop.name === 'class';
123
- const shouldCamelize = canCamelize
123
+ const shouldCamelize = isComponent
124
124
  && (0, shared_2.hyphenateAttr)(prop.name) === prop.name
125
125
  && !options.vueCompilerOptions.htmlAttributes.some(pattern => (0, minimatch_1.minimatch)(prop.name, pattern));
126
126
  if (shouldSpread) {
@@ -205,17 +205,7 @@ function* generatePropExp(options, ctx, prop, exp, features, isShorthand, enable
205
205
  }
206
206
  yield* (0, camelized_1.generateCamelized)(exp.loc.source, exp.loc.start.offset, features);
207
207
  if (enableCodeFeatures) {
208
- ctx.inlayHints.push({
209
- blockName: 'template',
210
- offset: prop.loc.end.offset,
211
- setting: 'vue.inlayHints.vBindShorthand',
212
- label: `="${propVariableName}"`,
213
- tooltip: [
214
- `This is a shorthand for \`${prop.loc.source}="${propVariableName}"\`.`,
215
- 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
216
- '[More info](https://github.com/vuejs/core/pull/9451)',
217
- ].join('\n\n'),
218
- });
208
+ ctx.inlayHints.push((0, inlayHints_1.createVBindShorthandInlayHintInfo)(prop.loc, propVariableName));
219
209
  }
220
210
  }
221
211
  }
@@ -10,6 +10,7 @@ export interface TemplateCodegenOptions {
10
10
  edited: boolean;
11
11
  scriptSetupBindingNames: Set<string>;
12
12
  scriptSetupImportComponentNames: Set<string>;
13
+ destructuredPropNames: Set<string>;
13
14
  templateRefNames: Set<string>;
14
15
  hasDefineSlots?: boolean;
15
16
  slotsAssignName?: string;
@@ -18,79 +18,89 @@ function* generateTemplate(options) {
18
18
  if (options.propsAssignName) {
19
19
  ctx.addLocalVariable(options.propsAssignName);
20
20
  }
21
+ ctx.addLocalVariable('$el');
21
22
  ctx.addLocalVariable('$refs');
22
- yield* generatePreResolveComponents();
23
+ yield* generatePreResolveComponents(options);
23
24
  if (options.template.ast) {
24
25
  yield* (0, templateChild_1.generateTemplateChild)(options, ctx, options.template.ast, undefined, undefined, undefined);
25
26
  }
26
27
  yield* (0, styleScopedClasses_1.generateStyleScopedClasses)(ctx);
27
28
  if (!options.hasDefineSlots) {
28
29
  yield `var __VLS_slots!:`;
29
- yield* generateSlotsType();
30
+ yield* generateSlotsType(options, ctx);
30
31
  yield common_1.endOfLine;
31
32
  }
32
- yield* generateInheritedAttrs();
33
33
  yield* ctx.generateAutoImportCompletion();
34
- yield* generateRefs();
34
+ yield* generateInheritedAttrs(ctx);
35
+ yield* generateRefs(ctx);
36
+ yield* generateRootEl(ctx);
35
37
  return ctx;
36
- function* generateRefs() {
37
- yield `const __VLS_refs = {${common_1.newLine}`;
38
- for (const [name, [varName, offset]] of ctx.templateRefs) {
39
- yield* (0, stringLiteralKey_1.generateStringLiteralKey)(name, offset, ctx.codeFeatures.navigationAndCompletion);
40
- yield `: ${varName},${common_1.newLine}`;
41
- }
42
- yield `}${common_1.endOfLine}`;
43
- yield `var $refs!: typeof __VLS_refs${common_1.endOfLine}`;
38
+ }
39
+ function* generateSlotsType(options, ctx) {
40
+ for (const { expVar, varName } of ctx.dynamicSlots) {
41
+ ctx.hasSlot = true;
42
+ yield `Partial<Record<NonNullable<typeof ${expVar}>, (_: typeof ${varName}) => any>> &${common_1.newLine}`;
44
43
  }
45
- function* generateSlotsType() {
46
- for (const { expVar, varName } of ctx.dynamicSlots) {
47
- ctx.hasSlot = true;
48
- yield `Partial<Record<NonNullable<typeof ${expVar}>, (_: typeof ${varName}) => any>> &${common_1.newLine}`;
44
+ yield `{${common_1.newLine}`;
45
+ for (const slot of ctx.slots) {
46
+ ctx.hasSlot = true;
47
+ if (slot.name && slot.loc !== undefined) {
48
+ yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slot.name, slot.loc, ctx.codeFeatures.withoutHighlightAndCompletion, slot.nodeLoc);
49
49
  }
50
- yield `{${common_1.newLine}`;
51
- for (const slot of ctx.slots) {
52
- ctx.hasSlot = true;
53
- if (slot.name && slot.loc !== undefined) {
54
- yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slot.name, slot.loc, ctx.codeFeatures.withoutHighlightAndCompletion, slot.nodeLoc);
55
- }
56
- else {
57
- yield* (0, common_1.wrapWith)(slot.tagRange[0], slot.tagRange[1], ctx.codeFeatures.withoutHighlightAndCompletion, `default`);
58
- }
59
- yield `?(_: typeof ${slot.varName}): any,${common_1.newLine}`;
50
+ else {
51
+ yield* (0, common_1.wrapWith)(slot.tagRange[0], slot.tagRange[1], ctx.codeFeatures.withoutHighlightAndCompletion, `default`);
60
52
  }
61
- yield `}`;
53
+ yield `?(_: typeof ${slot.varName}): any,${common_1.newLine}`;
62
54
  }
63
- function* generateInheritedAttrs() {
64
- yield 'var __VLS_inheritedAttrs!: {}';
65
- for (const varName of ctx.inheritedAttrVars) {
66
- yield ` & typeof ${varName}`;
67
- }
68
- yield common_1.endOfLine;
55
+ yield `}`;
56
+ }
57
+ function* generateInheritedAttrs(ctx) {
58
+ yield 'var __VLS_inheritedAttrs!: {}';
59
+ for (const varName of ctx.inheritedAttrVars) {
60
+ yield ` & typeof ${varName}`;
69
61
  }
70
- function* generatePreResolveComponents() {
71
- yield `let __VLS_resolvedLocalAndGlobalComponents!: Required<{}`;
72
- if (options.template.ast) {
73
- const components = new Set();
74
- for (const node of forEachElementNode(options.template.ast)) {
75
- if (node.tagType === CompilerDOM.ElementTypes.COMPONENT
76
- && node.tag.toLowerCase() !== 'component'
77
- && !node.tag.includes('.') // namespace tag
78
- ) {
79
- if (components.has(node.tag)) {
80
- continue;
81
- }
82
- components.add(node.tag);
83
- yield common_1.newLine;
84
- yield ` & __VLS_WithComponent<'${(0, element_1.getCanonicalComponentName)(node.tag)}', typeof __VLS_localComponents, `;
85
- yield (0, element_1.getPossibleOriginalComponentNames)(node.tag, false)
86
- .map(name => `"${name}"`)
87
- .join(', ');
88
- yield `>`;
62
+ yield common_1.endOfLine;
63
+ }
64
+ function* generateRefs(ctx) {
65
+ yield `const __VLS_refs = {${common_1.newLine}`;
66
+ for (const [name, [varName, offset]] of ctx.templateRefs) {
67
+ yield* (0, stringLiteralKey_1.generateStringLiteralKey)(name, offset, ctx.codeFeatures.navigationAndCompletion);
68
+ yield `: ${varName},${common_1.newLine}`;
69
+ }
70
+ yield `}${common_1.endOfLine}`;
71
+ yield `var $refs!: typeof __VLS_refs${common_1.endOfLine}`;
72
+ }
73
+ function* generateRootEl(ctx) {
74
+ if (ctx.singleRootElType) {
75
+ yield `var $el!: ${ctx.singleRootElType}${common_1.endOfLine}`;
76
+ }
77
+ else {
78
+ yield `var $el!: any${common_1.endOfLine}`;
79
+ }
80
+ }
81
+ function* generatePreResolveComponents(options) {
82
+ yield `let __VLS_resolvedLocalAndGlobalComponents!: Required<{}`;
83
+ if (options.template.ast) {
84
+ const components = new Set();
85
+ for (const node of forEachElementNode(options.template.ast)) {
86
+ if (node.tagType === CompilerDOM.ElementTypes.COMPONENT
87
+ && node.tag.toLowerCase() !== 'component'
88
+ && !node.tag.includes('.') // namespace tag
89
+ ) {
90
+ if (components.has(node.tag)) {
91
+ continue;
89
92
  }
93
+ components.add(node.tag);
94
+ yield common_1.newLine;
95
+ yield ` & __VLS_WithComponent<'${(0, element_1.getCanonicalComponentName)(node.tag)}', typeof __VLS_localComponents, `;
96
+ yield (0, element_1.getPossibleOriginalComponentNames)(node.tag, false)
97
+ .map(name => `"${name}"`)
98
+ .join(', ');
99
+ yield `>`;
90
100
  }
91
101
  }
92
- yield `>${common_1.endOfLine}`;
93
102
  }
103
+ yield `>${common_1.endOfLine}`;
94
104
  }
95
105
  function* forEachElementNode(node) {
96
106
  if (node.type === CompilerDOM.NodeTypes.ROOT) {
@@ -3,4 +3,4 @@ import type { Code, VueCodeInformation } from '../../types';
3
3
  import type { TemplateCodegenContext } from './context';
4
4
  import type { TemplateCodegenOptions } from './index';
5
5
  export declare function generateInterpolation(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, _code: string, astHolder: any, start: number | undefined, data: VueCodeInformation | ((offset: number) => VueCodeInformation) | undefined, prefix: string, suffix: string): Generator<Code>;
6
- export declare function forEachInterpolationSegment(ts: typeof import('typescript'), templateRefNames: Set<string> | undefined, ctx: TemplateCodegenContext, code: string, offset: number | undefined, ast: ts.SourceFile): Generator<[fragment: string, offset: number | undefined, errorMappingOnly?: boolean]>;
6
+ export declare function forEachInterpolationSegment(ts: typeof import('typescript'), destructuredPropNames: Set<string> | undefined, templateRefNames: Set<string> | undefined, ctx: TemplateCodegenContext, code: string, offset: number | undefined, ast: ts.SourceFile): Generator<[fragment: string, offset: number | undefined, type?: 'errorMappingOnly' | 'startText' | 'endText']>;