This commit is contained in:
2024-11-28 23:08:17 +01:00
parent 8895fde030
commit 0dda8e760c
16116 changed files with 2866428 additions and 71 deletions

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sfcBlockReg = /\<(script|style)\b([\s\S]*?)\>([\s\S]*?)\<\/\1\>/g;
const langReg = /\blang\s*=\s*(['\"]?)(\S*)\b\1/;
const plugin = ({ vueCompilerOptions }) => {
return {
version: 2.1,
getLanguageId(fileName) {
if (vueCompilerOptions.petiteVueExtensions.some(ext => fileName.endsWith(ext))) {
return 'html';
}
},
isValidFile(_fileName, languageId) {
return languageId === 'html';
},
parseSFC2(fileName, languageId, content) {
if (languageId !== 'html') {
return;
}
let sfc = {
descriptor: {
filename: fileName,
source: content,
template: null,
script: null,
scriptSetup: null,
styles: [],
customBlocks: [],
cssVars: [],
shouldForceReload: () => false,
slotted: false,
},
errors: [],
};
let templateContent = content;
for (const match of content.matchAll(sfcBlockReg)) {
const matchText = match[0];
const tag = match[1];
const attrs = match[2];
const lang = attrs.match(langReg)?.[2];
const content = match[3];
const contentStart = match.index + matchText.indexOf(content);
if (tag === 'style') {
sfc.descriptor.styles.push({
attrs: {},
content,
loc: {
start: { column: -1, line: -1, offset: contentStart },
end: { column: -1, line: -1, offset: contentStart + content.length },
source: content,
},
type: 'style',
lang,
});
}
// ignore `<script src="...">`
else if (tag === 'script' && attrs.indexOf('src=') === -1) {
let type = attrs.indexOf('type=') >= 0 ? 'scriptSetup' : 'script';
sfc.descriptor[type] = {
attrs: {},
content,
loc: {
start: { column: -1, line: -1, offset: contentStart },
end: { column: -1, line: -1, offset: contentStart + content.length },
source: content,
},
type: 'script',
lang,
};
}
templateContent = templateContent.substring(0, match.index) + ' '.repeat(matchText.length) + templateContent.substring(match.index + matchText.length);
}
sfc.descriptor.template = {
attrs: {},
content: templateContent,
loc: {
start: { column: -1, line: -1, offset: 0 },
end: { column: -1, line: -1, offset: templateContent.length },
source: templateContent,
},
type: 'template',
ast: {},
};
return sfc;
}
};
};
exports.default = plugin;
//# sourceMappingURL=file-html.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

93
node_modules/@vue/language-core/lib/plugins/file-md.js generated vendored Normal file
View File

@@ -0,0 +1,93 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const language_core_1 = require("@volar/language-core");
const muggle_string_1 = require("muggle-string");
const buildMappings_1 = require("../utils/buildMappings");
const parseSfc_1 = require("../utils/parseSfc");
const codeblockReg = /(`{3,})[\s\S]+?\1/g;
const inlineCodeblockReg = /`[^\n`]+?`/g;
const scriptSetupReg = /\\\<[\s\S]+?\>\n?/g;
const sfcBlockReg = /\<(script|style)\b[\s\S]*?\>([\s\S]*?)\<\/\1\>/g;
const angleBracketReg = /\<\S*\:\S*\>/g;
const linkReg = /\[[\s\S]*?\]\([\s\S]*?\)/g;
const codeSnippetImportReg = /^\s*<<<\s*.+/gm;
const plugin = ({ vueCompilerOptions }) => {
return {
version: 2.1,
getLanguageId(fileName) {
if (vueCompilerOptions.vitePressExtensions.some(ext => fileName.endsWith(ext))) {
return 'markdown';
}
},
isValidFile(_fileName, languageId) {
return languageId === 'markdown';
},
parseSFC2(_fileName, languageId, content) {
if (languageId !== 'markdown') {
return;
}
content = content
// code block
.replace(codeblockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
// inline code block
.replace(inlineCodeblockReg, match => `\`${' '.repeat(match.length - 2)}\``)
// # \<script setup>
.replace(scriptSetupReg, match => ' '.repeat(match.length))
// <<< https://vitepress.dev/guide/markdown#import-code-snippets
.replace(codeSnippetImportReg, match => ' '.repeat(match.length));
const codes = [];
for (const match of content.matchAll(sfcBlockReg)) {
if (match.index !== undefined) {
const matchText = match[0];
codes.push([matchText, undefined, match.index]);
codes.push('\n\n');
content = content.substring(0, match.index) + ' '.repeat(matchText.length) + content.substring(match.index + matchText.length);
}
}
content = content
// angle bracket: <http://foo.com>
.replace(angleBracketReg, match => ' '.repeat(match.length))
// [foo](http://foo.com)
.replace(linkReg, match => ' '.repeat(match.length));
codes.push('<template>\n');
codes.push([content, undefined, 0]);
codes.push('\n</template>');
const file2VueSourceMap = (0, language_core_1.defaultMapperFactory)((0, buildMappings_1.buildMappings)(codes));
const sfc = (0, parseSfc_1.parse)((0, muggle_string_1.toString)(codes));
if (sfc.descriptor.template) {
sfc.descriptor.template.lang = 'md';
transformRange(sfc.descriptor.template);
}
if (sfc.descriptor.script) {
transformRange(sfc.descriptor.script);
}
if (sfc.descriptor.scriptSetup) {
transformRange(sfc.descriptor.scriptSetup);
}
for (const style of sfc.descriptor.styles) {
transformRange(style);
}
for (const customBlock of sfc.descriptor.customBlocks) {
transformRange(customBlock);
}
return sfc;
function transformRange(block) {
const { start, end } = block.loc;
const startOffset = start.offset;
const endOffset = end.offset;
start.offset = -1;
end.offset = -1;
for (const [offset] of file2VueSourceMap.toSourceLocation(startOffset)) {
start.offset = offset;
break;
}
for (const [offset] of file2VueSourceMap.toSourceLocation(endOffset)) {
end.offset = offset;
break;
}
}
}
};
};
exports.default = plugin;
//# sourceMappingURL=file-md.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const parseSfc_1 = require("../utils/parseSfc");
const plugin = ({ vueCompilerOptions }) => {
return {
version: 2.1,
getLanguageId(fileName) {
if (vueCompilerOptions.extensions.some(ext => fileName.endsWith(ext))) {
return 'vue';
}
},
isValidFile(_fileName, languageId) {
return languageId === 'vue';
},
parseSFC2(_fileName, languageId, content) {
if (languageId !== 'vue') {
return;
}
return (0, parseSfc_1.parse)(content);
},
updateSFC(sfc, change) {
const blocks = [
sfc.descriptor.template,
sfc.descriptor.script,
sfc.descriptor.scriptSetup,
...sfc.descriptor.styles,
...sfc.descriptor.customBlocks,
].filter((block) => !!block);
const hitBlock = blocks.find(block => change.start >= block.loc.start.offset && change.end <= block.loc.end.offset);
if (!hitBlock) {
return;
}
const oldContent = hitBlock.content;
const newContent = hitBlock.content =
hitBlock.content.substring(0, change.start - hitBlock.loc.start.offset)
+ change.newText
+ hitBlock.content.substring(change.end - hitBlock.loc.start.offset);
// #3449
const endTagRegex = new RegExp(`</\\s*${hitBlock.type}\\s*>`);
const insertedEndTag = !!oldContent.match(endTagRegex) !== !!newContent.match(endTagRegex);
if (insertedEndTag) {
return;
}
const lengthDiff = change.newText.length - (change.end - change.start);
for (const block of blocks) {
if (block.loc.start.offset > change.end) {
block.loc.start.offset += lengthDiff;
}
if (block.loc.end.offset >= change.end) {
block.loc.end.offset += lengthDiff;
}
}
return sfc;
},
};
};
exports.default = plugin;
//# sourceMappingURL=file-vue.js.map

View File

@@ -0,0 +1,2 @@
import type { CodeInformation } from '@volar/language-core';
export declare const allCodeFeatures: CodeInformation;

12
node_modules/@vue/language-core/lib/plugins/shared.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.allCodeFeatures = void 0;
exports.allCodeFeatures = {
verification: true,
completion: true,
semantic: true,
navigation: true,
structure: true,
format: true,
};
//# sourceMappingURL=shared.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const muggle_string_1 = require("muggle-string");
const shared_1 = require("./shared");
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes() {
return [{
id: 'root_tags',
lang: 'vue-root-tags',
}];
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id === 'root_tags') {
embeddedFile.content.push([sfc.content, undefined, 0, shared_1.allCodeFeatures]);
for (const block of [
sfc.script,
sfc.scriptSetup,
sfc.template,
...sfc.styles,
...sfc.customBlocks,
]) {
if (!block) {
continue;
}
let content = block.content;
if (content.endsWith('\r\n')) {
content = content.slice(0, -2);
}
else if (content.endsWith('\n')) {
content = content.slice(0, -1);
}
const offset = content.lastIndexOf('\n') + 1;
// fix folding range end position failed to mapping
(0, muggle_string_1.replaceSourceRange)(embeddedFile.content, undefined, block.startTagEnd, block.endTagStart, sfc.content.substring(block.startTagEnd, block.startTagEnd + offset), [
'',
undefined,
block.startTagEnd + offset,
{ structure: true },
], sfc.content.substring(block.startTagEnd + offset, block.endTagStart));
}
}
else {
embeddedFile.parentCodeId ??= 'root_tags';
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-root-tags.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugin = ({ modules }) => {
return {
version: 2.1,
compileSFCScript(lang, script) {
if (lang === 'js' || lang === 'ts' || lang === 'jsx' || lang === 'tsx') {
const ts = modules.typescript;
return ts.createSourceFile('test.' + lang, script, 99);
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-script-js.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const shared_1 = require("./shared");
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
return sfc.customBlocks.map((customBlock, i) => ({
id: 'custom_block_' + i,
lang: customBlock.lang,
}));
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id.startsWith('custom_block_')) {
const index = parseInt(embeddedFile.id.slice('custom_block_'.length));
const customBlock = sfc.customBlocks[index];
embeddedFile.content.push([
customBlock.content,
customBlock.name,
0,
shared_1.allCodeFeatures,
]);
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-sfc-customblocks.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
const names = [];
if (sfc.script) {
names.push({ id: 'script_raw', lang: sfc.script.lang });
}
if (sfc.scriptSetup) {
names.push({ id: 'scriptsetup_raw', lang: sfc.scriptSetup.lang });
}
return names;
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
const script = embeddedFile.id === 'script_raw' ? sfc.script
: embeddedFile.id === 'scriptsetup_raw' ? sfc.scriptSetup
: undefined;
if (script) {
embeddedFile.content.push([
script.content,
script.name,
0,
{
structure: true,
format: true,
},
]);
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-sfc-scripts.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const shared_1 = require("./shared");
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
const result = [];
for (let i = 0; i < sfc.styles.length; i++) {
const style = sfc.styles[i];
if (style) {
result.push({
id: 'style_' + i,
lang: style.lang,
});
if (style.cssVars.length) {
result.push({
id: 'style_' + i + '_inline_ts',
lang: 'ts',
});
}
}
}
return result;
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id.startsWith('style_')) {
const index = parseInt(embeddedFile.id.split('_')[1]);
const style = sfc.styles[index];
if (embeddedFile.id.endsWith('_inline_ts')) {
embeddedFile.parentCodeId = 'style_' + index;
for (const cssVar of style.cssVars) {
embeddedFile.content.push('(', [
cssVar.text,
style.name,
cssVar.offset,
shared_1.allCodeFeatures,
], ');\n');
}
}
else {
embeddedFile.content.push([
style.content,
style.name,
0,
shared_1.allCodeFeatures,
]);
}
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-sfc-styles.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const shared_1 = require("./shared");
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
if (sfc.template?.lang === 'html') {
return [{
id: 'template',
lang: sfc.template.lang,
}];
}
return [];
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id === 'template' && sfc.template?.lang === 'html') {
embeddedFile.content.push([
sfc.template.content,
sfc.template.name,
0,
shared_1.allCodeFeatures,
]);
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-sfc-template.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,197 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const shouldAddSuffix = /(?<=<[^>/]+)$/;
const plugin = ({ modules }) => {
return {
version: 2.1,
compileSFCTemplate(lang, template, options) {
if (lang === 'html' || lang === 'md') {
const compiler = modules['@vue/compiler-dom'];
let addedSuffix = false;
// #4583
if (shouldAddSuffix.test(template)) {
template += '>';
addedSuffix = true;
}
const result = compiler.compile(template, {
...options,
comments: true,
});
// @ts-expect-error
result.__addedSuffix = addedSuffix;
return result;
}
},
updateSFCTemplate(oldResult, change) {
oldResult.code = oldResult.code.slice(0, change.start)
+ change.newText
+ oldResult.code.slice(change.end);
// @ts-expect-error
if (oldResult.__addedSuffix) {
const originalTemplate = oldResult.code.slice(0, -1); // remove added '>'
if (!shouldAddSuffix.test(originalTemplate)) {
return undefined;
}
}
const CompilerDOM = modules['@vue/compiler-dom'];
const lengthDiff = change.newText.length - (change.end - change.start);
let hitNodes = [];
if (tryUpdateNode(oldResult.ast) && hitNodes.length) {
hitNodes = hitNodes.sort((a, b) => a.loc.source.length - b.loc.source.length);
const hitNode = hitNodes[0];
if (hitNode.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
return oldResult;
}
}
function tryUpdateNode(node) {
if (withinChangeRange(node.loc)) {
hitNodes.push(node);
}
if (tryUpdateNodeLoc(node.loc)) {
if (node.type === CompilerDOM.NodeTypes.ROOT) {
for (const child of node.children) {
if (!tryUpdateNode(child)) {
return false;
}
}
}
else if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
if (withinChangeRange(node.loc)) {
// if not self closing, should not hit tag name
const start = node.loc.start.offset + 2;
const end = node.loc.start.offset + node.loc.source.lastIndexOf('</');
if (!withinChangeRange({ start: { offset: start }, end: { offset: end }, source: '' })) {
return false;
}
}
for (const prop of node.props) {
if (!tryUpdateNode(prop)) {
return false;
}
}
for (const child of node.children) {
if (!tryUpdateNode(child)) {
return false;
}
}
}
else if (node.type === CompilerDOM.NodeTypes.ATTRIBUTE) {
if (node.value && !tryUpdateNode(node.value)) {
return false;
}
}
else if (node.type === CompilerDOM.NodeTypes.DIRECTIVE) {
if (node.arg && withinChangeRange(node.arg.loc) && node.name === 'slot') {
return false;
}
if (node.exp && withinChangeRange(node.exp.loc) && node.name === 'for') { // #2266
return false;
}
if (node.arg && !tryUpdateNode(node.arg)) {
return false;
}
if (node.exp && !tryUpdateNode(node.exp)) {
return false;
}
}
else if (node.type === CompilerDOM.NodeTypes.TEXT_CALL) {
if (!tryUpdateNode(node.content)) {
return false;
}
}
else if (node.type === CompilerDOM.NodeTypes.COMPOUND_EXPRESSION) {
for (const childNode of node.children) {
if (typeof childNode === 'object') {
if (!tryUpdateNode(childNode)) {
return false;
}
}
}
}
else if (node.type === CompilerDOM.NodeTypes.IF) {
for (const branch of node.branches) {
if (branch.condition && !tryUpdateNode(branch.condition)) {
return false;
}
for (const child of branch.children) {
if (!tryUpdateNode(child)) {
return false;
}
}
}
}
else if (node.type === CompilerDOM.NodeTypes.FOR) {
for (const child of [
node.parseResult.source,
node.parseResult.value,
node.parseResult.key,
node.parseResult.index,
]) {
if (child) {
if (!tryUpdateNode(child)) {
return false;
}
if (child.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
const content = child.content.trim();
if (content.startsWith('(') || content.endsWith(')')) {
return false;
}
}
}
}
for (const child of node.children) {
if (!tryUpdateNode(child)) {
return false;
}
}
}
else if (node.type === CompilerDOM.NodeTypes.INTERPOLATION) {
if (!tryUpdateNode(node.content)) {
return false;
}
}
else if (node.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
if (withinChangeRange(node.loc)) { // TODO: review this (slot name?)
if (node.isStatic) {
return false;
}
else {
node.content = node.loc.source;
}
}
}
return true;
}
return false;
}
function tryUpdateNodeLoc(loc) {
delete loc.__endOffset;
if (withinChangeRange(loc)) {
loc.source =
loc.source.substring(0, change.start - loc.start.offset)
+ change.newText
+ loc.source.substring(change.end - loc.start.offset);
loc.__endOffset = loc.end.offset;
loc.end.offset += lengthDiff;
return true;
}
else if (change.end <= loc.start.offset) {
loc.__endOffset = loc.end.offset;
loc.start.offset += lengthDiff;
loc.end.offset += lengthDiff;
return true;
}
else if (change.start >= loc.end.offset) {
return true; // no need update
}
return false;
}
function withinChangeRange(loc) {
const originalLocEnd = loc.__endOffset ?? loc.end.offset;
return change.start >= loc.start.offset && change.end <= originalLocEnd;
}
},
};
};
exports.default = plugin;
//# sourceMappingURL=vue-template-html.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CompilerDOM = require("@vue/compiler-dom");
const template_1 = require("../codegen/template");
const shared_1 = require("./shared");
const codeFeatures = {
...shared_1.allCodeFeatures,
format: false,
structure: false,
};
const plugin = () => {
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
if (!sfc.template?.ast) {
return [];
}
return [{ id: 'template_inline_css', lang: 'css' }];
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id !== 'template_inline_css' || !sfc.template?.ast) {
return;
}
embeddedFile.parentCodeId = 'template';
embeddedFile.content.push(...generate(sfc.template.ast));
},
};
};
exports.default = plugin;
function* generate(templateAst) {
for (const node of (0, template_1.forEachElementNode)(templateAst)) {
for (const prop of node.props) {
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE
&& prop.name === 'bind'
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.arg.content === 'style'
&& prop.exp.constType === CompilerDOM.ConstantTypes.CAN_STRINGIFY) {
const endCrt = prop.arg.loc.source[prop.arg.loc.source.length - 1]; // " | '
const start = prop.arg.loc.source.indexOf(endCrt) + 1;
const end = prop.arg.loc.source.lastIndexOf(endCrt);
const content = prop.arg.loc.source.substring(start, end);
yield `x { `;
yield [
content,
'template',
prop.arg.loc.start.offset + start,
codeFeatures,
];
yield ` }\n`;
}
}
}
}
//# sourceMappingURL=vue-template-inline-css.js.map

View File

@@ -0,0 +1,3 @@
import type { VueLanguagePlugin } from '../types';
declare const plugin: VueLanguagePlugin;
export default plugin;

View File

@@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("../codegen/common");
const elementEvents_1 = require("../codegen/template/elementEvents");
const templateChild_1 = require("../codegen/template/templateChild");
const vFor_1 = require("../codegen/template/vFor");
const CompilerDOM = require("@vue/compiler-dom");
const codeFeatures = {
format: true,
};
const formatBrackets = {
normal: ['`${', '}`;'],
if: ['if (', ') { }'],
for: ['for (', ') { }'],
// fix https://github.com/vuejs/language-tools/issues/3572
params: ['(', ') => {};'],
// fix https://github.com/vuejs/language-tools/issues/1210
// fix https://github.com/vuejs/language-tools/issues/2305
curly: ['0 +', '+ 0;'],
event: ['() => ', ';'],
};
const plugin = ctx => {
const parseds = new WeakMap();
return {
version: 2.1,
getEmbeddedCodes(_fileName, sfc) {
if (!sfc.template?.ast) {
return [];
}
const parsed = parse(sfc);
parseds.set(sfc, parsed);
const result = [];
for (const [id] of parsed) {
result.push({ id, lang: 'ts' });
}
return result;
},
resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
// access template content to watch change
(() => sfc.template?.content)();
const parsed = parseds.get(sfc);
if (parsed) {
const codes = parsed.get(embeddedFile.id);
if (codes) {
embeddedFile.content.push(...codes);
embeddedFile.parentCodeId = 'template';
}
}
},
};
function parse(sfc) {
const data = new Map();
if (!sfc.template?.ast) {
return data;
}
const templateContent = sfc.template.content;
let i = 0;
sfc.template.ast.children.forEach(visit);
return data;
function visit(node) {
if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
for (const prop of node.props) {
if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE) {
continue;
}
const isShorthand = prop.arg?.loc.start.offset === prop.exp?.loc.start.offset; // vue 3.4+
if (isShorthand) {
continue;
}
if (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && !prop.arg.isStatic) {
addFormatCodes(prop.arg.content, prop.arg.loc.start.offset, formatBrackets.normal);
}
if (prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
&& prop.exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY // style='z-index: 2' will compile to {'z-index':'2'}
) {
if (prop.name === 'on' && prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
const ast = (0, common_1.createTsAst)(ctx.modules.typescript, prop.exp, prop.exp.content);
addFormatCodes(prop.exp.content, prop.exp.loc.start.offset, (0, elementEvents_1.isCompoundExpression)(ctx.modules.typescript, ast)
? formatBrackets.event
: formatBrackets.normal);
}
else {
addFormatCodes(prop.exp.content, prop.exp.loc.start.offset, formatBrackets.normal);
}
}
}
for (const child of node.children) {
visit(child);
}
}
else if (node.type === CompilerDOM.NodeTypes.IF) {
for (let i = 0; i < node.branches.length; i++) {
const branch = node.branches[i];
if (branch.condition?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
addFormatCodes(branch.condition.content, branch.condition.loc.start.offset, formatBrackets.if);
}
for (const childNode of branch.children) {
visit(childNode);
}
}
}
else if (node.type === CompilerDOM.NodeTypes.FOR) {
const { leftExpressionRange, leftExpressionText } = (0, vFor_1.parseVForNode)(node);
const { source } = node.parseResult;
if (leftExpressionRange && leftExpressionText && source.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) {
const start = leftExpressionRange.start;
const end = source.loc.start.offset + source.content.length;
addFormatCodes(templateContent.substring(start, end), start, formatBrackets.for);
}
for (const child of node.children) {
visit(child);
}
}
else if (node.type === CompilerDOM.NodeTypes.TEXT_CALL) {
// {{ var }}
visit(node.content);
}
else if (node.type === CompilerDOM.NodeTypes.COMPOUND_EXPRESSION) {
// {{ ... }} {{ ... }}
for (const childNode of node.children) {
if (typeof childNode === 'object') {
visit(childNode);
}
}
}
else if (node.type === CompilerDOM.NodeTypes.INTERPOLATION) {
// {{ ... }}
const [content, start] = (0, templateChild_1.parseInterpolationNode)(node, templateContent);
const lines = content.split('\n');
addFormatCodes(content, start, lines.length <= 1 ? formatBrackets.curly : [
lines[0].trim() === '' ? '(' : formatBrackets.curly[0],
lines[lines.length - 1].trim() === '' ? ');' : formatBrackets.curly[1],
]);
}
}
function addFormatCodes(code, offset, wrapper) {
const id = 'template_inline_ts_' + i++;
data.set(id, [
wrapper[0],
[
code,
'template',
offset,
codeFeatures,
],
wrapper[1],
]);
}
}
};
exports.default = plugin;
//# sourceMappingURL=vue-template-inline-ts.js.map

View File

@@ -0,0 +1,174 @@
import type { Mapping } from '@volar/language-core';
import type { Code, Sfc, VueLanguagePlugin } from '../types';
export declare const tsCodegen: WeakMap<Sfc, {
scriptRanges: import("alien-signals").ISignal<{
exportDefault: (import("../types").TextRange & {
expression: import("../types").TextRange;
args: import("../types").TextRange;
argsNode: import("typescript").ObjectLiteralExpression | undefined;
componentsOption: import("../types").TextRange | undefined;
componentsOptionNode: import("typescript").ObjectLiteralExpression | undefined;
directivesOption: import("../types").TextRange | undefined;
nameOption: import("../types").TextRange | undefined;
inheritAttrsOption: string | undefined;
}) | undefined;
classBlockEnd: number | undefined;
bindings: import("../types").TextRange[];
} | undefined>;
scriptSetupRanges: import("alien-signals").ISignal<{
leadingCommentEndOffset: number;
importSectionEndOffset: number;
bindings: import("../types").TextRange[];
importComponentNames: Set<string>;
props: {
name?: string;
destructured?: Set<string>;
destructuredRest?: string;
define?: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}> & {
statement: import("../types").TextRange;
};
withDefaults?: import("../types").TextRange & {
arg?: import("../types").TextRange;
};
};
slots: {
name?: string;
isObjectBindingPattern?: boolean;
define?: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}> & {
statement: import("../types").TextRange;
};
};
emits: {
name?: string;
define?: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}> & {
statement: import("../types").TextRange;
hasUnionTypeArg?: boolean;
};
};
expose: {
name?: string;
define?: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}>;
};
options: {
name?: string;
inheritAttrs?: string;
};
cssModules: {
define: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}>;
}[];
defineProp: {
localName: import("../types").TextRange | undefined;
name: import("../types").TextRange | undefined;
type: import("../types").TextRange | undefined;
modifierType?: import("../types").TextRange | undefined;
runtimeType: import("../types").TextRange | undefined;
defaultValue: import("../types").TextRange | undefined;
required: boolean;
isModel?: boolean;
}[];
templateRefs: {
name?: string;
define: ReturnType<(node: import("typescript").CallExpression) => import("../types").TextRange & {
exp: import("../types").TextRange;
arg?: import("../types").TextRange;
typeArg?: import("../types").TextRange;
}>;
}[];
} | undefined>;
lang: import("alien-signals").ISignal<string>;
generatedScript: import("alien-signals").ISignal<{
codes: Code[];
linkedCodeMappings: Mapping<unknown>[];
generatedTemplate: boolean;
generatedPropsType: boolean;
scriptSetupGeneratedOffset: number | undefined;
bypassDefineComponent: boolean;
bindingNames: Set<string>;
localTypes: {
generate: (names: string[]) => Generator<string, void, unknown>;
getUsedNames(): Set<string>;
readonly PrettifyLocal: string;
readonly OmitKeepDiscriminatedUnion: string;
readonly WithDefaults: string;
readonly WithTemplateSlots: string;
readonly PropsChildren: string;
readonly TypePropsToOption: string;
readonly OmitIndexSignature: string;
};
inlayHints: import("../codegen/inlayHints").InlayHintInfo[];
}>;
generatedTemplate: import("alien-signals").ISignal<{
codes: Code[];
slots: {
name: string;
loc?: number;
tagRange: [number, number];
varName: string;
nodeLoc: any;
}[];
dynamicSlots: {
expVar: string;
varName: string;
}[];
codeFeatures: {
all: import("../types").VueCodeInformation;
verification: import("../types").VueCodeInformation;
completion: import("../types").VueCodeInformation;
additionalCompletion: import("../types").VueCodeInformation;
navigation: import("../types").VueCodeInformation;
navigationWithoutRename: import("../types").VueCodeInformation;
navigationAndCompletion: import("../types").VueCodeInformation;
navigationAndAdditionalCompletion: import("../types").VueCodeInformation;
withoutHighlight: import("../types").VueCodeInformation;
withoutHighlightAndCompletion: import("../types").VueCodeInformation;
withoutHighlightAndCompletionAndNavigation: import("../types").VueCodeInformation;
};
accessExternalVariables: Map<string, Set<number>>;
hasSlotElements: Set<import("@vue/compiler-dom").ElementNode>;
blockConditions: string[];
usedComponentCtxVars: Set<string>;
scopedClasses: {
source: string;
className: string;
offset: number;
}[];
emptyClassOffsets: number[];
inlayHints: import("../codegen/inlayHints").InlayHintInfo[];
hasSlot: boolean;
inheritedAttrVars: Set<unknown>;
templateRefs: Map<string, [varName: string, offset: number]>;
singleRootElType: string | undefined;
singleRootNode: import("@vue/compiler-dom").ElementNode | undefined;
accessExternalVariable(name: string, offset?: number): void;
hasLocalVariable: (name: string) => boolean;
addLocalVariable: (name: string) => void;
removeLocalVariable: (name: string) => void;
getInternalVariable: () => string;
ignoreError: () => Generator<Code>;
expectError: (prevNode: import("@vue/compiler-dom").CommentNode) => Generator<Code>;
resetDirectiveComments: (endStr: string) => Generator<Code>;
generateAutoImportCompletion: () => Generator<Code>;
} | undefined>;
}>;
declare const plugin: VueLanguagePlugin;
export default plugin;

198
node_modules/@vue/language-core/lib/plugins/vue-tsx.js generated vendored Normal file
View File

@@ -0,0 +1,198 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tsCodegen = void 0;
const alien_signals_1 = require("alien-signals");
const script_1 = require("../codegen/script");
const template_1 = require("../codegen/template");
const scriptRanges_1 = require("../parsers/scriptRanges");
const scriptSetupRanges_1 = require("../parsers/scriptSetupRanges");
exports.tsCodegen = new WeakMap();
const fileEditTimes = new Map();
const plugin = ctx => {
let appendedGlobalTypes = false;
return {
version: 2.1,
requiredCompilerOptions: [
'noPropertyAccessFromIndexSignature',
'exactOptionalPropertyTypes',
],
getEmbeddedCodes(fileName, sfc) {
const tsx = useTsx(fileName, sfc);
const files = [];
if (['js', 'ts', 'jsx', 'tsx'].includes(tsx.lang.get())) {
files.push({ id: 'script_' + tsx.lang.get(), lang: tsx.lang.get() });
}
return files;
},
resolveEmbeddedCode(fileName, sfc, embeddedFile) {
const _tsx = useTsx(fileName, sfc);
if (/script_(js|jsx|ts|tsx)/.test(embeddedFile.id)) {
const tsx = _tsx.generatedScript.get();
if (tsx) {
const content = [...tsx.codes];
embeddedFile.content = content;
embeddedFile.linkedCodeMappings = [...tsx.linkedCodeMappings];
}
}
},
};
function useTsx(fileName, sfc) {
if (!exports.tsCodegen.has(sfc)) {
let appendGlobalTypes = false;
if (!ctx.vueCompilerOptions.__setupedGlobalTypes && !appendedGlobalTypes) {
appendGlobalTypes = true;
appendedGlobalTypes = true;
}
exports.tsCodegen.set(sfc, createTsx(fileName, sfc, ctx, appendGlobalTypes));
}
return exports.tsCodegen.get(sfc);
}
};
exports.default = plugin;
function createTsx(fileName, _sfc, ctx, appendGlobalTypes) {
const ts = ctx.modules.typescript;
const lang = (0, alien_signals_1.computed)(() => {
return !_sfc.script && !_sfc.scriptSetup ? 'ts'
: _sfc.scriptSetup && _sfc.scriptSetup.lang !== 'js' ? _sfc.scriptSetup.lang
: _sfc.script && _sfc.script.lang !== 'js' ? _sfc.script.lang
: 'js';
});
const scriptRanges = (0, alien_signals_1.computed)(() => _sfc.script
? (0, scriptRanges_1.parseScriptRanges)(ts, _sfc.script.ast, !!_sfc.scriptSetup, false)
: undefined);
const scriptSetupRanges = (0, alien_signals_1.computed)(() => _sfc.scriptSetup
? (0, scriptSetupRanges_1.parseScriptSetupRanges)(ts, _sfc.scriptSetup.ast, ctx.vueCompilerOptions)
: undefined);
const generatedTemplate = (0, alien_signals_1.computed)(() => {
if (ctx.vueCompilerOptions.skipTemplateCodegen || !_sfc.template) {
return;
}
const codes = [];
const codegen = (0, template_1.generateTemplate)({
ts,
compilerOptions: ctx.compilerOptions,
vueCompilerOptions: ctx.vueCompilerOptions,
template: _sfc.template,
edited: ctx.vueCompilerOptions.__test || (fileEditTimes.get(fileName) ?? 0) >= 2,
scriptSetupBindingNames: scriptSetupBindingNames.get(),
scriptSetupImportComponentNames: scriptSetupImportComponentNames.get(),
destructuredPropNames: destructuredPropNames.get(),
templateRefNames: templateRefNames.get(),
hasDefineSlots: hasDefineSlots.get(),
slotsAssignName: slotsAssignName.get(),
propsAssignName: propsAssignName.get(),
inheritAttrs: inheritAttrs.get(),
});
let current = codegen.next();
while (!current.done) {
const code = current.value;
codes.push(code);
current = codegen.next();
}
return {
...current.value,
codes: codes,
};
});
const scriptSetupBindingNames = (0, alien_signals_1.computed)(oldNames => {
const newNames = new Set();
const bindings = scriptSetupRanges.get()?.bindings;
if (_sfc.scriptSetup && bindings) {
for (const binding of bindings) {
newNames.add(_sfc.scriptSetup?.content.substring(binding.start, binding.end));
}
}
if (newNames && oldNames && twoSetsEqual(newNames, oldNames)) {
return oldNames;
}
return newNames;
});
const scriptSetupImportComponentNames = (0, alien_signals_1.computed)(oldNames => {
const newNames = scriptSetupRanges.get()?.importComponentNames ?? new Set();
if (oldNames && twoSetsEqual(newNames, oldNames)) {
return oldNames;
}
return newNames;
});
const destructuredPropNames = (0, alien_signals_1.computed)(oldNames => {
const newNames = scriptSetupRanges.get()?.props.destructured ?? new Set();
const rest = scriptSetupRanges.get()?.props.destructuredRest;
if (rest) {
newNames.add(rest);
}
if (oldNames && twoSetsEqual(newNames, oldNames)) {
return oldNames;
}
return newNames;
});
const templateRefNames = (0, alien_signals_1.computed)(oldNames => {
const newNames = new Set(scriptSetupRanges.get()?.templateRefs
.map(({ name }) => name)
.filter(name => name !== undefined));
if (oldNames && twoSetsEqual(newNames, oldNames)) {
return oldNames;
}
return newNames;
});
const hasDefineSlots = (0, alien_signals_1.computed)(() => !!scriptSetupRanges.get()?.slots.define);
const slotsAssignName = (0, alien_signals_1.computed)(() => scriptSetupRanges.get()?.slots.name);
const propsAssignName = (0, alien_signals_1.computed)(() => scriptSetupRanges.get()?.props.name);
const inheritAttrs = (0, alien_signals_1.computed)(() => {
const value = scriptSetupRanges.get()?.options.inheritAttrs ?? scriptRanges.get()?.exportDefault?.inheritAttrsOption;
return value !== 'false';
});
const generatedScript = (0, alien_signals_1.computed)(() => {
const codes = [];
const linkedCodeMappings = [];
let generatedLength = 0;
const codegen = (0, script_1.generateScript)({
ts,
fileName,
sfc: _sfc,
lang: lang.get(),
scriptRanges: scriptRanges.get(),
scriptSetupRanges: scriptSetupRanges.get(),
templateCodegen: generatedTemplate.get(),
compilerOptions: ctx.compilerOptions,
vueCompilerOptions: ctx.vueCompilerOptions,
edited: ctx.vueCompilerOptions.__test || (fileEditTimes.get(fileName) ?? 0) >= 2,
getGeneratedLength: () => generatedLength,
linkedCodeMappings,
appendGlobalTypes,
});
fileEditTimes.set(fileName, (fileEditTimes.get(fileName) ?? 0) + 1);
let current = codegen.next();
while (!current.done) {
const code = current.value;
codes.push(code);
generatedLength += typeof code === 'string'
? code.length
: code[0].length;
current = codegen.next();
}
return {
...current.value,
codes,
linkedCodeMappings,
};
});
return {
scriptRanges,
scriptSetupRanges,
lang,
generatedScript,
generatedTemplate,
};
}
function twoSetsEqual(a, b) {
if (a.size !== b.size) {
return false;
}
for (const file of a) {
if (!b.has(file)) {
return false;
}
}
return true;
}
//# sourceMappingURL=vue-tsx.js.map