Skip to content

Commit 5c7e153

Browse files
authored
feat(language-service): JSDoc display support when typing props on component template (#4796)
1 parent 282f6e1 commit 5c7e153

File tree

7 files changed

+213
-73
lines changed

7 files changed

+213
-73
lines changed

extensions/vscode/src/common.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang
264264
]) {
265265
try {
266266
const res = await fetch(url);
267-
onJson(await res.json());
267+
onJson(await res.json() as any);
268268
succeed = true;
269269
break;
270270
} catch { }

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,14 @@ export function* generateElementProps(
210210
...ctx.codeFeatures.withoutHighlightAndCompletion,
211211
};
212212
if (!options.vueCompilerOptions.strictTemplates) {
213+
const verification = codeInfo.verification;
213214
codeInfo.verification = {
214215
shouldReport(_source, code) {
215216
if (String(code) === '2353' || String(code) === '2561') {
216217
return false;
217218
}
218-
return typeof codeInfo.verification === 'object'
219-
? codeInfo.verification.shouldReport?.(_source, code) ?? true
219+
return typeof verification === 'object'
220+
? verification.shouldReport?.(_source, code) ?? true
220221
: true;
221222
},
222223
};
@@ -301,6 +302,12 @@ function* generatePropExp(
301302
isShorthand: boolean,
302303
enableCodeFeatures: boolean
303304
): Generator<Code> {
305+
if (isShorthand && features.completion) {
306+
features = {
307+
...features,
308+
completion: undefined,
309+
};
310+
}
304311
if (exp && exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) { // style='z-index: 2' will compile to {'z-index':'2'}
305312
if (!isShorthand) { // vue 3.4+
306313
yield* generateInterpolation(

packages/language-server/tests/completions.spec.ts

+47
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,53 @@ describe('Completions', async () => {
387387
`, ':-foo-bar');
388388
});
389389

390+
it('#4796', async () => {
391+
expect(
392+
(await requestCompletionItem('tsconfigProject/fixture.vue', 'vue', `
393+
<template>
394+
<HelloWorld :msg| />
395+
</template>
396+
397+
<script lang="ts" setup>
398+
import { defineComponent } from 'vue';
399+
400+
const HelloWorld = defineComponent({
401+
props: {
402+
/**
403+
* The message to display
404+
*/
405+
msg: String
406+
}
407+
})
408+
</script>
409+
`, ':msg'))
410+
).toMatchInlineSnapshot(`
411+
{
412+
"documentation": {
413+
"kind": "markdown",
414+
"value": "The message to display",
415+
},
416+
"insertTextFormat": 2,
417+
"kind": 5,
418+
"label": ":msg",
419+
"sortText": ":msg",
420+
"textEdit": {
421+
"newText": ":msg="$1"",
422+
"range": {
423+
"end": {
424+
"character": 21,
425+
"line": 2,
426+
},
427+
"start": {
428+
"character": 17,
429+
"line": 2,
430+
},
431+
},
432+
},
433+
}
434+
`);
435+
});
436+
390437
const openedDocuments: TextDocument[] = [];
391438
392439
afterEach(async () => {

packages/language-service/lib/ideFeatures/nameCasing.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export async function convertAttrName(
8686
for (const [tagName, { attrs }] of tags) {
8787
const componentName = components.find(component => component === tagName || hyphenateTag(component) === tagName);
8888
if (componentName) {
89-
const props = await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? [];
89+
const props = (await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? []).map(prop => prop.name);
9090
for (const [attrName, { offsets }] of attrs) {
9191
const propName = props.find(prop => prop === attrName || hyphenateAttr(prop) === attrName);
9292
if (propName) {

0 commit comments

Comments
 (0)