@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.
- package/lib/codegen/script/globalTypes.js +10 -14
- package/lib/codegen/script/index.d.ts +3 -6
- package/lib/codegen/script/index.js +12 -15
- package/lib/codegen/script/internalComponent.js +1 -1
- package/lib/codegen/script/scriptSetup.js +21 -23
- package/lib/codegen/script/template.d.ts +1 -1
- package/lib/codegen/script/template.js +45 -36
- package/lib/codegen/template/context.d.ts +8 -3
- package/lib/codegen/template/context.js +42 -13
- package/lib/codegen/template/element.js +81 -50
- package/lib/codegen/template/elementDirectives.js +1 -1
- package/lib/codegen/template/elementEvents.d.ts +2 -2
- package/lib/codegen/template/elementEvents.js +46 -35
- package/lib/codegen/template/elementProps.js +56 -63
- package/lib/codegen/template/index.d.ts +4 -46
- package/lib/codegen/template/index.js +36 -21
- package/lib/codegen/template/interpolation.d.ts +2 -2
- package/lib/codegen/template/interpolation.js +12 -46
- package/lib/codegen/template/vFor.js +13 -3
- package/lib/languageModule.d.ts +1 -1
- package/lib/languageModule.js +4 -4
- package/lib/parsers/scriptRanges.d.ts +1 -0
- package/lib/parsers/scriptRanges.js +7 -0
- package/lib/parsers/scriptSetupRanges.d.ts +4 -0
- package/lib/parsers/scriptSetupRanges.js +24 -0
- package/lib/plugins/file-md.js +1 -0
- package/lib/plugins/vue-script-js.d.ts +3 -0
- package/lib/plugins/vue-script-js.js +15 -0
- package/lib/plugins/vue-template-html.js +1 -1
- package/lib/plugins/vue-template-inline-ts.js +1 -1
- package/lib/plugins/vue-tsx.d.ts +46 -40
- package/lib/plugins/vue-tsx.js +34 -28
- package/lib/plugins.d.ts +1 -0
- package/lib/plugins.js +2 -0
- package/lib/types.d.ts +1 -15
- package/lib/utils/parseCssClassNames.js +1 -1
- package/lib/utils/ts.js +0 -1
- package/lib/virtualFile/computedSfc.js +20 -5
- 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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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
|
|
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 (
|
|
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 ${
|
|
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
|
-
|
|
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
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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.
|
|
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,
|
|
7
|
-
export declare function generateEventArg(
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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 `
|
|
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(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
65
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
propName =
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
:
|
|
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.
|
|
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
|
-
|
|
10
|
-
|
|
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;
|