Skip to content

Commit 0243d5e

Browse files
KazariEXso1vejohnsoncodehk
authored
fix(language-core): inlay hints for <component :is> and <slot :name> (#4661)
Co-authored-by: so1ve <[email protected]> Co-authored-by: Johnson Chu <[email protected]>
1 parent b17ef78 commit 0243d5e

File tree

8 files changed

+51
-40
lines changed

8 files changed

+51
-40
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type * as CompilerDOM from '@vue/compiler-dom';
2+
3+
export interface InlayHintInfo {
4+
blockName: string;
5+
offset: number;
6+
setting: string;
7+
label: string;
8+
tooltip?: string;
9+
paddingRight?: boolean;
10+
paddingLeft?: boolean;
11+
}
12+
13+
export function createVBindShorthandInlayHintInfo(loc: CompilerDOM.SourceLocation, variableName: string): InlayHintInfo {
14+
return {
15+
blockName: 'template',
16+
offset: loc.end.offset,
17+
setting: 'vue.inlayHints.vBindShorthand',
18+
label: `="${variableName}"`,
19+
tooltip: [
20+
`This is a shorthand for \`${loc.source}="${variableName}"\`.`,
21+
'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
22+
'[More info](https://github.com/vuejs/core/pull/9451)',
23+
].join('\n\n'),
24+
};
25+
}

packages/language-core/lib/codegen/script/context.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InlayHintInfo } from '../types';
1+
import { InlayHintInfo } from '../inlayHints';
22
import { getLocalTypesGenerator } from '../localTypes';
33
import type { ScriptCodegenOptions } from './index';
44

packages/language-core/lib/codegen/template/context.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type * as CompilerDOM from '@vue/compiler-dom';
22
import type { Code, VueCodeInformation } from '../../types';
33
import { endOfLine, newLine, wrapWith } from '../common';
44
import type { TemplateCodegenOptions } from './index';
5-
import { InlayHintInfo } from '../types';
5+
import { InlayHintInfo } from '../inlayHints';
66

77
const _codeFeatures = {
88
all: {

packages/language-core/lib/codegen/template/element.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { generateInterpolation } from './interpolation';
1515
import { generatePropertyAccess } from './propertyAccess';
1616
import { generateTemplateChild } from './templateChild';
1717
import { generateObjectProperty } from './objectProperty';
18+
import { createVBindShorthandInlayHintInfo } from '../inlayHints';
1819
import { getNodeText } from '../../parsers/scriptSetupRanges';
1920

2021
const colonReg = /:/g;
@@ -48,16 +49,24 @@ export function* generateComponent(
4849

4950
let props = node.props;
5051
let dynamicTagInfo: {
51-
exp: string;
52+
tag: string;
5253
offsets: [number, number | undefined];
53-
astHolder: any;
54+
astHolder: CompilerDOM.SourceLocation;
5455
} | undefined;
5556

5657
if (isComponentTag) {
5758
for (const prop of node.props) {
58-
if (prop.type === CompilerDOM.NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg?.loc.source === 'is' && prop.exp) {
59+
if (
60+
prop.type === CompilerDOM.NodeTypes.DIRECTIVE
61+
&& prop.name === 'bind'
62+
&& prop.arg?.loc.source === 'is'
63+
&& prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
64+
) {
65+
if (prop.arg.loc.end.offset === prop.exp.loc.end.offset) {
66+
ctx.inlayHints.push(createVBindShorthandInlayHintInfo(prop.exp.loc, 'is'));
67+
}
5968
dynamicTagInfo = {
60-
exp: prop.exp.loc.source,
69+
tag: prop.exp.content,
6170
offsets: [prop.exp.loc.start.offset, undefined],
6271
astHolder: prop.exp.loc,
6372
};
@@ -69,9 +78,9 @@ export function* generateComponent(
6978
else if (node.tag.includes('.')) {
7079
// namespace tag
7180
dynamicTagInfo = {
72-
exp: node.tag,
73-
astHolder: node.loc,
81+
tag: node.tag,
7482
offsets: [startTagOffset, endTagOffset],
83+
astHolder: node.loc,
7584
};
7685
}
7786

@@ -110,7 +119,7 @@ export function* generateComponent(
110119
yield* generateInterpolation(
111120
options,
112121
ctx,
113-
dynamicTagInfo.exp,
122+
dynamicTagInfo.tag,
114123
dynamicTagInfo.astHolder,
115124
dynamicTagInfo.offsets[0],
116125
ctx.codeFeatures.all,
@@ -122,7 +131,7 @@ export function* generateComponent(
122131
yield* generateInterpolation(
123132
options,
124133
ctx,
125-
dynamicTagInfo.exp,
134+
dynamicTagInfo.tag,
126135
dynamicTagInfo.astHolder,
127136
dynamicTagInfo.offsets[1],
128137
{

packages/language-core/lib/codegen/template/elementProps.ts

+2-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { generateEventArg, generateEventExpression } from './elementEvents';
1111
import type { TemplateCodegenOptions } from './index';
1212
import { generateInterpolation } from './interpolation';
1313
import { generateObjectProperty } from './objectProperty';
14+
import { createVBindShorthandInlayHintInfo } from '../inlayHints';
1415

1516
export function* generateElementProps(
1617
options: TemplateCodegenOptions,
@@ -334,17 +335,7 @@ function* generatePropExp(
334335
features
335336
);
336337
if (enableCodeFeatures) {
337-
ctx.inlayHints.push({
338-
blockName: 'template',
339-
offset: prop.loc.end.offset,
340-
setting: 'vue.inlayHints.vBindShorthand',
341-
label: `="${propVariableName}"`,
342-
tooltip: [
343-
`This is a shorthand for \`${prop.loc.source}="${propVariableName}"\`.`,
344-
'To hide this hint, set `vue.inlayHints.vBindShorthand` to `false` in IDE settings.',
345-
'[More info](https://github.com/vuejs/core/pull/9451)',
346-
].join('\n\n'),
347-
});
338+
ctx.inlayHints.push(createVBindShorthandInlayHintInfo(prop.loc, propVariableName));
348339
}
349340
}
350341
}

packages/language-core/lib/codegen/template/interpolation.ts

-10
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ export function* generateInterpolation(
1818
): Generator<Code> {
1919
const code = prefix + _code + suffix;
2020
const ast = createTsAst(options.ts, astHolder, code);
21-
const vars: {
22-
text: string,
23-
isShorthand: boolean,
24-
offset: number,
25-
}[] = [];
2621
for (let [section, offset, type] of forEachInterpolationSegment(
2722
options.ts,
2823
options.destructuredPropNames,
@@ -70,11 +65,6 @@ export function* generateInterpolation(
7065
yield addSuffix;
7166
}
7267
}
73-
if (start !== undefined) {
74-
for (const v of vars) {
75-
v.offset = start + v.offset - prefix.length;
76-
}
77-
}
7868
}
7969

8070
export function* forEachInterpolationSegment(

packages/language-core/lib/codegen/template/slotOutlet.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { generateElementChildren } from './elementChildren';
66
import { generateElementProps } from './elementProps';
77
import type { TemplateCodegenOptions } from './index';
88
import { generateInterpolation } from './interpolation';
9+
import { createVBindShorthandInlayHintInfo } from '../inlayHints';
910

1011
export function* generateSlotOutlet(
1112
options: TemplateCodegenOptions,
@@ -80,6 +81,10 @@ export function* generateSlotOutlet(
8081
nameProp?.type === CompilerDOM.NodeTypes.DIRECTIVE
8182
&& nameProp.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
8283
) {
84+
const isShortHand = nameProp.arg?.loc.start.offset === nameProp.exp.loc.start.offset;
85+
if (isShortHand) {
86+
ctx.inlayHints.push(createVBindShorthandInlayHintInfo(nameProp.exp.loc, 'name'));
87+
}
8388
const slotExpVar = ctx.getInternalVariable();
8489
yield `var ${slotExpVar} = `;
8590
yield* generateInterpolation(

packages/language-core/lib/codegen/types.ts

-9
This file was deleted.

0 commit comments

Comments
 (0)