Skip to content

Commit

Permalink
fix(language-core): resolve components with various name cases correc…
Browse files Browse the repository at this point in the history
…tly (vuejs#5067)
  • Loading branch information
KazariEX authored Dec 21, 2024
1 parent 8cf123f commit e4ec4ea
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 38 deletions.
19 changes: 10 additions & 9 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ export function* generateComponent(
];
}
else {
const shouldCapitalize = matchImportName[0].toUpperCase() === matchImportName[0];
yield* generateCamelized(
capitalize(node.tag),
shouldCapitalize ? capitalize(node.tag) : node.tag,
tagOffset,
{
...ctx.codeFeatures.withoutHighlightAndCompletion,
Expand Down Expand Up @@ -144,15 +145,15 @@ export function* generateComponent(
yield `)${endOfLine}`;
}
else if (!isComponentTag) {
yield `const ${var_originalComponent} = __VLS_resolvedLocalAndGlobalComponents.`;
yield `const ${var_originalComponent} = ({} as __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
yield getPossibleOriginalComponentNames(node.tag, false)
.map(name => `'${name}'`)
.join(`, `);
yield `>).`;
yield* generateCanonicalComponentName(
node.tag,
startTagOffset,
{
// with hover support
...ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation,
...ctx.codeFeatures.verification,
}
ctx.codeFeatures.withoutHighlightAndCompletionAndNavigation
);
yield `${endOfLine}`;

Expand Down Expand Up @@ -413,13 +414,13 @@ function* generateVScope(
return [refName, offset];
}

export function getCanonicalComponentName(tagText: string) {
function getCanonicalComponentName(tagText: string) {
return variableNameRegex.test(tagText)
? tagText
: capitalize(camelize(tagText.replace(colonReg, '-')));
}

export function getPossibleOriginalComponentNames(tagText: string, deduplicate: boolean) {
function getPossibleOriginalComponentNames(tagText: string, deduplicate: boolean) {
const name1 = capitalize(camelize(tagText));
const name2 = camelize(tagText);
const name3 = tagText;
Expand Down
29 changes: 0 additions & 29 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getSlotsPropertyName } from '../../utils/shared';
import { endOfLine, newLine, wrapWith } from '../utils';
import { generateStringLiteralKey } from '../utils/stringLiteralKey';
import { TemplateCodegenContext, createTemplateCodegenContext } from './context';
import { getCanonicalComponentName, getPossibleOriginalComponentNames } from './element';
import { generateObjectProperty } from './objectProperty';
import { generateStyleScopedClassReferences } from './styleScopedClasses';
import { generateTemplateChild, getVForNode } from './templateChild';
Expand Down Expand Up @@ -40,8 +39,6 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co
ctx.addLocalVariable('$refs');
ctx.addLocalVariable('$el');

yield* generatePreResolveComponents(options);

if (options.template.ast) {
yield* generateTemplateChild(options, ctx, options.template.ast, undefined, undefined, undefined);
}
Expand Down Expand Up @@ -138,32 +135,6 @@ function* generateRootEl(ctx: TemplateCodegenContext): Generator<Code> {
}
}

function* generatePreResolveComponents(options: TemplateCodegenOptions): Generator<Code> {
yield `let __VLS_resolvedLocalAndGlobalComponents!: Required<{}`;
if (options.template.ast) {
const components = new Set<string>();
for (const node of forEachElementNode(options.template.ast)) {
if (
node.tagType === CompilerDOM.ElementTypes.COMPONENT
&& node.tag.toLowerCase() !== 'component'
&& !node.tag.includes('.') // namespace tag
) {
if (components.has(node.tag)) {
continue;
}
components.add(node.tag);
yield newLine;
yield ` & __VLS_WithComponent<'${getCanonicalComponentName(node.tag)}', __VLS_LocalComponents, `;
yield getPossibleOriginalComponentNames(node.tag, false)
.map(name => `'${name}'`)
.join(', ');
yield `>`;
}
}
}
yield `>${endOfLine}`;
}

export function* forEachElementNode(node: CompilerDOM.RootNode | CompilerDOM.TemplateChildNode): Generator<CompilerDOM.ElementNode> {
if (node.type === CompilerDOM.NodeTypes.ROOT) {
for (const child of node.children) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script setup lang="ts" generic="T">
defineProps<{
foo?: T;
}>();
defineEmits<{
foo: [value: T]
}>();
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { exactType } from '../../shared';
import {
default as isComp1,
default as IsComp2
} from './comp.vue';
const isComp3 = isComp1;
const IsComp4 = isComp3;
</script>

<template>
<is-comp1 foo="" @foo="v => exactType(v, {} as string)" />
<isComp1 foo="" @foo="v => exactType(v, {} as string)" />
<!-- @vue-expect-error -->
<IsComp1 />

<is-comp2 foo="" @foo="v => exactType(v, {} as string)" />
<isComp2 foo="" @foo="v => exactType(v, {} as string)" />
<IsComp2 foo="" @foo="v => exactType(v, {} as string)" />

<is-comp3 foo="" @foo="v => exactType(v, {} as string)" />
<isComp3 foo="" @foo="v => exactType(v, {} as string)" />
<!-- @vue-expect-error -->
<IsComp3 />

<is-comp4 foo="" @foo="v => exactType(v, {} as string)" />
<isComp4 foo="" @foo="v => exactType(v, {} as string)" />
<IsComp4 foo="" @foo="v => exactType(v, {} as string)" />
</template>

0 comments on commit e4ec4ea

Please sign in to comment.