@vue/language-core 2.0.16 → 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/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 +21 -19
- 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/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/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/types.d.ts +0 -15
- package/lib/utils/parseCssClassNames.js +1 -1
- package/lib/utils/ts.js +0 -1
- 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
|
|
@@ -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];
|
package/lib/languageModule.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export interface _Plugin extends LanguagePlugin<VueVirtualCode> {
|
|
|
6
6
|
getCanonicalFileName: (fileName: string) => string;
|
|
7
7
|
pluginContext: Parameters<VueLanguagePlugin>[0];
|
|
8
8
|
}
|
|
9
|
-
export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (
|
|
9
|
+
export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (scriptId: string) => string, useCaseSensitiveFileNames: boolean, getProjectVersion: () => string, getScriptFileNames: () => string[] | Set<string>, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions): _Plugin;
|