/
petite-vue-script.ts
96 lines (83 loc) · 2.6 KB
/
petite-vue-script.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { CodeGen } from '@volar/code-gen';
import { EmbeddedFileMappingData } from '@volar/vue-code-gen';
import { EmbeddedFile, VueLanguagePlugin } from '../sourceFile';
export default function (
ts: typeof import('typescript/lib/tsserverlibrary'),
): VueLanguagePlugin {
return {
getEmbeddedFilesCount(fileName, sfc) {
return fileName.endsWith('.html') ? 1 : 0;
},
getEmbeddedFile(fileName, sfc, i) {
if (sfc.script) {
const ast = ts.createSourceFile(fileName, sfc.script.content, ts.ScriptTarget.Latest);
let createAppArgRange: [number, number] | undefined;
ast.forEachChild(child => walkNode(child));
const codeGen = new CodeGen<EmbeddedFileMappingData>();
codeGen.addCode2(sfc.script.content, 0, {
vueTag: 'script',
capabilities: {
basic: true,
references: true,
definitions: true,
diagnostic: true,
rename: true,
completion: true,
semanticTokens: true,
},
});
codeGen.addText('\n\n');
codeGen.addText(`const __VLS_scope = `);
if (createAppArgRange) {
const createAppArgText = sfc.script.content.slice(createAppArgRange[0], createAppArgRange[1]);
if (createAppArgText.trim()) {
codeGen.addCode2(createAppArgText, createAppArgRange[0], {
vueTag: 'script',
capabilities: {
references: true,
definitions: true,
rename: true,
},
});
}
else {
codeGen.addText('{}');
}
}
else {
codeGen.addText('{}');
}
codeGen.addText(';\n');
codeGen.addText(`const __VLS_component = (await import('vue')).defineComponent({});\n`);
codeGen.addText(`declare const __VLS_export: new () => typeof __VLS_scope & import('./__VLS_types').PickNotAny<InstanceType<typeof __VLS_component>, {}>;\n`);
codeGen.addText('export default __VLS_export;\n');
const file: EmbeddedFile = {
fileName: fileName + '.__VLS_script.' + sfc.script.lang,
content: codeGen.getText(),
capabilities: {
diagnostics: true,
foldingRanges: false,
formatting: false,
documentSymbol: false,
codeActions: true,
inlayHints: true,
},
isTsHostFile: true,
mappings: codeGen.getMappings(),
};
return file;
function walkNode(node: ts.Node) {
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'createApp') {
if (node.arguments.length) {
const arg0 = node.arguments[0];
createAppArgRange = [arg0.getStart(ast), arg0.getEnd()];
}
}
else {
node.forEachChild(child => walkNode(child));
}
}
}
},
};
}