fix(completions): exclude default keyword from expression-body arrow function completions#63604
Open
tsushanth wants to merge 1 commit into
Open
Conversation
…w function completions `default` is not a valid expression so it should not appear in keyword completions when completing inside an expression-bodied arrow function (`(x) => <here>`). It was being included because: 1. `tryGetFunctionLikeBodyCompletionContainer` missed the expression-body case: `getRelevantTokens` sets `contextToken` to the `=>` token (the preceding token before the identifier/keyword being typed), so `prev` is `undefined` on the first `findAncestor` iteration and the check `prev === node.body` never matches. 2. Without a detected container, `getGlobalCompletions` fell back to `KeywordCompletionFilters.All`, which includes every `isFunctionLikeBodyKeyword` — and `default` passed that test because it is neither a contextual keyword nor a class-member keyword. Fix: - Detect the expression-body `=>` context directly in `tryGetFunctionLikeBodyCompletionContainer`: when `contextToken` is `EqualsGreaterThanToken` whose parent is an `ArrowFunction` with a non-block body, return that arrow function as the container. - Add `FunctionLikeExpressionBodyKeywords` filter that delegates to `isFunctionLikeBodyKeyword` but excludes `DefaultKeyword`. - In `getGlobalCompletions`, use the new filter when the detected container has a non-block body, so `default` is omitted only in expression contexts (block bodies inside switch statements are unaffected). - Update the two fourslash tests that had TODOs acknowledging this bug. Fixes microsoft#63463
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a keyword-completion edge case in the language service where default was incorrectly suggested within expression-bodied arrow functions, by refining how the completion context is detected and applying a more appropriate keyword filter for concise arrow bodies.
Changes:
- Teach
tryGetFunctionLikeBodyCompletionContainerto recognize the=>token context for expression-bodied arrows and treat the containingArrowFunctionas the completion container. - Add a new keyword filter (
FunctionLikeExpressionBodyKeywords) that excludesdefaultwhile keeping existing block-body behavior unchanged. - Update two fourslash tests to assert
"default"is excluded (removing prior TODO/known-bad expectations).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/services/completions.ts |
Detect expression-bodied arrow => context and apply a new keyword filter that omits default only for concise bodies. |
tests/cases/fourslash/completionListAtEndOfWordInArrowFunction02.ts |
Update completion assertions to exclude "default" in expression-bodied arrow completion context. |
tests/cases/fourslash/completionListAtEndOfWordInArrowFunction03.ts |
Update completion assertions to exclude "default" (matching the corrected keyword filtering behavior). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #63463
Problem
defaultappeared as a keyword completion inside expression-bodied arrow functions:Two existing fourslash tests already acknowledged this with
TODOand "probably stop working" comments.Root cause
getRelevantTokenssetscontextTokento the=>token (the preceding token before the identifier/keyword being typed). InsidetryGetFunctionLikeBodyCompletionContainer,findAncestorstarts atcontextToken.parent(theArrowFunction) withprev = undefined, so the checkprev === node.bodynever matches on the first iteration. The function returnsundefined, andgetGlobalCompletionsfalls back toKeywordCompletionFilters.All, which includes everyisFunctionLikeBodyKeywordhit — anddefaultpasses that test because it is neither a contextual keyword nor a class-member keyword.Fix
Detect the expression-body
=>context directly intryGetFunctionLikeBodyCompletionContainer: whencontextTokenisEqualsGreaterThanTokenwhose parent is anArrowFunctionwith a non-block body, return that arrow function as the container.Add
FunctionLikeExpressionBodyKeywordsfilter that delegates toisFunctionLikeBodyKeywordbut excludesDefaultKeyword.In
getGlobalCompletions, use the new filter when the detected container has a non-block body, sodefaultis omitted only in expression-body contexts. Block bodies (includingswitch/default:inside functions) are unaffected.Update the two fourslash tests to assert
excludes: ["default"]instead of including the TODO/known-bad expectation.Tests
completionListAtEndOfWordInArrowFunction02.ts— updated, passescompletionListAtEndOfWordInArrowFunction03.ts— updated, passescompletionList*fourslash tests passcompletionListKeywords.ts(global scopedefault) continues to pass