From d69ea421952a3546e89adfbef9ec13c294d04a77 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 23 Apr 2023 13:57:17 +0800 Subject: [PATCH 1/5] refactor: deprecate `nativeTags` [skip-ci] --- .../src/generators/script.ts | 2 +- .../src/generators/template.ts | 55 +++---------------- packages/vue-language-core/src/types.ts | 1 - .../vue-language-core/src/utils/localTypes.ts | 14 +++-- packages/vue-language-core/src/utils/ts.ts | 33 ----------- .../src/languageServerPlugin.ts | 4 +- packages/vue-language-service/src/helpers.ts | 20 +++---- .../src/ideFeatures/nameCasing.ts | 5 +- .../src/plugins/vue-template.ts | 14 ++--- packages/vue-test-workspace/tsconfig.json | 3 + 10 files changed, 37 insertions(+), 114 deletions(-) diff --git a/packages/vue-language-core/src/generators/script.ts b/packages/vue-language-core/src/generators/script.ts index 2a700dfd9c..a89ad83aa4 100644 --- a/packages/vue-language-core/src/generators/script.ts +++ b/packages/vue-language-core/src/generators/script.ts @@ -812,7 +812,7 @@ declare function defineProp(value?: T | (() => T), required?: boolean, rest?: codes.push('/* Components */\n'); codes.push(`let __VLS_localComponents!: NonNullable & typeof __VLS_componentsOption & typeof __VLS_ctx;\n`); codes.push(`let __VLS_otherComponents!: typeof __VLS_localComponents & import('./__VLS_types').GlobalComponents;\n`); - codes.push(`let __VLS_own!: import('./__VLS_types').SelfComponent { ${getSlotsPropertyName(vueCompilerOptions.target ?? 3)}: typeof __VLS_slots })>;\n`); + codes.push(`let __VLS_own!: import('./__VLS_types').SelfComponent { ${getSlotsPropertyName(vueCompilerOptions.target)}: typeof __VLS_slots })>;\n`); codes.push(`let __VLS_components!: typeof __VLS_otherComponents & Omit;\n`); /* Style Scoped */ diff --git a/packages/vue-language-core/src/generators/template.ts b/packages/vue-language-core/src/generators/template.ts index 61ff32f1a5..2a90f1b3dd 100644 --- a/packages/vue-language-core/src/generators/template.ts +++ b/packages/vue-language-core/src/generators/template.ts @@ -59,7 +59,6 @@ export function generate( cssScopedClasses: string[] = [], ) { - const nativeTags = new Set(vueCompilerOptions.nativeTags); const codes: Code[] = []; const formatCodes: Code[] = []; const cssCodes: Code[] = []; @@ -160,26 +159,18 @@ export function generate( for (const tagName in tagNames) { - if (nativeTags.has(tagName)) - continue; - const isNamespacedTag = tagName.indexOf('.') >= 0; if (isNamespacedTag) continue; - const names = new Set([ - // order is important: https://github.com/johnsoncodehk/volar/issues/2010 - capitalize(camelize(tagName)), - camelize(tagName), - tagName, - ]); const varName = validTsVar.test(tagName) ? tagName : capitalize(camelize(tagName.replace(/:/g, '-'))); codes.push( - '& import("./__VLS_types").WithComponent<"', - varName, - '", typeof __VLS_components, ', - [...names].map(name => `'${name}'`).join(', '), + '& import("./__VLS_types").WithComponent\n', ); @@ -206,7 +197,7 @@ export function generate( for (const name of names) { for (const tagRange of tagRanges) { codes.push( - '__VLS_components', + name === tagName ? '__VLS_templateComponents' : '__VLS_components', ...createPropertyAccessCode([ name, 'template', @@ -493,26 +484,11 @@ export function generate( const propsFailedExps: CompilerDOM.SimpleExpressionNode[] = []; const tagOffsets = endTagOffset !== undefined ? [startTagOffset, endTagOffset] : [startTagOffset]; - const isIntrinsicElement = nativeTags.has(node.tag); const isNamespacedTag = node.tag.indexOf('.') >= 0; const componentVar = `__VLS_${elementIndex++}`; const componentInstanceVar = `__VLS_${elementIndex++}`; - if (isIntrinsicElement) { - codes.push( - 'const ', - componentVar, - ` = (await import('./__VLS_types')).asFunctionalComponent(({} as import('./__VLS_types').IntrinsicElements)[`, - ...createStringLiteralKeyCode([ - node.tag, - 'template', - tagOffsets[0], - capabilitiesPresets.diagnosticOnly, - ]), - ']);\n', - ); - } - else if (isNamespacedTag) { + if (isNamespacedTag) { codes.push( `const ${componentVar} = (await import('./__VLS_types')).asFunctionalComponent(${node.tag}, new ${node.tag}({`, ...createPropsCode(node, 'slots'), @@ -530,22 +506,7 @@ export function generate( } for (const offset of tagOffsets) { - if (isIntrinsicElement) { - codes.push( - `({} as import('./__VLS_types').IntrinsicElements)`, - ...createPropertyAccessCode([ - node.tag, - 'template', - offset, - { - ...capabilitiesPresets.tagReference, - ...capabilitiesPresets.tagHover, - }, - ]), - ';\n', - ); - } - else if (isNamespacedTag) { + if (isNamespacedTag) { codes.push( [node.tag, 'template', [offset, offset + node.tag.length], capabilitiesPresets.all], ';\n', diff --git a/packages/vue-language-core/src/types.ts b/packages/vue-language-core/src/types.ts index c838f9e00c..f086789109 100644 --- a/packages/vue-language-core/src/types.ts +++ b/packages/vue-language-core/src/types.ts @@ -21,7 +21,6 @@ export interface VueCompilerOptions { extensions: string[]; strictTemplates: boolean; skipTemplateCodegen: boolean; - nativeTags: string[]; dataAttributes: string[]; htmlAttributes: string[]; optionsWrapper: [string, string] | []; diff --git a/packages/vue-language-core/src/utils/localTypes.ts b/packages/vue-language-core/src/utils/localTypes.ts index b4cddbefc1..f1be2afc2f 100644 --- a/packages/vue-language-core/src/utils/localTypes.ts +++ b/packages/vue-language-core/src/utils/localTypes.ts @@ -16,7 +16,7 @@ import type { } from '${libName}'; ${vueCompilerOptions.target >= 3.3 ? `import { JSX } from 'vue/jsx-runtime';` : ''} -export type IntrinsicElements = JSX.IntrinsicElements; +export type IntrinsicElements = PickNotAny>; export type Element = JSX.Element; type IsAny = boolean extends (T extends never ? true : false) ? true : false; @@ -58,11 +58,13 @@ export declare function withScope(ctx: T, scope: K): ctx is T & K; export declare function makeOptional(t: T): { [K in keyof T]?: T[K] }; export type SelfComponent = string extends N ? {} : N extends string ? { [P in N]: C } : {}; -export type WithComponent = - N1 extends keyof Components ? { [K in N0]: Components[N1] } : - N2 extends keyof Components ? { [K in N0]: Components[N2] } : - N3 extends keyof Components ? { [K in N0]: Components[N3] } : - ${vueCompilerOptions.strictTemplates ? '{}' : '{ [K in N0]: any }'}; +export type WithComponent = + IsAny extends true ? ( + N1 extends keyof Components ? N1 extends N0 ? Pick : { [K in N0]: Components[N1] } : + N2 extends keyof Components ? N2 extends N0 ? Pick : { [K in N0]: Components[N2] } : + N0 extends keyof Components ? Pick : + ${vueCompilerOptions.strictTemplates ? '{}' : '{ [K in N0]: any }'} + ) : Pick; export type FillingEventArg_ParametersLength any> = IsAny> extends true ? -1 : Parameters['length']; export type FillingEventArg = E extends (...args: any) => any ? FillingEventArg_ParametersLength extends 0 ? ($event?: undefined) => ReturnType : E : E; diff --git a/packages/vue-language-core/src/utils/ts.ts b/packages/vue-language-core/src/utils/ts.ts index 69920c028e..a5f15f33a3 100644 --- a/packages/vue-language-core/src/utils/ts.ts +++ b/packages/vue-language-core/src/utils/ts.ts @@ -170,31 +170,6 @@ function getVueCompilerOptions( } } -// https://developer.mozilla.org/en-US/docs/Web/HTML/Element -const HTML_TAGS = - 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' + - 'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' + - 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' + - 'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' + - 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' + - 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' + - 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' + - 'option,output,progress,select,textarea,details,dialog,menu,' + - 'summary,template,blockquote,iframe,tfoot'; - -// https://developer.mozilla.org/en-US/docs/Web/SVG/Element -const SVG_TAGS = - 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' + - 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' + - 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' + - 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' + - 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' + - 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' + - 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' + - 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' + - 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' + - 'text,textPath,title,tspan,unknown,use,view'; - export function resolveVueCompilerOptions(vueOptions: Partial): VueCompilerOptions { const target = vueOptions.target ?? 3.3; return { @@ -203,14 +178,6 @@ export function resolveVueCompilerOptions(vueOptions: Partial, uri: string, casing: AttrNameCasing, - vueCompilerOptions: VueCompilerOptions, ) { const rootFile = context.documents.getSourceByUri(uri)?.root; @@ -71,7 +70,7 @@ export async function convertAttrName( for (const [tagName, { attrs }] of tags) { const componentName = components.find(component => component === tagName || hyphenate(component) === tagName); if (componentName) { - const props = checkPropsOfTag(_ts.module, _ts.languageService, rootFile, componentName, vueCompilerOptions); + const props = checkPropsOfTag(_ts.module, _ts.languageService, rootFile, componentName); for (const [attrName, { offsets }] of attrs) { const propName = props.find(prop => prop === attrName || hyphenate(prop) === attrName); if (propName) { diff --git a/packages/vue-language-service/src/plugins/vue-template.ts b/packages/vue-language-service/src/plugins/vue-template.ts index 1163a01a96..ae2ccce316 100644 --- a/packages/vue-language-service/src/plugins/vue-template.ts +++ b/packages/vue-language-service/src/plugins/vue-template.ts @@ -67,7 +67,6 @@ export default function useVueTemplateLanguagePlugin= 0 ? components.find(component => component === tagName.split('.')[0]) - : components.find(component => - component === tagName - || (!options.vueCompilerOptions.nativeTags.includes(hyphenate(component)) && hyphenate(component) === tagName) - ); + : components.find(component => component === tagName || hyphenate(component) === tagName); const checkTag = tagName.indexOf('.') >= 0 ? tagName : component; if (checkTag) { - componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, options.vueCompilerOptions, true); + componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, true); current = { unburnedRequiredProps: [...componentProps[checkTag]], labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(), @@ -296,7 +292,7 @@ export default function useVueTemplateLanguagePlugin !nativeTags.has(name)), + ...templateScriptData.map(hyphenate), ]); const offsetRange = { start: document.offsetAt(range.start), @@ -410,8 +406,8 @@ export default function useVueTemplateLanguagePlugin { const attrs = getElementAttrs(_ts.module, _ts.languageService, vueSourceFile.fileName, tag); - const props = new Set(checkPropsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag, options.vueCompilerOptions)); - const events = checkEventsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag, options.vueCompilerOptions); + const props = new Set(checkPropsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag)); + const events = checkEventsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag); const attributes: html.IAttributeData[] = []; for (const prop of [...props, ...attrs]) { diff --git a/packages/vue-test-workspace/tsconfig.json b/packages/vue-test-workspace/tsconfig.json index f04a895297..316a257b9d 100644 --- a/packages/vue-test-workspace/tsconfig.json +++ b/packages/vue-test-workspace/tsconfig.json @@ -21,6 +21,9 @@ ] } }, + "vueCompilerOptions": { + "target": 3.2 + }, "include": [ "**/*" ] From 81c7c87e9cf1d0d4df40af5fef678070a4c67951 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 23 Apr 2023 15:09:27 +0800 Subject: [PATCH 2/5] chore: fall back to JSX namespace if `vue/jsx-runtime` not exist --- packages/vue-language-core/src/utils/localTypes.ts | 5 ++--- packages/vue-test-workspace/tsconfig.json | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/vue-language-core/src/utils/localTypes.ts b/packages/vue-language-core/src/utils/localTypes.ts index f1be2afc2f..15ed41f94d 100644 --- a/packages/vue-language-core/src/utils/localTypes.ts +++ b/packages/vue-language-core/src/utils/localTypes.ts @@ -14,10 +14,9 @@ import type { ObjectDirective, FunctionDirective, } from '${libName}'; -${vueCompilerOptions.target >= 3.3 ? `import { JSX } from 'vue/jsx-runtime';` : ''} -export type IntrinsicElements = PickNotAny>; -export type Element = JSX.Element; +export type IntrinsicElements = PickNotAny>>; +export type Element = PickNotAny; type IsAny = boolean extends (T extends never ? true : false) ? true : false; export type PickNotAny = IsAny extends true ? B : A; diff --git a/packages/vue-test-workspace/tsconfig.json b/packages/vue-test-workspace/tsconfig.json index 316a257b9d..f04a895297 100644 --- a/packages/vue-test-workspace/tsconfig.json +++ b/packages/vue-test-workspace/tsconfig.json @@ -21,9 +21,6 @@ ] } }, - "vueCompilerOptions": { - "target": 3.2 - }, "include": [ "**/*" ] From 58fa728ee453e44d8c7b25c4128054029d58eb9e Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 23 Apr 2023 15:22:48 +0800 Subject: [PATCH 3/5] chore: collect nativeTags at runtime --- packages/vue-language-service/src/helpers.ts | 51 ++++++++++++++++--- .../src/ideFeatures/nameCasing.ts | 13 +++-- .../src/plugins/vue-template.ts | 20 +++++--- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/packages/vue-language-service/src/helpers.ts b/packages/vue-language-service/src/helpers.ts index dae995200d..aa1f8802be 100644 --- a/packages/vue-language-service/src/helpers.ts +++ b/packages/vue-language-service/src/helpers.ts @@ -3,6 +3,7 @@ import * as embedded from '@volar/language-core'; import * as CompilerDOM from '@vue/compiler-dom'; import { computed, ComputedRef } from '@vue/reactivity'; import { typesFileName } from '@volar/vue-language-core/out/utils/localTypes'; +import { camelize, capitalize } from '@vue/shared'; import type * as ts from 'typescript/lib/tsserverlibrary'; @@ -11,6 +12,7 @@ export function checkPropsOfTag( tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, tag: string, + nativeTags: Set, requiredOnly = false, ) { @@ -23,10 +25,10 @@ export function checkPropsOfTag( let componentSymbol = components.componentsType.getProperty(name[0]); - // if (!componentSymbol && !vueCompilerOptions.nativeTags.includes(name[0])) { - // componentSymbol = components.componentsType.getProperty(camelize(name[0])) - // ?? components.componentsType.getProperty(capitalize(camelize(name[0]))); - // } + if (!componentSymbol && !nativeTags.has(name[0])) { + componentSymbol = components.componentsType.getProperty(camelize(name[0])) + ?? components.componentsType.getProperty(capitalize(camelize(name[0]))); + } if (!componentSymbol) return []; @@ -83,6 +85,7 @@ export function checkEventsOfTag( tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, tag: string, + nativeTags: Set, ) { const checker = tsLs.getProgram()!.getTypeChecker(); @@ -94,10 +97,10 @@ export function checkEventsOfTag( let componentSymbol = components.componentsType.getProperty(name[0]); - // if (!componentSymbol && !vueCompilerOptions.nativeTags.includes(name[0])) { - // componentSymbol = components.componentsType.getProperty(camelize(name[0])) - // ?? components.componentsType.getProperty(capitalize(camelize(name[0]))); - // } + if (!componentSymbol && !nativeTags.has(name[0])) { + componentSymbol = components.componentsType.getProperty(camelize(name[0])) + ?? components.componentsType.getProperty(capitalize(camelize(name[0]))); + } if (!componentSymbol) return []; @@ -147,15 +150,47 @@ export function checkComponentNames( ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, + nativeTags: Set, ) { return getComponentsType(ts, tsLs, sourceFile) ?.componentsType ?.getProperties() .map(c => c.name) .filter(entry => entry.indexOf('$') === -1 && !entry.startsWith('_')) + .filter(entry => !nativeTags.has(entry)) ?? []; } +export function checkNativeTags( + ts: typeof import('typescript/lib/tsserverlibrary'), + tsLs: ts.LanguageService, + fileName: string, +) { + + const sharedTypesFileName = fileName.substring(0, fileName.lastIndexOf('/')) + '/' + typesFileName; + const result = new Set(); + + let tsSourceFile: ts.SourceFile | undefined; + + if (tsSourceFile = tsLs.getProgram()?.getSourceFile(sharedTypesFileName)) { + + const typeNode = tsSourceFile.statements.find((node): node is ts.TypeAliasDeclaration => ts.isTypeAliasDeclaration(node) && node.name.getText() === 'IntrinsicElements'); + const checker = tsLs.getProgram()?.getTypeChecker(); + + if (checker && typeNode) { + + const type = checker.getTypeFromTypeNode(typeNode.type); + const props = type.getProperties(); + + for (const prop of props) { + result.add(prop.name); + } + } + } + + return result; +} + export function getElementAttrs( ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, diff --git a/packages/vue-language-service/src/ideFeatures/nameCasing.ts b/packages/vue-language-service/src/ideFeatures/nameCasing.ts index ff9f38f378..9fee06dce5 100644 --- a/packages/vue-language-service/src/ideFeatures/nameCasing.ts +++ b/packages/vue-language-service/src/ideFeatures/nameCasing.ts @@ -1,6 +1,6 @@ import { hyphenate } from '@vue/shared'; import { LanguageServicePluginContext, VirtualFile } from '@volar/language-service'; -import { checkComponentNames, getTemplateTagsAndAttrs, checkPropsOfTag } from '../helpers'; +import { checkComponentNames, getTemplateTagsAndAttrs, checkPropsOfTag, checkNativeTags } from '../helpers'; import * as vue from '@volar/vue-language-core'; import * as vscode from 'vscode-languageserver-protocol'; import { AttrNameCasing, TagNameCasing } from '../types'; @@ -23,7 +23,8 @@ export async function convertTagName( const template = desc.template; const document = context.documents.getDocumentByFileName(rootFile.snapshot, rootFile.fileName); const edits: vscode.TextEdit[] = []; - const components = checkComponentNames(_ts.module, _ts.languageService, rootFile); + const nativeTags = checkNativeTags(_ts.module, _ts.languageService, rootFile.fileName); + const components = checkComponentNames(_ts.module, _ts.languageService, rootFile, nativeTags); const tags = getTemplateTagsAndAttrs(rootFile); for (const [tagName, { offsets }] of tags) { @@ -64,13 +65,14 @@ export async function convertAttrName( const template = desc.template; const document = context.documents.getDocumentByFileName(rootFile.snapshot, rootFile.fileName); const edits: vscode.TextEdit[] = []; - const components = checkComponentNames(_ts.module, _ts.languageService, rootFile); + const nativeTags = checkNativeTags(_ts.module, _ts.languageService, rootFile.fileName); + const components = checkComponentNames(_ts.module, _ts.languageService, rootFile, nativeTags); const tags = getTemplateTagsAndAttrs(rootFile); for (const [tagName, { attrs }] of tags) { const componentName = components.find(component => component === tagName || hyphenate(component) === tagName); if (componentName) { - const props = checkPropsOfTag(_ts.module, _ts.languageService, rootFile, componentName); + const props = checkPropsOfTag(_ts.module, _ts.languageService, rootFile, componentName, nativeTags); for (const [attrName, { offsets }] of attrs) { const propName = props.find(prop => prop === attrName || hyphenate(prop) === attrName); if (propName) { @@ -161,7 +163,8 @@ export function detect( } function getTagNameCase(file: VirtualFile): TagNameCasing[] { - const components = checkComponentNames(_ts.module, _ts.languageService, file); + const nativeTags = checkNativeTags(_ts.module, _ts.languageService, file.fileName); + const components = checkComponentNames(_ts.module, _ts.languageService, file, nativeTags); const tagNames = getTemplateTagsAndAttrs(file); const result: TagNameCasing[] = []; diff --git a/packages/vue-language-service/src/plugins/vue-template.ts b/packages/vue-language-service/src/plugins/vue-template.ts index ae2ccce316..5e8e9680a8 100644 --- a/packages/vue-language-service/src/plugins/vue-template.ts +++ b/packages/vue-language-service/src/plugins/vue-template.ts @@ -5,7 +5,7 @@ import { hyphenate, capitalize, camelize } from '@vue/shared'; import * as html from 'vscode-html-languageservice'; import * as vscode from 'vscode-languageserver-protocol'; import { TextDocument } from 'vscode-languageserver-textdocument'; -import { checkComponentNames, checkEventsOfTag, checkPropsOfTag, getElementAttrs } from '../helpers'; +import { checkComponentNames, checkEventsOfTag, checkPropsOfTag, getElementAttrs, checkNativeTags } from '../helpers'; import { getNameCasing } from '../ideFeatures/nameCasing'; import { AttrNameCasing, VueCompilerOptions, TagNameCasing } from '../types'; import { loadTemplateData, loadModelModifiersData } from './data'; @@ -118,7 +118,8 @@ export default function useVueTemplateLanguagePlugin = {}; let token: html.TokenType; let current: { @@ -135,7 +136,7 @@ export default function useVueTemplateLanguagePlugin component === tagName || hyphenate(component) === tagName); const checkTag = tagName.indexOf('.') >= 0 ? tagName : component; if (checkTag) { - componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, true); + componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, nativeTags); current = { unburnedRequiredProps: [...componentProps[checkTag]], labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(), @@ -289,7 +290,8 @@ export default function useVueTemplateLanguagePlugin true, provideTags: () => { - const components = checkComponentNames(_ts.module, _ts.languageService, vueSourceFile) + const components = checkComponentNames(_ts.module, _ts.languageService, vueSourceFile, nativeTags) .filter(name => name !== 'Transition' && name !== 'TransitionGroup' @@ -406,8 +409,8 @@ export default function useVueTemplateLanguagePlugin { const attrs = getElementAttrs(_ts.module, _ts.languageService, vueSourceFile.fileName, tag); - const props = new Set(checkPropsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag)); - const events = checkEventsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag); + const props = new Set(checkPropsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag, nativeTags)); + const events = checkEventsOfTag(_ts.module, _ts.languageService, vueSourceFile, tag, nativeTags); const attributes: html.IAttributeData[] = []; for (const prop of [...props, ...attrs]) { @@ -512,7 +515,8 @@ export default function useVueTemplateLanguagePlugin, vueSourceFile: vue.VueFile) { const replacement = getReplacement(completionList, map.sourceFileDocument); - const componentNames = new Set(checkComponentNames(_ts.module, _ts.languageService, vueSourceFile).map(hyphenate)); + const nativeTags = checkNativeTags(_ts.module, _ts.languageService, vueSourceFile.fileName); + const componentNames = new Set(checkComponentNames(_ts.module, _ts.languageService, vueSourceFile, nativeTags).map(hyphenate)); if (replacement) { From ea7d6810389e1b16dd187c466955a19119e40a5e Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 23 Apr 2023 15:27:29 +0800 Subject: [PATCH 4/5] chore: update schemas --- .../schemas/vue-tsconfig.deprecated.schema.json | 7 ++++++- .../vue-language-core/schemas/vue-tsconfig.schema.json | 9 --------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/vue-language-core/schemas/vue-tsconfig.deprecated.schema.json b/packages/vue-language-core/schemas/vue-tsconfig.deprecated.schema.json index f1a0e21267..a165e396ed 100644 --- a/packages/vue-language-core/schemas/vue-tsconfig.deprecated.schema.json +++ b/packages/vue-language-core/schemas/vue-tsconfig.deprecated.schema.json @@ -61,7 +61,12 @@ "deprecated": true }, "jsxTemplates": { - "deprecated": true + "deprecated": true, + "description": "Deprecated since v1.5.0." + }, + "nativeTags": { + "deprecated": true, + "description": "Deprecated since v1.5.1." } } } diff --git a/packages/vue-language-core/schemas/vue-tsconfig.schema.json b/packages/vue-language-core/schemas/vue-tsconfig.schema.json index f0d2697d34..1d938859f5 100644 --- a/packages/vue-language-core/schemas/vue-tsconfig.schema.json +++ b/packages/vue-language-core/schemas/vue-tsconfig.schema.json @@ -28,15 +28,6 @@ "type": "boolean", "markdownDescription": "https://github.com/johnsoncodehk/volar/issues/577" }, - "nativeTags": { - "type": "array", - "default": [ - "div", - "img", - "..." - ], - "markdownDescription": "List of valid intrinsic elements." - }, "dataAttributes": { "type": "array", "default": [ ], From 5adad81cd2668947aedcd54c7e92718ca787559f Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 23 Apr 2023 15:34:30 +0800 Subject: [PATCH 5/5] chore: fix missing props hint --- packages/vue-language-service/src/plugins/vue-template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vue-language-service/src/plugins/vue-template.ts b/packages/vue-language-service/src/plugins/vue-template.ts index 5e8e9680a8..5e3f00392f 100644 --- a/packages/vue-language-service/src/plugins/vue-template.ts +++ b/packages/vue-language-service/src/plugins/vue-template.ts @@ -136,7 +136,7 @@ export default function useVueTemplateLanguagePlugin component === tagName || hyphenate(component) === tagName); const checkTag = tagName.indexOf('.') >= 0 ? tagName : component; if (checkTag) { - componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, nativeTags); + componentProps[checkTag] ??= checkPropsOfTag(_ts.module, _ts.languageService, virtualFile, checkTag, nativeTags, true); current = { unburnedRequiredProps: [...componentProps[checkTag]], labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(),