Skip to content

Commit

Permalink
refactor: use comment syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX committed Nov 2, 2024
1 parent 8d8a220 commit 63c4f50
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 34 deletions.
6 changes: 3 additions & 3 deletions extensions/vscode/syntaxes/vue.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -977,10 +977,10 @@
"include": "#vue-directives-style-attr"
},
{
"include": "#vue-directives-generic-attr"
"include": "#vue-directives-original"
},
{
"include": "#vue-directives-original"
"include": "#vue-directives-generic-attr"
}
]
},
Expand Down Expand Up @@ -1199,7 +1199,7 @@
]
},
"vue-directives-generic-attr": {
"begin": "\\b((?:v-)?generic)\\s*(=)",
"begin": "\\b(generic)\\s*(=)",
"captures": {
"1": {
"name": "entity.other.attribute-name.html.vue"
Expand Down
5 changes: 5 additions & 0 deletions packages/language-core/lib/codegen/template/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
errors: number;
node: CompilerDOM.CommentNode;
} | undefined;
let lastGenericComment: {
content: string;
offset: number;
} | undefined;
let variableId = 0;

const codeFeatures = new Proxy(_codeFeatures, {
Expand Down Expand Up @@ -123,6 +127,7 @@ export function createTemplateCodegenContext(options: Pick<TemplateCodegenOption
dynamicSlots,
codeFeatures,
accessExternalVariables,
lastGenericComment,
hasSlotElements,
blockConditions,
usedComponentCtxVars,
Expand Down
21 changes: 9 additions & 12 deletions packages/language-core/lib/codegen/template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export function* generateComponent(
yield `}))${endOfLine}`;

yield `const ${var_componentInstance} = ${var_functionalComponent}`;
yield* generateComponentGeneric(ctx, props);
yield* generateComponentGeneric(ctx);
yield `(`;
yield* wrapWith(
startTagOffset,
Expand Down Expand Up @@ -455,28 +455,25 @@ function* generateCanonicalComponentName(tagText: string, offset: number, featur
}

function* generateComponentGeneric(
ctx: TemplateCodegenContext,
props: (CompilerDOM.AttributeNode | CompilerDOM.DirectiveNode)[]
ctx: TemplateCodegenContext
): Generator<Code> {
for (const prop of props) {
if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE || prop.name !== 'generic' || !prop.exp) {
continue;
}
if (ctx.lastGenericComment) {
const { content, offset } = ctx.lastGenericComment;
yield* wrapWith(
prop.exp.loc.start.offset,
prop.exp.loc.end.offset,
offset,
offset + content.length,
ctx.codeFeatures.verification,
`<`,
[
prop.exp.loc.source,
content,
'template',
prop.exp.loc.start.offset,
offset,
ctx.codeFeatures.all
],
`>`
);
break;
}
ctx.lastGenericComment = undefined;
}

function* generateComponentSlot(
Expand Down
16 changes: 13 additions & 3 deletions packages/language-core/lib/codegen/template/templateChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,26 @@ export function* generateTemplateChild(
): Generator<Code> {
if (prevNode?.type === CompilerDOM.NodeTypes.COMMENT) {
const commentText = prevNode.content.trim().split(' ')[0];
if (commentText.match(/^@vue-skip\b[\s\S]*/)) {
if (/^@vue-skip\b[\s\S]*/.test(commentText)) {
yield `// @vue-skip${newLine}`;
return;
}
else if (commentText.match(/^@vue-ignore\b[\s\S]*/)) {
else if (/^@vue-ignore\b[\s\S]*/.test(commentText)) {
yield* ctx.ignoreError();
}
else if (commentText.match(/^@vue-expect-error\b[\s\S]*/)) {
else if (/^@vue-expect-error\b[\s\S]*/.test(commentText)) {
yield* ctx.expectError(prevNode);
}
else {
const match = prevNode.loc.source.match(/^<!--\s*@vue-generic\b\s*\{(?<content>[^}]*)\}/);
if (match) {
const { content } = match.groups ?? {};
ctx.lastGenericComment = {
content,
offset: prevNode.loc.start.offset + match[0].indexOf(content)
};
}
}
}

const shouldInheritRootNodeAttrs = options.inheritAttrs;
Expand Down
14 changes: 13 additions & 1 deletion packages/language-core/lib/plugins/vue-template-inline-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const formatBrackets = {
// fix https://github.com/vuejs/language-tools/issues/2305
curly: ['0 +', '+ 0;'] as [string, string],
event: ['() => ', ';'] as [string, string],
generic: ['<', '>() => {};'] as [string, string],
};

const plugin: VueLanguagePlugin = ctx => {
Expand Down Expand Up @@ -71,7 +72,18 @@ const plugin: VueLanguagePlugin = ctx => {
return data;

function visit(node: CompilerDOM.TemplateChildNode | CompilerDOM.SimpleExpressionNode) {
if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
if (node.type === CompilerDOM.NodeTypes.COMMENT) {
const match = node.loc.source.match(/^<!--\s*@vue-generic\b\s*\{(?<content>[^}]*)\}/);
if (match) {
const { content } = match.groups ?? {};
addFormatCodes(
content,
node.loc.start.offset + match[0].indexOf(content),
formatBrackets.generic
);
}
}
else if (node.type === CompilerDOM.NodeTypes.ELEMENT) {
for (const prop of node.props) {
if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE) {
continue;
Expand Down
17 changes: 10 additions & 7 deletions packages/language-service/lib/plugins/vue-directive-comments.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { CompletionItem, LanguageServicePlugin, LanguageServicePluginInstance } from '@volar/language-service';
import type * as vscode from 'vscode-languageserver-protocol';

const cmds = [
'vue-ignore',
'vue-skip',
'vue-expect-error',
['vue-ignore'],
['vue-skip'],
['vue-expect-error'],
['vue-generic', 'vue-generic {$1}'],
];

const directiveCommentReg = /<!--\s*@/;
Expand Down Expand Up @@ -34,17 +36,17 @@ export function create(): LanguageServicePlugin {
const remainText = line.substring(startIndex);
const result: CompletionItem[] = [];

for (const cmd of cmds) {
for (const [label, text = label] of cmds) {
let match = true;
for (let i = 0; i < remainText.length; i++) {
if (remainText[i] !== cmd[i]) {
if (remainText[i] !== label[i]) {
match = false;
break;
}
}
if (match) {
result.push({
label: '@' + cmd,
label: '@' + label,
textEdit: {
range: {
start: {
Expand All @@ -53,8 +55,9 @@ export function create(): LanguageServicePlugin {
},
end: position,
},
newText: '@' + cmd,
newText: '@' + text,
},
insertTextFormat: 2 satisfies typeof vscode.InsertTextFormat.Snippet
});
}
}
Expand Down
19 changes: 11 additions & 8 deletions test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import Comp from './comp.vue';
</script>

<template>
<Comp v-generic="string" @foo="(bar) => exactType(bar, {} as string)"/>
<Comp v-generic="number, boolean" @foo="(bar, baz) => (
exactType(bar, {} as number),
exactType(baz, {} as boolean)
)"/>
<!-- @vue-expect-error -->
<Comp v-generic="boolean" />
</template>
<!-- @vue-generic {string} -->
<Comp @foo="(bar) => exactType(bar, {} as string)" />
<!-- @vue-generic {number, boolean} -->
<Comp @foo="(bar, baz) => (
exactType(bar, {} as number),
exactType(baz, {} as boolean)
)" />
<!-- @vue-expect-error -->
<!-- @vue-generic {boolean} -->
<Comp />
</template>

0 comments on commit 63c4f50

Please sign in to comment.