@vue/language-core 2.0.15 → 2.0.17
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/component.js +2 -2
- package/lib/codegen/script/globalTypes.js +3 -3
- 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 +25 -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 -49
- package/lib/codegen/template/elementChildren.js +2 -1
- package/lib/codegen/template/elementDirectives.js +1 -1
- package/lib/codegen/template/elementEvents.d.ts +2 -2
- package/lib/codegen/template/elementEvents.js +16 -7
- package/lib/codegen/template/elementProps.js +18 -14
- 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/slotOutlet.js +29 -30
- 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/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 -1
- package/lib/types.d.ts +1 -15
- package/lib/utils/parseCssClassNames.js +1 -1
- package/lib/utils/ts.js +0 -1
- package/lib/virtualFile/computedFiles.js +34 -33
- package/lib/virtualFile/computedSfc.js +0 -3
- package/package.json +3 -3
|
@@ -16,20 +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
35
|
let usedComponentEventsVar = false;
|
|
34
36
|
if (isComponentTag) {
|
|
35
37
|
for (const prop of node.props) {
|
|
@@ -44,42 +46,59 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
|
-
else if (tag.includes('.')) {
|
|
49
|
+
else if (node.tag.includes('.')) {
|
|
48
50
|
// namespace tag
|
|
49
51
|
dynamicTagInfo = {
|
|
50
|
-
exp: tag,
|
|
52
|
+
exp: node.tag,
|
|
51
53
|
astHolder: node.loc,
|
|
52
54
|
offset: startTagOffset,
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
|
-
if (
|
|
57
|
+
if (matchImportName) {
|
|
58
|
+
// hover, renaming / find references support
|
|
59
|
+
yield `// @ts-ignore${common_1.newLine}`; // #2304
|
|
60
|
+
yield `[`;
|
|
61
|
+
for (const tagOffset of tagOffsets) {
|
|
62
|
+
if (var_originalComponent === node.tag) {
|
|
63
|
+
yield [
|
|
64
|
+
var_originalComponent,
|
|
65
|
+
'template',
|
|
66
|
+
tagOffset,
|
|
67
|
+
ctx.codeFeatures.withoutHighlightAndCompletion,
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(node.tag), tagOffset, {
|
|
72
|
+
...ctx.codeFeatures.withoutHighlightAndCompletion,
|
|
73
|
+
navigation: {
|
|
74
|
+
resolveRenameNewName: camelizeComponentName,
|
|
75
|
+
resolveRenameEditText: getTagRenameApply(node.tag),
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
yield `,`;
|
|
80
|
+
}
|
|
81
|
+
yield `]${common_1.endOfLine}`;
|
|
82
|
+
}
|
|
83
|
+
else if (dynamicTagInfo) {
|
|
56
84
|
yield `const ${var_originalComponent} = `;
|
|
57
85
|
yield* (0, interpolation_1.generateInterpolation)(options, ctx, dynamicTagInfo.exp, dynamicTagInfo.astHolder, dynamicTagInfo.offset, ctx.codeFeatures.all, '(', ')');
|
|
58
86
|
yield common_1.endOfLine;
|
|
59
87
|
}
|
|
60
88
|
else if (!isComponentTag) {
|
|
61
89
|
yield `const ${var_originalComponent} = ({} as `;
|
|
62
|
-
for (const componentName of
|
|
63
|
-
yield `'${componentName}' extends keyof typeof __VLS_ctx ? { '${getCanonicalComponentName(tag)}': typeof __VLS_ctx`;
|
|
90
|
+
for (const componentName of possibleOriginalNames) {
|
|
91
|
+
yield `'${componentName}' extends keyof typeof __VLS_ctx ? { '${getCanonicalComponentName(node.tag)}': typeof __VLS_ctx`;
|
|
64
92
|
yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, componentName);
|
|
65
93
|
yield ` }: `;
|
|
66
94
|
}
|
|
67
95
|
yield `typeof __VLS_resolvedLocalAndGlobalComponents)`;
|
|
68
|
-
yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, getCanonicalComponentName(tag), startTagOffset, ctx.codeFeatures.verification);
|
|
96
|
+
yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, getCanonicalComponentName(node.tag), startTagOffset, ctx.codeFeatures.verification);
|
|
69
97
|
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
98
|
// hover support
|
|
80
99
|
for (const offset of tagOffsets) {
|
|
81
|
-
yield `({} as { ${getCanonicalComponentName(tag)}: typeof ${var_originalComponent} }).`;
|
|
82
|
-
yield* generateCanonicalComponentName(tag, offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation);
|
|
100
|
+
yield `({} as { ${getCanonicalComponentName(node.tag)}: typeof ${var_originalComponent} }).`;
|
|
101
|
+
yield* generateCanonicalComponentName(node.tag, offset, ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation);
|
|
83
102
|
yield common_1.endOfLine;
|
|
84
103
|
}
|
|
85
104
|
const camelizedTag = (0, shared_1.camelize)(node.tag);
|
|
@@ -114,10 +133,16 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
|
|
|
114
133
|
yield `]${common_1.endOfLine}`;
|
|
115
134
|
}
|
|
116
135
|
}
|
|
136
|
+
else {
|
|
137
|
+
yield `const ${var_originalComponent} = {} as any${common_1.endOfLine}`;
|
|
138
|
+
}
|
|
139
|
+
yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`;
|
|
140
|
+
yield* (0, elementProps_1.generateElementProps)(options, ctx, node, props, false);
|
|
141
|
+
yield `}))${common_1.endOfLine}`;
|
|
117
142
|
if (options.vueCompilerOptions.strictTemplates) {
|
|
118
143
|
// with strictTemplates, generate once for props type-checking + instance type
|
|
119
144
|
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), `}`);
|
|
145
|
+
yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
|
|
121
146
|
yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
|
|
122
147
|
}
|
|
123
148
|
else {
|
|
@@ -127,33 +152,31 @@ function* generateComponent(options, ctx, node, currentComponent, componentCtxVa
|
|
|
127
152
|
yield `}, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${common_1.endOfLine}`;
|
|
128
153
|
// and this for props type-checking
|
|
129
154
|
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), `}`);
|
|
155
|
+
yield* (0, common_1.wrapWith)(startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{`, ...(0, elementProps_1.generateElementProps)(options, ctx, node, props, true, propsFailedExps), `}`);
|
|
131
156
|
yield `)${common_1.endOfLine}`;
|
|
132
157
|
}
|
|
133
|
-
|
|
134
|
-
componentCtxVar = defineComponentCtxVar;
|
|
158
|
+
componentCtxVar = var_defineComponentCtx;
|
|
135
159
|
currentComponent = node;
|
|
136
160
|
for (const failedExp of propsFailedExps) {
|
|
137
161
|
yield* (0, interpolation_1.generateInterpolation)(options, ctx, failedExp.loc.source, failedExp.loc, failedExp.loc.start.offset, ctx.codeFeatures.all, '(', ')');
|
|
138
162
|
yield common_1.endOfLine;
|
|
139
163
|
}
|
|
140
164
|
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
|
-
}
|
|
165
|
+
ctx.usedComponentCtxVars.add(componentCtxVar);
|
|
166
|
+
yield* (0, elementEvents_1.generateElementEvents)(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents, () => usedComponentEventsVar = true);
|
|
145
167
|
const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot');
|
|
146
|
-
if (slotDir
|
|
168
|
+
if (slotDir) {
|
|
147
169
|
yield* generateComponentSlot(options, ctx, node, slotDir, currentComponent, componentCtxVar);
|
|
148
170
|
}
|
|
149
171
|
else {
|
|
150
172
|
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, componentCtxVar);
|
|
151
173
|
}
|
|
152
|
-
if (
|
|
174
|
+
if (var_defineComponentCtx && ctx.usedComponentCtxVars.has(var_defineComponentCtx)) {
|
|
153
175
|
yield `const ${componentCtxVar} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!${common_1.endOfLine}`;
|
|
154
176
|
}
|
|
155
177
|
if (usedComponentEventsVar) {
|
|
156
|
-
yield `let ${
|
|
178
|
+
yield `let ${var_componentEmit}!: typeof ${componentCtxVar}.emit${common_1.endOfLine}`;
|
|
179
|
+
yield `let ${var_componentEvents}!: __VLS_NormalizeEmits<typeof ${var_componentEmit}>${common_1.endOfLine}`;
|
|
157
180
|
}
|
|
158
181
|
}
|
|
159
182
|
exports.generateComponent = generateComponent;
|
|
@@ -207,9 +230,7 @@ function* generateVScope(options, ctx, node, props) {
|
|
|
207
230
|
}
|
|
208
231
|
yield* (0, elementDirectives_1.generateElementDirectives)(options, ctx, node);
|
|
209
232
|
yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
|
|
210
|
-
|
|
211
|
-
yield* generateReferencesForScopedCssClasses(ctx, node);
|
|
212
|
-
}
|
|
233
|
+
yield* generateReferencesForScopedCssClasses(ctx, node);
|
|
213
234
|
if (inScope) {
|
|
214
235
|
yield `}${common_1.newLine}`;
|
|
215
236
|
ctx.blockConditions.length = originalConditionsNum;
|
|
@@ -339,20 +360,31 @@ function* generateReferencesForScopedCssClasses(ctx, node) {
|
|
|
339
360
|
&& prop.name === 'class'
|
|
340
361
|
&& prop.value) {
|
|
341
362
|
let startOffset = prop.value.loc.start.offset;
|
|
342
|
-
let
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
363
|
+
let content = prop.value.loc.source;
|
|
364
|
+
if ((content.startsWith(`'`) && content.endsWith(`'`))
|
|
365
|
+
|| (content.startsWith(`"`) && content.endsWith(`"`))) {
|
|
366
|
+
startOffset++;
|
|
367
|
+
content = content.slice(1, -1);
|
|
368
|
+
}
|
|
369
|
+
if (content) {
|
|
370
|
+
let currentClassName = '';
|
|
371
|
+
for (const char of (content + ' ')) {
|
|
372
|
+
if (char.trim() === '') {
|
|
373
|
+
if (currentClassName !== '') {
|
|
374
|
+
ctx.scopedClasses.push({ className: currentClassName, offset: startOffset });
|
|
375
|
+
startOffset += currentClassName.length;
|
|
376
|
+
currentClassName = '';
|
|
377
|
+
}
|
|
378
|
+
startOffset += char.length;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
currentClassName += char;
|
|
349
382
|
}
|
|
350
|
-
startOffset += char.length;
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
tempClassName += char;
|
|
354
383
|
}
|
|
355
384
|
}
|
|
385
|
+
else {
|
|
386
|
+
ctx.emptyClassOffsets.push(startOffset);
|
|
387
|
+
}
|
|
356
388
|
}
|
|
357
389
|
else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
358
390
|
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
|
|
@@ -13,7 +13,8 @@ function* generateElementChildren(options, ctx, node, currentComponent, componen
|
|
|
13
13
|
}
|
|
14
14
|
yield* ctx.generateAutoImportCompletion();
|
|
15
15
|
// fix https://github.com/vuejs/language-tools/issues/932
|
|
16
|
-
if (
|
|
16
|
+
if (componentCtxVar
|
|
17
|
+
&& !ctx.hasSlotElements.has(node)
|
|
17
18
|
&& node.children.length
|
|
18
19
|
&& node.tagType !== CompilerDOM.ElementTypes.ELEMENT
|
|
19
20
|
&& node.tagType !== CompilerDOM.ElementTypes.TEMPLATE) {
|
|
@@ -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, 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, used: () => void): Generator<Code>;
|
|
7
|
+
export declare function generateEventArg(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, arg: CompilerDOM.SimpleExpressionNode, access: boolean, 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;
|
|
@@ -8,17 +8,19 @@ const common_1 = require("../common");
|
|
|
8
8
|
const camelized_1 = require("./camelized");
|
|
9
9
|
const interpolation_1 = require("./interpolation");
|
|
10
10
|
const objectProperty_1 = require("./objectProperty");
|
|
11
|
-
function* generateElementEvents(options, ctx, node, componentVar, componentInstanceVar, eventsVar, used) {
|
|
11
|
+
function* generateElementEvents(options, ctx, node, componentVar, componentInstanceVar, emitVar, eventsVar, used) {
|
|
12
12
|
for (const prop of node.props) {
|
|
13
13
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
14
14
|
&& prop.name === 'on'
|
|
15
15
|
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
16
16
|
used();
|
|
17
17
|
const eventVar = ctx.getInternalVariable();
|
|
18
|
-
yield `let ${eventVar} = {
|
|
18
|
+
yield `let ${eventVar} = {${common_1.newLine}`;
|
|
19
|
+
yield `/**__VLS_emit,${emitVar},${prop.arg.loc.source}*/${common_1.newLine}`;
|
|
20
|
+
yield `'${prop.arg.loc.source}': __VLS_pickEvent(`;
|
|
19
21
|
yield `${eventsVar}['${prop.arg.loc.source}'], `;
|
|
20
22
|
yield `({} as __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>)`;
|
|
21
|
-
yield* generateEventArg(options, ctx, prop.arg, true);
|
|
23
|
+
yield* generateEventArg(options, ctx, prop.arg, true, false);
|
|
22
24
|
yield `) }${common_1.endOfLine}`;
|
|
23
25
|
yield `${eventVar} = { `;
|
|
24
26
|
if (prop.arg.loc.source.startsWith('[') && prop.arg.loc.source.endsWith(']')) {
|
|
@@ -31,7 +33,8 @@ function* generateElementEvents(options, ctx, node, componentVar, componentInsta
|
|
|
31
33
|
}
|
|
32
34
|
yield `: `;
|
|
33
35
|
yield* generateEventExpression(options, ctx, prop);
|
|
34
|
-
yield
|
|
36
|
+
yield common_1.newLine;
|
|
37
|
+
yield `}${common_1.endOfLine}`;
|
|
35
38
|
}
|
|
36
39
|
else if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
37
40
|
&& prop.name === 'on'
|
|
@@ -60,7 +63,13 @@ const eventArgFeatures = {
|
|
|
60
63
|
},
|
|
61
64
|
},
|
|
62
65
|
};
|
|
63
|
-
function* generateEventArg(options, ctx, arg, access) {
|
|
66
|
+
function* generateEventArg(options, ctx, arg, access, enableHover) {
|
|
67
|
+
const features = enableHover
|
|
68
|
+
? {
|
|
69
|
+
...ctx.codeFeatures.withoutHighlightAndCompletion,
|
|
70
|
+
...eventArgFeatures,
|
|
71
|
+
}
|
|
72
|
+
: eventArgFeatures;
|
|
64
73
|
if (arg.loc.source.startsWith('[') && arg.loc.source.endsWith(']')) {
|
|
65
74
|
yield `[`;
|
|
66
75
|
yield* (0, interpolation_1.generateInterpolation)(options, ctx, arg.loc.source.slice(1, -1), arg.loc, arg.loc.start.offset + 1, ctx.codeFeatures.all, '', '');
|
|
@@ -70,7 +79,7 @@ function* generateEventArg(options, ctx, arg, access) {
|
|
|
70
79
|
if (access) {
|
|
71
80
|
yield `.`;
|
|
72
81
|
}
|
|
73
|
-
yield ['', 'template', arg.loc.start.offset,
|
|
82
|
+
yield ['', 'template', arg.loc.start.offset, features];
|
|
74
83
|
yield `on`;
|
|
75
84
|
yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(arg.loc.source), arg.loc.start.offset, common_1.combineLastMapping);
|
|
76
85
|
}
|
|
@@ -78,7 +87,7 @@ function* generateEventArg(options, ctx, arg, access) {
|
|
|
78
87
|
if (access) {
|
|
79
88
|
yield `[`;
|
|
80
89
|
}
|
|
81
|
-
yield* (0, common_1.wrapWith)(arg.loc.start.offset, arg.loc.end.offset,
|
|
90
|
+
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), `'`);
|
|
82
91
|
if (access) {
|
|
83
92
|
yield `]`;
|
|
84
93
|
}
|
|
@@ -24,7 +24,23 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
|
|
|
24
24
|
styleAttrNum++;
|
|
25
25
|
classAttrNum++;
|
|
26
26
|
}
|
|
27
|
-
if (
|
|
27
|
+
if (isIntrinsicElement) {
|
|
28
|
+
for (const prop of props) {
|
|
29
|
+
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
30
|
+
&& prop.name === 'on') {
|
|
31
|
+
if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
32
|
+
yield* (0, elementEvents_1.generateEventArg)(options, ctx, prop.arg, false, true);
|
|
33
|
+
yield `: `;
|
|
34
|
+
yield* (0, elementEvents_1.generateEventExpression)(options, ctx, prop);
|
|
35
|
+
yield `,${common_1.newLine}`;
|
|
36
|
+
}
|
|
37
|
+
else if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
38
|
+
propsFailedExps?.push(prop.exp);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
28
44
|
let generatedEvent = false;
|
|
29
45
|
for (const prop of props) {
|
|
30
46
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
@@ -44,18 +60,6 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
|
|
|
44
60
|
yield `}, `;
|
|
45
61
|
}
|
|
46
62
|
}
|
|
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}`;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
63
|
for (const prop of props) {
|
|
60
64
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
61
65
|
&& (prop.name === 'bind' || prop.name === 'model')
|
|
@@ -172,7 +176,7 @@ function* genereatePropExp(options, ctx, exp, features, isShorthand, inlayHints)
|
|
|
172
176
|
const propVariableName = (0, shared_1.camelize)(exp.loc.source);
|
|
173
177
|
if (common_1.variableNameRegex.test(propVariableName)) {
|
|
174
178
|
if (!ctx.hasLocalVariable(propVariableName)) {
|
|
175
|
-
ctx.
|
|
179
|
+
ctx.accessExternalVariable(propVariableName, exp.loc.start.offset);
|
|
176
180
|
yield `__VLS_ctx.`;
|
|
177
181
|
}
|
|
178
182
|
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;
|
|
@@ -6,11 +6,9 @@ const common_1 = require("../common");
|
|
|
6
6
|
const context_1 = require("./context");
|
|
7
7
|
const element_1 = require("./element");
|
|
8
8
|
const objectProperty_1 = require("./objectProperty");
|
|
9
|
-
const stringLiteralKey_1 = require("./stringLiteralKey");
|
|
10
9
|
const templateChild_1 = require("./templateChild");
|
|
11
10
|
function* generateTemplate(options) {
|
|
12
|
-
const ctx = (0, context_1.createTemplateCodegenContext)();
|
|
13
|
-
let hasSlot = false;
|
|
11
|
+
const ctx = (0, context_1.createTemplateCodegenContext)(options.scriptSetupBindingNames);
|
|
14
12
|
if (options.slotsAssignName) {
|
|
15
13
|
ctx.addLocalVariable(options.slotsAssignName);
|
|
16
14
|
}
|
|
@@ -28,29 +26,20 @@ function* generateTemplate(options) {
|
|
|
28
26
|
yield common_1.endOfLine;
|
|
29
27
|
}
|
|
30
28
|
yield* ctx.generateAutoImportCompletion();
|
|
31
|
-
return
|
|
32
|
-
ctx,
|
|
33
|
-
hasSlot,
|
|
34
|
-
};
|
|
29
|
+
return ctx;
|
|
35
30
|
function* generateSlotsType() {
|
|
36
31
|
for (const { expVar, varName } of ctx.dynamicSlots) {
|
|
37
|
-
hasSlot = true;
|
|
32
|
+
ctx.hasSlot = true;
|
|
38
33
|
yield `Partial<Record<NonNullable<typeof ${expVar}>, (_: typeof ${varName}) => any>> &${common_1.newLine}`;
|
|
39
34
|
}
|
|
40
35
|
yield `{${common_1.newLine}`;
|
|
41
36
|
for (const slot of ctx.slots) {
|
|
42
|
-
hasSlot = true;
|
|
37
|
+
ctx.hasSlot = true;
|
|
43
38
|
if (slot.name && slot.loc !== undefined) {
|
|
44
|
-
yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slot.name, slot.loc,
|
|
45
|
-
...ctx.codeFeatures.withoutHighlightAndCompletion,
|
|
46
|
-
__referencesCodeLens: true,
|
|
47
|
-
}, slot.nodeLoc);
|
|
39
|
+
yield* (0, objectProperty_1.generateObjectProperty)(options, ctx, slot.name, slot.loc, ctx.codeFeatures.withoutHighlightAndCompletion, slot.nodeLoc);
|
|
48
40
|
}
|
|
49
41
|
else {
|
|
50
|
-
yield* (0, common_1.wrapWith)(slot.tagRange[0], slot.tagRange[1],
|
|
51
|
-
...ctx.codeFeatures.withoutHighlightAndCompletion,
|
|
52
|
-
__referencesCodeLens: true,
|
|
53
|
-
}, `default`);
|
|
42
|
+
yield* (0, common_1.wrapWith)(slot.tagRange[0], slot.tagRange[1], ctx.codeFeatures.withoutHighlightAndCompletion, `default`);
|
|
54
43
|
}
|
|
55
44
|
yield `?(_: typeof ${slot.varName}): any,${common_1.newLine}`;
|
|
56
45
|
}
|
|
@@ -58,12 +47,38 @@ function* generateTemplate(options) {
|
|
|
58
47
|
}
|
|
59
48
|
function* generateStyleScopedClasses() {
|
|
60
49
|
yield `if (typeof __VLS_styleScopedClasses === 'object' && !Array.isArray(__VLS_styleScopedClasses)) {${common_1.newLine}`;
|
|
50
|
+
for (const offset of ctx.emptyClassOffsets) {
|
|
51
|
+
yield `__VLS_styleScopedClasses['`;
|
|
52
|
+
yield [
|
|
53
|
+
'',
|
|
54
|
+
'template',
|
|
55
|
+
offset,
|
|
56
|
+
ctx.codeFeatures.additionalCompletion,
|
|
57
|
+
];
|
|
58
|
+
yield `']${common_1.endOfLine}`;
|
|
59
|
+
}
|
|
61
60
|
for (const { className, offset } of ctx.scopedClasses) {
|
|
62
61
|
yield `__VLS_styleScopedClasses[`;
|
|
63
|
-
yield
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
yield [
|
|
63
|
+
'',
|
|
64
|
+
'template',
|
|
65
|
+
offset,
|
|
66
|
+
ctx.codeFeatures.navigationWithoutRename,
|
|
67
|
+
];
|
|
68
|
+
yield `'`;
|
|
69
|
+
yield [
|
|
70
|
+
className,
|
|
71
|
+
'template',
|
|
72
|
+
offset,
|
|
73
|
+
ctx.codeFeatures.navigationAndAdditionalCompletion,
|
|
74
|
+
];
|
|
75
|
+
yield `'`;
|
|
76
|
+
yield [
|
|
77
|
+
'',
|
|
78
|
+
'template',
|
|
79
|
+
offset + className.length,
|
|
80
|
+
ctx.codeFeatures.navigationWithoutRename,
|
|
81
|
+
];
|
|
67
82
|
yield `]${common_1.endOfLine}`;
|
|
68
83
|
}
|
|
69
84
|
yield `}${common_1.newLine}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
-
import type { Code, VueCodeInformation
|
|
2
|
+
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 | (() => VueCodeInformation) | undefined, prefix: string, suffix: string): Generator<Code>;
|
|
6
|
-
export declare function forEachInterpolationSegment(ts: typeof import('typescript'),
|
|
6
|
+
export declare function forEachInterpolationSegment(ts: typeof import('typescript'), ctx: TemplateCodegenContext, code: string, offset: number | undefined, ast: ts.SourceFile): Generator<[fragment: string, offset: number | undefined, isJustForErrorMapping?: boolean]>;
|
|
@@ -8,7 +8,7 @@ function* generateInterpolation(options, ctx, _code, astHolder, start, data, pre
|
|
|
8
8
|
const code = prefix + _code + suffix;
|
|
9
9
|
const ast = (0, common_1.createTsAst)(options.ts, astHolder, code);
|
|
10
10
|
const vars = [];
|
|
11
|
-
for (let [section, offset, onlyError] of forEachInterpolationSegment(options.ts,
|
|
11
|
+
for (let [section, offset, onlyError] of forEachInterpolationSegment(options.ts, ctx, code, start !== undefined ? start - prefix.length : undefined, ast)) {
|
|
12
12
|
if (offset === undefined) {
|
|
13
13
|
yield section;
|
|
14
14
|
}
|
|
@@ -48,7 +48,7 @@ function* generateInterpolation(options, ctx, _code, astHolder, start, data, pre
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
exports.generateInterpolation = generateInterpolation;
|
|
51
|
-
function* forEachInterpolationSegment(ts,
|
|
51
|
+
function* forEachInterpolationSegment(ts, ctx, code, offset, ast) {
|
|
52
52
|
let ctxVars = [];
|
|
53
53
|
const varCb = (id, isShorthand) => {
|
|
54
54
|
const text = (0, scriptSetupRanges_1.getNodeText)(ts, id, ast);
|
|
@@ -66,10 +66,10 @@ function* forEachInterpolationSegment(ts, vueOptions, ctx, code, offset, ast) {
|
|
|
66
66
|
offset: (0, scriptSetupRanges_1.getStartEnd)(ts, id, ast).start,
|
|
67
67
|
});
|
|
68
68
|
if (offset !== undefined) {
|
|
69
|
-
ctx.
|
|
69
|
+
ctx.accessExternalVariable(text, offset + (0, scriptSetupRanges_1.getStartEnd)(ts, id, ast).start);
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
ctx.
|
|
72
|
+
ctx.accessExternalVariable(text);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
};
|
|
@@ -87,52 +87,18 @@ function* forEachInterpolationSegment(ts, vueOptions, ctx, code, offset, ast) {
|
|
|
87
87
|
// fix https://github.com/vuejs/language-tools/issues/1205
|
|
88
88
|
// fix https://github.com/vuejs/language-tools/issues/1264
|
|
89
89
|
yield ['', ctxVars[i + 1].offset, true];
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
yield ['
|
|
94
|
-
yield ['', varStart, true];
|
|
95
|
-
yield ["'", undefined];
|
|
96
|
-
yield [code.substring(varStart, varEnd), varStart];
|
|
97
|
-
yield ["'", undefined];
|
|
98
|
-
yield ['', varEnd, true];
|
|
99
|
-
yield [']', undefined];
|
|
100
|
-
if (ctxVars[i + 1].isShorthand) {
|
|
101
|
-
yield [code.substring(varEnd, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), varEnd];
|
|
102
|
-
yield [': ', undefined];
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
yield [code.substring(varEnd, ctxVars[i + 1].offset), varEnd];
|
|
106
|
-
}
|
|
90
|
+
yield ['__VLS_ctx.', undefined];
|
|
91
|
+
if (ctxVars[i + 1].isShorthand) {
|
|
92
|
+
yield [code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset];
|
|
93
|
+
yield [': ', undefined];
|
|
107
94
|
}
|
|
108
95
|
else {
|
|
109
|
-
yield [
|
|
110
|
-
if (ctxVars[i + 1].isShorthand) {
|
|
111
|
-
yield [code.substring(ctxVars[i].offset, ctxVars[i + 1].offset + ctxVars[i + 1].text.length), ctxVars[i].offset];
|
|
112
|
-
yield [': ', undefined];
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
yield [code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset];
|
|
116
|
-
}
|
|
96
|
+
yield [code.substring(ctxVars[i].offset, ctxVars[i + 1].offset), ctxVars[i].offset];
|
|
117
97
|
}
|
|
118
98
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
yield ['__VLS_ctx[', undefined];
|
|
123
|
-
yield ['', varStart, true];
|
|
124
|
-
yield ["'", undefined];
|
|
125
|
-
yield [code.substring(varStart, varEnd), varStart];
|
|
126
|
-
yield ["'", undefined];
|
|
127
|
-
yield ['', varEnd, true];
|
|
128
|
-
yield [']', undefined];
|
|
129
|
-
yield [code.substring(varEnd), varEnd];
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
yield ['', ctxVars[ctxVars.length - 1].offset, true];
|
|
133
|
-
yield ['__VLS_ctx.', undefined];
|
|
134
|
-
yield [code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset];
|
|
135
|
-
}
|
|
99
|
+
yield ['', ctxVars[ctxVars.length - 1].offset, true];
|
|
100
|
+
yield ['__VLS_ctx.', undefined];
|
|
101
|
+
yield [code.substring(ctxVars[ctxVars.length - 1].offset), ctxVars[ctxVars.length - 1].offset];
|
|
136
102
|
}
|
|
137
103
|
else {
|
|
138
104
|
yield [code, 0];
|