From d8b21a8d6cef772fea5cf2a507b651c5d38194bd Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 7 Mar 2022 14:18:55 -0800 Subject: [PATCH] Don't crash on non-literal computed property names during getPropertyAssignment (#48079) --- src/compiler/utilities.ts | 10 +++++++--- src/harness/client.ts | 4 +--- .../server/tsconfigComputedPropertyError.ts | 12 ++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/server/tsconfigComputedPropertyError.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 651b29d0dc9..0c438527d80 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -987,7 +987,7 @@ namespace ts { return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression); } - export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String { + export function tryGetTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String | undefined { switch (name.kind) { case SyntaxKind.Identifier: case SyntaxKind.PrivateIdentifier: @@ -998,12 +998,16 @@ namespace ts { return escapeLeadingUnderscores(name.text); case SyntaxKind.ComputedPropertyName: if (isStringOrNumericLiteralLike(name.expression)) return escapeLeadingUnderscores(name.expression.text); - return Debug.fail("Text of property name cannot be read from non-literal-valued ComputedPropertyNames"); + return undefined; default: return Debug.assertNever(name); } } + export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String { + return Debug.checkDefined(tryGetTextOfPropertyName(name)); + } + export function entityNameToString(name: EntityNameOrEntityNameExpression | JSDocMemberName | JsxTagNameExpression | PrivateIdentifier): string { switch (name.kind) { case SyntaxKind.ThisKeyword: @@ -1573,7 +1577,7 @@ namespace ts { export function getPropertyAssignment(objectLiteral: ObjectLiteralExpression, key: string, key2?: string): readonly PropertyAssignment[] { return objectLiteral.properties.filter((property): property is PropertyAssignment => { if (property.kind === SyntaxKind.PropertyAssignment) { - const propName = getTextOfPropertyName(property.name); + const propName = tryGetTextOfPropertyName(property.name); return key === propName || (!!key2 && key2 === propName); } return false; diff --git a/src/harness/client.ts b/src/harness/client.ts index 537aa7321e5..fab3c070fdf 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -110,14 +110,12 @@ namespace ts.server { } } - // verify the sequence numbers - Debug.assert(response.request_seq === request.seq, "Malformed response: response sequence number did not match request sequence number."); - // unmarshal errors if (!response.success) { throw new Error("Error " + response.message); } + Debug.assert(response.request_seq === request.seq, "Malformed response: response sequence number did not match request sequence number."); Debug.assert(expectEmptyBody || !!response.body, "Malformed response: Unexpected empty response body."); Debug.assert(!expectEmptyBody || !response.body, "Malformed response: Unexpected non-empty response body."); diff --git a/tests/cases/fourslash/server/tsconfigComputedPropertyError.ts b/tests/cases/fourslash/server/tsconfigComputedPropertyError.ts new file mode 100644 index 00000000000..7d2eef6b04c --- /dev/null +++ b/tests/cases/fourslash/server/tsconfigComputedPropertyError.ts @@ -0,0 +1,12 @@ +/// + +// @filename: tsconfig.json +////{ +//// ["oops!" + 42]: "true", +//// "files": [ +//// "nonexistentfile.ts" +//// ], +//// "compileOnSave": true +////} + +verify.getSemanticDiagnostics([]);