Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into fix/call-template-ref
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyuanzmj committed Aug 31, 2024
2 parents ec83d68 + 923f835 commit d2b1361
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 17 deletions.
8 changes: 4 additions & 4 deletions extensions/vscode/syntaxes/vue.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@
]
},
"template-tag-1": {
"begin": "(<)(template)\\b(>)",
"begin": "(<)(template[a-zA-Z0-9:-]*)\\b(>)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.html.vue"
Expand All @@ -878,7 +878,7 @@
"patterns": [
{
"begin": "\\G",
"end": "(?=/>)|((</)(template)\\b)",
"end": "(?=/>)|((</)(template[a-zA-Z0-9:-]*)\\b)",
"endCaptures": {
"2": {
"name": "punctuation.definition.tag.begin.html.vue"
Expand All @@ -897,7 +897,7 @@
]
},
"template-tag-2": {
"begin": "(<)(template)\\b",
"begin": "(<)(template[a-zA-Z0-9:-]*)\\b",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.html.vue"
Expand All @@ -916,7 +916,7 @@
"patterns": [
{
"begin": "\\G",
"end": "(?=/>)|((</)(template)\\b)",
"end": "(?=/>)|((</)(template[a-zA-Z0-9:-]*)\\b)",
"endCaptures": {
"2": {
"name": "punctuation.definition.tag.begin.html.vue"
Expand Down
39 changes: 39 additions & 0 deletions extensions/vscode/tests/__snapshots__/grammar.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,45 @@ exports[`grammar > script-tag-in-script.vue 1`] = `
#^ source.vue"
`;
exports[`grammar > tag-starts-with-template.vue 1`] = `
"><template>
#^ source.vue punctuation.definition.tag.begin.html.vue
# ^^^^^^^^ source.vue entity.name.tag.template.html.vue
# ^ source.vue meta.tag-stuff punctuation.definition.tag.end.html.vue
> <template-foo></template-foo>
#^ source.vue text.html.derivative
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start entity.name.tag.template-foo.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
# ^^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end entity.name.tag.template-foo.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
> <template:bar></template:bar>
#^ source.vue text.html.derivative
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start entity.name.tag.template:bar.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
# ^^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end entity.name.tag.template:bar.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
> <template-foo />
#^ source.vue text.html.derivative
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start entity.name.tag.template-foo.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end meta.tag-stuff
# ^^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
> <template:bar />
#^ source.vue text.html.derivative
# ^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.begin.html.vue
# ^^^^^^^^^^^^ source.vue text.html.derivative meta.template-tag.start entity.name.tag.template:bar.html.vue
# ^ source.vue text.html.derivative meta.template-tag.start meta.template-tag.end meta.tag-stuff
# ^^ source.vue text.html.derivative meta.template-tag.start punctuation.definition.tag.end.html.vue
></template>
#^^ source.vue punctuation.definition.tag.begin.html.vue
# ^^^^^^^^ source.vue entity.name.tag.template.html.vue
# ^ source.vue punctuation.definition.tag.end.html.vue"
`;
exports[`grammar > template-expression.vue 1`] = `
"><template>
#^ source.vue punctuation.definition.tag.begin.html.vue
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<template-foo></template-foo>
<template:bar></template:bar>
<template-foo />
<template:bar />
</template>
10 changes: 9 additions & 1 deletion packages/language-core/lib/codegen/script/scriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,15 @@ function* generateSetupFunction(
}
for (const { define } of scriptSetupRanges.templateRefs) {
if (define?.arg) {
setupCodeModifies.push([[`<__VLS_Refs[${scriptSetup.content.slice(define.arg.start, define.arg.end)}], keyof __VLS_Refs>`], define.arg.start - 1, define.arg.start - 1]);
setupCodeModifies.push([
[
`<__VLS_Refs[`,
generateSfcBlockSection(scriptSetup, define.arg.start, define.arg.end, codeFeatures.navigation),
`], keyof __VLS_Refs>`
],
define.arg.start - 1,
define.arg.start - 1
]);
}
}
setupCodeModifies = setupCodeModifies.sort((a, b) => a[1] - b[1]);
Expand Down
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 @@ -223,10 +223,10 @@ export function* generateComponent(
yield endOfLine;
}

const refName = yield* generateVScope(options, ctx, node, props);
const [refName, offset] = yield* generateVScope(options, ctx, node, props);
if (refName) {
const varName = ctx.getInternalVariable();
options.templateRefNames.set(refName, varName);
options.templateRefNames.set(refName, [varName, offset!]);
ctx.usedComponentCtxVars.add(var_defineComponentCtx);

yield `var ${varName} = {} as (Parameters<typeof ${var_defineComponentCtx}['expose']>[0] | null)`;
Expand Down Expand Up @@ -331,9 +331,9 @@ export function* generateElement(
yield endOfLine;
}

const refName = yield* generateVScope(options, ctx, node, node.props);
const [refName, offset] = yield* generateVScope(options, ctx, node, node.props);
if (refName) {
options.templateRefNames.set(refName, `__VLS_intrinsicElements['${node.tag}']`);
options.templateRefNames.set(refName, [`__VLS_intrinsicElements['${node.tag}']`, offset!]);
}

const slotDir = node.props.find(p => p.type === CompilerDOM.NodeTypes.DIRECTIVE && p.name === 'slot') as CompilerDOM.DirectiveNode;
Expand All @@ -360,7 +360,7 @@ function* generateVScope(
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode,
props: (CompilerDOM.AttributeNode | CompilerDOM.DirectiveNode)[]
): Generator<Code> {
): Generator<Code, [refName?: string, offset?: number]> {
const vScope = props.find(prop => prop.type === CompilerDOM.NodeTypes.DIRECTIVE && (prop.name === 'scope' || prop.name === 'data'));
let inScope = false;
let originalConditionsNum = ctx.blockConditions.length;
Expand All @@ -384,14 +384,14 @@ function* generateVScope(
}

yield* generateElementDirectives(options, ctx, node);
const refName = yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
const [refName, offset] = yield* generateReferencesForElements(options, ctx, node); // <el ref="foo" />
yield* generateReferencesForScopedCssClasses(options, ctx, node);

if (inScope) {
yield `}${newLine}`;
ctx.blockConditions.length = originalConditionsNum;
}
return refName;
return [refName, offset];
}

export function getCanonicalComponentName(tagText: string) {
Expand Down Expand Up @@ -540,7 +540,7 @@ function* generateReferencesForElements(
options: TemplateCodegenOptions,
ctx: TemplateCodegenContext,
node: CompilerDOM.ElementNode
): Generator<Code> {
): Generator<Code, [refName: string, offset: number] | []> {
for (const prop of node.props) {
if (
prop.type === CompilerDOM.NodeTypes.ATTRIBUTE
Expand All @@ -565,9 +565,10 @@ function* generateReferencesForElements(
ctx.accessExternalVariable(content, startOffset);
}

return prop.value.content;
return [content, startOffset];
}
}
return [];
}

function* generateReferencesForScopedCssClasses(
Expand Down
12 changes: 9 additions & 3 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { endOfLine, newLine, wrapWith } from '../common';
import { TemplateCodegenContext, createTemplateCodegenContext } from './context';
import { getCanonicalComponentName, getPossibleOriginalComponentNames } from './element';
import { generateObjectProperty } from './objectProperty';
import { generateStringLiteralKey } from './stringLiteralKey';
import { generateTemplateChild, getVForNode } from './templateChild';
import { generateStyleScopedClasses } from './styleScopedClasses';

Expand All @@ -16,7 +17,7 @@ export interface TemplateCodegenOptions {
scriptSetupBindingNames: Set<string>;
scriptSetupImportComponentNames: Set<string>;
edited: boolean;
templateRefNames: Map<string, string>;
templateRefNames: Map<string, [varName: string, offset: number]>;
hasDefineSlots?: boolean;
slotsAssignName?: string;
propsAssignName?: string;
Expand Down Expand Up @@ -58,8 +59,13 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator<Co

function* generateRefs(): Generator<Code> {
yield `const __VLS_refs = {${newLine}`;
for (const [name, varName] of options.templateRefNames) {
yield `'${name}': ${varName},${newLine}`;
for (const [name, [varName, offset]] of options.templateRefNames) {
yield* generateStringLiteralKey(
name,
offset,
ctx.codeFeatures.navigationAndCompletion
)
yield `: ${varName},${newLine}`;
}
yield `}${endOfLine}`;
yield `declare var $refs: typeof __VLS_refs${endOfLine}`;
Expand Down
48 changes: 48 additions & 0 deletions packages/language-server/tests/renaming.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,54 @@ describe('Renaming', async () => {
`);
});

it('Template Ref', async () => {
expect(
await requestRename('tsconfigProject/fixture.vue', 'vue', `
<template>
<a ref="foo"></a>
</template>
<script lang="ts" setup>
import { useTemplateRef } from 'vue';
const el = useTemplateRef('foo|');
</script>
`, 'bar')
).toMatchInlineSnapshot(`
{
"changes": {
"file://\${testWorkspacePath}/tsconfigProject/fixture.vue": [
{
"newText": "bar",
"range": {
"end": {
"character": 16,
"line": 2,
},
"start": {
"character": 13,
"line": 2,
},
},
},
{
"newText": "bar",
"range": {
"end": {
"character": 34,
"line": 7,
},
"start": {
"character": 31,
"line": 7,
},
},
},
],
},
}
`);
});

const openedDocuments: TextDocument[] = [];

afterEach(async () => {
Expand Down

0 comments on commit d2b1361

Please sign in to comment.