@vue/language-core 2.0.14 → 2.0.15
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.d.ts +1 -1
- package/lib/codegen/script/component.js +12 -4
- package/lib/codegen/script/globalTypes.js +1 -1
- package/lib/codegen/script/internalComponent.js +1 -1
- package/lib/codegen/script/scriptSetup.js +52 -19
- package/lib/codegen/script/template.js +5 -2
- package/lib/codegen/template/context.js +0 -1
- package/lib/codegen/template/element.d.ts +2 -1
- package/lib/codegen/template/element.js +101 -48
- package/lib/codegen/template/elementChildren.d.ts +2 -2
- package/lib/codegen/template/elementChildren.js +8 -3
- package/lib/codegen/template/elementEvents.d.ts +2 -0
- package/lib/codegen/template/elementEvents.js +47 -31
- package/lib/codegen/template/elementProps.js +33 -8
- package/lib/codegen/template/index.d.ts +10 -10
- package/lib/codegen/template/index.js +12 -99
- package/lib/codegen/template/slotOutlet.d.ts +1 -1
- package/lib/codegen/template/slotOutlet.js +2 -2
- package/lib/codegen/template/templateChild.d.ts +1 -1
- package/lib/codegen/template/templateChild.js +14 -10
- package/lib/codegen/template/vFor.d.ts +1 -1
- package/lib/codegen/template/vFor.js +2 -2
- package/lib/codegen/template/vIf.d.ts +1 -1
- package/lib/codegen/template/vIf.js +2 -2
- package/lib/languageModule.d.ts +1 -2
- package/lib/languageModule.js +30 -12
- package/lib/parsers/scriptSetupRanges.d.ts +1 -0
- package/lib/parsers/scriptSetupRanges.js +6 -1
- package/lib/plugins/file-html.js +63 -66
- package/lib/plugins/file-md.js +47 -50
- package/lib/plugins/vue-tsx.d.ts +1 -0
- package/lib/plugins.d.ts +2 -1
- package/lib/plugins.js +18 -9
- package/lib/types.d.ts +2 -0
- package/lib/utils/ts.js +20 -3
- package/lib/virtualFile/computedFiles.d.ts +1 -0
- package/lib/virtualFile/computedFiles.js +19 -3
- package/package.json +3 -3
|
@@ -10,9 +10,11 @@ const camelized_1 = require("./camelized");
|
|
|
10
10
|
const interpolation_1 = require("./interpolation");
|
|
11
11
|
const objectProperty_1 = require("./objectProperty");
|
|
12
12
|
const language_core_1 = require("@volar/language-core");
|
|
13
|
+
const elementEvents_1 = require("./elementEvents");
|
|
13
14
|
function* generateElementProps(options, ctx, node, props, enableCodeFeatures, propsFailedExps) {
|
|
14
15
|
let styleAttrNum = 0;
|
|
15
16
|
let classAttrNum = 0;
|
|
17
|
+
const isIntrinsicElement = node.tagType === CompilerDOM.ElementTypes.ELEMENT || node.tagType === CompilerDOM.ElementTypes.TEMPLATE;
|
|
16
18
|
const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT;
|
|
17
19
|
if (props.some(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
18
20
|
&& prop.name === 'bind'
|
|
@@ -22,15 +24,38 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
|
|
|
22
24
|
styleAttrNum++;
|
|
23
25
|
classAttrNum++;
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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) {
|
|
37
|
+
yield `...{ `;
|
|
38
|
+
generatedEvent = true;
|
|
39
|
+
}
|
|
40
|
+
yield `'${(0, shared_1.camelize)('on-' + prop.arg.loc.source)}': {} as any, `;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (generatedEvent) {
|
|
44
|
+
yield `}, `;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
for (const prop of props) {
|
|
49
|
+
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
50
|
+
&& prop.name === 'on'
|
|
51
|
+
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
|
|
52
|
+
yield* (0, elementEvents_1.generateEventArg)(options, ctx, prop.arg, false);
|
|
53
|
+
yield `: `;
|
|
54
|
+
yield* (0, elementEvents_1.generateEventExpression)(options, ctx, prop);
|
|
55
|
+
yield `,${common_1.newLine}`;
|
|
56
|
+
}
|
|
31
57
|
}
|
|
32
58
|
}
|
|
33
|
-
yield `}, `;
|
|
34
59
|
for (const prop of props) {
|
|
35
60
|
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
|
|
36
61
|
&& (prop.name === 'bind' || prop.name === 'model')
|
|
@@ -71,7 +96,7 @@ function* generateElementProps(options, ctx, node, props, enableCodeFeatures, pr
|
|
|
71
96
|
}
|
|
72
97
|
: false,
|
|
73
98
|
}
|
|
74
|
-
: ctx.codeFeatures.withoutHighlightAndCompletion, prop.loc.name_2 ?? (prop.loc.name_2 = {}), shouldCamelize), `: (`, ...genereatePropExp(options, ctx, prop.exp, ctx.codeFeatures.
|
|
99
|
+
: ctx.codeFeatures.withoutHighlightAndCompletion, prop.loc.name_2 ?? (prop.loc.name_2 = {}), shouldCamelize), `: (`, ...genereatePropExp(options, ctx, prop.exp, ctx.codeFeatures.all, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, enableCodeFeatures), `)`);
|
|
75
100
|
if (!enableCodeFeatures) {
|
|
76
101
|
yield (0, language_core_1.toString)([...codes]);
|
|
77
102
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as CompilerDOM from '@vue/compiler-dom';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
import type { Code, Sfc,
|
|
3
|
+
import type { Code, Sfc, VueCompilerOptions } from '../../types';
|
|
4
4
|
export interface TemplateCodegenOptions {
|
|
5
5
|
ts: typeof ts;
|
|
6
6
|
compilerOptions: ts.CompilerOptions;
|
|
@@ -26,15 +26,15 @@ export declare function generateTemplate(options: TemplateCodegenOptions): Gener
|
|
|
26
26
|
varName: string;
|
|
27
27
|
}[];
|
|
28
28
|
codeFeatures: {
|
|
29
|
-
all: VueCodeInformation;
|
|
30
|
-
verification: VueCodeInformation;
|
|
31
|
-
completion: VueCodeInformation;
|
|
32
|
-
additionalCompletion: VueCodeInformation;
|
|
33
|
-
navigation: VueCodeInformation;
|
|
34
|
-
navigationAndCompletion: VueCodeInformation;
|
|
35
|
-
withoutHighlight: VueCodeInformation;
|
|
36
|
-
withoutHighlightAndCompletion: VueCodeInformation;
|
|
37
|
-
withoutHighlightAndCompletionAndNavigation: VueCodeInformation;
|
|
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
38
|
};
|
|
39
39
|
accessGlobalVariables: Map<string, Set<number>>;
|
|
40
40
|
hasSlotElements: Set<CompilerDOM.ElementNode>;
|
|
@@ -2,19 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isFragment = exports.forEachElementNode = exports.generateTemplate = void 0;
|
|
4
4
|
const CompilerDOM = require("@vue/compiler-dom");
|
|
5
|
-
const shared_1 = require("@vue/shared");
|
|
6
|
-
const shared_2 = require("../../utils/shared");
|
|
7
5
|
const common_1 = require("../common");
|
|
8
|
-
const camelized_1 = require("./camelized");
|
|
9
6
|
const context_1 = require("./context");
|
|
10
7
|
const element_1 = require("./element");
|
|
11
8
|
const objectProperty_1 = require("./objectProperty");
|
|
12
|
-
const propertyAccess_1 = require("./propertyAccess");
|
|
13
9
|
const stringLiteralKey_1 = require("./stringLiteralKey");
|
|
14
10
|
const templateChild_1 = require("./templateChild");
|
|
15
11
|
function* generateTemplate(options) {
|
|
16
12
|
const ctx = (0, context_1.createTemplateCodegenContext)();
|
|
17
|
-
const { componentTagNameOffsets, elementTagNameOffsets } = collectTagOffsets();
|
|
18
13
|
let hasSlot = false;
|
|
19
14
|
if (options.slotsAssignName) {
|
|
20
15
|
ctx.addLocalVariable(options.slotsAssignName);
|
|
@@ -37,46 +32,6 @@ function* generateTemplate(options) {
|
|
|
37
32
|
ctx,
|
|
38
33
|
hasSlot,
|
|
39
34
|
};
|
|
40
|
-
function collectTagOffsets() {
|
|
41
|
-
const componentTagNameOffsets = new Map();
|
|
42
|
-
const elementTagNameOffsets = new Map();
|
|
43
|
-
if (!options.template.ast) {
|
|
44
|
-
return {
|
|
45
|
-
componentTagNameOffsets,
|
|
46
|
-
elementTagNameOffsets,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
for (const node of forEachElementNode(options.template.ast)) {
|
|
50
|
-
if (node.tagType === CompilerDOM.ElementTypes.SLOT) {
|
|
51
|
-
// ignore
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (node.tag === 'component' || node.tag === 'Component') {
|
|
55
|
-
// ignore
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
const map = node.tagType === CompilerDOM.ElementTypes.COMPONENT
|
|
59
|
-
? componentTagNameOffsets
|
|
60
|
-
: elementTagNameOffsets;
|
|
61
|
-
let offsets = map.get(node.tag);
|
|
62
|
-
if (!offsets) {
|
|
63
|
-
map.set(node.tag, offsets = []);
|
|
64
|
-
}
|
|
65
|
-
const source = options.template.content.substring(node.loc.start.offset);
|
|
66
|
-
const startTagOffset = node.loc.start.offset + source.indexOf(node.tag);
|
|
67
|
-
offsets.push(startTagOffset); // start tag
|
|
68
|
-
if (!node.isSelfClosing && options.template.lang === 'html') {
|
|
69
|
-
const endTagOffset = node.loc.start.offset + node.loc.source.lastIndexOf(node.tag);
|
|
70
|
-
if (endTagOffset !== startTagOffset) {
|
|
71
|
-
offsets.push(endTagOffset); // end tag
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
componentTagNameOffsets,
|
|
77
|
-
elementTagNameOffsets,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
35
|
function* generateSlotsType() {
|
|
81
36
|
for (const { expVar, varName } of ctx.dynamicSlots) {
|
|
82
37
|
hasSlot = true;
|
|
@@ -115,57 +70,21 @@ function* generateTemplate(options) {
|
|
|
115
70
|
}
|
|
116
71
|
function* generatePreResolveComponents() {
|
|
117
72
|
yield `let __VLS_resolvedLocalAndGlobalComponents!: {}`;
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
yield common_1.endOfLine;
|
|
130
|
-
for (const [tagName, offsets] of elementTagNameOffsets) {
|
|
131
|
-
for (const tagOffset of offsets) {
|
|
132
|
-
yield `__VLS_intrinsicElements`;
|
|
133
|
-
yield* (0, propertyAccess_1.generatePropertyAccess)(options, ctx, tagName, tagOffset, ctx.codeFeatures.withoutHighlightAndCompletion);
|
|
134
|
-
yield `;`;
|
|
135
|
-
}
|
|
136
|
-
yield `${common_1.newLine}`;
|
|
137
|
-
}
|
|
138
|
-
for (const [tagName, offsets] of componentTagNameOffsets) {
|
|
139
|
-
if (!common_1.variableNameRegex.test((0, shared_1.camelize)(tagName))) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
for (const tagOffset of offsets) {
|
|
143
|
-
for (const shouldCapitalize of (tagName[0] === tagName[0].toUpperCase() ? [false] : [true, false])) {
|
|
144
|
-
const expectName = shouldCapitalize ? (0, shared_1.capitalize)((0, shared_1.camelize)(tagName)) : (0, shared_1.camelize)(tagName);
|
|
145
|
-
yield `__VLS_components.`;
|
|
146
|
-
yield* (0, camelized_1.generateCamelized)(shouldCapitalize ? (0, shared_1.capitalize)(tagName) : tagName, tagOffset, {
|
|
147
|
-
navigation: {
|
|
148
|
-
resolveRenameNewName: tagName !== expectName ? camelizeComponentName : undefined,
|
|
149
|
-
resolveRenameEditText: getTagRenameApply(tagName),
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
yield `;`;
|
|
73
|
+
if (options.template.ast) {
|
|
74
|
+
for (const node of forEachElementNode(options.template.ast)) {
|
|
75
|
+
if (node.tagType === CompilerDOM.ElementTypes.COMPONENT
|
|
76
|
+
&& node.tag.toLowerCase() !== 'component'
|
|
77
|
+
&& !node.tag.includes('.') // namespace tag
|
|
78
|
+
) {
|
|
79
|
+
yield ` & __VLS_WithComponent<'${(0, element_1.getCanonicalComponentName)(node.tag)}', typeof __VLS_localComponents, `;
|
|
80
|
+
yield (0, element_1.getPossibleOriginalComponentNames)(node.tag, false)
|
|
81
|
+
.map(name => `"${name}"`)
|
|
82
|
+
.join(', ');
|
|
83
|
+
yield `>`;
|
|
153
84
|
}
|
|
154
85
|
}
|
|
155
|
-
yield `${common_1.newLine}`;
|
|
156
|
-
yield `// @ts-ignore${common_1.newLine}`; // #2304
|
|
157
|
-
yield `[`;
|
|
158
|
-
for (const tagOffset of offsets) {
|
|
159
|
-
yield* (0, camelized_1.generateCamelized)((0, shared_1.capitalize)(tagName), tagOffset, {
|
|
160
|
-
completion: {
|
|
161
|
-
isAdditional: true,
|
|
162
|
-
onlyImport: true,
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
yield `,`;
|
|
166
|
-
}
|
|
167
|
-
yield `]${common_1.endOfLine}`;
|
|
168
86
|
}
|
|
87
|
+
yield common_1.endOfLine;
|
|
169
88
|
}
|
|
170
89
|
}
|
|
171
90
|
exports.generateTemplate = generateTemplate;
|
|
@@ -204,12 +123,6 @@ function* forEachElementNode(node) {
|
|
|
204
123
|
}
|
|
205
124
|
}
|
|
206
125
|
exports.forEachElementNode = forEachElementNode;
|
|
207
|
-
function camelizeComponentName(newName) {
|
|
208
|
-
return (0, shared_1.camelize)('-' + newName);
|
|
209
|
-
}
|
|
210
|
-
function getTagRenameApply(oldName) {
|
|
211
|
-
return oldName === (0, shared_2.hyphenateTag)(oldName) ? shared_2.hyphenateTag : undefined;
|
|
212
|
-
}
|
|
213
126
|
function isFragment(node) {
|
|
214
127
|
return node.codegenNode && 'consequent' in node.codegenNode && 'tag' in node.codegenNode.consequent && node.codegenNode.consequent.tag === CompilerDOM.FRAGMENT;
|
|
215
128
|
}
|
|
@@ -2,4 +2,4 @@ import * as CompilerDOM from '@vue/compiler-dom';
|
|
|
2
2
|
import type { Code } from '../../types';
|
|
3
3
|
import type { TemplateCodegenContext } from './context';
|
|
4
4
|
import type { TemplateCodegenOptions } from './index';
|
|
5
|
-
export declare function generateSlotOutlet(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.SlotOutletNode,
|
|
5
|
+
export declare function generateSlotOutlet(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.SlotOutletNode, currentComponent: CompilerDOM.ElementNode | undefined, componentCtxVar: string | undefined): Generator<Code>;
|
|
@@ -6,7 +6,7 @@ const common_1 = require("../common");
|
|
|
6
6
|
const elementChildren_1 = require("./elementChildren");
|
|
7
7
|
const elementProps_1 = require("./elementProps");
|
|
8
8
|
const interpolation_1 = require("./interpolation");
|
|
9
|
-
function* generateSlotOutlet(options, ctx, node,
|
|
9
|
+
function* generateSlotOutlet(options, ctx, node, currentComponent, componentCtxVar) {
|
|
10
10
|
const startTagOffset = node.loc.start.offset + options.template.content.substring(node.loc.start.offset).indexOf(node.tag);
|
|
11
11
|
const varSlot = ctx.getInternalVariable();
|
|
12
12
|
const nameProp = node.props.find(prop => {
|
|
@@ -66,7 +66,7 @@ function* generateSlotOutlet(options, ctx, node, currentElement, componentCtxVar
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
yield* ctx.generateAutoImportCompletion();
|
|
69
|
-
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node,
|
|
69
|
+
yield* (0, elementChildren_1.generateElementChildren)(options, ctx, node, currentComponent, componentCtxVar);
|
|
70
70
|
}
|
|
71
71
|
exports.generateSlotOutlet = generateSlotOutlet;
|
|
72
72
|
//# sourceMappingURL=slotOutlet.js.map
|
|
@@ -2,6 +2,6 @@ import * as CompilerDOM from '@vue/compiler-dom';
|
|
|
2
2
|
import type { Code } from '../../types';
|
|
3
3
|
import type { TemplateCodegenContext } from './context';
|
|
4
4
|
import type { TemplateCodegenOptions } from './index';
|
|
5
|
-
export declare function generateTemplateChild(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode,
|
|
5
|
+
export declare function generateTemplateChild(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode, currentComponent: CompilerDOM.ElementNode | undefined, prevNode: CompilerDOM.TemplateChildNode | undefined, componentCtxVar: string | undefined): Generator<Code>;
|
|
6
6
|
export declare function getVForNode(node: CompilerDOM.ElementNode): CompilerDOM.ForNode | undefined;
|
|
7
7
|
export declare function parseInterpolationNode(node: CompilerDOM.InterpolationNode, template: string): readonly [string, number];
|
|
@@ -23,7 +23,7 @@ const transformContext = {
|
|
|
23
23
|
},
|
|
24
24
|
expressionPlugins: ['typescript'],
|
|
25
25
|
};
|
|
26
|
-
function* generateTemplateChild(options, ctx, node,
|
|
26
|
+
function* generateTemplateChild(options, ctx, node, currentComponent, prevNode, componentCtxVar) {
|
|
27
27
|
if (prevNode?.type === CompilerDOM.NodeTypes.COMMENT) {
|
|
28
28
|
const commentText = prevNode.content.trim().split(' ')[0];
|
|
29
29
|
if (commentText.match(/^@vue-skip\b[\s\S]*/)) {
|
|
@@ -40,7 +40,7 @@ function* generateTemplateChild(options, ctx, node, currentElement, prevNode, co
|
|
|
40
40
|
if (node.type === CompilerDOM.NodeTypes.ROOT) {
|
|
41
41
|
let prev;
|
|
42
42
|
for (const childNode of node.children) {
|
|
43
|
-
yield* generateTemplateChild(options, ctx, childNode,
|
|
43
|
+
yield* generateTemplateChild(options, ctx, childNode, currentComponent, prev, componentCtxVar);
|
|
44
44
|
prev = childNode;
|
|
45
45
|
}
|
|
46
46
|
yield* ctx.resetDirectiveComments('end of root');
|
|
@@ -49,29 +49,33 @@ function* generateTemplateChild(options, ctx, node, currentElement, prevNode, co
|
|
|
49
49
|
const vForNode = getVForNode(node);
|
|
50
50
|
const vIfNode = getVIfNode(node);
|
|
51
51
|
if (vForNode) {
|
|
52
|
-
yield* (0, vFor_1.generateVFor)(options, ctx, vForNode,
|
|
52
|
+
yield* (0, vFor_1.generateVFor)(options, ctx, vForNode, currentComponent, componentCtxVar);
|
|
53
53
|
}
|
|
54
54
|
else if (vIfNode) {
|
|
55
|
-
yield* (0, vIf_1.generateVIf)(options, ctx, vIfNode,
|
|
55
|
+
yield* (0, vIf_1.generateVIf)(options, ctx, vIfNode, currentComponent, componentCtxVar);
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
if (node.tagType === CompilerDOM.ElementTypes.SLOT) {
|
|
59
|
-
yield* (0, slotOutlet_1.generateSlotOutlet)(options, ctx, node,
|
|
59
|
+
yield* (0, slotOutlet_1.generateSlotOutlet)(options, ctx, node, currentComponent, componentCtxVar);
|
|
60
|
+
}
|
|
61
|
+
else if (node.tagType === CompilerDOM.ElementTypes.ELEMENT
|
|
62
|
+
|| node.tagType === CompilerDOM.ElementTypes.TEMPLATE) {
|
|
63
|
+
yield* (0, element_1.generateElement)(options, ctx, node, currentComponent, componentCtxVar);
|
|
60
64
|
}
|
|
61
65
|
else {
|
|
62
|
-
yield* (0, element_1.
|
|
66
|
+
yield* (0, element_1.generateComponent)(options, ctx, node, currentComponent, componentCtxVar);
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
else if (node.type === CompilerDOM.NodeTypes.TEXT_CALL) {
|
|
67
71
|
// {{ var }}
|
|
68
|
-
yield* generateTemplateChild(options, ctx, node.content,
|
|
72
|
+
yield* generateTemplateChild(options, ctx, node.content, currentComponent, undefined, componentCtxVar);
|
|
69
73
|
}
|
|
70
74
|
else if (node.type === CompilerDOM.NodeTypes.COMPOUND_EXPRESSION) {
|
|
71
75
|
// {{ ... }} {{ ... }}
|
|
72
76
|
for (const childNode of node.children) {
|
|
73
77
|
if (typeof childNode === 'object') {
|
|
74
|
-
yield* generateTemplateChild(options, ctx, childNode,
|
|
78
|
+
yield* generateTemplateChild(options, ctx, childNode, currentComponent, undefined, componentCtxVar);
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
}
|
|
@@ -83,11 +87,11 @@ function* generateTemplateChild(options, ctx, node, currentElement, prevNode, co
|
|
|
83
87
|
}
|
|
84
88
|
else if (node.type === CompilerDOM.NodeTypes.IF) {
|
|
85
89
|
// v-if / v-else-if / v-else
|
|
86
|
-
yield* (0, vIf_1.generateVIf)(options, ctx, node,
|
|
90
|
+
yield* (0, vIf_1.generateVIf)(options, ctx, node, currentComponent, componentCtxVar);
|
|
87
91
|
}
|
|
88
92
|
else if (node.type === CompilerDOM.NodeTypes.FOR) {
|
|
89
93
|
// v-for
|
|
90
|
-
yield* (0, vFor_1.generateVFor)(options, ctx, node,
|
|
94
|
+
yield* (0, vFor_1.generateVFor)(options, ctx, node, currentComponent, componentCtxVar);
|
|
91
95
|
}
|
|
92
96
|
else if (node.type === CompilerDOM.NodeTypes.TEXT) {
|
|
93
97
|
// not needed progress
|
|
@@ -2,7 +2,7 @@ import * as CompilerDOM from '@vue/compiler-dom';
|
|
|
2
2
|
import type { Code } from '../../types';
|
|
3
3
|
import type { TemplateCodegenContext } from './context';
|
|
4
4
|
import type { TemplateCodegenOptions } from './index';
|
|
5
|
-
export declare function generateVFor(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ForNode,
|
|
5
|
+
export declare function generateVFor(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ForNode, currentComponent: CompilerDOM.ElementNode | undefined, componentCtxVar: string | undefined): Generator<Code>;
|
|
6
6
|
export declare function parseVForNode(node: CompilerDOM.ForNode): {
|
|
7
7
|
leftExpressionRange: {
|
|
8
8
|
start: number;
|
|
@@ -6,7 +6,7 @@ const common_1 = require("../common");
|
|
|
6
6
|
const index_1 = require("./index");
|
|
7
7
|
const interpolation_1 = require("./interpolation");
|
|
8
8
|
const templateChild_1 = require("./templateChild");
|
|
9
|
-
function* generateVFor(options, ctx, node,
|
|
9
|
+
function* generateVFor(options, ctx, node, currentComponent, componentCtxVar) {
|
|
10
10
|
const { source } = node.parseResult;
|
|
11
11
|
const { leftExpressionRange, leftExpressionText } = parseVForNode(node);
|
|
12
12
|
const forBlockVars = [];
|
|
@@ -39,7 +39,7 @@ function* generateVFor(options, ctx, node, currentElement, componentCtxVar) {
|
|
|
39
39
|
}
|
|
40
40
|
let prev;
|
|
41
41
|
for (const childNode of node.children) {
|
|
42
|
-
yield* (0, templateChild_1.generateTemplateChild)(options, ctx, childNode,
|
|
42
|
+
yield* (0, templateChild_1.generateTemplateChild)(options, ctx, childNode, currentComponent, prev, componentCtxVar);
|
|
43
43
|
prev = childNode;
|
|
44
44
|
}
|
|
45
45
|
for (const varName of forBlockVars) {
|
|
@@ -2,4 +2,4 @@ import * as CompilerDOM from '@vue/compiler-dom';
|
|
|
2
2
|
import type { Code } from '../../types';
|
|
3
3
|
import type { TemplateCodegenContext } from './context';
|
|
4
4
|
import type { TemplateCodegenOptions } from './index';
|
|
5
|
-
export declare function generateVIf(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.IfNode,
|
|
5
|
+
export declare function generateVIf(options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.IfNode, currentComponent: CompilerDOM.ElementNode | undefined, componentCtxVar: string | undefined): Generator<Code>;
|
|
@@ -7,7 +7,7 @@ const common_1 = require("../common");
|
|
|
7
7
|
const index_1 = require("./index");
|
|
8
8
|
const interpolation_1 = require("./interpolation");
|
|
9
9
|
const templateChild_1 = require("./templateChild");
|
|
10
|
-
function* generateVIf(options, ctx, node,
|
|
10
|
+
function* generateVIf(options, ctx, node, currentComponent, componentCtxVar) {
|
|
11
11
|
let originalBlockConditionsLength = ctx.blockConditions.length;
|
|
12
12
|
for (let i = 0; i < node.branches.length; i++) {
|
|
13
13
|
const branch = node.branches[i];
|
|
@@ -38,7 +38,7 @@ function* generateVIf(options, ctx, node, currentElement, componentCtxVar) {
|
|
|
38
38
|
}
|
|
39
39
|
let prev;
|
|
40
40
|
for (const childNode of branch.children) {
|
|
41
|
-
yield* (0, templateChild_1.generateTemplateChild)(options, ctx, childNode,
|
|
41
|
+
yield* (0, templateChild_1.generateTemplateChild)(options, ctx, childNode, currentComponent, prev, componentCtxVar);
|
|
42
42
|
prev = childNode;
|
|
43
43
|
}
|
|
44
44
|
yield* ctx.generateAutoImportCompletion();
|
package/lib/languageModule.d.ts
CHANGED
|
@@ -2,9 +2,8 @@ import { type LanguagePlugin } from '@volar/language-core';
|
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
import type { VueCompilerOptions, VueLanguagePlugin } from './types';
|
|
4
4
|
import { VueVirtualCode } from './virtualFile/vueFile';
|
|
5
|
-
interface _Plugin extends LanguagePlugin<VueVirtualCode> {
|
|
5
|
+
export interface _Plugin extends LanguagePlugin<VueVirtualCode> {
|
|
6
6
|
getCanonicalFileName: (fileName: string) => string;
|
|
7
7
|
pluginContext: Parameters<VueLanguagePlugin>[0];
|
|
8
8
|
}
|
|
9
9
|
export declare function createVueLanguagePlugin(ts: typeof import('typescript'), getFileName: (fileId: string) => string, useCaseSensitiveFileNames: boolean, getProjectVersion: () => string, getScriptFileNames: () => string[] | Set<string>, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions): _Plugin;
|
|
10
|
-
export {};
|
package/lib/languageModule.js
CHANGED
|
@@ -6,6 +6,9 @@ const plugins_1 = require("./plugins");
|
|
|
6
6
|
const vueFile_1 = require("./virtualFile/vueFile");
|
|
7
7
|
const CompilerDOM = require("@vue/compiler-dom");
|
|
8
8
|
const CompilerVue2 = require("./utils/vue2TemplateCompiler");
|
|
9
|
+
const file_html_1 = require("./plugins/file-html");
|
|
10
|
+
const file_md_1 = require("./plugins/file-md");
|
|
11
|
+
const file_vue_1 = require("./plugins/file-vue");
|
|
9
12
|
const normalFileRegistries = [];
|
|
10
13
|
const holderFileRegistries = [];
|
|
11
14
|
function getVueFileRegistry(isGlobalTypesHolder, key, plugins) {
|
|
@@ -36,7 +39,6 @@ function getFileRegistryKey(compilerOptions, vueCompilerOptions, plugins) {
|
|
|
36
39
|
return JSON.stringify(values);
|
|
37
40
|
}
|
|
38
41
|
function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, getProjectVersion, getScriptFileNames, compilerOptions, vueCompilerOptions) {
|
|
39
|
-
const allowLanguageIds = new Set(['vue']);
|
|
40
42
|
const pluginContext = {
|
|
41
43
|
modules: {
|
|
42
44
|
'@vue/compiler-dom': vueCompilerOptions.target < 3
|
|
@@ -51,13 +53,10 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
|
|
|
51
53
|
vueCompilerOptions,
|
|
52
54
|
globalTypesHolder: undefined,
|
|
53
55
|
};
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (vueCompilerOptions.extensions.includes('.html')) {
|
|
59
|
-
allowLanguageIds.add('html');
|
|
60
|
-
}
|
|
56
|
+
const basePlugins = (0, plugins_1.getBasePlugins)(pluginContext);
|
|
57
|
+
const vueSfcPlugin = (0, file_vue_1.default)(pluginContext);
|
|
58
|
+
const vitePressSfcPlugin = (0, file_md_1.default)(pluginContext);
|
|
59
|
+
const petiteVueSfcPlugin = (0, file_html_1.default)(pluginContext);
|
|
61
60
|
const getCanonicalFileName = useCaseSensitiveFileNames
|
|
62
61
|
? (fileName) => fileName
|
|
63
62
|
: (fileName) => fileName.toLowerCase();
|
|
@@ -66,8 +65,19 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
|
|
|
66
65
|
return {
|
|
67
66
|
getCanonicalFileName,
|
|
68
67
|
pluginContext,
|
|
68
|
+
getLanguageId(scriptId) {
|
|
69
|
+
if (vueCompilerOptions.extensions.some(ext => scriptId.endsWith(ext))) {
|
|
70
|
+
return 'vue';
|
|
71
|
+
}
|
|
72
|
+
if (vueCompilerOptions.vitePressExtensions.some(ext => scriptId.endsWith(ext))) {
|
|
73
|
+
return 'markdown';
|
|
74
|
+
}
|
|
75
|
+
if (vueCompilerOptions.petiteVueExtensions.some(ext => scriptId.endsWith(ext))) {
|
|
76
|
+
return 'html';
|
|
77
|
+
}
|
|
78
|
+
},
|
|
69
79
|
createVirtualCode(fileId, languageId, snapshot) {
|
|
70
|
-
if (
|
|
80
|
+
if (languageId === 'vue' || languageId === 'markdown' || languageId === 'html') {
|
|
71
81
|
const fileName = getFileName(fileId);
|
|
72
82
|
const projectVersion = getProjectVersion();
|
|
73
83
|
if (projectVersion !== canonicalRootFileNamesVersion) {
|
|
@@ -84,7 +94,11 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
|
|
|
84
94
|
return code;
|
|
85
95
|
}
|
|
86
96
|
else {
|
|
87
|
-
const code = new vueFile_1.VueVirtualCode(fileName, languageId, snapshot, vueCompilerOptions,
|
|
97
|
+
const code = new vueFile_1.VueVirtualCode(fileName, languageId, snapshot, vueCompilerOptions, languageId === 'html'
|
|
98
|
+
? [petiteVueSfcPlugin, ...basePlugins]
|
|
99
|
+
: languageId === 'markdown'
|
|
100
|
+
? [vitePressSfcPlugin, ...basePlugins]
|
|
101
|
+
: [vueSfcPlugin, ...basePlugins], ts);
|
|
88
102
|
fileRegistry.set(fileId, code);
|
|
89
103
|
return code;
|
|
90
104
|
}
|
|
@@ -119,7 +133,11 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
|
|
|
119
133
|
// }
|
|
120
134
|
// },
|
|
121
135
|
typescript: {
|
|
122
|
-
extraFileExtensions:
|
|
136
|
+
extraFileExtensions: [
|
|
137
|
+
...vueCompilerOptions.extensions,
|
|
138
|
+
...vueCompilerOptions.vitePressExtensions,
|
|
139
|
+
...vueCompilerOptions.petiteVueExtensions,
|
|
140
|
+
].map(ext => ({
|
|
123
141
|
extension: ext.slice(1),
|
|
124
142
|
isMixedContent: true,
|
|
125
143
|
scriptKind: 7,
|
|
@@ -142,7 +160,7 @@ function createVueLanguagePlugin(ts, getFileName, useCaseSensitiveFileNames, get
|
|
|
142
160
|
},
|
|
143
161
|
};
|
|
144
162
|
function getFileRegistry(isGlobalTypesHolder) {
|
|
145
|
-
return getVueFileRegistry(isGlobalTypesHolder, getFileRegistryKey(compilerOptions, vueCompilerOptions,
|
|
163
|
+
return getVueFileRegistry(isGlobalTypesHolder, getFileRegistryKey(compilerOptions, vueCompilerOptions, basePlugins), vueCompilerOptions.plugins);
|
|
146
164
|
}
|
|
147
165
|
}
|
|
148
166
|
exports.createVueLanguagePlugin = createVueLanguagePlugin;
|
|
@@ -20,6 +20,7 @@ export declare function parseScriptSetupRanges(ts: typeof import('typescript'),
|
|
|
20
20
|
};
|
|
21
21
|
slots: {
|
|
22
22
|
name?: string | undefined;
|
|
23
|
+
isObjectBindingPattern?: boolean | undefined;
|
|
23
24
|
define?: (TextRange & {
|
|
24
25
|
arg?: TextRange | undefined;
|
|
25
26
|
typeArg?: TextRange | undefined;
|
|
@@ -139,7 +139,12 @@ function parseScriptSetupRanges(ts, ast, vueCompilerOptions) {
|
|
|
139
139
|
else if (vueCompilerOptions.macros.defineSlots.includes(callText)) {
|
|
140
140
|
slots.define = parseDefineFunction(node);
|
|
141
141
|
if (ts.isVariableDeclaration(parent)) {
|
|
142
|
-
|
|
142
|
+
if (ts.isIdentifier(parent.name)) {
|
|
143
|
+
slots.name = getNodeText(ts, parent.name, ast);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
slots.isObjectBindingPattern = ts.isObjectBindingPattern(parent.name);
|
|
147
|
+
}
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
else if (vueCompilerOptions.macros.defineEmits.includes(callText)) {
|