@vue/language-core 2.0.0 → 2.0.2
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/index.d.ts +13 -0
- package/index.js +31 -0
- package/lib/generators/script.d.ts +13 -0
- package/lib/generators/script.js +1060 -0
- package/lib/generators/template.d.ts +9 -0
- package/lib/generators/template.js +1567 -0
- package/lib/generators/utils.d.ts +6 -0
- package/lib/generators/utils.js +58 -0
- package/lib/languageModule.d.ts +5 -0
- package/lib/languageModule.js +114 -0
- package/lib/parsers/scriptRanges.d.ts +15 -0
- package/lib/parsers/scriptRanges.js +63 -0
- package/lib/parsers/scriptSetupRanges.d.ts +57 -0
- package/lib/parsers/scriptSetupRanges.js +298 -0
- package/lib/plugins/file-html.d.ts +3 -0
- package/lib/plugins/file-html.js +81 -0
- package/lib/plugins/file-md.d.ts +3 -0
- package/lib/plugins/file-md.js +71 -0
- package/lib/plugins/file-vue.d.ts +3 -0
- package/lib/plugins/file-vue.js +47 -0
- package/lib/plugins/vue-sfc-customblocks.d.ts +3 -0
- package/lib/plugins/vue-sfc-customblocks.js +28 -0
- package/lib/plugins/vue-sfc-scripts.d.ts +3 -0
- package/lib/plugins/vue-sfc-scripts.js +36 -0
- package/lib/plugins/vue-sfc-styles.d.ts +3 -0
- package/lib/plugins/vue-sfc-styles.js +28 -0
- package/lib/plugins/vue-sfc-template.d.ts +3 -0
- package/lib/plugins/vue-sfc-template.js +29 -0
- package/lib/plugins/vue-template-html.d.ts +3 -0
- package/lib/plugins/vue-template-html.js +169 -0
- package/lib/plugins/vue-tsx.d.ts +80 -0
- package/lib/plugins/vue-tsx.js +212 -0
- package/lib/plugins.d.ts +37 -0
- package/lib/plugins.js +64 -0
- package/lib/types.d.ts +142 -0
- package/lib/types.js +5 -0
- package/lib/utils/parseCssClassNames.d.ts +4 -0
- package/lib/utils/parseCssClassNames.js +19 -0
- package/lib/utils/parseCssVars.d.ts +5 -0
- package/lib/utils/parseCssVars.js +28 -0
- package/lib/utils/parseSfc.d.ts +2 -0
- package/lib/utils/parseSfc.js +121 -0
- package/lib/utils/shared.d.ts +3 -0
- package/lib/utils/shared.js +20 -0
- package/lib/utils/transform.d.ts +8 -0
- package/lib/utils/transform.js +195 -0
- package/lib/utils/ts.d.ts +8 -0
- package/lib/utils/ts.js +225 -0
- package/lib/utils/vue2TemplateCompiler.d.ts +2 -0
- package/lib/utils/vue2TemplateCompiler.js +89 -0
- package/lib/virtualFile/computedFiles.d.ts +3 -0
- package/lib/virtualFile/computedFiles.js +217 -0
- package/lib/virtualFile/computedMappings.d.ts +4 -0
- package/lib/virtualFile/computedMappings.js +36 -0
- package/lib/virtualFile/computedSfc.d.ts +4 -0
- package/lib/virtualFile/computedSfc.js +197 -0
- package/lib/virtualFile/computedVueSfc.d.ts +4 -0
- package/lib/virtualFile/computedVueSfc.js +41 -0
- package/lib/virtualFile/embeddedFile.d.ts +12 -0
- package/lib/virtualFile/embeddedFile.js +15 -0
- package/lib/virtualFile/vueFile.d.ts +25 -0
- package/lib/virtualFile/vueFile.js +43 -0
- package/package.json +4 -4
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tsCodegen = void 0;
|
|
4
|
+
const language_core_1 = require("@volar/language-core");
|
|
5
|
+
const computeds_1 = require("computeds");
|
|
6
|
+
const script_1 = require("../generators/script");
|
|
7
|
+
const template_1 = require("../generators/template");
|
|
8
|
+
const utils_1 = require("../generators/utils");
|
|
9
|
+
const scriptRanges_1 = require("../parsers/scriptRanges");
|
|
10
|
+
const scriptSetupRanges_1 = require("../parsers/scriptSetupRanges");
|
|
11
|
+
exports.tsCodegen = new WeakMap();
|
|
12
|
+
const plugin = (ctx) => {
|
|
13
|
+
return {
|
|
14
|
+
version: 2,
|
|
15
|
+
requiredCompilerOptions: [
|
|
16
|
+
'noPropertyAccessFromIndexSignature',
|
|
17
|
+
'exactOptionalPropertyTypes',
|
|
18
|
+
],
|
|
19
|
+
getEmbeddedCodes(fileName, sfc) {
|
|
20
|
+
const tsx = useTsx(fileName, sfc);
|
|
21
|
+
const files = [];
|
|
22
|
+
if (['js', 'ts', 'jsx', 'tsx'].includes(tsx.lang())) {
|
|
23
|
+
files.push({ id: 'script_' + tsx.lang(), lang: tsx.lang() });
|
|
24
|
+
}
|
|
25
|
+
if (sfc.template) {
|
|
26
|
+
files.push({ id: 'template_format', lang: 'ts' });
|
|
27
|
+
files.push({ id: 'template_style', lang: 'css' });
|
|
28
|
+
}
|
|
29
|
+
return files;
|
|
30
|
+
},
|
|
31
|
+
resolveEmbeddedCode(fileName, sfc, embeddedFile) {
|
|
32
|
+
const _tsx = useTsx(fileName, sfc);
|
|
33
|
+
if (embeddedFile.id.startsWith('script_')) {
|
|
34
|
+
const tsx = _tsx.generatedScript();
|
|
35
|
+
if (tsx) {
|
|
36
|
+
const [content, contentStacks] = ctx.codegenStack ? (0, language_core_1.track)([...tsx.codes], [...tsx.codeStacks]) : [[...tsx.codes], [...tsx.codeStacks]];
|
|
37
|
+
content.forEach(code => {
|
|
38
|
+
if (typeof code !== 'string') {
|
|
39
|
+
code[3].structure = false;
|
|
40
|
+
code[3].format = false;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
embeddedFile.content = content;
|
|
44
|
+
embeddedFile.contentStacks = contentStacks;
|
|
45
|
+
embeddedFile.linkedCodeMappings = [...tsx.linkedCodeMappings];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (embeddedFile.id === 'template_format') {
|
|
49
|
+
embeddedFile.parentCodeId = 'template';
|
|
50
|
+
const template = _tsx.generatedTemplate();
|
|
51
|
+
if (template) {
|
|
52
|
+
const [content, contentStacks] = ctx.codegenStack
|
|
53
|
+
? (0, language_core_1.track)([...template.formatCodes], template.formatCodeStacks.map(stack => ({ stack, length: 1 })))
|
|
54
|
+
: [[...template.formatCodes], template.formatCodeStacks.map(stack => ({ stack, length: 1 }))];
|
|
55
|
+
embeddedFile.content = content;
|
|
56
|
+
embeddedFile.contentStacks = contentStacks;
|
|
57
|
+
}
|
|
58
|
+
for (const style of sfc.styles) {
|
|
59
|
+
embeddedFile.content.push('\n\n');
|
|
60
|
+
for (const cssVar of style.cssVars) {
|
|
61
|
+
embeddedFile.content.push('(');
|
|
62
|
+
embeddedFile.content.push([
|
|
63
|
+
cssVar.text,
|
|
64
|
+
style.name,
|
|
65
|
+
cssVar.offset,
|
|
66
|
+
(0, utils_1.enableAllFeatures)({}),
|
|
67
|
+
]);
|
|
68
|
+
embeddedFile.content.push(');\n');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (embeddedFile.id === 'template_style') {
|
|
73
|
+
embeddedFile.parentCodeId = 'template';
|
|
74
|
+
const template = _tsx.generatedTemplate();
|
|
75
|
+
if (template) {
|
|
76
|
+
const [content, contentStacks] = ctx.codegenStack
|
|
77
|
+
? (0, language_core_1.track)([...template.cssCodes], template.cssCodeStacks.map(stack => ({ stack, length: 1 })))
|
|
78
|
+
: [[...template.cssCodes], template.cssCodeStacks.map(stack => ({ stack, length: 1 }))];
|
|
79
|
+
embeddedFile.content = content;
|
|
80
|
+
embeddedFile.contentStacks = contentStacks;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
function useTsx(fileName, sfc) {
|
|
86
|
+
if (!exports.tsCodegen.has(sfc)) {
|
|
87
|
+
exports.tsCodegen.set(sfc, createTsx(fileName, sfc, ctx));
|
|
88
|
+
}
|
|
89
|
+
return exports.tsCodegen.get(sfc);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.default = plugin;
|
|
93
|
+
function createTsx(fileName, _sfc, ctx) {
|
|
94
|
+
const ts = ctx.modules.typescript;
|
|
95
|
+
const lang = (0, computeds_1.computed)(() => {
|
|
96
|
+
return !_sfc.script && !_sfc.scriptSetup ? 'ts'
|
|
97
|
+
: _sfc.scriptSetup && _sfc.scriptSetup.lang !== 'js' ? _sfc.scriptSetup.lang
|
|
98
|
+
: _sfc.script && _sfc.script.lang !== 'js' ? _sfc.script.lang
|
|
99
|
+
: 'js';
|
|
100
|
+
});
|
|
101
|
+
const scriptRanges = (0, computeds_1.computed)(() => _sfc.script
|
|
102
|
+
? (0, scriptRanges_1.parseScriptRanges)(ts, _sfc.script.ast, !!_sfc.scriptSetup, false)
|
|
103
|
+
: undefined);
|
|
104
|
+
const scriptSetupRanges = (0, computeds_1.computed)(() => _sfc.scriptSetup
|
|
105
|
+
? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, _sfc.scriptSetup.ast, ctx.vueCompilerOptions)
|
|
106
|
+
: undefined);
|
|
107
|
+
const shouldGenerateScopedClasses = (0, computeds_1.computed)(() => {
|
|
108
|
+
const option = ctx.vueCompilerOptions.experimentalResolveStyleCssClasses;
|
|
109
|
+
return _sfc.styles.some(s => {
|
|
110
|
+
return option === 'always' || (option === 'scoped' && s.scoped);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
const stylesScopedClasses = (0, computeds_1.computedSet)(() => {
|
|
114
|
+
const classes = new Set();
|
|
115
|
+
if (!shouldGenerateScopedClasses()) {
|
|
116
|
+
return classes;
|
|
117
|
+
}
|
|
118
|
+
for (const style of _sfc.styles) {
|
|
119
|
+
const option = ctx.vueCompilerOptions.experimentalResolveStyleCssClasses;
|
|
120
|
+
if (option === 'always' || (option === 'scoped' && style.scoped)) {
|
|
121
|
+
for (const className of style.classNames) {
|
|
122
|
+
classes.add(className.text.substring(1));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return classes;
|
|
127
|
+
});
|
|
128
|
+
const generatedTemplate = (0, computeds_1.computed)(() => {
|
|
129
|
+
if (!_sfc.template)
|
|
130
|
+
return;
|
|
131
|
+
const tsCodes = [];
|
|
132
|
+
const tsFormatCodes = [];
|
|
133
|
+
const inlineCssCodes = [];
|
|
134
|
+
const tsCodegenStacks = [];
|
|
135
|
+
const tsFormatCodegenStacks = [];
|
|
136
|
+
const inlineCssCodegenStacks = [];
|
|
137
|
+
const codegen = (0, template_1.generate)(ts, ctx.compilerOptions, ctx.vueCompilerOptions, _sfc.template, shouldGenerateScopedClasses(), stylesScopedClasses(), hasScriptSetupSlots(), slotsAssignName(), propsAssignName(), ctx.codegenStack);
|
|
138
|
+
let current = codegen.next();
|
|
139
|
+
while (!current.done) {
|
|
140
|
+
const [type, code, stack] = current.value;
|
|
141
|
+
if (type === 'ts') {
|
|
142
|
+
tsCodes.push(code);
|
|
143
|
+
}
|
|
144
|
+
else if (type === 'tsFormat') {
|
|
145
|
+
tsFormatCodes.push(code);
|
|
146
|
+
}
|
|
147
|
+
else if (type === 'inlineCss') {
|
|
148
|
+
inlineCssCodes.push(code);
|
|
149
|
+
}
|
|
150
|
+
if (ctx.codegenStack) {
|
|
151
|
+
if (type === 'ts') {
|
|
152
|
+
tsCodegenStacks.push(stack);
|
|
153
|
+
}
|
|
154
|
+
else if (type === 'tsFormat') {
|
|
155
|
+
tsFormatCodegenStacks.push(stack);
|
|
156
|
+
}
|
|
157
|
+
else if (type === 'inlineCss') {
|
|
158
|
+
inlineCssCodegenStacks.push(stack);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
current = codegen.next();
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
...current.value,
|
|
165
|
+
codes: tsCodes,
|
|
166
|
+
codeStacks: tsCodegenStacks,
|
|
167
|
+
formatCodes: tsFormatCodes,
|
|
168
|
+
formatCodeStacks: tsFormatCodegenStacks,
|
|
169
|
+
cssCodes: inlineCssCodes,
|
|
170
|
+
cssCodeStacks: inlineCssCodegenStacks,
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
const hasScriptSetupSlots = (0, computeds_1.computed)(() => !!scriptSetupRanges()?.slots.define);
|
|
174
|
+
const slotsAssignName = (0, computeds_1.computed)(() => scriptSetupRanges()?.slots.name);
|
|
175
|
+
const propsAssignName = (0, computeds_1.computed)(() => scriptSetupRanges()?.props.name);
|
|
176
|
+
const generatedScript = (0, computeds_1.computed)(() => {
|
|
177
|
+
const codes = [];
|
|
178
|
+
const codeStacks = [];
|
|
179
|
+
const linkedCodeMappings = [];
|
|
180
|
+
const _template = generatedTemplate();
|
|
181
|
+
let generatedLength = 0;
|
|
182
|
+
for (const [code, stack] of (0, script_1.generate)(ts, fileName, _sfc.script, _sfc.scriptSetup, _sfc.styles, lang(), scriptRanges(), scriptSetupRanges(), _template ? {
|
|
183
|
+
tsCodes: _template.codes,
|
|
184
|
+
tsCodegenStacks: _template.codeStacks,
|
|
185
|
+
accessedGlobalVariables: _template.accessedGlobalVariables,
|
|
186
|
+
hasSlot: _template.hasSlot,
|
|
187
|
+
tagNames: new Set(_template.tagOffsetsMap.keys()),
|
|
188
|
+
} : undefined, ctx.compilerOptions, ctx.vueCompilerOptions, ctx.globalTypesHolder, () => generatedLength, linkedCodeMappings, ctx.codegenStack)) {
|
|
189
|
+
codes.push(code);
|
|
190
|
+
if (ctx.codegenStack) {
|
|
191
|
+
codeStacks.push({ stack, length: 1 });
|
|
192
|
+
}
|
|
193
|
+
generatedLength += typeof code === 'string'
|
|
194
|
+
? code.length
|
|
195
|
+
: code[0].length;
|
|
196
|
+
}
|
|
197
|
+
;
|
|
198
|
+
return {
|
|
199
|
+
codes,
|
|
200
|
+
codeStacks,
|
|
201
|
+
linkedCodeMappings,
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
scriptRanges,
|
|
206
|
+
scriptSetupRanges,
|
|
207
|
+
lang,
|
|
208
|
+
generatedScript,
|
|
209
|
+
generatedTemplate,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=vue-tsx.js.map
|
package/lib/plugins.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as CompilerDOM from '@vue/compiler-dom';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
import { type VueCompilerOptions, type VueLanguagePlugin } from './types';
|
|
4
|
+
export declare function createPluginContext(ts: typeof import('typescript'), compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions, codegenStack: boolean, globalTypesHolder: string | undefined): {
|
|
5
|
+
modules: {
|
|
6
|
+
typescript: typeof import("typescript");
|
|
7
|
+
'@vue/compiler-dom': typeof CompilerDOM;
|
|
8
|
+
};
|
|
9
|
+
compilerOptions: ts.CompilerOptions;
|
|
10
|
+
vueCompilerOptions: VueCompilerOptions;
|
|
11
|
+
codegenStack: boolean;
|
|
12
|
+
globalTypesHolder: string | undefined;
|
|
13
|
+
};
|
|
14
|
+
export declare function getDefaultVueLanguagePlugins(pluginContext: Parameters<VueLanguagePlugin>[0]): {
|
|
15
|
+
version: 2;
|
|
16
|
+
name?: string | undefined;
|
|
17
|
+
order?: number | undefined;
|
|
18
|
+
requiredCompilerOptions?: string[] | undefined;
|
|
19
|
+
parseSFC?(fileName: string, content: string): import("@vue/compiler-sfc").SFCParseResult | undefined;
|
|
20
|
+
updateSFC?(oldResult: import("@vue/compiler-sfc").SFCParseResult, textChange: {
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
23
|
+
newText: string;
|
|
24
|
+
}): import("@vue/compiler-sfc").SFCParseResult | undefined;
|
|
25
|
+
resolveTemplateCompilerOptions?(options: CompilerDOM.CompilerOptions): CompilerDOM.CompilerOptions;
|
|
26
|
+
compileSFCTemplate?(lang: string, template: string, options: CompilerDOM.CompilerOptions): CompilerDOM.CodegenResult | undefined;
|
|
27
|
+
updateSFCTemplate?(oldResult: CompilerDOM.CodegenResult, textChange: {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
newText: string;
|
|
31
|
+
}): CompilerDOM.CodegenResult | undefined;
|
|
32
|
+
getEmbeddedCodes?(fileName: string, sfc: import("./types").Sfc): {
|
|
33
|
+
id: string;
|
|
34
|
+
lang: string;
|
|
35
|
+
}[];
|
|
36
|
+
resolveEmbeddedCode?(fileName: string, sfc: import("./types").Sfc, embeddedFile: import("./virtualFile/embeddedFile").VueEmbeddedCode): void;
|
|
37
|
+
}[];
|
package/lib/plugins.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultVueLanguagePlugins = exports.createPluginContext = void 0;
|
|
4
|
+
const CompilerDOM = require("@vue/compiler-dom");
|
|
5
|
+
const file_html_1 = require("./plugins/file-html");
|
|
6
|
+
const file_md_1 = require("./plugins/file-md");
|
|
7
|
+
const file_vue_1 = require("./plugins/file-vue");
|
|
8
|
+
const vue_sfc_customblocks_1 = require("./plugins/vue-sfc-customblocks");
|
|
9
|
+
const vue_sfc_scripts_1 = require("./plugins/vue-sfc-scripts");
|
|
10
|
+
const vue_sfc_styles_1 = require("./plugins/vue-sfc-styles");
|
|
11
|
+
const vue_sfc_template_1 = require("./plugins/vue-sfc-template");
|
|
12
|
+
const vue_template_html_1 = require("./plugins/vue-template-html");
|
|
13
|
+
const vue_tsx_1 = require("./plugins/vue-tsx");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
const CompilerVue2 = require("./utils/vue2TemplateCompiler");
|
|
16
|
+
function createPluginContext(ts, compilerOptions, vueCompilerOptions, codegenStack, globalTypesHolder) {
|
|
17
|
+
const pluginCtx = {
|
|
18
|
+
modules: {
|
|
19
|
+
'@vue/compiler-dom': vueCompilerOptions.target < 3
|
|
20
|
+
? {
|
|
21
|
+
...CompilerDOM,
|
|
22
|
+
compile: CompilerVue2.compile,
|
|
23
|
+
}
|
|
24
|
+
: CompilerDOM,
|
|
25
|
+
typescript: ts,
|
|
26
|
+
},
|
|
27
|
+
compilerOptions,
|
|
28
|
+
vueCompilerOptions,
|
|
29
|
+
codegenStack,
|
|
30
|
+
globalTypesHolder,
|
|
31
|
+
};
|
|
32
|
+
return pluginCtx;
|
|
33
|
+
}
|
|
34
|
+
exports.createPluginContext = createPluginContext;
|
|
35
|
+
function getDefaultVueLanguagePlugins(pluginContext) {
|
|
36
|
+
const plugins = [
|
|
37
|
+
file_md_1.default, // .md for VitePress
|
|
38
|
+
file_html_1.default, // .html for PetiteVue
|
|
39
|
+
file_vue_1.default, // .vue and others for Vue
|
|
40
|
+
vue_template_html_1.default,
|
|
41
|
+
vue_sfc_styles_1.default,
|
|
42
|
+
vue_sfc_customblocks_1.default,
|
|
43
|
+
vue_sfc_scripts_1.default,
|
|
44
|
+
vue_sfc_template_1.default,
|
|
45
|
+
vue_tsx_1.default,
|
|
46
|
+
...pluginContext.vueCompilerOptions.plugins,
|
|
47
|
+
];
|
|
48
|
+
const pluginInstances = plugins
|
|
49
|
+
.map(plugin => plugin(pluginContext))
|
|
50
|
+
.sort((a, b) => {
|
|
51
|
+
const aOrder = a.order ?? 0;
|
|
52
|
+
const bOrder = b.order ?? 0;
|
|
53
|
+
return aOrder - bOrder;
|
|
54
|
+
});
|
|
55
|
+
return pluginInstances.filter((plugin) => {
|
|
56
|
+
const valid = plugin.version === types_1.pluginVersion;
|
|
57
|
+
if (!valid) {
|
|
58
|
+
console.warn(`Plugin ${JSON.stringify(plugin.name)} API version incompatible, expected ${JSON.stringify(types_1.pluginVersion)} but got ${JSON.stringify(plugin.version)}`);
|
|
59
|
+
}
|
|
60
|
+
return valid;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
exports.getDefaultVueLanguagePlugins = getDefaultVueLanguagePlugins;
|
|
64
|
+
//# sourceMappingURL=plugins.js.map
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type * as CompilerDOM from '@vue/compiler-dom';
|
|
2
|
+
import type { SFCParseResult } from '@vue/compiler-sfc';
|
|
3
|
+
import type * as ts from 'typescript';
|
|
4
|
+
import type { VueEmbeddedCode } from './virtualFile/embeddedFile';
|
|
5
|
+
import type { CodeInformation, Segment } from '@volar/language-core';
|
|
6
|
+
export type { SFCParseResult } from '@vue/compiler-sfc';
|
|
7
|
+
export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' | 'plugins'>> & {
|
|
8
|
+
target?: 'auto' | 2 | 2.7 | 3 | 3.3;
|
|
9
|
+
plugins?: string[];
|
|
10
|
+
};
|
|
11
|
+
export interface VueCodeInformation extends CodeInformation {
|
|
12
|
+
__referencesCodeLens?: boolean;
|
|
13
|
+
__displayWithLink?: boolean;
|
|
14
|
+
__hint?: {
|
|
15
|
+
setting: string;
|
|
16
|
+
label: string;
|
|
17
|
+
tooltip: string;
|
|
18
|
+
paddingRight?: boolean;
|
|
19
|
+
paddingLeft?: boolean;
|
|
20
|
+
};
|
|
21
|
+
__combineLastMappping?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export type CodeAndStack = [code: Code, stack: string];
|
|
24
|
+
export type Code = Segment<VueCodeInformation>;
|
|
25
|
+
export interface VueCompilerOptions {
|
|
26
|
+
target: number;
|
|
27
|
+
lib: string;
|
|
28
|
+
extensions: string[];
|
|
29
|
+
jsxSlots: boolean;
|
|
30
|
+
strictTemplates: boolean;
|
|
31
|
+
skipTemplateCodegen: boolean;
|
|
32
|
+
nativeTags: string[];
|
|
33
|
+
dataAttributes: string[];
|
|
34
|
+
htmlAttributes: string[];
|
|
35
|
+
optionsWrapper: [string, string] | [];
|
|
36
|
+
macros: {
|
|
37
|
+
defineProps: string[];
|
|
38
|
+
defineSlots: string[];
|
|
39
|
+
defineEmits: string[];
|
|
40
|
+
defineExpose: string[];
|
|
41
|
+
defineModel: string[];
|
|
42
|
+
defineOptions: string[];
|
|
43
|
+
withDefaults: string[];
|
|
44
|
+
};
|
|
45
|
+
plugins: VueLanguagePlugin[];
|
|
46
|
+
experimentalDefinePropProposal: 'kevinEdition' | 'johnsonEdition' | false;
|
|
47
|
+
experimentalResolveStyleCssClasses: 'scoped' | 'always' | 'never';
|
|
48
|
+
experimentalModelPropName: Record<string, Record<string, boolean | Record<string, string> | Record<string, string>[]>>;
|
|
49
|
+
experimentalUseElementAccessInTemplate: boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare const pluginVersion = 2;
|
|
52
|
+
export type VueLanguagePlugin = (ctx: {
|
|
53
|
+
modules: {
|
|
54
|
+
typescript: typeof import('typescript');
|
|
55
|
+
'@vue/compiler-dom': typeof import('@vue/compiler-dom');
|
|
56
|
+
};
|
|
57
|
+
compilerOptions: ts.CompilerOptions;
|
|
58
|
+
vueCompilerOptions: VueCompilerOptions;
|
|
59
|
+
codegenStack: boolean;
|
|
60
|
+
globalTypesHolder: string | undefined;
|
|
61
|
+
}) => {
|
|
62
|
+
version: typeof pluginVersion;
|
|
63
|
+
name?: string;
|
|
64
|
+
order?: number;
|
|
65
|
+
requiredCompilerOptions?: string[];
|
|
66
|
+
parseSFC?(fileName: string, content: string): SFCParseResult | undefined;
|
|
67
|
+
updateSFC?(oldResult: SFCParseResult, textChange: {
|
|
68
|
+
start: number;
|
|
69
|
+
end: number;
|
|
70
|
+
newText: string;
|
|
71
|
+
}): SFCParseResult | undefined;
|
|
72
|
+
resolveTemplateCompilerOptions?(options: CompilerDOM.CompilerOptions): CompilerDOM.CompilerOptions;
|
|
73
|
+
compileSFCTemplate?(lang: string, template: string, options: CompilerDOM.CompilerOptions): CompilerDOM.CodegenResult | undefined;
|
|
74
|
+
updateSFCTemplate?(oldResult: CompilerDOM.CodegenResult, textChange: {
|
|
75
|
+
start: number;
|
|
76
|
+
end: number;
|
|
77
|
+
newText: string;
|
|
78
|
+
}): CompilerDOM.CodegenResult | undefined;
|
|
79
|
+
getEmbeddedCodes?(fileName: string, sfc: Sfc): {
|
|
80
|
+
id: string;
|
|
81
|
+
lang: string;
|
|
82
|
+
}[];
|
|
83
|
+
resolveEmbeddedCode?(fileName: string, sfc: Sfc, embeddedFile: VueEmbeddedCode): void;
|
|
84
|
+
};
|
|
85
|
+
export interface SfcBlock {
|
|
86
|
+
name: string;
|
|
87
|
+
start: number;
|
|
88
|
+
end: number;
|
|
89
|
+
startTagEnd: number;
|
|
90
|
+
endTagStart: number;
|
|
91
|
+
lang: string;
|
|
92
|
+
content: string;
|
|
93
|
+
attrs: Record<string, string | true>;
|
|
94
|
+
}
|
|
95
|
+
export interface Sfc {
|
|
96
|
+
template: SfcBlock & {
|
|
97
|
+
ast: CompilerDOM.RootNode | undefined;
|
|
98
|
+
errors: CompilerDOM.CompilerError[];
|
|
99
|
+
warnings: CompilerDOM.CompilerError[];
|
|
100
|
+
} | undefined;
|
|
101
|
+
script: (SfcBlock & {
|
|
102
|
+
src: string | undefined;
|
|
103
|
+
srcOffset: number;
|
|
104
|
+
ast: ts.SourceFile;
|
|
105
|
+
}) | undefined;
|
|
106
|
+
scriptSetup: SfcBlock & {
|
|
107
|
+
generic: string | undefined;
|
|
108
|
+
genericOffset: number;
|
|
109
|
+
ast: ts.SourceFile;
|
|
110
|
+
} | undefined;
|
|
111
|
+
styles: readonly (SfcBlock & {
|
|
112
|
+
module: string | undefined;
|
|
113
|
+
scoped: boolean;
|
|
114
|
+
cssVars: {
|
|
115
|
+
text: string;
|
|
116
|
+
offset: number;
|
|
117
|
+
}[];
|
|
118
|
+
classNames: {
|
|
119
|
+
text: string;
|
|
120
|
+
offset: number;
|
|
121
|
+
}[];
|
|
122
|
+
})[];
|
|
123
|
+
customBlocks: readonly (SfcBlock & {
|
|
124
|
+
type: string;
|
|
125
|
+
})[];
|
|
126
|
+
/**
|
|
127
|
+
* @deprecated use `template.ast` instead
|
|
128
|
+
*/
|
|
129
|
+
templateAst: CompilerDOM.RootNode | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* @deprecated use `script.ast` instead
|
|
132
|
+
*/
|
|
133
|
+
scriptAst: ts.SourceFile | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* @deprecated use `scriptSetup.ast` instead
|
|
136
|
+
*/
|
|
137
|
+
scriptSetupAst: ts.SourceFile | undefined;
|
|
138
|
+
}
|
|
139
|
+
export interface TextRange {
|
|
140
|
+
start: number;
|
|
141
|
+
end: number;
|
|
142
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCssClassNames = void 0;
|
|
4
|
+
const parseCssVars_1 = require("./parseCssVars");
|
|
5
|
+
const cssClassNameReg = /(?=([\.]{1}[a-zA-Z_]+[\w\_\-]*)[\s\.\+\{\>#\:]{1})/g;
|
|
6
|
+
function* parseCssClassNames(styleContent) {
|
|
7
|
+
styleContent = (0, parseCssVars_1.clearComments)(styleContent);
|
|
8
|
+
const matches = styleContent.matchAll(cssClassNameReg);
|
|
9
|
+
for (const match of matches) {
|
|
10
|
+
if (match.index !== undefined) {
|
|
11
|
+
const matchText = match[1];
|
|
12
|
+
if (matchText !== undefined) {
|
|
13
|
+
yield { offset: match.index, text: matchText };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.parseCssClassNames = parseCssClassNames;
|
|
19
|
+
//# sourceMappingURL=parseCssClassNames.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/cssVars.ts#L47-L61
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.clearComments = exports.parseCssVars = void 0;
|
|
5
|
+
const vBindCssVarReg = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g;
|
|
6
|
+
const commentReg1 = /\/\*([\s\S]*?)\*\//g;
|
|
7
|
+
const commentReg2 = /\/\/([\s\S]*?)\n/g;
|
|
8
|
+
function* parseCssVars(styleContent) {
|
|
9
|
+
styleContent = clearComments(styleContent);
|
|
10
|
+
const matchs = styleContent.matchAll(vBindCssVarReg);
|
|
11
|
+
for (const match of matchs) {
|
|
12
|
+
if (match.index !== undefined) {
|
|
13
|
+
const matchText = match[1] ?? match[2] ?? match[3];
|
|
14
|
+
if (matchText !== undefined) {
|
|
15
|
+
const offset = match.index + styleContent.slice(match.index).indexOf(matchText);
|
|
16
|
+
yield { offset, text: matchText };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.parseCssVars = parseCssVars;
|
|
22
|
+
function clearComments(css) {
|
|
23
|
+
return css
|
|
24
|
+
.replace(commentReg1, match => `/*${' '.repeat(match.length - 4)}*/`)
|
|
25
|
+
.replace(commentReg2, match => `//${' '.repeat(match.length - 3)}\n`);
|
|
26
|
+
}
|
|
27
|
+
exports.clearComments = clearComments;
|
|
28
|
+
//# sourceMappingURL=parseCssVars.js.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parse = void 0;
|
|
4
|
+
const compiler = require("@vue/compiler-dom");
|
|
5
|
+
function parse(source) {
|
|
6
|
+
const errors = [];
|
|
7
|
+
const ast = compiler.parse(source, {
|
|
8
|
+
// there are no components at SFC parsing level
|
|
9
|
+
isNativeTag: () => true,
|
|
10
|
+
// preserve all whitespaces
|
|
11
|
+
isPreTag: () => true,
|
|
12
|
+
parseMode: 'sfc',
|
|
13
|
+
onError: e => {
|
|
14
|
+
errors.push(e);
|
|
15
|
+
},
|
|
16
|
+
comments: true,
|
|
17
|
+
});
|
|
18
|
+
const descriptor = {
|
|
19
|
+
filename: 'anonymous.vue',
|
|
20
|
+
source,
|
|
21
|
+
template: null,
|
|
22
|
+
script: null,
|
|
23
|
+
scriptSetup: null,
|
|
24
|
+
styles: [],
|
|
25
|
+
customBlocks: [],
|
|
26
|
+
cssVars: [],
|
|
27
|
+
slotted: false,
|
|
28
|
+
shouldForceReload: () => false,
|
|
29
|
+
};
|
|
30
|
+
ast.children.forEach(node => {
|
|
31
|
+
if (node.type !== compiler.NodeTypes.ELEMENT) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
switch (node.tag) {
|
|
35
|
+
case 'template':
|
|
36
|
+
descriptor.template = createBlock(node, source);
|
|
37
|
+
break;
|
|
38
|
+
case 'script':
|
|
39
|
+
const scriptBlock = createBlock(node, source);
|
|
40
|
+
const isSetup = !!scriptBlock.attrs.setup;
|
|
41
|
+
if (isSetup && !descriptor.scriptSetup) {
|
|
42
|
+
descriptor.scriptSetup = scriptBlock;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
if (!isSetup && !descriptor.script) {
|
|
46
|
+
descriptor.script = scriptBlock;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
case 'style':
|
|
51
|
+
const styleBlock = createBlock(node, source);
|
|
52
|
+
descriptor.styles.push(styleBlock);
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
descriptor.customBlocks.push(createBlock(node, source));
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
descriptor,
|
|
61
|
+
errors,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
exports.parse = parse;
|
|
65
|
+
function createBlock(node, source) {
|
|
66
|
+
const type = node.tag;
|
|
67
|
+
let { start, end } = node.loc;
|
|
68
|
+
let content = '';
|
|
69
|
+
if (node.children.length) {
|
|
70
|
+
start = node.children[0].loc.start;
|
|
71
|
+
end = node.children[node.children.length - 1].loc.end;
|
|
72
|
+
content = source.slice(start.offset, end.offset);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const offset = node.loc.source.indexOf(`</`);
|
|
76
|
+
if (offset > -1) {
|
|
77
|
+
start = {
|
|
78
|
+
line: start.line,
|
|
79
|
+
column: start.column + offset,
|
|
80
|
+
offset: start.offset + offset
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
end = Object.assign({}, start);
|
|
84
|
+
}
|
|
85
|
+
const loc = {
|
|
86
|
+
source: content,
|
|
87
|
+
start,
|
|
88
|
+
end
|
|
89
|
+
};
|
|
90
|
+
const attrs = {};
|
|
91
|
+
const block = {
|
|
92
|
+
type,
|
|
93
|
+
content,
|
|
94
|
+
loc,
|
|
95
|
+
attrs
|
|
96
|
+
};
|
|
97
|
+
node.props.forEach(p => {
|
|
98
|
+
if (p.type === compiler.NodeTypes.ATTRIBUTE) {
|
|
99
|
+
attrs[p.name] = p.value ? p.value.content || true : true;
|
|
100
|
+
if (p.name === 'lang') {
|
|
101
|
+
block.lang = p.value && p.value.content;
|
|
102
|
+
}
|
|
103
|
+
else if (p.name === 'src') {
|
|
104
|
+
block.src = p.value && p.value.content;
|
|
105
|
+
}
|
|
106
|
+
else if (type === 'style') {
|
|
107
|
+
if (p.name === 'scoped') {
|
|
108
|
+
block.scoped = true;
|
|
109
|
+
}
|
|
110
|
+
else if (p.name === 'module') {
|
|
111
|
+
block.module = attrs[p.name];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (type === 'script' && p.name === 'setup') {
|
|
115
|
+
block.setup = attrs.setup;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return block;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=parseSfc.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hyphenateAttr = exports.hyphenateTag = exports.getSlotsPropertyName = void 0;
|
|
4
|
+
const shared_1 = require("@vue/shared");
|
|
5
|
+
function getSlotsPropertyName(vueVersion) {
|
|
6
|
+
return vueVersion < 3 ? '$scopedSlots' : '$slots';
|
|
7
|
+
}
|
|
8
|
+
exports.getSlotsPropertyName = getSlotsPropertyName;
|
|
9
|
+
var shared_2 = require("@vue/shared");
|
|
10
|
+
Object.defineProperty(exports, "hyphenateTag", { enumerable: true, get: function () { return shared_2.hyphenate; } });
|
|
11
|
+
function hyphenateAttr(str) {
|
|
12
|
+
let hyphencase = (0, shared_1.hyphenate)(str);
|
|
13
|
+
// fix https://github.com/vuejs/core/issues/8811
|
|
14
|
+
if (str.length && str[0] !== str[0].toLowerCase()) {
|
|
15
|
+
hyphencase = '-' + hyphencase;
|
|
16
|
+
}
|
|
17
|
+
return hyphencase;
|
|
18
|
+
}
|
|
19
|
+
exports.hyphenateAttr = hyphenateAttr;
|
|
20
|
+
//# sourceMappingURL=shared.js.map
|