From 17f6f77de5dc6629b487d4a9d060b48811e46882 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 26 Jun 2019 11:49:45 -0700 Subject: [PATCH 1/3] Fix declaration emit for negative number property declarations --- src/compiler/checker.ts | 3 +++ .../computedPropertyNamesDeclarationEmit6_ES5.ts | 5 +++++ .../computedPropertyNamesDeclarationEmit6_ES6.ts | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts create mode 100644 tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 64bf09d8b37..61bdee79e39 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4652,6 +4652,9 @@ namespace ts { if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) { return `"${escapeString(name, CharacterCodes.doubleQuote)}"`; } + if (isNumericLiteralName(name) && startsWith(name, "-")) { + return `[${name}]`; + } return name; } if (nameType.flags & TypeFlags.UniqueESSymbol) { diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts new file mode 100644 index 00000000000..cb120d70822 --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts @@ -0,0 +1,5 @@ +// @target: es5 +// @declaration: true +var v = { + [-1]: {} +} diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts new file mode 100644 index 00000000000..8d904244f3f --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts @@ -0,0 +1,5 @@ +// @target: es6 +// @declaration: true +var v = { + [-1]: {} +} \ No newline at end of file From aaf818b4eb133992fc3a02c118b205e1811d840f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 26 Jun 2019 13:57:34 -0700 Subject: [PATCH 2/3] Treat negative numbers as non-dynamic names --- src/compiler/binder.ts | 3 +++ src/compiler/utilities.ts | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 660b19a5872..38d5ed24eae 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -274,6 +274,9 @@ namespace ts { if (isStringOrNumericLiteralLike(nameExpression)) { return escapeLeadingUnderscores(nameExpression.text); } + if (isSignedNumericLiteral(nameExpression)) { + return tokenToString(nameExpression.operator) + nameExpression.operand.text as __String; + } Debug.assert(isWellKnownSymbolSyntactically(nameExpression)); return getPropertyNameForKnownSymbolName(idText((nameExpression).name)); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ae5b60cd864..f1cee2d118a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2705,11 +2705,19 @@ namespace ts { return isStringLiteralLike(node) || isNumericLiteral(node); } + export function isSignedNumericLiteral(node: Node): node is PrefixUnaryExpression & { operand: NumericLiteral } { + return isPrefixUnaryExpression(node) && (node.operator === SyntaxKind.PlusToken || node.operator === SyntaxKind.MinusToken) && isNumericLiteral(node.operand); + } + /** - * A declaration has a dynamic name if both of the following are true: - * 1. The declaration has a computed property name - * 2. The computed name is *not* expressed as Symbol., where name - * is a property of the Symbol constructor that denotes a built in + * A declaration has a dynamic name if all of the following are true: + * 1. The declaration has a computed property name. + * 2. The computed name is *not* expressed as a StringLiteral. + * 3. The computed name is *not* expressed as a NumericLiteral. + * 4. The computed name is *not* expressed as a PlusToken or MinusToken + * immediately followed by a NumericLiteral. + * 5. The computed name is *not* expressed as `Symbol.`, where `` + * is a property of the Symbol constructor that denotes a built-in * Symbol. */ export function hasDynamicName(declaration: Declaration): declaration is DynamicNamedDeclaration { @@ -2720,6 +2728,7 @@ namespace ts { export function isDynamicName(name: DeclarationName): boolean { return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression) && + !isSignedNumericLiteral(name.expression) && !isWellKnownSymbolSyntactically(name.expression); } From 5ff3cda078b03bc02b4465f1c5eb208b18b83121 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 26 Jun 2019 14:01:50 -0700 Subject: [PATCH 3/3] Add some negative test cases and accept baselines --- ...opertyNamesDeclarationEmit6_ES5.errors.txt | 13 ++++++++ ...mputedPropertyNamesDeclarationEmit6_ES5.js | 25 ++++++++++++++++ ...dPropertyNamesDeclarationEmit6_ES5.symbols | 17 +++++++++++ ...tedPropertyNamesDeclarationEmit6_ES5.types | 30 +++++++++++++++++++ ...opertyNamesDeclarationEmit6_ES6.errors.txt | 13 ++++++++ ...mputedPropertyNamesDeclarationEmit6_ES6.js | 24 +++++++++++++++ ...dPropertyNamesDeclarationEmit6_ES6.symbols | 17 +++++++++++ ...tedPropertyNamesDeclarationEmit6_ES6.types | 30 +++++++++++++++++++ ...mputedPropertyNamesDeclarationEmit6_ES5.ts | 5 +++- ...mputedPropertyNamesDeclarationEmit6_ES6.ts | 7 +++-- 10 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.errors.txt create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.js create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.symbols create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.types create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.errors.txt create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.js create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.symbols create mode 100644 tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.types diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.errors.txt b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.errors.txt new file mode 100644 index 00000000000..ec8f9f5ea58 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts(5,3): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. + + +==== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts (1 errors) ==== + var v = { + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} + ~~~~ +!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.js b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.js new file mode 100644 index 00000000000..a0a7b11fa9b --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.js @@ -0,0 +1,25 @@ +//// [computedPropertyNamesDeclarationEmit6_ES5.ts] +var v = { + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} +} + + +//// [computedPropertyNamesDeclarationEmit6_ES5.js] +var _a; +var v = (_a = {}, + _a[-1] = {}, + _a[+1] = {}, + _a[~1] = {}, + _a[!1] = {}, + _a); + + +//// [computedPropertyNamesDeclarationEmit6_ES5.d.ts] +declare var v: { + [x: number]: {}; + [-1]: {}; + 1: {}; +}; diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.symbols b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.symbols new file mode 100644 index 00000000000..40280f88d4c --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts === +var v = { +>v : Symbol(v, Decl(computedPropertyNamesDeclarationEmit6_ES5.ts, 0, 3)) + + [-1]: {}, +>[-1] : Symbol([-1], Decl(computedPropertyNamesDeclarationEmit6_ES5.ts, 0, 9)) + + [+1]: {}, +>[+1] : Symbol([+1], Decl(computedPropertyNamesDeclarationEmit6_ES5.ts, 1, 11)) + + [~1]: {}, +>[~1] : Symbol([~1], Decl(computedPropertyNamesDeclarationEmit6_ES5.ts, 2, 11)) + + [!1]: {} +>[!1] : Symbol([!1], Decl(computedPropertyNamesDeclarationEmit6_ES5.ts, 3, 11)) +} + diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.types b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.types new file mode 100644 index 00000000000..ed412b8041c --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES5.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts === +var v = { +>v : { [x: number]: {}; [-1]: {}; 1: {}; } +>{ [-1]: {}, [+1]: {}, [~1]: {}, [!1]: {}} : { [x: number]: {}; [-1]: {}; [+1]: {}; } + + [-1]: {}, +>[-1] : {} +>-1 : -1 +>1 : 1 +>{} : {} + + [+1]: {}, +>[+1] : {} +>+1 : 1 +>1 : 1 +>{} : {} + + [~1]: {}, +>[~1] : {} +>~1 : number +>1 : 1 +>{} : {} + + [!1]: {} +>[!1] : {} +>!1 : boolean +>1 : 1 +>{} : {} +} + diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.errors.txt b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.errors.txt new file mode 100644 index 00000000000..d5db4741dd2 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts(5,3): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. + + +==== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts (1 errors) ==== + var v = { + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} + ~~~~ +!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.js b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.js new file mode 100644 index 00000000000..0adc9fb6de7 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.js @@ -0,0 +1,24 @@ +//// [computedPropertyNamesDeclarationEmit6_ES6.ts] +var v = { + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} +} + + +//// [computedPropertyNamesDeclarationEmit6_ES6.js] +var v = { + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} +}; + + +//// [computedPropertyNamesDeclarationEmit6_ES6.d.ts] +declare var v: { + [x: number]: {}; + [-1]: {}; + 1: {}; +}; diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.symbols b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.symbols new file mode 100644 index 00000000000..0be9c2e9441 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts === +var v = { +>v : Symbol(v, Decl(computedPropertyNamesDeclarationEmit6_ES6.ts, 0, 3)) + + [-1]: {}, +>[-1] : Symbol([-1], Decl(computedPropertyNamesDeclarationEmit6_ES6.ts, 0, 9)) + + [+1]: {}, +>[+1] : Symbol([+1], Decl(computedPropertyNamesDeclarationEmit6_ES6.ts, 1, 11)) + + [~1]: {}, +>[~1] : Symbol([~1], Decl(computedPropertyNamesDeclarationEmit6_ES6.ts, 2, 11)) + + [!1]: {} +>[!1] : Symbol([!1], Decl(computedPropertyNamesDeclarationEmit6_ES6.ts, 3, 11)) +} + diff --git a/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.types b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.types new file mode 100644 index 00000000000..d68d458621c --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesDeclarationEmit6_ES6.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts === +var v = { +>v : { [x: number]: {}; [-1]: {}; 1: {}; } +>{ [-1]: {}, [+1]: {}, [~1]: {}, [!1]: {}} : { [x: number]: {}; [-1]: {}; [+1]: {}; } + + [-1]: {}, +>[-1] : {} +>-1 : -1 +>1 : 1 +>{} : {} + + [+1]: {}, +>[+1] : {} +>+1 : 1 +>1 : 1 +>{} : {} + + [~1]: {}, +>[~1] : {} +>~1 : number +>1 : 1 +>{} : {} + + [!1]: {} +>[!1] : {} +>!1 : boolean +>1 : 1 +>{} : {} +} + diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts index cb120d70822..002ad4be296 100644 --- a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES5.ts @@ -1,5 +1,8 @@ // @target: es5 // @declaration: true var v = { - [-1]: {} + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} } diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts index 8d904244f3f..b146f3de98a 100644 --- a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesDeclarationEmit6_ES6.ts @@ -1,5 +1,8 @@ // @target: es6 // @declaration: true var v = { - [-1]: {} -} \ No newline at end of file + [-1]: {}, + [+1]: {}, + [~1]: {}, + [!1]: {} +}