Skip to content

Commit

Permalink
feat(language-service): Complete inside @switch (#52153)
Browse files Browse the repository at this point in the history
We now visit the unknown nodes inside a `@switch` block, enabling completions in that context.

PR Close #52153
  • Loading branch information
dylhunn authored and atscott committed Oct 11, 2023
1 parent 9d19c8e commit 449830f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
23 changes: 13 additions & 10 deletions packages/language-service/src/completions.ts
Expand Up @@ -9,7 +9,7 @@
import {AST, ASTWithSource, BindingPipe, BindingType, Call, EmptyExpr, ImplicitReceiver, LiteralPrimitive, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SafePropertyRead, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstText, TmplAstTextAttribute, TmplAstVariable} from '@angular/compiler';
import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
import {CompletionKind, PotentialDirective, SymbolKind, TemplateDeclarationSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import {BoundEvent, DeferredBlock, TextAttribute, UnknownBlock} from '@angular/compiler/src/render3/r3_ast';
import {BoundEvent, DeferredBlock, SwitchBlock, TextAttribute, UnknownBlock} from '@angular/compiler/src/render3/r3_ast';
import ts from 'typescript';

import {addAttributeCompletionEntries, AsciiSortPriority, AttributeCompletionKind, buildAnimationCompletionEntries, buildAttributeCompletionTable, getAttributeCompletionSymbol} from './attribute_completions';
Expand Down Expand Up @@ -130,15 +130,18 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
length: this.node.name.length,
}
};
const completionEntries: ts.CompletionEntry[] = [
...blocksWithParens, ...blocksWithoutParens
].map(name => ({
name,
sortText: `${AsciiSortPriority.First}${name}`,
insertText: buildBlockSnippet(useSnippet, name, blocksWithParens.includes(name)),
isSnippet: useSnippet || undefined,
...partialCompletionEntryWholeBlock,
}));
let competionKeywords: string[] = [...blocksWithParens, ...blocksWithoutParens];
if (this.nodeParent instanceof SwitchBlock) {
competionKeywords = ['case', 'default'];
}
const completionEntries: ts.CompletionEntry[] = competionKeywords.map(
name => ({
name,
sortText: `${AsciiSortPriority.First}${name}`,
insertText: buildBlockSnippet(useSnippet, name, blocksWithParens.includes(name)),
isSnippet: useSnippet || undefined,
...partialCompletionEntryWholeBlock,
}));

// Return the completions.
const completionInfo: ts.CompletionInfo = {
Expand Down
1 change: 1 addition & 0 deletions packages/language-service/src/template_target.ts
Expand Up @@ -499,6 +499,7 @@ class TemplateTargetVisitor implements t.Visitor {
visitSwitchBlock(block: t.SwitchBlock) {
this.visitBinding(block.expression);
this.visitAll(block.cases);
this.visitAll(block.unknownBlocks);
}

visitSwitchBlockCase(block: t.SwitchBlockCase) {
Expand Down
9 changes: 9 additions & 0 deletions packages/language-service/test/completions_spec.ts
Expand Up @@ -298,6 +298,15 @@ describe('completions', () => {
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.BLOCK),
['switch']);
});

it('inside switch', () => {
const {templateFile} = setup(`@switch (1) { @c }`, ``);
templateFile.moveCursorToText('@c¦');
const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.BLOCK),
['case']);
});
});

describe('in an expression scope', () => {
Expand Down

0 comments on commit 449830f

Please sign in to comment.