Skip to content

Commit

Permalink
Merge pull request #28857 from JoshuaKGoldberg/identifiers-after-nume…
Browse files Browse the repository at this point in the history
…ric-literals

Added error for IdentifierStart immediately after a NumericLiteral
  • Loading branch information
DanielRosenwasser committed Dec 6, 2018
2 parents 07dbc56 + a211184 commit 8150169
Show file tree
Hide file tree
Showing 13 changed files with 409 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -1011,6 +1011,10 @@
"category": "Message",
"code": 1350
},
"An identifier or keyword cannot immediately follow a numeric literal.": {
"category": "Error",
"code": 1351
},

"Duplicate identifier '{0}'.": {
"category": "Error",
Expand Down
14 changes: 14 additions & 0 deletions src/compiler/scanner.ts
Expand Up @@ -974,7 +974,9 @@ namespace ts {
else {
result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
}

if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
checkForIdentifierStartAfterNumericLiteral();
return {
type: SyntaxKind.NumericLiteral,
value: "" + +result // if value is not an integer, it can be safely coerced to a number
Expand All @@ -983,10 +985,22 @@ namespace ts {
else {
tokenValue = result;
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
checkForIdentifierStartAfterNumericLiteral();
return { type, value: tokenValue };
}
}

function checkForIdentifierStartAfterNumericLiteral() {
if (!isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
return;
}

const identifierStart = pos;
const { length } = scanIdentifierParts();
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
pos = identifierStart;
}

function scanOctalDigits(): number {
const start = pos;
while (isOctalDigit(text.charCodeAt(pos))) {
Expand Down
@@ -0,0 +1,135 @@
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(1,16): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(3,2): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(3,2): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(4,4): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(4,4): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(5,3): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(5,4): error TS2538: Type 'null' cannot be used as an index type.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(6,5): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(6,6): error TS2538: Type 'null' cannot be used as an index type.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(7,2): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(8,4): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(9,3): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(9,3): error TS2304: Cannot find name 'n'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(10,5): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(10,5): error TS2304: Cannot find name 'n'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(11,2): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(11,2): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(12,4): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(12,4): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(13,4): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(13,4): error TS2304: Cannot find name 'abc'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(14,3): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(15,5): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(18,3): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(18,3): error TS2304: Cannot find name 'e'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(19,5): error TS1124: Digit expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(19,5): error TS2304: Cannot find name 'e'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(22,3): error TS1005: ';' expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(23,5): error TS1005: ';' expected.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(24,3): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(24,3): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(25,5): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(25,5): error TS2304: Cannot find name 'a'.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(26,5): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(26,5): error TS2304: Cannot find name 'abc'.


==== tests/cases/compiler/identifierStartAfterNumericLiteral.ts (35 errors) ====
let valueIn = 3in[null];
~~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.

3a[null]
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
123a[null]
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
3e[null]

!!! error TS1124: Digit expected.
~~~~
!!! error TS2538: Type 'null' cannot be used as an index type.
123e[null]

!!! error TS1124: Digit expected.
~~~~
!!! error TS2538: Type 'null' cannot be used as an index type.
3in[null]
~~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
123in[null]
~~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
3en[null]

!!! error TS1124: Digit expected.
~
!!! error TS2304: Cannot find name 'n'.
123en[null]

!!! error TS1124: Digit expected.
~
!!! error TS2304: Cannot find name 'n'.
1a
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
123a
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
123abc
~~~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~~~
!!! error TS2304: Cannot find name 'abc'.
1e

!!! error TS1124: Digit expected.
123e

!!! error TS1124: Digit expected.
1e9
123e9
1ee

!!! error TS1124: Digit expected.
~
!!! error TS2304: Cannot find name 'e'.
123ee

!!! error TS1124: Digit expected.
~
!!! error TS2304: Cannot find name 'e'.
1n
123n
2n2
~
!!! error TS1005: ';' expected.
123n2
~
!!! error TS1005: ';' expected.
2na
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
123na
~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~
!!! error TS2304: Cannot find name 'a'.
123nabc
~~~
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
~~~
!!! error TS2304: Cannot find name 'abc'.

69 changes: 69 additions & 0 deletions tests/baselines/reference/identifierStartAfterNumericLiteral.js
@@ -0,0 +1,69 @@
//// [identifierStartAfterNumericLiteral.ts]
let valueIn = 3in[null];

3a[null]
123a[null]
3e[null]
123e[null]
3in[null]
123in[null]
3en[null]
123en[null]
1a
123a
123abc
1e
123e
1e9
123e9
1ee
123ee
1n
123n
2n2
123n2
2na
123na
123nabc


//// [identifierStartAfterNumericLiteral.js]
var valueIn = 3 in [null];
3;
a[null];
123;
a[null];
3e[null];
123e[null];
3 in [null];
123 in [null];
3e;
n[null];
123e;
n[null];
1;
a;
123;
a;
123;
abc;
1e;
123e;
1e9;
123e9;
1e;
e;
123e;
e;
1n;
123n;
2n;
2;
123n;
2;
2n;
a;
123n;
a;
123n;
abc;
@@ -0,0 +1,29 @@
=== tests/cases/compiler/identifierStartAfterNumericLiteral.ts ===
let valueIn = 3in[null];
>valueIn : Symbol(valueIn, Decl(identifierStartAfterNumericLiteral.ts, 0, 3))

3a[null]
123a[null]
3e[null]
123e[null]
3in[null]
123in[null]
3en[null]
123en[null]
1a
123a
123abc
1e
123e
1e9
123e9
1ee
123ee
1n
123n
2n2
123n2
2na
123na
123nabc

112 changes: 112 additions & 0 deletions tests/baselines/reference/identifierStartAfterNumericLiteral.types
@@ -0,0 +1,112 @@
=== tests/cases/compiler/identifierStartAfterNumericLiteral.ts ===
let valueIn = 3in[null];
>valueIn : boolean
>3in[null] : boolean
>3 : 3
>[null] : null[]
>null : null

3a[null]
>3 : 3
>a[null] : any
>a : any
>null : null

123a[null]
>123 : 123
>a[null] : any
>a : any
>null : null

3e[null]
>3e[null] : any
>3e : 3
>null : null

123e[null]
>123e[null] : any
>123e : 123
>null : null

3in[null]
>3in[null] : boolean
>3 : 3
>[null] : null[]
>null : null

123in[null]
>123in[null] : boolean
>123 : 123
>[null] : null[]
>null : null

3en[null]
>3e : 3
>n[null] : any
>n : any
>null : null

123en[null]
>123e : 123
>n[null] : any
>n : any
>null : null

1a
>1 : 1
>a : any

123a
>123 : 123
>a : any

123abc
>123 : 123
>abc : any

1e
>1e : 1

123e
>123e : 123

1e9
>1e9 : 1000000000

123e9
>123e9 : 123000000000

1ee
>1e : 1
>e : any

123ee
>123e : 123
>e : any

1n
>1n : 1n

123n
>123n : 123n

2n2
>2n : 2n
>2 : 2

123n2
>123n : 123n
>2 : 2

2na
>2n : 2n
>a : any

123na
>123n : 123n
>a : any

123nabc
>123n : 123n
>abc : any

0 comments on commit 8150169

Please sign in to comment.