@vue/language-core 2.0.16 → 2.0.18

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 (39) hide show
  1. package/lib/codegen/script/globalTypes.js +10 -14
  2. package/lib/codegen/script/index.d.ts +3 -6
  3. package/lib/codegen/script/index.js +12 -15
  4. package/lib/codegen/script/internalComponent.js +1 -1
  5. package/lib/codegen/script/scriptSetup.js +21 -23
  6. package/lib/codegen/script/template.d.ts +1 -1
  7. package/lib/codegen/script/template.js +45 -36
  8. package/lib/codegen/template/context.d.ts +8 -3
  9. package/lib/codegen/template/context.js +42 -13
  10. package/lib/codegen/template/element.js +81 -50
  11. package/lib/codegen/template/elementDirectives.js +1 -1
  12. package/lib/codegen/template/elementEvents.d.ts +2 -2
  13. package/lib/codegen/template/elementEvents.js +46 -35
  14. package/lib/codegen/template/elementProps.js +56 -63
  15. package/lib/codegen/template/index.d.ts +4 -46
  16. package/lib/codegen/template/index.js +36 -21
  17. package/lib/codegen/template/interpolation.d.ts +2 -2
  18. package/lib/codegen/template/interpolation.js +12 -46
  19. package/lib/codegen/template/vFor.js +13 -3
  20. package/lib/languageModule.d.ts +1 -1
  21. package/lib/languageModule.js +4 -4
  22. package/lib/parsers/scriptRanges.d.ts +1 -0
  23. package/lib/parsers/scriptRanges.js +7 -0
  24. package/lib/parsers/scriptSetupRanges.d.ts +4 -0
  25. package/lib/parsers/scriptSetupRanges.js +24 -0
  26. package/lib/plugins/file-md.js +1 -0
  27. package/lib/plugins/vue-script-js.d.ts +3 -0
  28. package/lib/plugins/vue-script-js.js +15 -0
  29. package/lib/plugins/vue-template-html.js +1 -1
  30. package/lib/plugins/vue-template-inline-ts.js +1 -1
  31. package/lib/plugins/vue-tsx.d.ts +46 -40
  32. package/lib/plugins/vue-tsx.js +34 -28
  33. package/lib/plugins.d.ts +1 -0
  34. package/lib/plugins.js +2 -0
  35. package/lib/types.d.ts +1 -15
  36. package/lib/utils/parseCssClassNames.js +1 -1
  37. package/lib/utils/ts.js +0 -1
  38. package/lib/virtualFile/computedSfc.js +20 -5
  39. package/package.json +3 -3
@@ -16,21 +16,22 @@ const templateChild_1 = require("./templateChild");
16
16
  const colonReg = /:/g;
17
17
  function* generateComponent(options, ctx, node, currentComponent, componentCtxVar) {
18
18
  const startTagOffset = node.loc.start.offset + options.template.content.substring(node.loc.start.offset).indexOf(node.tag);
19
+ const endTagOffset = !node.isSelfClosing && options.template.lang === 'html' ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) : undefined;
20
+ const tagOffsets = endTagOffset !== undefined
21
+ ? [startTagOffset, endTagOffset]
22
+ : [startTagOffset];
19
23
  const propsFailedExps = [];
20
- const var_originalComponent = ctx.getInternalVariable();
24
+ const possibleOriginalNames = getPossibleOriginalComponentNames(node.tag, true);
25
+ const matchImportName = possibleOriginalNames.find(name => options.scriptSetupImportComponentNames.has(name));
26
+ const var_originalComponent = matchImportName ?? ctx.getInternalVariable();
21
27
  const var_functionalComponent = ctx.getInternalVariable();
22
28
  const var_componentInstance = ctx.getInternalVariable();
29
+ const var_componentEmit = ctx.getInternalVariable();
23
30
  const var_componentEvents = ctx.getInternalVariable();
31
+ const var_defineComponentCtx = ctx.getInternalVariable();
24
32
  const isComponentTag = node.tag.toLowerCase() === 'component';
25
- let endTagOffset = !node.isSelfClosing && options.template.lang === 'html' ? node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) : undefined;
26
- let tag = node.tag;
27
- let tagOffsets = endTagOffset !== undefined
28
- ? [startTagOffset, endTagOffset]
29
- : [startTagOffset];
30
33
  let props = node.props;
31
34
  let dynamicTagInfo;
32
- let defineComponentCtxVar;
33
- let usedComponentEventsVar = false;
34
35
  if (isComponentTag) {
35
36
  for (const prop of node.props) {
36
37
  if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) {
@@ -44,42 +45,59 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
44
45
  }
45
46
  }
46
47
  }
47
- else if (tag.includes('.')) {
48
+ else if (node.tag.includes('.')) {
48
49
  // namespace tag
49
50
  dynamicTagInfo = {
50
- exp: tag,
51
+ exp: node.tag,
51
52
  astHolder: node.loc,
52
53
  offset: startTagOffset,
53
54
  };
54
55
  }
55
- if (dynamicTagInfo) {
56
+ if (matchImportName) {
57
+ // hover, renaming / find references support
58
+ yield `// @ts-ignore${common_1.newLine}`; // #2304
59
+ yield `[`;
60
+ for (const tagOffset of tagOffsets) {
61
+ if (var_originalComponent === node.tag) {
62
+ yield [
63
+ var_originalComponent,
64
+ 'template',
65
+ tagOffset,
66
+ ctx.codeFeatures.withoutHighlightAndCompletion,
67
+ ];
68
+ }
69
+ else {
70
+ yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), tagOffset, {
71
+ ...ctx.codeFeatures.withoutHighlightAndCompletion,
72
+ navigation: {
73
+ resolveRenameNewName: camelizeComponentName,
74
+ resolveRenameEditText: getTagRenameApply(node.tag),
75
+ },
76
+ });
77
+ }
78
+ yield `,`;
79
+ }
80
+ yield `]${common_1.endOfLine}`;
81
+ }
82
+ else if (dynamicTagInfo) {
56
83
  yield `const ${var_originalComponent} = `;
57
84
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offset, ctx.codeFeatures.all, '(', ')');
58
85
  yield common_1.endOfLine;
59
86
  }
60
87
  else if (!isComponentTag) {
61
88
  yield `const ${var_originalComponent} = ({} as `;
62
- for (const componentName of getPossibleOriginalComponentNames(tag, true)) {
63
- yield `'${componentName}' extends keyof typeof __VLS_ctx ? { '${getCanonicalComponentName(tag)}': typeof __VLS_ctx`;
89
+ for (const componentName of possibleOriginalNames) {
90
+ yield `'${componentName}' extends keyof typeof __VLS_ctx ? { '${getCanonicalComponentName(node.tag)}': typeof __VLS_ctx`;
64
91
  yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, componentName);
65
92
  yield ` }: `;
66
93
  }
67
94
  yield `typeof __VLS_resolvedLocalAndGlobalComponents)`;
68
- yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, getCanonicalComponentName(tag), startTagOffset, ctx.codeFeatures.verification);
95
+ yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, getCanonicalComponentName(node.tag), startTagOffset, ctx.codeFeatures.verification);
69
96
  yield common_1.endOfLine;
70
- }
71
- else {
72
- yield `const ${var_originalComponent} = {} as any${common_1.endOfLine}`;
73
- }
74
- yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`;
75
- yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, false);
76
- yield `}))${common_1.endOfLine}`;
77
- if (!dynamicTagInfo
78
- && !isComponentTag) {
79
97
  // hover support
80
98
  for (const offset of tagOffsets) {
81
- yield `({} as { ${getCanonicalComponentName(tag)}: typeof ${var_originalComponent} }).`;
82
- yield* generateCanonicalComponentName(tag, offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation);
99
+ yield `({} as { ${getCanonicalComponentName(node.tag)}: typeof ${var_originalComponent} }).`;
100
+ yield* generateCanonicalComponentName(node.tag, offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation);
83
101
  yield common_1.endOfLine;
84
102
  }
85
103
  const camelizedTag = (0, shared_1.camelize)(node.tag);
@@ -114,10 +132,16 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
114
132
  yield `]${common_1.endOfLine}`;
115
133
  }
116
134
  }
135
+ else {
136
+ yield `const ${var_originalComponent} = {} as any${common_1.endOfLine}`;
137
+ }
138
+ yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`;
139
+ yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, false);
140
+ yield `}))${common_1.endOfLine}`;
117
141
  if (options.vueCompilerOptions.strictTemplates) {
118
142
  // with strictTemplates, generate once for props type-checking + instance type
119
143
  yield `const ${var_componentInstance} = ${var_functionalComponent}(`;
120
- yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
144
+ yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
121
145
  yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
122
146
  }
123
147
  else {
@@ -127,33 +151,31 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
127
151
  yield `}, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
128
152
  // and this for props type-checking
129
153
  yield `({} as (props: __VLS_FunctionalComponentProps<typeof ${var_originalComponent}, typeof ${var_componentInstance}> & Record<string, unknown>) => void)(`;
130
- yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
154
+ yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
131
155
  yield `)${common_1.endOfLine}`;
132
156
  }
133
- defineComponentCtxVar = ctx.getInternalVariable();
134
- componentCtxVar = defineComponentCtxVar;
157
+ componentCtxVar = var_defineComponentCtx;
135
158
  currentComponent = node;
136
159
  for (const failedExp of propsFailedExps) {
137
160
  yield* (0, interpolation_1.generateInterpolation)(options, ctx, failedExp.loc.source, failedExp.loc, failedExp.loc.start.offset, ctx.codeFeatures.all, '(', ')');
138
161
  yield common_1.endOfLine;
139
162
  }
140
163
  yield* generateVScope(options, ctx, node, props);
141
- if (componentCtxVar) {
142
- ctx.usedComponentCtxVars.add(componentCtxVar);
143
- yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEvents, () => usedComponentEventsVar = true);
144
- }
164
+ ctx.usedComponentCtxVars.add(componentCtxVar);
165
+ const usedComponentEventsVar = yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents);
145
166
  const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
146
- if (slotDir && componentCtxVar) {
167
+ if (slotDir) {
147
168
  yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
148
169
  }
149
170
  else {
150
171
  yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, componentCtxVar);
151
172
  }
152
- if (defineComponentCtxVar && ctx.usedComponentCtxVars.has(defineComponentCtxVar)) {
173
+ if (var_defineComponentCtx && ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
153
174
  yield `const ${componentCtxVar} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!${common_1.endOfLine}`;
154
175
  }
155
176
  if (usedComponentEventsVar) {
156
- yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${componentCtxVar}.emit>${common_1.endOfLine}`;
177
+ yield `let ${var_componentEmit}!: typeof ${componentCtxVar}.emit${common_1.endOfLine}`;
178
+ yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${var_componentEmit}>${common_1.endOfLine}`;
157
179
  }
158
180
  }
159
181
  exports.generateComponent = generateComponent;
@@ -207,9 +229,7 @@ function* generateVScope(options, ctx, node, props) {
207
229
  }
208
230
  yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
209
231
  yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
210
- if (options.shouldGenerateScopedClasses) {
211
- yield* generateReferencesForScopedCssClasses(ctx, node);
212
- }
232
+ yield* generateReferencesForScopedCssClasses(ctx, node);
213
233
  if (inScope) {
214
234
  yield `}${common_1.newLine}`;
215
235
  ctx.blockConditions.length = originalConditionsNum;
@@ -339,20 +359,31 @@ function* generateReferencesForScopedCssClasses(ctx, node) {
339
359
  && prop.name === 'class'
340
360
  && prop.value) {
341
361
  let startOffset = prop.value.loc.start.offset;
342
- let tempClassName = '';
343
- for (const char of (prop.value.loc.source + ' ')) {
344
- if (char.trim() === '' || char === '"' || char === "'") {
345
- if (tempClassName !== '') {
346
- ctx.scopedClasses.push({ className: tempClassName, offset: startOffset });
347
- startOffset += tempClassName.length;
348
- tempClassName = '';
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;
349
381
  }
350
- startOffset += char.length;
351
- }
352
- else {
353
- tempClassName += char;
354
382
  }
355
383
  }
384
+ else {
385
+ ctx.emptyClassOffsets.push(startOffset);
386
+ }
356
387
  }
357
388
  else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
358
389
  && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
@@ -16,7 +16,7 @@ function* generateElementDirectives(options, ctx, node) {
16
16
  && prop.name !== 'bind'
17
17
  && prop.name !== 'scope'
18
18
  && prop.name !== 'data') {
19
- ctx.accessGlobalVariable((0, shared_1.camelize)('v-' + prop.name), prop.loc.start.offset);
19
+ ctx.accessExternalVariable((0, shared_1.camelize)('v-' + prop.name), prop.loc.start.offset);
20
20
  if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && !prop.arg.isStatic) {
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;
@@ -3,7 +3,7 @@ import type * as ts from 'typescript';
3
3
  import type { Code } from '../../types';
4
4
  import type { TemplateCodegenContext } from './context';
5
5
  import type { TemplateCodegenOptions } from './index';
6
- export declare function generateElementEvents(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, componentVar: string, componentInstanceVar: string, eventsVar: string, used: () => void): Generator<Code>;
7
- export declare function generateEventArg(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, arg: CompilerDOM.SimpleExpressionNode, access: boolean): Generator<Code>;
6
+ export declare function generateElementEvents(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, componentVar: string, componentInstanceVar: string, emitVar: string, eventsVar: string): Generator<Code>;
7
+ export declare function generateEventArg(ctx: TemplateCodegenContext, arg: CompilerDOM.SimpleExpressionNode, enableHover: boolean): Generator<Code>;
8
8
  export declare function generateEventExpression(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode): Generator<Code>;
9
9
  export declare function isCompoundExpression(ts: typeof import('typescript'), ast: ts.SourceFile): boolean;
@@ -7,31 +7,49 @@ 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
- function* generateElementEvents(options, ctx, node, componentVar, componentInstanceVar, eventsVar, used) {
10
+ function* generateElementEvents(options, ctx, node, componentVar, componentInstanceVar, emitVar, eventsVar) {
11
+ let usedComponentEventsVar = false;
12
+ let propsVar;
12
13
  for (const prop of node.props) {
13
14
  if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
14
15
  && prop.name === 'on'
15
- && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
16
- used();
17
- const eventVar = ctx.getInternalVariable();
18
- yield `let ${eventVar} = { '${prop.arg.loc.source}': __VLS_pickEvent(`;
19
- yield `${eventsVar}['${prop.arg.loc.source}'], `;
20
- yield `({} as __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>)`;
21
- yield* generateEventArg(options, ctx, prop.arg, true);
22
- yield `) }${common_1.endOfLine}`;
23
- yield `${eventVar} = { `;
24
- if (prop.arg.loc.source.startsWith('[') && prop.arg.loc.source.endsWith(']')) {
25
- yield `[(`;
26
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, prop.arg.loc.source.slice(1, -1), prop.arg.loc, prop.arg.loc.start.offset + 1, ctx.codeFeatures.all, '', '');
27
- yield `)!]`;
16
+ && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
17
+ && !prop.arg.loc.source.startsWith('[')
18
+ && !prop.arg.loc.source.endsWith(']')) {
19
+ usedComponentEventsVar = true;
20
+ if (!propsVar) {
21
+ propsVar = ctx.getInternalVariable();
22
+ yield `let ${propsVar}!: __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>${common_1.endOfLine}`;
28
23
  }
29
- else {
30
- yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, prop.arg.loc.source, prop.arg.loc.start.offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation, prop.arg.loc);
24
+ const originalPropName = (0, shared_1.camelize)('on-' + prop.arg.loc.source);
25
+ const originalPropNameObjectKey = common_1.variableNameRegex.test(originalPropName)
26
+ ? originalPropName
27
+ : `'${originalPropName}'`;
28
+ yield `const ${ctx.getInternalVariable()}: `;
29
+ if (!options.vueCompilerOptions.strictTemplates) {
30
+ yield `Record<string, unknown> & `;
31
31
  }
32
+ yield `(`;
33
+ yield `__VLS_IsAny<__VLS_AsFunctionOrAny<typeof ${propsVar}['${originalPropName}']>> extends false${common_1.newLine}`;
34
+ yield `? typeof ${propsVar}${common_1.newLine}`;
35
+ yield `: __VLS_IsAny<typeof ${eventsVar}['${prop.arg.loc.source}']> extends false${common_1.newLine}`;
36
+ yield `? {${common_1.newLine}`;
37
+ yield `/**__VLS_emit,${emitVar},${prop.arg.loc.source}*/${common_1.newLine}`;
38
+ yield `${originalPropNameObjectKey}?: typeof ${eventsVar}['${prop.arg.loc.source}']${common_1.newLine}`;
39
+ yield `}${common_1.newLine}`;
40
+ if (prop.arg.loc.source !== (0, shared_1.camelize)(prop.arg.loc.source)) {
41
+ yield `: __VLS_IsAny<typeof ${eventsVar}['${(0, shared_1.camelize)(prop.arg.loc.source)}']> extends false${common_1.newLine}`;
42
+ yield `? {${common_1.newLine}`;
43
+ yield `/**__VLS_emit,${emitVar},${(0, shared_1.camelize)(prop.arg.loc.source)}*/${common_1.newLine}`;
44
+ yield `${originalPropNameObjectKey}?: typeof ${eventsVar}['${(0, shared_1.camelize)(prop.arg.loc.source)}']${common_1.newLine}`;
45
+ yield `}${common_1.newLine}`;
46
+ }
47
+ yield `: typeof ${propsVar}${common_1.newLine}`;
48
+ yield `) = {${common_1.newLine}`;
49
+ yield* generateEventArg(ctx, prop.arg, true);
32
50
  yield `: `;
33
51
  yield* generateEventExpression(options, ctx, prop);
34
- yield ` }${common_1.endOfLine}`;
52
+ yield `}${common_1.endOfLine}`;
35
53
  }
36
54
  else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
37
55
  && prop.name === 'on'
@@ -42,6 +60,7 @@ function* generateElementEvents(options, ctx, node, componentVar, componentInsta
42
60
  yield common_1.endOfLine;
43
61
  }
44
62
  }
63
+ return usedComponentEventsVar;
45
64
  }
46
65
  exports.generateElementEvents = generateElementEvents;
47
66
  const eventArgFeatures = {
@@ -60,28 +79,20 @@ const eventArgFeatures = {
60
79
  },
61
80
  },
62
81
  };
63
- function* generateEventArg(options, ctx, arg, access) {
64
- if (arg.loc.source.startsWith('[') && arg.loc.source.endsWith(']')) {
65
- yield `[`;
66
- yield* (0, interpolation_1.generateInterpolation)(options, ctx, arg.loc.source.slice(1, -1), arg.loc, arg.loc.start.offset + 1, ctx.codeFeatures.all, '', '');
67
- yield `]`;
68
- }
69
- else if (common_1.variableNameRegex.test((0, shared_1.camelize)(arg.loc.source))) {
70
- if (access) {
71
- yield `.`;
82
+ function* generateEventArg(ctx, arg, enableHover) {
83
+ const features = enableHover
84
+ ? {
85
+ ...ctx.codeFeatures.withoutHighlightAndCompletion,
86
+ ...eventArgFeatures,
72
87
  }
73
- yield ['', 'template', arg.loc.start.offset, eventArgFeatures];
88
+ : eventArgFeatures;
89
+ if (common_1.variableNameRegex.test((0, shared_1.camelize)(arg.loc.source))) {
90
+ yield ['', 'template', arg.loc.start.offset, features];
74
91
  yield `on`;
75
92
  yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(arg.loc.source), arg.loc.start.offset, common_1.combineLastMapping);
76
93
  }
77
94
  else {
78
- if (access) {
79
- yield `[`;
80
- }
81
- yield* (0, common_1.wrapWith)(arg.loc.start.offset, arg.loc.end.offset, eventArgFeatures, `'`, ['', 'template', arg.loc.start.offset, common_1.combineLastMapping], 'on', ...(0, camelized_1.generateCamelized)((0, shared_1.capitalize)(arg.loc.source), arg.loc.start.offset, common_1.combineLastMapping), `'`);
82
- if (access) {
83
- yield `]`;
84
- }
95
+ yield* (0, common_1.wrapWith)(arg.loc.start.offset, arg.loc.end.offset, features, `'`, ['', 'template', arg.loc.start.offset, common_1.combineLastMapping], 'on', ...(0, camelized_1.generateCamelized)((0, shared_1.capitalize)(arg.loc.source), arg.loc.start.offset, common_1.combineLastMapping), `'`);
85
96
  }
86
97
  }
87
98
  exports.generateEventArg = generateEventArg;
@@ -12,47 +12,34 @@ const objectProperty_1 = require("./objectProperty");
12
12
  const language_core_1 = require("@volar/language-core");
13
13
  const elementEvents_1 = require("./elementEvents");
14
14
  function* generateElementProps(options, ctx, node, props, enableCodeFeatures, propsFailedExps) {
15
- let styleAttrNum = 0;
16
- let classAttrNum = 0;
17
15
  const isIntrinsicElement = node.tagType === CompilerDOM.ElementTypes.ELEMENT || node.tagType === CompilerDOM.ElementTypes.TEMPLATE;
18
16
  const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
19
- if (props.some(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE
20
- && prop.name === 'bind'
21
- && !prop.arg
22
- && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)) {
23
- // fix https://github.com/vuejs/language-tools/issues/2166
24
- styleAttrNum++;
25
- classAttrNum++;
26
- }
27
- if (!isIntrinsicElement) {
28
- let generatedEvent = false;
29
- for (const prop of props) {
30
- if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
31
- && prop.name === 'on'
32
- && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
33
- if (prop.arg.loc.source.startsWith('[') && prop.arg.loc.source.endsWith(']')) {
34
- continue;
35
- }
36
- if (!generatedEvent) {
17
+ for (const prop of props) {
18
+ if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
19
+ && prop.name === 'on') {
20
+ if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
21
+ && !prop.arg.loc.source.startsWith('[')
22
+ && !prop.arg.loc.source.endsWith(']')) {
23
+ if (isIntrinsicElement) {
37
24
  yield `...{ `;
38
- generatedEvent = true;
25
+ yield* (0, elementEvents_1.generateEventArg)(ctx, prop.arg, true);
26
+ yield `: `;
27
+ yield* (0, elementEvents_1.generateEventExpression)(options, ctx, prop);
28
+ yield `}, `;
29
+ }
30
+ else {
31
+ yield `...{ '${(0, shared_1.camelize)('on-' + prop.arg.loc.source)}': {} as any }, `;
39
32
  }
40
- yield `'${(0, shared_1.camelize)('on-' + prop.arg.loc.source)}': {} as any, `;
41
33
  }
42
- }
43
- if (generatedEvent) {
44
- yield `}, `;
45
- }
46
- }
47
- else {
48
- for (const prop of props) {
49
- if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
50
- && prop.name === 'on'
51
- && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
52
- yield* (0, elementEvents_1.generateEventArg)(options, ctx, prop.arg, false);
53
- yield `: `;
54
- yield* (0, elementEvents_1.generateEventExpression)(options, ctx, prop);
55
- yield `,${common_1.newLine}`;
34
+ else {
35
+ if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
36
+ && prop.arg.loc.source.startsWith('[')
37
+ && prop.arg.loc.source.endsWith(']')) {
38
+ propsFailedExps?.push(prop.arg);
39
+ }
40
+ if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
41
+ propsFailedExps?.push(prop.exp);
42
+ }
56
43
  }
57
44
  }
58
45
  }
@@ -61,33 +48,35 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
61
48
  && (prop.name === 'bind' || prop.name === 'model')
62
49
  && (prop.name === 'model' || prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)
63
50
  && (!prop.exp || prop.exp.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION)) {
64
- let propName = prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
65
- ? prop.arg.constType === CompilerDOM.ConstantTypes.CAN_STRINGIFY
51
+ let propName;
52
+ if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
53
+ propName = prop.arg.constType === CompilerDOM.ConstantTypes.CAN_STRINGIFY
66
54
  ? prop.arg.content
67
- : prop.arg.loc.source
68
- : getModelValuePropName(node, options.vueCompilerOptions.target, options.vueCompilerOptions);
69
- if (prop.modifiers.some(m => m === 'prop' || m === 'attr')) {
70
- propName = propName?.substring(1);
55
+ : prop.arg.loc.source;
56
+ }
57
+ else {
58
+ propName = getModelValuePropName(node, options.vueCompilerOptions.target, options.vueCompilerOptions);
71
59
  }
72
60
  if (propName === undefined
73
- || options.vueCompilerOptions.dataAttributes.some(pattern => (0, minimatch_1.minimatch)(propName, pattern))
74
- || (propName === 'style' && ++styleAttrNum >= 2)
75
- || (propName === 'class' && ++classAttrNum >= 2)
76
- || (propName === 'name' && node.tagType === CompilerDOM.ElementTypes.SLOT) // #2308
77
- ) {
61
+ || options.vueCompilerOptions.dataAttributes.some(pattern => (0, minimatch_1.minimatch)(propName, pattern))) {
78
62
  if (prop.exp && prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
79
63
  propsFailedExps?.push(prop.exp);
80
64
  }
81
65
  continue;
82
66
  }
67
+ if (prop.modifiers.some(m => m === 'prop' || m === 'attr')) {
68
+ propName = propName.substring(1);
69
+ }
70
+ const shouldSpread = propName === 'style' || propName === 'class';
83
71
  const shouldCamelize = canCamelize
84
72
  && (!prop.arg || (prop.arg.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && prop.arg.isStatic)) // isStatic
85
73
  && (0, shared_2.hyphenateAttr)(propName) === propName
86
74
  && !options.vueCompilerOptions.htmlAttributes.some(pattern => (0, minimatch_1.minimatch)(propName, pattern));
87
- const codes = (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(0, objectProperty_1.generateObjectProperty)(options, ctx, propName, prop.arg
88
- ? prop.arg.loc.start.offset
89
- : prop.loc.start.offset, prop.arg
90
- ? {
75
+ if (shouldSpread) {
76
+ yield `...{ `;
77
+ }
78
+ const codes = (0, common_1.wrapWith)(prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, ...(prop.arg
79
+ ? (0, objectProperty_1.generateObjectProperty)(options, ctx, propName, prop.arg.loc.start.offset, {
91
80
  ...ctx.codeFeatures.withoutHighlightAndCompletion,
92
81
  navigation: ctx.codeFeatures.withoutHighlightAndCompletion.navigation
93
82
  ? {
@@ -95,33 +84,34 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
95
84
  resolveRenameEditText: shouldCamelize ? shared_2.hyphenateAttr : undefined,
96
85
  }
97
86
  : false,
98
- }
99
- : ctx.codeFeatures.withoutHighlightAndCompletion, prop.loc.name_2 ?? (prop.loc.name_2 = {}), shouldCamelize), `: (`, ...genereatePropExp(options, ctx, prop.exp, ctx.codeFeatures.all, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, enableCodeFeatures), `)`);
87
+ }, prop.loc.name_2 ?? (prop.loc.name_2 = {}), shouldCamelize)
88
+ : [propName]), `: (`, ...genereatePropExp(options, ctx, prop.exp, ctx.codeFeatures.all, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, enableCodeFeatures), `)`);
100
89
  if (!enableCodeFeatures) {
101
90
  yield (0, language_core_1.toString)([...codes]);
102
91
  }
103
92
  else {
104
93
  yield* codes;
105
94
  }
95
+ if (shouldSpread) {
96
+ yield ` }`;
97
+ }
106
98
  yield `, `;
107
99
  }
108
100
  else if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE) {
109
101
  if (options.vueCompilerOptions.dataAttributes.some(pattern => (0, minimatch_1.minimatch)(prop.name, pattern))
110
- || (prop.name === 'style' && ++styleAttrNum >= 2)
111
- || (prop.name === 'class' && ++classAttrNum >= 2)
112
- || (prop.name === 'name' && node.tagType === CompilerDOM.ElementTypes.SLOT) // #2308
113
- ) {
114
- continue;
115
- }
116
- if (options.vueCompilerOptions.target < 3
117
- && prop.name === 'persisted'
118
- && node.tag.toLowerCase() === 'transition') {
119
102
  // Vue 2 Transition doesn't support "persisted" property but `@vue/compiler-dom always adds it (#3881)
103
+ || (options.vueCompilerOptions.target < 3
104
+ && prop.name === 'persisted'
105
+ && node.tag.toLowerCase() === 'transition')) {
120
106
  continue;
121
107
  }
108
+ const shouldSpread = prop.name === 'style' || prop.name === 'class';
122
109
  const shouldCamelize = canCamelize
123
110
  && (0, shared_2.hyphenateAttr)(prop.name) === prop.name
124
111
  && !options.vueCompilerOptions.htmlAttributes.some(pattern => (0, minimatch_1.minimatch)(prop.name, pattern));
112
+ if (shouldSpread) {
113
+ yield `...{ `;
114
+ }
125
115
  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
126
116
  ? {
127
117
  ...ctx.codeFeatures.withoutHighlightAndCompletion,
@@ -141,6 +131,9 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
141
131
  else {
142
132
  yield* codes;
143
133
  }
134
+ if (shouldSpread) {
135
+ yield ` }`;
136
+ }
144
137
  yield `, `;
145
138
  }
146
139
  else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
@@ -172,7 +165,7 @@ function* genereatePropExp(options, ctx, exp, features, isShorthand, inlayHints)
172
165
  const propVariableName = (0, shared_1.camelize)(exp.loc.source);
173
166
  if (common_1.variableNameRegex.test(propVariableName)) {
174
167
  if (!ctx.hasLocalVariable(propVariableName)) {
175
- ctx.accessGlobalVariable(propVariableName, exp.loc.start.offset);
168
+ ctx.accessExternalVariable(propVariableName, exp.loc.start.offset);
176
169
  yield `__VLS_ctx.`;
177
170
  }
178
171
  yield* (0, camelized_1.generateCamelized)(exp.loc.source, exp.loc.start.offset, features);
@@ -1,60 +1,18 @@
1
1
  import * as CompilerDOM from '@vue/compiler-dom';
2
2
  import type * as ts from 'typescript';
3
3
  import type { Code, Sfc, VueCompilerOptions } from '../../types';
4
+ import { TemplateCodegenContext } from './context';
4
5
  export interface TemplateCodegenOptions {
5
6
  ts: typeof ts;
6
7
  compilerOptions: ts.CompilerOptions;
7
8
  vueCompilerOptions: VueCompilerOptions;
8
9
  template: NonNullable<Sfc['template']>;
9
- shouldGenerateScopedClasses?: boolean;
10
- stylesScopedClasses: Set<string>;
10
+ scriptSetupBindingNames: Set<string>;
11
+ scriptSetupImportComponentNames: Set<string>;
11
12
  hasDefineSlots?: boolean;
12
13
  slotsAssignName?: string;
13
14
  propsAssignName?: string;
14
15
  }
15
- export declare function generateTemplate(options: TemplateCodegenOptions): Generator<Code, {
16
- ctx: {
17
- slots: {
18
- name: string;
19
- loc?: number | undefined;
20
- tagRange: [number, number];
21
- varName: string;
22
- nodeLoc: any;
23
- }[];
24
- dynamicSlots: {
25
- expVar: string;
26
- varName: string;
27
- }[];
28
- codeFeatures: {
29
- all: import("../../types").VueCodeInformation;
30
- verification: import("../../types").VueCodeInformation;
31
- completion: import("../../types").VueCodeInformation;
32
- additionalCompletion: import("../../types").VueCodeInformation;
33
- navigation: import("../../types").VueCodeInformation;
34
- navigationAndCompletion: import("../../types").VueCodeInformation;
35
- withoutHighlight: import("../../types").VueCodeInformation;
36
- withoutHighlightAndCompletion: import("../../types").VueCodeInformation;
37
- withoutHighlightAndCompletionAndNavigation: import("../../types").VueCodeInformation;
38
- };
39
- accessGlobalVariables: Map<string, Set<number>>;
40
- hasSlotElements: Set<CompilerDOM.ElementNode>;
41
- blockConditions: string[];
42
- usedComponentCtxVars: Set<string>;
43
- scopedClasses: {
44
- className: string;
45
- offset: number;
46
- }[];
47
- accessGlobalVariable(name: string, offset?: number | undefined): void;
48
- hasLocalVariable: (name: string) => boolean;
49
- addLocalVariable: (name: string) => void;
50
- removeLocalVariable: (name: string) => void;
51
- getInternalVariable: () => string;
52
- ignoreError: () => Generator<Code, any, unknown>;
53
- expectError: (prevNode: CompilerDOM.CommentNode) => Generator<Code, any, unknown>;
54
- resetDirectiveComments: (endStr: string) => Generator<Code, any, unknown>;
55
- generateAutoImportCompletion: () => Generator<Code, any, unknown>;
56
- };
57
- hasSlot: boolean;
58
- }, unknown>;
16
+ export declare function generateTemplate(options: TemplateCodegenOptions): Generator<Code, TemplateCodegenContext>;
59
17
  export declare function forEachElementNode(node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode): Generator<CompilerDOM.ElementNode>;
60
18
  export declare function isFragment(node: CompilerDOM.IfNode | CompilerDOM.ForNode): boolean | undefined;