extends true ? B : A;
@@ -65,7 +60,11 @@ export function generateGlobalTypes(options: VueCompilerOptions) {
? K extends { __ctx?: { props?: infer P } } ? NonNullable : never
: T extends (props: infer P, ...args: any) => any ? P
: {};
- type __VLS_FunctionalComponent = (props: ${fnPropsType}, ctx?: any) => __VLS_Element & {
+ type __VLS_FunctionalComponent = (props: ${fnPropsType}, ctx?: any) => ${
+ target >= 3.3
+ ? `import('${lib}/jsx-runtime').JSX.Element`
+ : `globalThis.JSX.Element`
+ } & {
__ctx?: {
attrs?: any;
slots?: T extends { $slots: infer Slots } ? Slots : Record;
diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts
index 526a757037..f0e2f937c7 100644
--- a/packages/language-core/lib/codegen/script/template.ts
+++ b/packages/language-core/lib/codegen/script/template.ts
@@ -20,7 +20,6 @@ export function* generateTemplate(
yield* generateSelf(options);
yield* generateTemplateCtx(options, ctx);
- yield* generateTemplateElements();
yield* generateTemplateComponents(options);
yield* generateTemplateDirectives(options);
yield* generateTemplateBody(options, ctx);
@@ -109,10 +108,6 @@ function* generateTemplateCtx(
yield endOfLine;
}
-function* generateTemplateElements(): Generator {
- yield `let __VLS_elements!: __VLS_IntrinsicElements${endOfLine}`;
-}
-
function* generateTemplateComponents(options: ScriptCodegenOptions): Generator {
const types: string[] = [`typeof __VLS_ctx`];
diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts
index 247f357708..fb60ea595d 100644
--- a/packages/language-core/lib/codegen/template/element.ts
+++ b/packages/language-core/lib/codegen/template/element.ts
@@ -292,7 +292,7 @@ export function* generateElement(
const [startTagOffset, endTagOffset] = getElementTagOffsets(node, options.template);
const failedPropExps: FailedPropExpression[] = [];
- yield `__VLS_asFunctionalElement(__VLS_elements`;
+ yield `__VLS_asFunctionalElement(__VLS_intrinsics`;
yield* generatePropertyAccess(
options,
ctx,
@@ -301,7 +301,7 @@ export function* generateElement(
codeFeatures.withoutHighlightAndCompletion,
);
if (endTagOffset !== undefined) {
- yield `, __VLS_elements`;
+ yield `, __VLS_intrinsics`;
yield* generatePropertyAccess(
options,
ctx,
@@ -334,18 +334,18 @@ export function* generateElement(
const reference = yield* generateElementReference(options, ctx, node);
if (reference) {
- let typeExp = `__VLS_NativeElements['${node.tag}']`;
+ let typeExp = `__VLS_Elements['${node.tag}']`;
if (ctx.inVFor) {
typeExp += `[]`;
}
ctx.addTemplateRef(reference.name, typeExp, reference.offset);
}
if (ctx.singleRootNodes.has(node)) {
- ctx.singleRootElTypes.push(`__VLS_NativeElements['${node.tag}']`);
+ ctx.singleRootElTypes.push(`__VLS_Elements['${node.tag}']`);
}
if (hasVBindAttrs(options, ctx, node)) {
- ctx.inheritedAttrVars.add(`__VLS_elements.${node.tag}`);
+ ctx.inheritedAttrVars.add(`__VLS_intrinsics.${node.tag}`);
}
collectStyleScopedClassReferences(options, ctx, node);
diff --git a/packages/language-core/package.json b/packages/language-core/package.json
index f5699e9a1c..6a1bee9959 100644
--- a/packages/language-core/package.json
+++ b/packages/language-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/language-core",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"**/*.js",
diff --git a/packages/language-plugin-pug/package.json b/packages/language-plugin-pug/package.json
index 99c7b229e5..63302fe4ae 100644
--- a/packages/language-plugin-pug/package.json
+++ b/packages/language-plugin-pug/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/language-plugin-pug",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"**/*.js",
@@ -19,6 +19,6 @@
"devDependencies": {
"@types/node": "^22.10.4",
"@vue/compiler-dom": "^3.5.0",
- "@vue/language-core": "3.1.2"
+ "@vue/language-core": "3.1.3"
}
}
diff --git a/packages/language-server/package.json b/packages/language-server/package.json
index d6c6d09776..490951917f 100644
--- a/packages/language-server/package.json
+++ b/packages/language-server/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/language-server",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"**/*.js",
@@ -17,9 +17,9 @@
},
"dependencies": {
"@volar/language-server": "2.4.23",
- "@vue/language-core": "3.1.2",
- "@vue/language-service": "3.1.2",
- "@vue/typescript-plugin": "3.1.2",
+ "@vue/language-core": "3.1.3",
+ "@vue/language-service": "3.1.3",
+ "@vue/typescript-plugin": "3.1.3",
"vscode-uri": "^3.0.8"
},
"peerDependencies": {
diff --git a/packages/language-service/package.json b/packages/language-service/package.json
index c930afd574..c96ac6cb80 100644
--- a/packages/language-service/package.json
+++ b/packages/language-service/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/language-service",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"data",
@@ -18,7 +18,7 @@
},
"dependencies": {
"@volar/language-service": "2.4.23",
- "@vue/language-core": "3.1.2",
+ "@vue/language-core": "3.1.3",
"@vue/shared": "^3.5.0",
"path-browserify": "^1.0.1",
"volar-service-css": "0.0.65",
@@ -37,7 +37,7 @@
"@volar/kit": "2.4.23",
"@volar/typescript": "2.4.23",
"@vue/compiler-dom": "^3.5.0",
- "@vue/typescript-plugin": "3.1.2",
+ "@vue/typescript-plugin": "3.1.3",
"vscode-css-languageservice": "^6.3.1"
}
}
diff --git a/packages/tsc/package.json b/packages/tsc/package.json
index a39cbf2eac..b63372eb0f 100644
--- a/packages/tsc/package.json
+++ b/packages/tsc/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-tsc",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"bin",
@@ -21,7 +21,7 @@
},
"dependencies": {
"@volar/typescript": "2.4.23",
- "@vue/language-core": "3.1.2"
+ "@vue/language-core": "3.1.3"
},
"devDependencies": {
"@types/node": "^22.10.4"
diff --git a/packages/typescript-plugin/index.ts b/packages/typescript-plugin/index.ts
index 55724d9c78..41ef3e3967 100644
--- a/packages/typescript-plugin/index.ts
+++ b/packages/typescript-plugin/index.ts
@@ -163,12 +163,12 @@ export = createLanguageServicePlugin(
session.addProtocolHandler('_vue:getElementAttrs', request => {
const [fileName, tag]: Parameters = request.arguments;
const { project } = getProject(fileName);
- return createResponse(getElementAttrs(ts, project.getLanguageService().getProgram()!, fileName, tag));
+ return createResponse(getElementAttrs(ts, project.getLanguageService().getProgram()!, tag));
});
session.addProtocolHandler('_vue:getElementNames', request => {
const [fileName]: Parameters = request.arguments;
const { project } = getProject(fileName);
- return createResponse(getElementNames(ts, project.getLanguageService().getProgram()!, fileName));
+ return createResponse(getElementNames(ts, project.getLanguageService().getProgram()!));
});
projectService.logger.info('Vue specific commands are successfully added.');
diff --git a/packages/typescript-plugin/lib/common.ts b/packages/typescript-plugin/lib/common.ts
index 796996f7d2..1207c58be6 100644
--- a/packages/typescript-plugin/lib/common.ts
+++ b/packages/typescript-plugin/lib/common.ts
@@ -14,6 +14,8 @@ export function createVueLanguageServiceProxy(
const proxyCache = new Map();
const getProxyMethod = (target: ts.LanguageService, p: string | symbol): Function | undefined => {
switch (p) {
+ case 'findReferences':
+ return findReferences(ts, language, languageService, asScriptId, target[p]);
case 'getCompletionsAtPosition':
return getCompletionsAtPosition(ts, language, asScriptId, vueOptions, target[p]);
case 'getCompletionEntryDetails':
@@ -21,7 +23,7 @@ export function createVueLanguageServiceProxy(
case 'getCodeFixesAtPosition':
return getCodeFixesAtPosition(target[p]);
case 'getDefinitionAndBoundSpan':
- return getDefinitionAndBoundSpan(ts, language, asScriptId, languageService, vueOptions, target[p]);
+ return getDefinitionAndBoundSpan(ts, language, asScriptId, target[p]);
}
};
@@ -42,6 +44,56 @@ export function createVueLanguageServiceProxy(
});
}
+function findReferences(
+ ts: typeof import('typescript'),
+ language: Language,
+ languageService: ts.LanguageService,
+ asScriptId: (fileName: string) => T,
+ findReferences: ts.LanguageService['findReferences'],
+): ts.LanguageService['findReferences'] {
+ return (fileName, position) => {
+ const result = findReferences(fileName, position);
+
+ const sourceScript = language.scripts.get(asScriptId(fileName));
+ const root = sourceScript?.generated?.root;
+ if (!(root instanceof VueVirtualCode)) {
+ return result;
+ }
+
+ const { template } = root.sfc;
+ if (template) {
+ const textSpan = {
+ start: template.start + 1,
+ length: 'template'.length,
+ };
+ if (position >= textSpan.start && position <= textSpan.start + textSpan.length) {
+ result?.push({
+ definition: {
+ fileName,
+ textSpan,
+ kind: ts.ScriptElementKind.scriptElement,
+ name: fileName,
+ containerKind: ts.ScriptElementKind.unknown,
+ containerName: '',
+ displayParts: [],
+ },
+ references: [
+ {
+ fileName,
+ textSpan,
+ isDefinition: true,
+ isWriteAccess: false,
+ },
+ ...languageService.getFileReferences(fileName),
+ ],
+ });
+ }
+ }
+
+ return result;
+ };
+}
+
function getCompletionsAtPosition(
ts: typeof import('typescript'),
language: Language,
@@ -193,25 +245,39 @@ function getDefinitionAndBoundSpan(
ts: typeof import('typescript'),
language: Language,
asScriptId: (fileName: string) => T,
- languageService: ts.LanguageService,
- vueOptions: VueCompilerOptions,
getDefinitionAndBoundSpan: ts.LanguageService['getDefinitionAndBoundSpan'],
): ts.LanguageService['getDefinitionAndBoundSpan'] {
return (fileName, position) => {
const result = getDefinitionAndBoundSpan(fileName, position);
- if (!result?.definitions?.length) {
- return result;
- }
- const program = languageService.getProgram()!;
const sourceScript = language.scripts.get(asScriptId(fileName));
- if (!sourceScript?.generated) {
+ const root = sourceScript?.generated?.root;
+ if (!(root instanceof VueVirtualCode)) {
return result;
}
- const root = sourceScript.generated.root;
- if (!(root instanceof VueVirtualCode)) {
- return result;
+ if (!result?.definitions?.length) {
+ const { template } = root.sfc;
+ if (template) {
+ const textSpan = {
+ start: template.start + 1,
+ length: 'template'.length,
+ };
+ if (position >= textSpan.start && position <= textSpan.start + textSpan.length) {
+ return {
+ textSpan,
+ definitions: [{
+ fileName,
+ textSpan,
+ kind: ts.ScriptElementKind.scriptElement,
+ name: fileName,
+ containerKind: ts.ScriptElementKind.unknown,
+ containerName: '',
+ }],
+ };
+ }
+ }
+ return;
}
if (
@@ -223,7 +289,6 @@ function getDefinitionAndBoundSpan(
}
const definitions = new Set(result.definitions);
- const skippedDefinitions: ts.DefinitionInfo[] = [];
// #5275
if (result.definitions.length >= 2) {
@@ -232,75 +297,14 @@ function getDefinitionAndBoundSpan(
root.sfc.content[definition.textSpan.start - 1] === '@'
|| root.sfc.content.slice(definition.textSpan.start - 5, definition.textSpan.start) === 'v-on:'
) {
- skippedDefinitions.push(definition);
+ definitions.delete(definition);
}
}
}
- for (const definition of result.definitions) {
- if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
- continue;
- }
-
- const sourceFile = program.getSourceFile(definition.fileName);
- if (!sourceFile) {
- continue;
- }
-
- visit(sourceFile, definition, sourceFile);
- }
-
- for (const definition of skippedDefinitions) {
- definitions.delete(definition);
- }
-
return {
definitions: [...definitions],
textSpan: result.textSpan,
};
-
- function visit(
- node: ts.Node,
- definition: ts.DefinitionInfo,
- sourceFile: ts.SourceFile,
- ) {
- if (ts.isPropertySignature(node) && node.type) {
- proxy(node.name, node.type, definition, sourceFile);
- }
- else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.type && !node.initializer) {
- proxy(node.name, node.type, definition, sourceFile);
- }
- else {
- ts.forEachChild(node, child => visit(child, definition, sourceFile));
- }
- }
-
- function proxy(
- name: ts.PropertyName,
- type: ts.TypeNode,
- definition: ts.DefinitionInfo,
- sourceFile: ts.SourceFile,
- ) {
- const { textSpan, fileName } = definition;
- const start = name.getStart(sourceFile);
- const end = name.getEnd();
-
- if (start !== textSpan.start || end - start !== textSpan.length) {
- return;
- }
-
- if (!ts.isIndexedAccessTypeNode(type)) {
- return;
- }
-
- const pos = type.indexType.getStart(sourceFile);
- const res = getDefinitionAndBoundSpan(fileName, pos);
- if (res?.definitions?.length) {
- for (const definition of res.definitions) {
- definitions.add(definition);
- }
- skippedDefinitions.push(definition);
- }
- }
};
}
diff --git a/packages/typescript-plugin/lib/requests/getElementAttrs.ts b/packages/typescript-plugin/lib/requests/getElementAttrs.ts
index fbfeceb4d0..e6d70995b5 100644
--- a/packages/typescript-plugin/lib/requests/getElementAttrs.ts
+++ b/packages/typescript-plugin/lib/requests/getElementAttrs.ts
@@ -1,23 +1,20 @@
import type * as ts from 'typescript';
-import { getVariableType } from './utils';
export function getElementAttrs(
ts: typeof import('typescript'),
program: ts.Program,
- fileName: string,
tag: string,
): string[] {
const checker = program.getTypeChecker();
- const elements = getVariableType(ts, program, fileName, '__VLS_elements');
+ const elements = checker.resolveName('__VLS_intrinsics', undefined, ts.SymbolFlags.Variable, false);
if (!elements) {
return [];
}
- const elementType = elements.type.getProperty(tag);
+ const elementType = checker.getTypeOfSymbol(elements).getProperty(tag);
if (!elementType) {
return [];
}
- const attrs = checker.getTypeOfSymbol(elementType).getProperties();
- return attrs.map(c => c.name);
+ return checker.getTypeOfSymbol(elementType).getProperties().map(c => c.name);
}
diff --git a/packages/typescript-plugin/lib/requests/getElementNames.ts b/packages/typescript-plugin/lib/requests/getElementNames.ts
index bb1a793849..ced63b13f6 100644
--- a/packages/typescript-plugin/lib/requests/getElementNames.ts
+++ b/packages/typescript-plugin/lib/requests/getElementNames.ts
@@ -1,14 +1,14 @@
import type * as ts from 'typescript';
-import { getVariableType } from './utils';
export function getElementNames(
ts: typeof import('typescript'),
program: ts.Program,
- fileName: string,
): string[] {
- return getVariableType(ts, program, fileName, '__VLS_elements')
- ?.type
- .getProperties()
- .map(c => c.name)
- ?? [];
+ const checker = program.getTypeChecker();
+ const elements = checker.resolveName('__VLS_intrinsics', undefined, ts.SymbolFlags.Variable, false);
+ if (!elements) {
+ return [];
+ }
+
+ return checker.getTypeOfSymbol(elements).getProperties().map(c => c.name);
}
diff --git a/packages/typescript-plugin/package.json b/packages/typescript-plugin/package.json
index 7aaab7ff74..b8571f2eff 100644
--- a/packages/typescript-plugin/package.json
+++ b/packages/typescript-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/typescript-plugin",
- "version": "3.1.2",
+ "version": "3.1.3",
"license": "MIT",
"files": [
"**/*.js",
@@ -14,7 +14,7 @@
},
"dependencies": {
"@volar/typescript": "2.4.23",
- "@vue/language-core": "3.1.2",
+ "@vue/language-core": "3.1.3",
"@vue/shared": "^3.5.0",
"path-browserify": "^1.0.1"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 11c3ce4659..47305266f4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -60,13 +60,13 @@ importers:
specifier: ^3.5.0
version: 3.5.13
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../../packages/language-core
'@vue/language-server':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../../packages/language-server
'@vue/typescript-plugin':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../../packages/typescript-plugin
laplacenoma:
specifier: ^0.0.3
@@ -84,8 +84,8 @@ importers:
specifier: ^1.0.2
version: 1.0.2
vscode-tmlanguage-snapshot:
- specifier: ^0.1.3
- version: 0.1.3
+ specifier: ^1.0.1
+ version: 1.0.1
packages/component-meta:
dependencies:
@@ -93,7 +93,7 @@ importers:
specifier: 2.4.23
version: 2.4.23
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
path-browserify:
specifier: ^1.0.1
@@ -102,7 +102,7 @@ importers:
specifier: '*'
version: 5.9.2
vue-component-type-helpers:
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../component-type-helpers
devDependencies:
'@types/node':
@@ -173,7 +173,7 @@ importers:
specifier: ^3.5.0
version: 3.5.13
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
packages/language-server:
@@ -182,13 +182,13 @@ importers:
specifier: 2.4.23
version: 2.4.23
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
'@vue/language-service':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-service
'@vue/typescript-plugin':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../typescript-plugin
typescript:
specifier: '*'
@@ -210,7 +210,7 @@ importers:
specifier: 2.4.23
version: 2.4.23
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
'@vue/shared':
specifier: ^3.5.0
@@ -262,7 +262,7 @@ importers:
specifier: ^3.5.0
version: 3.5.13
'@vue/typescript-plugin':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../typescript-plugin
vscode-css-languageservice:
specifier: ^6.3.1
@@ -274,7 +274,7 @@ importers:
specifier: 2.4.23
version: 2.4.23
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
typescript:
specifier: '>=5.0.0'
@@ -290,7 +290,7 @@ importers:
specifier: 2.4.23
version: 2.4.23
'@vue/language-core':
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../language-core
'@vue/shared':
specifier: ^3.5.0
@@ -315,10 +315,10 @@ importers:
specifier: https://pkg.pr.new/vue@e1bc0eb02e22bc0c236e1471c11d96a368764b72
version: https://pkg.pr.new/vue@e1bc0eb02e22bc0c236e1471c11d96a368764b72(typescript@5.9.2)
vue-component-meta:
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../packages/component-meta
vue-component-type-helpers:
- specifier: 3.1.2
+ specifier: 3.1.3
version: link:../packages/component-type-helpers
vue3.4:
specifier: npm:vue@3.4.38
@@ -3624,11 +3624,11 @@ packages:
vscode-oniguruma@2.0.1:
resolution: {integrity: sha512-poJU8iHIWnC3vgphJnrLZyI3YdqRlR27xzqDmpPXYzA93R4Gk8z7T6oqDzDoHjoikA2aS82crdXFkjELCdJsjQ==}
- vscode-textmate@9.2.0:
- resolution: {integrity: sha512-rkvG4SraZQaPSN/5XjwKswdU0OP9MF28QjrYzUBbhb8QyG3ljB1Ky996m++jiI7KdiAP2CkBiQZd9pqEDTClqA==}
+ vscode-textmate@9.2.1:
+ resolution: {integrity: sha512-eXiUi2yYFv9bdvgrYtJynA7UemCEkpVNE50S9iBBA08LYG5t9+/TB+8IRS/YoYOubCez2OkSyZ1Q12eQMwzbrw==}
- vscode-tmlanguage-snapshot@0.1.3:
- resolution: {integrity: sha512-UqBD+5nJgAWNUQZAwBLCgMYn1CNfjoJJm7L1KF04mcpEIf0F7h7x+CTPT6zLAT1CcHV/p4MqosaNVscyi9roSw==}
+ vscode-tmlanguage-snapshot@1.0.1:
+ resolution: {integrity: sha512-8Um3RGrNDR6LfiK/FVETR/o1rwjlxMAphvSff3bxqb20DweJGV/yV6LJLdhImx4MeUg7euAe6JotY+K6UKg+KQ==}
vscode-uri@3.1.0:
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
@@ -7418,12 +7418,12 @@ snapshots:
vscode-oniguruma@2.0.1: {}
- vscode-textmate@9.2.0: {}
+ vscode-textmate@9.2.1: {}
- vscode-tmlanguage-snapshot@0.1.3:
+ vscode-tmlanguage-snapshot@1.0.1:
dependencies:
vscode-oniguruma: 2.0.1
- vscode-textmate: 9.2.0
+ vscode-textmate: 9.2.1
vscode-uri@3.1.0: {}
diff --git a/test-workspace/package.json b/test-workspace/package.json
index a23d475424..2a5121a778 100644
--- a/test-workspace/package.json
+++ b/test-workspace/package.json
@@ -1,11 +1,11 @@
{
"private": true,
- "version": "3.1.2",
+ "version": "3.1.3",
"devDependencies": {
"typescript": "latest",
"vue": "https://pkg.pr.new/vue@e1bc0eb02e22bc0c236e1471c11d96a368764b72",
- "vue-component-meta": "3.1.2",
- "vue-component-type-helpers": "3.1.2",
+ "vue-component-meta": "3.1.3",
+ "vue-component-type-helpers": "3.1.3",
"vue3.4": "npm:vue@3.4.38"
}
}