Skip to content

Commit 38b951e

Browse files
authored
Fixed crash in switch completions related to parenthesized expressions (#52881)
1 parent e88fe15 commit 38b951e

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

src/services/stringCompletions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL
431431
// export * from "/*completion position*/";
432432
return { kind: StringLiteralCompletionKind.Paths, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker, preferences) };
433433
case SyntaxKind.CaseClause:
434-
const tracker = newCaseClauseTracker(typeChecker, (node.parent as CaseClause).parent.clauses);
434+
const tracker = newCaseClauseTracker(typeChecker, (parent as CaseClause).parent.clauses);
435435
const literals = fromContextualType().types.filter(literal => !tracker.hasValue(literal.value));
436436
return { kind: StringLiteralCompletionKind.Types, types: literals, isNewIdentifier: false };
437437
default:

src/services/utilities.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ import {
312312
singleOrUndefined,
313313
skipAlias,
314314
skipOuterExpressions,
315+
skipParentheses,
315316
some,
316317
SortKind,
317318
SourceFile,
@@ -360,6 +361,7 @@ import {
360361
VariableDeclaration,
361362
visitEachChild,
362363
VoidExpression,
364+
walkUpParenthesizedExpressions,
363365
YieldExpression,
364366
} from "./_namespaces/ts";
365367

@@ -3298,7 +3300,7 @@ export function needsParentheses(expression: Expression): boolean {
32983300

32993301
/** @internal */
33003302
export function getContextualTypeFromParent(node: Expression, checker: TypeChecker, contextFlags?: ContextFlags): Type | undefined {
3301-
const { parent } = node;
3303+
const parent = walkUpParenthesizedExpressions(node.parent);
33023304
switch (parent.kind) {
33033305
case SyntaxKind.NewExpression:
33043306
return checker.getContextualType(parent as NewExpression, contextFlags);
@@ -3309,7 +3311,7 @@ export function getContextualTypeFromParent(node: Expression, checker: TypeCheck
33093311
: checker.getContextualType(node, contextFlags);
33103312
}
33113313
case SyntaxKind.CaseClause:
3312-
return (parent as CaseClause).expression === node ? getSwitchedType(parent as CaseClause, checker) : undefined;
3314+
return getSwitchedType(parent as CaseClause, checker);
33133315
default:
33143316
return checker.getContextualType(node, contextFlags);
33153317
}
@@ -4098,8 +4100,8 @@ export function newCaseClauseTracker(checker: TypeChecker, clauses: readonly (Ca
40984100

40994101
for (const clause of clauses) {
41004102
if (!isDefaultClause(clause)) {
4101-
if (isLiteralExpression(clause.expression)) {
4102-
const expression = clause.expression;
4103+
const expression = skipParentheses(clause.expression);
4104+
if (isLiteralExpression(expression)) {
41034105
switch (expression.kind) {
41044106
case SyntaxKind.NoSubstitutionTemplateLiteral:
41054107
case SyntaxKind.StringLiteral:

tests/cases/fourslash/switchCompletions.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
//// return 1;
2020
//// case '/*3*/'
2121
//// }
22+
////
23+
//// // repro from #52874
24+
//// declare let x: "foo" | "bar";
25+
//// switch (x) {
26+
//// case ('/*4*/')
27+
//// }
2228

2329
verify.completions(
2430
{
@@ -38,5 +44,10 @@ verify.completions(
3844
isNewIdentifierLocation: false,
3945
includes: ["foo", "baz"],
4046
excludes: "bar",
47+
},
48+
{
49+
marker: "4",
50+
isNewIdentifierLocation: false,
51+
includes: ["foo", "bar"],
4152
}
4253
);

0 commit comments

Comments
 (0)