mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-10 21:07:52 -05:00
Merge pull request #385 from Microsoft/octal
Disallow octal literals in strict mode and ES5
This commit is contained in:
@@ -105,6 +105,7 @@ module ts {
|
||||
An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: { code: 1118, category: DiagnosticCategory.Error, key: "An object literal cannot have multiple get/set accessors with the same name." },
|
||||
An_object_literal_cannot_have_property_and_accessor_with_the_same_name: { code: 1119, category: DiagnosticCategory.Error, key: "An object literal cannot have property and accessor with the same name." },
|
||||
An_export_assignment_cannot_have_modifiers: { code: 1120, category: DiagnosticCategory.Error, key: "An export assignment cannot have modifiers." },
|
||||
Octal_literals_are_not_allowed_in_strict_mode: { code: 1121, category: DiagnosticCategory.Error, key: "Octal literals are not allowed in strict mode." },
|
||||
Duplicate_identifier_0: { code: 2000, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||
Extends_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 2018, category: DiagnosticCategory.Error, key: "Extends clause of exported class '{0}' has or is using private name '{1}'." },
|
||||
Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 2019, category: DiagnosticCategory.Error, key: "Implements clause of exported class '{0}' has or is using private name '{1}'." },
|
||||
|
||||
@@ -412,6 +412,10 @@
|
||||
"category": "Error",
|
||||
"code": 1120
|
||||
},
|
||||
"Octal literals are not allowed in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1121
|
||||
},
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2000
|
||||
|
||||
@@ -1055,8 +1055,29 @@ module ts {
|
||||
function parseLiteralNode(): LiteralExpression {
|
||||
var node = <LiteralExpression>createNode(token);
|
||||
node.text = scanner.getTokenValue();
|
||||
var tokenPos = scanner.getTokenPos();
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
finishNode(node);
|
||||
|
||||
// Octal literals are not allowed in strict mode or ES5
|
||||
// Note that theoretically the following condition would hold true literals like 009,
|
||||
// which is not octal.But because of how the scanner separates the tokens, we would
|
||||
// never get a token like this.Instead, we would get 00 and 9 as two separate tokens.
|
||||
// We also do not need to check for negatives because any prefix operator would be part of a
|
||||
// parent unary expression.
|
||||
if (node.kind === SyntaxKind.NumericLiteral
|
||||
&& sourceText.charCodeAt(tokenPos) === CharacterCodes._0
|
||||
&& isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
|
||||
|
||||
if (isInStrictMode) {
|
||||
grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode);
|
||||
}
|
||||
else if (languageVersion >= ScriptTarget.ES5) {
|
||||
grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function parseStringLiteral(): LiteralExpression {
|
||||
|
||||
@@ -300,6 +300,10 @@ module ts {
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
|
||||
}
|
||||
|
||||
export function isOctalDigit(ch: number): boolean {
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._7;
|
||||
}
|
||||
|
||||
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
|
||||
while (true) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
@@ -360,7 +364,9 @@ module ts {
|
||||
var precedingLineBreak: boolean;
|
||||
|
||||
function error(message: DiagnosticMessage): void {
|
||||
if (onError) onError(message);
|
||||
if (onError) {
|
||||
onError(message);
|
||||
}
|
||||
}
|
||||
|
||||
function isIdentifierStart(ch: number): boolean {
|
||||
@@ -398,6 +404,14 @@ module ts {
|
||||
return +(text.substring(start, end));
|
||||
}
|
||||
|
||||
function scanOctalDigits(): number {
|
||||
var start = pos;
|
||||
while (isOctalDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
return +(text.substring(start, pos));
|
||||
}
|
||||
|
||||
function scanHexDigits(count: number, exact?: boolean): number {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
@@ -681,7 +695,7 @@ module ts {
|
||||
|
||||
if (!commentClosed) {
|
||||
pos++;
|
||||
onError(Diagnostics.Asterisk_Slash_expected);
|
||||
error(Diagnostics.Asterisk_Slash_expected);
|
||||
}
|
||||
|
||||
if (onComment) {
|
||||
@@ -708,6 +722,14 @@ module ts {
|
||||
tokenValue = "" + value;
|
||||
return SyntaxKind.NumericLiteral;
|
||||
}
|
||||
// Try to parse as an octal
|
||||
if (pos + 1 < len && isOctalDigit(text.charCodeAt(pos + 1))) {
|
||||
tokenValue = "" + scanOctalDigits();
|
||||
return SyntaxKind.NumericLiteral;
|
||||
}
|
||||
// This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
|
||||
// can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
|
||||
// permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
|
||||
case CharacterCodes._1:
|
||||
case CharacterCodes._2:
|
||||
case CharacterCodes._3:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
==== tests/cases/conformance/expressions/literals/literals.ts (4 errors) ====
|
||||
==== tests/cases/conformance/expressions/literals/literals.ts (6 errors) ====
|
||||
|
||||
//typeof null is Null
|
||||
//typeof true is Boolean
|
||||
@@ -27,11 +27,15 @@
|
||||
var n = 1.0;
|
||||
var n = 1e4;
|
||||
var n = 001; // Error in ES5
|
||||
~~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
var n = 0x1;
|
||||
var n = -1;
|
||||
var n = -1.0;
|
||||
var n = -1e-4;
|
||||
var n = -003; // Error in ES5
|
||||
~~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
var n = -0x1;
|
||||
|
||||
var s: string;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
//// [literals.ts]
|
||||
|
||||
//typeof null is Null
|
||||
//typeof true is Boolean
|
||||
//typeof false is Boolean
|
||||
//typeof numeric literal is Number
|
||||
//typeof string literal is String
|
||||
//typeof regex literal is Regex
|
||||
|
||||
var nu = null / null;
|
||||
var u = undefined / undefined;
|
||||
|
||||
var b: boolean;
|
||||
var b = true;
|
||||
var b = false;
|
||||
|
||||
var n: number;
|
||||
var n = 1;
|
||||
var n = 1.0;
|
||||
var n = 1e4;
|
||||
var n = 001; // Error in ES5
|
||||
var n = 0x1;
|
||||
var n = -1;
|
||||
var n = -1.0;
|
||||
var n = -1e-4;
|
||||
var n = -003; // Error in ES5
|
||||
var n = -0x1;
|
||||
|
||||
var s: string;
|
||||
var s = '';
|
||||
var s = "";
|
||||
var s = 'foo\
|
||||
bar';
|
||||
var s = "foo\
|
||||
bar";
|
||||
|
||||
var r: RegExp;
|
||||
var r = /what/;
|
||||
var r = /\\\\/;
|
||||
|
||||
|
||||
//// [literals.js]
|
||||
var nu = null / null;
|
||||
var u = undefined / undefined;
|
||||
var b;
|
||||
var b = true;
|
||||
var b = false;
|
||||
var n;
|
||||
var n = 1;
|
||||
var n = 1.0;
|
||||
var n = 1e4;
|
||||
var n = 001;
|
||||
var n = 0x1;
|
||||
var n = -1;
|
||||
var n = -1.0;
|
||||
var n = -1e-4;
|
||||
var n = -003;
|
||||
var n = -0x1;
|
||||
var s;
|
||||
var s = '';
|
||||
var s = "";
|
||||
var s = 'foo\
|
||||
bar';
|
||||
var s = "foo\
|
||||
bar";
|
||||
var r;
|
||||
var r = /what/;
|
||||
var r = /\\\\/;
|
||||
@@ -1,4 +1,4 @@
|
||||
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (59 errors) ====
|
||||
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts (61 errors) ====
|
||||
|
||||
// Multiple properties with the same name
|
||||
var e1 = { a: 0, a: 0 };
|
||||
@@ -45,6 +45,8 @@
|
||||
!!! Duplicate identifier '0x0'.
|
||||
var e14 = { 0: 0, 000: 0 };
|
||||
~~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
~~~
|
||||
!!! Duplicate identifier '000'.
|
||||
var e15 = { "100": 0, 1e2: 0 };
|
||||
~~~
|
||||
@@ -129,6 +131,8 @@
|
||||
!!! Duplicate identifier '0x0'.
|
||||
var f14 = { 0: 0, get 000() { return 0; } };
|
||||
~~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
~~~
|
||||
!!! An object literal cannot have property and accessor with the same name.
|
||||
~~~
|
||||
!!! Duplicate identifier '000'.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
==== tests/cases/conformance/parser/ecmascript5/StrictMode/octalLiteralInStrictModeES3.ts (1 errors) ====
|
||||
"use strict";
|
||||
03;
|
||||
~~
|
||||
!!! Octal literals are not allowed in strict mode.
|
||||
@@ -0,0 +1,4 @@
|
||||
==== tests/cases/conformance/scanner/ecmascript3/scannerES3NumericLiteral3.ts (1 errors) ====
|
||||
01.0
|
||||
~~
|
||||
!!! ';' expected.
|
||||
@@ -1,5 +0,0 @@
|
||||
//// [scannerES3NumericLiteral3.ts]
|
||||
01.0
|
||||
|
||||
//// [scannerES3NumericLiteral3.js]
|
||||
01.0;
|
||||
@@ -0,0 +1,4 @@
|
||||
==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral2.ts (1 errors) ====
|
||||
01
|
||||
~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
@@ -1,5 +0,0 @@
|
||||
//// [scannerNumericLiteral2.ts]
|
||||
01
|
||||
|
||||
//// [scannerNumericLiteral2.js]
|
||||
01;
|
||||
@@ -0,0 +1,6 @@
|
||||
==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral3.ts (2 errors) ====
|
||||
01.0
|
||||
~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
~~
|
||||
!!! ';' expected.
|
||||
@@ -1,5 +0,0 @@
|
||||
//// [scannerNumericLiteral3.ts]
|
||||
01.0
|
||||
|
||||
//// [scannerNumericLiteral3.js]
|
||||
01.0;
|
||||
@@ -0,0 +1,4 @@
|
||||
==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts (1 errors) ====
|
||||
-03
|
||||
~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
@@ -0,0 +1,6 @@
|
||||
==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral9.ts (2 errors) ====
|
||||
009
|
||||
~~
|
||||
!!! Octal literals are not available when targeting ECMAScript 5 and higher.
|
||||
~
|
||||
!!! ';' expected.
|
||||
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
03;
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
0
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
01
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
01.0
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
1e
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
1e0
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
1e+
|
||||
@@ -1 +1,2 @@
|
||||
// @target: ES5
|
||||
1e+0
|
||||
@@ -0,0 +1,2 @@
|
||||
// @target: ES5
|
||||
-03
|
||||
@@ -0,0 +1,2 @@
|
||||
// @target: ES5
|
||||
009
|
||||
Reference in New Issue
Block a user