Skip to content

Commit

Permalink
[typespec-vscode] Meta property autocomplete (#5353)
Browse files Browse the repository at this point in the history
Fix #4976

metadata will prompt after '::', i.e. 'type', 'parameters', 'returnType'
  • Loading branch information
mzhongl524 authored Jan 10, 2025
1 parent 5e26257 commit 8774715
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
---

Meta property are auto-completed, current only supported '::type', '::parameters', '::returnType'
20 changes: 19 additions & 1 deletion packages/compiler/src/core/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2928,12 +2928,30 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
}
} else if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
let base = resolver.getNodeLinks(identifier.parent.base).resolvedSymbol;

if (base) {
if (base.flags & SymbolFlags.Alias) {
base = getAliasedSymbol(base, undefined);
}

if (base) {
addCompletions(base.exports ?? base.members);
if (identifier.parent.selector === "::") {
if (base?.node === undefined && base?.declarations && base.declarations.length > 0) {
// Process meta properties separately, such as `::parameters`, `::returnType`
const nodeModels = base?.declarations[0];
if (nodeModels.kind === SyntaxKind.OperationStatement) {
const operation = nodeModels as OperationStatementNode;
addCompletion("parameters", operation.symbol);
addCompletion("returnType", operation.symbol);
}
} else if (base?.node?.kind === SyntaxKind.ModelProperty) {
// Process meta properties separately, such as `::type`
const metaProperty = base.node as ModelPropertyNode;
addCompletion("type", metaProperty.symbol);
}
} else {
addCompletions(base.exports ?? base.members);
}
}
}
} else {
Expand Down
91 changes: 91 additions & 0 deletions packages/compiler/test/server/completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,97 @@ describe("identifiers", () => {
]);
});

it("completes meta property '::type' on model property", async () => {
const completions = await complete(
`
model A{
name: string;
}
model B{
a: A;
}
model C {
...B.a::┆;
}
`,
);

check(completions, [
{
label: "type",
insertText: "type",
kind: CompletionItemKind.Field,
documentation: {
kind: MarkupKind.Markdown,
value: "(model property)\n```typespec\nB.a: A\n```",
},
},
]);
});

it("completes meta property '::parameters' and '::returnType' on operation", async () => {
const completions = await complete(
`
op base(one: string): void;
@@doc(base::par┆, "Override");
`,
);

check(completions, [
{
label: "parameters",
insertText: "parameters",
kind: CompletionItemKind.Method,
documentation: {
kind: MarkupKind.Markdown,
value: "```typespec\nop base(one: string): void\n```",
},
},
{
label: "returnType",
insertText: "returnType",
kind: CompletionItemKind.Method,
documentation: {
kind: MarkupKind.Markdown,
value: "```typespec\nop base(one: string): void\n```",
},
},
]);
});

it("completes meta property '::parameters' and '::returnType' using alias on operation", async () => {
const completions = await complete(
`
op a(@doc("base doc") one: string): void;
op b is a;
@@doc(b::par┆, "override for b");
`,
);

check(completions, [
{
label: "parameters",
insertText: "parameters",
kind: CompletionItemKind.Method,
documentation: {
kind: MarkupKind.Markdown,
value: "```typespec\nop b(one: string): void\n```",
},
},
{
label: "returnType",
insertText: "returnType",
kind: CompletionItemKind.Method,
documentation: {
kind: MarkupKind.Markdown,
value: "```typespec\nop b(one: string): void\n```",
},
},
]);
});

it("completes partial identifiers", async () => {
const completions = await complete(
`
Expand Down

0 comments on commit 8774715

Please sign in to comment.