From e7774c61447d1cc0288c3e38caba2aa98bd0cc44 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Apr 2020 12:58:38 -0700 Subject: [PATCH] Handle non literal computed name when trying to get the name for object literal property name in json object (#37988) Fixes #37984 --- src/compiler/checker.ts | 4 --- src/compiler/commandLineParser.ts | 2 +- src/compiler/utilities.ts | 4 +++ ...sonFileWithComputedPropertyName.errors.txt | 17 +++++++++++ ...quireOfJsonFileWithComputedPropertyName.js | 29 +++++++++++++++++++ ...OfJsonFileWithComputedPropertyName.symbols | 24 +++++++++++++++ ...reOfJsonFileWithComputedPropertyName.types | 29 +++++++++++++++++++ ...quireOfJsonFileWithComputedPropertyName.ts | 15 ++++++++++ 8 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.types create mode 100644 tests/cases/compiler/requireOfJsonFileWithComputedPropertyName.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5eb685cb61c..30d4c5b7c2a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7192,10 +7192,6 @@ namespace ts { return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false); } - function isComputedNonLiteralName(name: PropertyName): boolean { - return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression); - } - function getRestType(source: Type, properties: PropertyName[], symbol: Symbol | undefined): Type { source = filterType(source, t => !(t.flags & TypeFlags.Nullable)); if (source.flags & TypeFlags.Never) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 35ef50db8ad..8d4f332032d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1721,7 +1721,7 @@ namespace ts { errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, Diagnostics.String_literal_with_double_quotes_expected)); } - const textOfKey = getTextOfPropertyName(element.name); + const textOfKey = isComputedNonLiteralName(element.name) ? undefined : getTextOfPropertyName(element.name); const keyText = textOfKey && unescapeLeadingUnderscores(textOfKey); const option = keyText && knownOptions ? knownOptions.get(keyText) : undefined; if (keyText && extraKeyDiagnostics && !option) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 02705662f1f..080f2ed932e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -876,6 +876,10 @@ namespace ts { return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined; } + export function isComputedNonLiteralName(name: PropertyName): boolean { + return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression); + } + export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String { switch (name.kind) { case SyntaxKind.Identifier: diff --git a/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.errors.txt b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.errors.txt new file mode 100644 index 00000000000..83691479939 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/b.json(2,5): error TS1327: String literal with double quotes expected. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + import b1 = require('./b.json'); + let x = b1; + import b2 = require('./b.json'); + if (x) { + x = b2; + } + +==== tests/cases/compiler/b.json (1 errors) ==== + { + [a]: 10 + ~~~ +!!! error TS1327: String literal with double quotes expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.js b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.js new file mode 100644 index 00000000000..da94ca6d0a3 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.js @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/requireOfJsonFileWithComputedPropertyName.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1; +import b2 = require('./b.json'); +if (x) { + x = b2; +} + +//// [b.json] +{ + [a]: 10 +} + +//// [b.json] +var _a; +_a = {}, + _a[a] = 10, + _a; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1; +var b2 = require("./b.json"); +if (x) { + x = b2; +} diff --git a/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.symbols b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.symbols new file mode 100644 index 00000000000..4327461265e --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 11)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + x = b2; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 11)) +} + +=== tests/cases/compiler/b.json === +{ + [a]: 10 +>[a] : Symbol([a], Decl(b.json, 0, 1)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.types b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.types new file mode 100644 index 00000000000..3fc20bb2cce --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithComputedPropertyName.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { [x: number]: number; } + +let x = b1; +>x : { [x: number]: number; } +>b1 : { [x: number]: number; } + +import b2 = require('./b.json'); +>b2 : { [x: number]: number; } + +if (x) { +>x : { [x: number]: number; } + + x = b2; +>x = b2 : { [x: number]: number; } +>x : { [x: number]: number; } +>b2 : { [x: number]: number; } +} + +=== tests/cases/compiler/b.json === +{ +>{ [a]: 10} : { [x: number]: number; } + + [a]: 10 +>[a] : number +>a : any +>10 : 10 +} diff --git a/tests/cases/compiler/requireOfJsonFileWithComputedPropertyName.ts b/tests/cases/compiler/requireOfJsonFileWithComputedPropertyName.ts new file mode 100644 index 00000000000..f5dc94ea251 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithComputedPropertyName.ts @@ -0,0 +1,15 @@ +// @outdir: out/ +// @resolveJsonModule: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1; +import b2 = require('./b.json'); +if (x) { + x = b2; +} + +// @Filename: b.json +{ + [a]: 10 +} \ No newline at end of file