From f11e9eb445cccaa7910f6d12c5ce3b0180f39a33 Mon Sep 17 00:00:00 2001 From: so1ve Date: Thu, 25 Apr 2024 17:35:26 +0800 Subject: [PATCH] wip --- .../lib/codegen/template/element.ts | 5 +++++ .../lib/codegen/template/elementProps.ts | 18 ++-------------- .../lib/codegen/template/slotOutlet.ts | 4 +++- .../template/vBindShorthandInlayHint.ts | 21 +++++++++++++++++++ packages/language-service/tests/inlayHint.ts | 4 ++-- .../tests/utils/createTester.ts | 1 + .../inlay-hint/v-bind-shorthand/entry.vue | 15 +++++++++++++ 7 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 packages/language-core/lib/codegen/template/vBindShorthandInlayHint.ts create mode 100644 test-workspace/language-service/inlay-hint/v-bind-shorthand/entry.vue diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 50c408761..945832227 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -13,6 +13,7 @@ import { generateInterpolation } from './interpolation'; import { generatePropertyAccess } from './propertyAccess'; import { generateStringLiteralKey } from './stringLiteralKey'; import { generateTemplateChild } from './templateChild'; +import { generateVBindShorthandInlayHint } from './vBindShorthandInlayHint'; const colonReg = /:/g; @@ -50,6 +51,10 @@ export function* generateElement( if (isComponentTag) { for (const prop of node.props) { if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) { + if (prop.arg.loc.start.offset === prop.exp.loc.start.offset) { + yield generateVBindShorthandInlayHint(prop.exp.loc, 'is'); + } + dynamicTagInfo = { exp: prop.exp.loc.source, offset: prop.exp.loc.start.offset, diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index 490143004..55000435c 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -10,6 +10,7 @@ import type { TemplateCodegenOptions } from './index'; import { generateInterpolation } from './interpolation'; import { generateObjectProperty } from './objectProperty'; import { toString } from '@volar/language-core'; +import { generateVBindShorthandInlayHint } from './vBindShorthandInlayHint'; export function* generateElementProps( options: TemplateCodegenOptions, @@ -263,22 +264,7 @@ function* genereatePropExp( features, ); if (inlayHints) { - yield [ - '', - 'template', - exp.loc.end.offset, - { - __hint: { - setting: 'vue.inlayHints.vBindShorthand', - label: `="${propVariableName}"`, - tooltip: [ - `This is a shorthand for \`${exp.loc.source}="${propVariableName}"\`.`, - 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.', - '[More info](https://github.com/vuejs/core/pull/9451)', - ].join('\n\n'), - }, - } as VueCodeInformation, - ]; + yield generateVBindShorthandInlayHint(exp.loc, propVariableName); } } } diff --git a/packages/language-core/lib/codegen/template/slotOutlet.ts b/packages/language-core/lib/codegen/template/slotOutlet.ts index 44dcbb644..8ba8c6c14 100644 --- a/packages/language-core/lib/codegen/template/slotOutlet.ts +++ b/packages/language-core/lib/codegen/template/slotOutlet.ts @@ -6,6 +6,8 @@ import { generateElementChildren } from './elementChildren'; import { generateElementProps } from './elementProps'; import type { TemplateCodegenOptions } from './index'; import { generateInterpolation } from './interpolation'; +import { generateVBindShorthandInlayHint } from './vBindShorthandInlayHint'; +import { camelize } from '@vue/shared'; export function* generateSlotOutlet( options: TemplateCodegenOptions, @@ -44,7 +46,7 @@ export function* generateSlotOutlet( ? `'${nameProp.value.content}'` : nameProp?.type === CompilerDOM.NodeTypes.DIRECTIVE && nameProp.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION ? nameProp.exp.content - : `('default' as const)` + : `('default' as const)`, ), `]`, ); diff --git a/packages/language-core/lib/codegen/template/vBindShorthandInlayHint.ts b/packages/language-core/lib/codegen/template/vBindShorthandInlayHint.ts new file mode 100644 index 000000000..215258cd2 --- /dev/null +++ b/packages/language-core/lib/codegen/template/vBindShorthandInlayHint.ts @@ -0,0 +1,21 @@ +import type * as CompilerDOM from '@vue/compiler-dom'; +import type { Code, VueCodeInformation } from "../../types"; + +export function generateVBindShorthandInlayHint(loc: CompilerDOM.SourceLocation, variableName: string): Code { + return [ + '', + 'template', + loc.end.offset, + { + __hint: { + setting: 'vue.inlayHints.vBindShorthand', + label: `="${variableName}"`, + tooltip: [ + `This is a shorthand for \`${loc.source}="${variableName}"\`.`, + 'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.', + '[More info](https://github.com/vuejs/core/pull/9451)', + ].join('\n\n'), + }, + } as VueCodeInformation, + ]; +}; \ No newline at end of file diff --git a/packages/language-service/tests/inlayHint.ts b/packages/language-service/tests/inlayHint.ts index 4d760eded..5ea0e33a2 100644 --- a/packages/language-service/tests/inlayHint.ts +++ b/packages/language-service/tests/inlayHint.ts @@ -62,14 +62,14 @@ function readFiles(dir: string) { return filesText; } -const inlayHintReg = /(\^*)inlayHint:\s*"(.+)"/g; +const inlayHintReg = /(\^*)inlayHint:\s*(['"])(.+)\2/g; function findActions(text: string) { return [...text.matchAll(inlayHintReg)].map(flag => { const offset = flag.index!; - const label = flag[2]; + const label = flag[3]; return { offset, diff --git a/packages/language-service/tests/utils/createTester.ts b/packages/language-service/tests/utils/createTester.ts index 746c6633f..b2a18ec76 100644 --- a/packages/language-service/tests/utils/createTester.ts +++ b/packages/language-service/tests/utils/createTester.ts @@ -45,6 +45,7 @@ function createTester(rootUri: string) { 'vue.inlayHints.missingProps': true, 'vue.inlayHints.optionsWrapper': true, 'vue.inlayHints.inlineHandlerLeading': true, + 'vue.inlayHints.vBindShorthand': true, }; let currentVSCodeSettings: any; const language = createTypeScriptLanguage( diff --git a/test-workspace/language-service/inlay-hint/v-bind-shorthand/entry.vue b/test-workspace/language-service/inlay-hint/v-bind-shorthand/entry.vue new file mode 100644 index 000000000..b37d49517 --- /dev/null +++ b/test-workspace/language-service/inlay-hint/v-bind-shorthand/entry.vue @@ -0,0 +1,15 @@ + + +