From 7854385e6d6ba136f85b7ffe3a4420fdb52907ed Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Fri, 1 Nov 2024 01:55:27 +0800 Subject: [PATCH 1/7] feat: support `v-generic` --- .../vscode/syntaxes/vue.tmLanguage.json | 6 ++--- .../lib/codegen/template/element.ts | 25 ++++++++++++++++++- .../lib/codegen/template/elementDirectives.ts | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/extensions/vscode/syntaxes/vue.tmLanguage.json b/extensions/vscode/syntaxes/vue.tmLanguage.json index 71109bc144..cb700da6e7 100644 --- a/extensions/vscode/syntaxes/vue.tmLanguage.json +++ b/extensions/vscode/syntaxes/vue.tmLanguage.json @@ -977,10 +977,10 @@ "include": "#vue-directives-style-attr" }, { - "include": "#vue-directives-original" + "include": "#vue-directives-generic-attr" }, { - "include": "#vue-directives-generic-attr" + "include": "#vue-directives-original" } ] }, @@ -1199,7 +1199,7 @@ ] }, "vue-directives-generic-attr": { - "begin": "\\b(generic)\\s*(=)", + "begin": "\\b((?:v-)?generic)\\s*(=)", "captures": { "1": { "name": "entity.other.attribute-name.html.vue" diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 258f317f59..98859e9324 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -205,7 +205,9 @@ export function* generateComponent( yield* generateElementProps(options, ctx, node, props, false); yield `}))${endOfLine}`; - yield `const ${var_componentInstance} = ${var_functionalComponent}(`; + yield `const ${var_componentInstance} = ${var_functionalComponent}`; + yield* generateComponentGeneric(ctx, props); + yield `(`; yield* wrapWith( startTagOffset, startTagOffset + node.tag.length, @@ -452,6 +454,27 @@ function* generateCanonicalComponentName(tagText: string, offset: number, featur } } +function* generateComponentGeneric( + ctx: TemplateCodegenContext, + props: (CompilerDOM.AttributeNode | CompilerDOM.DirectiveNode)[] +): Generator { + for (const prop of props) { + if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE || prop.name !== 'generic') { + continue; + } + yield `<`; + if (prop.exp) { + yield [ + prop.exp.loc.source, + 'template', + prop.exp.loc.start.offset, + ctx.codeFeatures.all + ] + } + yield `>`; + } +} + function* generateComponentSlot( options: TemplateCodegenOptions, ctx: TemplateCodegenContext, diff --git a/packages/language-core/lib/codegen/template/elementDirectives.ts b/packages/language-core/lib/codegen/template/elementDirectives.ts index 3c67bce054..c8ebf4758a 100644 --- a/packages/language-core/lib/codegen/template/elementDirectives.ts +++ b/packages/language-core/lib/codegen/template/elementDirectives.ts @@ -24,6 +24,7 @@ export function* generateElementDirectives( || prop.name === 'bind' || prop.name === 'scope' || prop.name === 'data' + || prop.name === 'generic' ) { continue; } From 86230c45834e148e20a5a881ec1f906edfab1a9b Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Fri, 1 Nov 2024 01:59:17 +0800 Subject: [PATCH 2/7] fix: should break --- packages/language-core/lib/codegen/template/element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 98859e9324..e4658e5d00 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -472,6 +472,7 @@ function* generateComponentGeneric( ] } yield `>`; + break; } } From f8ba3212024d18b741a002e326ffebe105c8d18f Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Fri, 1 Nov 2024 02:18:41 +0800 Subject: [PATCH 3/7] test: add --- .../tsc/passedFixtures/vue3/v-generic/comp.vue | 5 +++++ .../tsc/passedFixtures/vue3/v-generic/main.vue | 11 +++++++++++ 2 files changed, 16 insertions(+) create mode 100644 test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue create mode 100644 test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue diff --git a/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue b/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue new file mode 100644 index 0000000000..4ad1b21578 --- /dev/null +++ b/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue b/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue new file mode 100644 index 0000000000..2d917c7ce0 --- /dev/null +++ b/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue @@ -0,0 +1,11 @@ + + + \ No newline at end of file From ea0c3583c09b72c34f099370478917c6efd4ad8b Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Fri, 1 Nov 2024 02:21:25 +0800 Subject: [PATCH 4/7] test: exclude --- test-workspace/tsc/passedFixtures/vue2/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test-workspace/tsc/passedFixtures/vue2/tsconfig.json b/test-workspace/tsc/passedFixtures/vue2/tsconfig.json index c7626d3065..50361e864d 100644 --- a/test-workspace/tsc/passedFixtures/vue2/tsconfig.json +++ b/test-workspace/tsc/passedFixtures/vue2/tsconfig.json @@ -41,5 +41,6 @@ "../vue3/slots", "../vue3/templateRef", "../vue3/templateRef_native", + "../vue3/v-generic" ] } From 3b2082156fb42b0b8f5de0114640e3bc3a0a9762 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Fri, 1 Nov 2024 18:23:29 +0800 Subject: [PATCH 5/7] fix: use `wrapWith` --- .../lib/codegen/template/element.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index e4658e5d00..556d634f3e 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -459,19 +459,22 @@ function* generateComponentGeneric( props: (CompilerDOM.AttributeNode | CompilerDOM.DirectiveNode)[] ): Generator { for (const prop of props) { - if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE || prop.name !== 'generic') { + if (prop.type !== CompilerDOM.NodeTypes.DIRECTIVE || prop.name !== 'generic' || !prop.exp) { continue; } - yield `<`; - if (prop.exp) { - yield [ + yield* wrapWith( + prop.exp.loc.start.offset, + prop.exp.loc.end.offset, + ctx.codeFeatures.verification, + `<`, + [ prop.exp.loc.source, 'template', prop.exp.loc.start.offset, ctx.codeFeatures.all - ] - } - yield `>`; + ], + `>` + ); break; } } From 8d8a220caa9f5c7937f4ee1ad61f9206fb7c8c7a Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Sat, 2 Nov 2024 02:11:33 +0800 Subject: [PATCH 6/7] test: multiple generic params --- test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue | 4 ++-- test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue b/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue index 4ad1b21578..80a6229b95 100644 --- a/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue +++ b/test-workspace/tsc/passedFixtures/vue3/v-generic/comp.vue @@ -1,5 +1,5 @@ - \ No newline at end of file diff --git a/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue b/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue index 2d917c7ce0..8b12f00b57 100644 --- a/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/v-generic/main.vue @@ -4,8 +4,11 @@ import Comp from './comp.vue'; \ No newline at end of file From 63c4f50230432d657c4658790a8a4a06fbafa44c Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Sat, 2 Nov 2024 16:21:45 +0800 Subject: [PATCH 7/7] refactor: use comment syntax --- .../vscode/syntaxes/vue.tmLanguage.json | 6 +++--- .../lib/codegen/template/context.ts | 5 +++++ .../lib/codegen/template/element.ts | 21 ++++++++----------- .../lib/codegen/template/templateChild.ts | 16 +++++++++++--- .../lib/plugins/vue-template-inline-ts.ts | 14 ++++++++++++- .../lib/plugins/vue-directive-comments.ts | 17 ++++++++------- .../passedFixtures/vue3/v-generic/main.vue | 19 ++++++++++------- 7 files changed, 64 insertions(+), 34 deletions(-) diff --git a/extensions/vscode/syntaxes/vue.tmLanguage.json b/extensions/vscode/syntaxes/vue.tmLanguage.json index cb700da6e7..71109bc144 100644 --- a/extensions/vscode/syntaxes/vue.tmLanguage.json +++ b/extensions/vscode/syntaxes/vue.tmLanguage.json @@ -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" } ] }, @@ -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" diff --git a/packages/language-core/lib/codegen/template/context.ts b/packages/language-core/lib/codegen/template/context.ts index c5abab54e1..7334ae85a3 100644 --- a/packages/language-core/lib/codegen/template/context.ts +++ b/packages/language-core/lib/codegen/template/context.ts @@ -63,6 +63,10 @@ export function createTemplateCodegenContext(options: Pick { - 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( diff --git a/packages/language-core/lib/codegen/template/templateChild.ts b/packages/language-core/lib/codegen/template/templateChild.ts index c7df01b522..69be101239 100644 --- a/packages/language-core/lib/codegen/template/templateChild.ts +++ b/packages/language-core/lib/codegen/template/templateChild.ts @@ -36,16 +36,26 @@ export function* generateTemplateChild( ): Generator { 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(/^ - - \ No newline at end of file + + + + + + + +