From db1fda5e7755d3838f3131fc5f15175dc04197f4 Mon Sep 17 00:00:00 2001 From: Alexander Rusakov Date: Tue, 20 Dec 2016 17:55:14 +0300 Subject: [PATCH] Improve diagnostic message for negative old style literals --- src/compiler/checker.ts | 12 +++++++++--- src/compiler/diagnosticMessages.json | 6 +++--- src/compiler/utilities.ts | 5 +++++ tests/baselines/reference/literals.errors.txt | 6 +++--- .../reference/oldStyleOctalLiteralTypes.errors.txt | 6 +++--- .../reference/scannerNumericLiteral8.errors.txt | 6 +++--- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16b8c119b63..2b815c40aba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21857,11 +21857,17 @@ namespace ts { function checkGrammarNumericLiteral(node: NumericLiteral): boolean { // Grammar checking if (node.isOctalLiteral) { + let diagnosticMessage: DiagnosticMessage | undefined; if (languageVersion >= ScriptTarget.ES5) { - return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0o_0, node.text); + diagnosticMessage = Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0; } - if (isChildOfLiteralType(node)) { - return grammarErrorOnNode(node, Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0o_0, node.text); + else if (isChildOfLiteralType(node)) { + diagnosticMessage = Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0; + } + if (diagnosticMessage) { + const withMinus = isMinusPrefixUnaryExpression(node.parent); + const literal = `${withMinus ? "-" : ""}0o${node.text}`; + return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal); } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6d19826e951..7b2208e4ca1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -227,7 +227,7 @@ "category": "Error", "code": 1084 }, - "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o{0}'.": { + "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'.": { "category": "Error", "code": 1085 }, @@ -2952,7 +2952,7 @@ "Resolution for module '{0}' was found in cache": { "category": "Message", "code": 6147 - }, + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 @@ -3243,7 +3243,7 @@ "category": "Message", "code": 90015 }, - "Octal literal types must use ES2015 syntax. Use the syntax '0o{0}'.": { + "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { "category": "Error", "code": 8017 } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c542fdb74f8..f272805ced2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -742,6 +742,11 @@ namespace ts { return false; } + export function isMinusPrefixUnaryExpression(node: Node): boolean { + return node.kind === SyntaxKind.PrefixUnaryExpression && + (node as PrefixUnaryExpression).operator === SyntaxKind.MinusToken; + } + // Warning: This has the same semantics as the forEach family of functions, // in that traversal terminates in the event that 'visitor' supplies a truthy value. export function forEachReturnStatement(body: Block, visitor: (stmt: ReturnStatement) => T): T { diff --git a/tests/baselines/reference/literals.errors.txt b/tests/baselines/reference/literals.errors.txt index 2920498bde4..6fa1d7d3abd 100644 --- a/tests/baselines/reference/literals.errors.txt +++ b/tests/baselines/reference/literals.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/expressions/literals/literals.ts(9,17): error TS2363: Th tests/cases/conformance/expressions/literals/literals.ts(10,9): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/literals/literals.ts(10,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/literals/literals.ts(20,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. -tests/cases/conformance/expressions/literals/literals.ts(25,10): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o3'. +tests/cases/conformance/expressions/literals/literals.ts(25,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. ==== tests/cases/conformance/expressions/literals/literals.ts (6 errors) ==== @@ -42,8 +42,8 @@ tests/cases/conformance/expressions/literals/literals.ts(25,10): error TS1085: O var n = -1.0; var n = -1e-4; var n = -003; // Error in ES5 - ~~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o3'. + ~~~~ +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. var n = -0x1; var s: string; diff --git a/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt b/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt index 4dc81f370a4..7d42963b05d 100644 --- a/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt +++ b/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/oldStyleOctalLiteralTypes.ts(1,8): error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o10'. -tests/cases/compiler/oldStyleOctalLiteralTypes.ts(2,9): error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o20'. +tests/cases/compiler/oldStyleOctalLiteralTypes.ts(2,8): error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '-0o20'. ==== tests/cases/compiler/oldStyleOctalLiteralTypes.ts (2 errors) ==== @@ -7,6 +7,6 @@ tests/cases/compiler/oldStyleOctalLiteralTypes.ts(2,9): error TS8017: Octal lite ~~~ !!! error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o10'. let y: -020; - ~~~ -!!! error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o20'. + ~~~~ +!!! error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '-0o20'. \ No newline at end of file diff --git a/tests/baselines/reference/scannerNumericLiteral8.errors.txt b/tests/baselines/reference/scannerNumericLiteral8.errors.txt index 5aad01449f2..6545050afc2 100644 --- a/tests/baselines/reference/scannerNumericLiteral8.errors.txt +++ b/tests/baselines/reference/scannerNumericLiteral8.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts(1,2): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o3'. +tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts(1,1): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. ==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts (1 errors) ==== -03 - ~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o3'. \ No newline at end of file + ~~~ +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. \ No newline at end of file