Skip to content

Commit 174816f

Browse files
author
Josh Goldberg
committed
Added error for IdentifierStart immediately after a NumericLiteral
Fixes #4702.
1 parent 2103ed6 commit 174816f

18 files changed

+643
-87
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,10 @@
10111011
"category": "Message",
10121012
"code": 1350
10131013
},
1014+
"An identifier cannot follow a numeric literal.": {
1015+
"category": "Error",
1016+
"code": 1351
1017+
},
10141018

10151019
"Duplicate identifier '{0}'.": {
10161020
"category": "Error",

src/compiler/scanner.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,10 @@ namespace ts {
974974
else {
975975
result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
976976
}
977+
978+
checkForIdentifierAfterNumericLiteral();
977979
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
980+
checkForIdentifierAfterNumericLiteral();
978981
return {
979982
type: SyntaxKind.NumericLiteral,
980983
value: "" + +result // if value is not an integer, it can be safely coerced to a number
@@ -983,10 +986,17 @@ namespace ts {
983986
else {
984987
tokenValue = result;
985988
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
989+
checkForIdentifierAfterNumericLiteral();
986990
return { type, value: tokenValue };
987991
}
988992
}
989993

994+
function checkForIdentifierAfterNumericLiteral() {
995+
if (isIdentifierStart(text.charCodeAt(pos), languageVersion)) {
996+
error(Diagnostics.An_identifier_cannot_follow_a_numeric_literal, pos, 1);
997+
}
998+
}
999+
9901000
function scanOctalDigits(): number {
9911001
const start = pos;
9921002
while (isOctalDigit(text.charCodeAt(pos))) {
Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1-
tests/cases/compiler/bigIntWithTargetES3.ts(5,22): error TS2737: BigInt literals are not available when targeting lower than ESNext.
2-
tests/cases/compiler/bigIntWithTargetES3.ts(5,29): error TS2737: BigInt literals are not available when targeting lower than ESNext.
3-
tests/cases/compiler/bigIntWithTargetES3.ts(5,39): error TS2737: BigInt literals are not available when targeting lower than ESNext.
4-
tests/cases/compiler/bigIntWithTargetES3.ts(5,48): error TS2737: BigInt literals are not available when targeting lower than ESNext.
1+
tests/cases/compiler/bigIntWithTargetES3.ts(3,27): error TS1351: An identifier cannot follow a numeric literal.
2+
tests/cases/compiler/bigIntWithTargetES3.ts(4,36): error TS1351: An identifier cannot follow a numeric literal.
3+
tests/cases/compiler/bigIntWithTargetES3.ts(5,25): error TS1351: An identifier cannot follow a numeric literal.
54

65

7-
==== tests/cases/compiler/bigIntWithTargetES3.ts (4 errors) ====
6+
==== tests/cases/compiler/bigIntWithTargetES3.ts (3 errors) ====
87
const normalNumber = 123; // should not error
98
let bigintType: bigint; // should not error
109
let bigintLiteralType: 123n; // should not error when used as type
10+
~
11+
!!! error TS1351: An identifier cannot follow a numeric literal.
1112
let bigintNegativeLiteralType: -123n; // should not error when used as type
13+
~
14+
!!! error TS1351: An identifier cannot follow a numeric literal.
1215
const bigintNumber = 123n * 0b1111n + 0o444n * 0x7fn; // each literal should error
13-
~~~~
14-
!!! error TS2737: BigInt literals are not available when targeting lower than ESNext.
15-
~~~~~~~
16-
!!! error TS2737: BigInt literals are not available when targeting lower than ESNext.
17-
~~~~~~
18-
!!! error TS2737: BigInt literals are not available when targeting lower than ESNext.
19-
~~~~~
20-
!!! error TS2737: BigInt literals are not available when targeting lower than ESNext.
16+
~
17+
!!! error TS1351: An identifier cannot follow a numeric literal.
2118

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
tests/cases/compiler/a.ts(2,6): error TS1023: An index signature parameter type must be 'string' or 'number'.
21
tests/cases/compiler/a.ts(8,11): error TS2538: Type '1n' cannot be used as an index type.
2+
tests/cases/compiler/a.ts(8,12): error TS1351: An identifier cannot follow a numeric literal.
33
tests/cases/compiler/a.ts(14,1): error TS2322: Type '123n' is not assignable to type 'string | number | symbol'.
4+
tests/cases/compiler/a.ts(14,10): error TS1351: An identifier cannot follow a numeric literal.
5+
tests/cases/compiler/a.ts(17,25): error TS1351: An identifier cannot follow a numeric literal.
46
tests/cases/compiler/a.ts(19,12): error TS2538: Type 'bigint' cannot be used as an index type.
57
tests/cases/compiler/b.ts(2,12): error TS1136: Property assignment expected.
8+
tests/cases/compiler/b.ts(2,13): error TS1351: An identifier cannot follow a numeric literal.
69
tests/cases/compiler/b.ts(2,14): error TS1005: ';' expected.
710
tests/cases/compiler/b.ts(2,19): error TS1128: Declaration or statement expected.
811
tests/cases/compiler/b.ts(3,12): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
12+
tests/cases/compiler/b.ts(3,14): error TS1351: An identifier cannot follow a numeric literal.
913
tests/cases/compiler/b.ts(4,12): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
1014

1115

12-
==== tests/cases/compiler/a.ts (4 errors) ====
16+
==== tests/cases/compiler/a.ts (6 errors) ====
1317
interface BigIntIndex<E> {
1418
[index: bigint]: E; // should error
15-
~~~~~
16-
!!! error TS1023: An index signature parameter type must be 'string' or 'number'.
1719
}
1820

1921
const arr: number[] = [1, 2, 3];
@@ -22,6 +24,8 @@ tests/cases/compiler/b.ts(4,12): error TS2464: A computed property name must be
2224
num = arr[1n]; // should error
2325
~~
2426
!!! error TS2538: Type '1n' cannot be used as an index type.
27+
~
28+
!!! error TS1351: An identifier cannot follow a numeric literal.
2529

2630
let key: keyof any; // should be type "string | number | symbol"
2731
key = 123;
@@ -30,9 +34,13 @@ tests/cases/compiler/b.ts(4,12): error TS2464: A computed property name must be
3034
key = 123n; // should error
3135
~~~
3236
!!! error TS2322: Type '123n' is not assignable to type 'string | number | symbol'.
37+
~
38+
!!! error TS1351: An identifier cannot follow a numeric literal.
3339

3440
// Show correct usage of bigint index: explicitly convert to string
3541
const bigNum: bigint = 0n;
42+
~
43+
!!! error TS1351: An identifier cannot follow a numeric literal.
3644
const typedArray = new Uint8Array(3);
3745
typedArray[bigNum] = 0xAA; // should error
3846
~~~~~~
@@ -42,18 +50,22 @@ tests/cases/compiler/b.ts(4,12): error TS2464: A computed property name must be
4250
typedArray[2] = 0xCC;
4351

4452
// {1n: 123} is a syntax error; must go in separate file so BigIntIndex error is shown
45-
==== tests/cases/compiler/b.ts (5 errors) ====
53+
==== tests/cases/compiler/b.ts (7 errors) ====
4654
// BigInt cannot be used as an object literal property
4755
const a = {1n: 123};
4856
~~
4957
!!! error TS1136: Property assignment expected.
58+
~
59+
!!! error TS1351: An identifier cannot follow a numeric literal.
5060
~
5161
!!! error TS1005: ';' expected.
5262
~
5363
!!! error TS1128: Declaration or statement expected.
5464
const b = {[1n]: 456};
5565
~~~~
5666
!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
67+
~
68+
!!! error TS1351: An identifier cannot follow a numeric literal.
5769
const c = {[bigNum]: 789};
5870
~~~~~~~~
5971
!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.

tests/baselines/reference/bigintWithLib.errors.txt

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
tests/cases/compiler/bigintWithLib.ts(4,1): error TS2350: Only a void function can be called with the 'new' keyword.
2+
tests/cases/compiler/bigintWithLib.ts(15,35): error TS1351: An identifier cannot follow a numeric literal.
3+
tests/cases/compiler/bigintWithLib.ts(15,39): error TS1351: An identifier cannot follow a numeric literal.
4+
tests/cases/compiler/bigintWithLib.ts(15,43): error TS1351: An identifier cannot follow a numeric literal.
25
tests/cases/compiler/bigintWithLib.ts(16,33): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'.
36
Type 'number[]' is missing the following properties from type 'SharedArrayBuffer': byteLength, [Symbol.species], [Symbol.toStringTag]
47
tests/cases/compiler/bigintWithLib.ts(21,13): error TS2540: Cannot assign to 'length' because it is a read-only property.
8+
tests/cases/compiler/bigintWithLib.ts(27,37): error TS1351: An identifier cannot follow a numeric literal.
9+
tests/cases/compiler/bigintWithLib.ts(27,41): error TS1351: An identifier cannot follow a numeric literal.
10+
tests/cases/compiler/bigintWithLib.ts(27,45): error TS1351: An identifier cannot follow a numeric literal.
511
tests/cases/compiler/bigintWithLib.ts(28,35): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'.
612
Type 'number[]' is not assignable to type 'SharedArrayBuffer'.
713
tests/cases/compiler/bigintWithLib.ts(33,13): error TS2540: Cannot assign to 'length' because it is a read-only property.
14+
tests/cases/compiler/bigintWithLib.ts(38,27): error TS1351: An identifier cannot follow a numeric literal.
15+
tests/cases/compiler/bigintWithLib.ts(39,27): error TS1351: An identifier cannot follow a numeric literal.
816
tests/cases/compiler/bigintWithLib.ts(40,25): error TS2345: Argument of type '-1' is not assignable to parameter of type 'bigint'.
17+
tests/cases/compiler/bigintWithLib.ts(41,29): error TS1351: An identifier cannot follow a numeric literal.
18+
tests/cases/compiler/bigintWithLib.ts(42,29): error TS1351: An identifier cannot follow a numeric literal.
919
tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '123' is not assignable to parameter of type 'bigint'.
20+
tests/cases/compiler/bigintWithLib.ts(50,13): error TS1351: An identifier cannot follow a numeric literal.
21+
tests/cases/compiler/bigintWithLib.ts(51,14): error TS1351: An identifier cannot follow a numeric literal.
22+
tests/cases/compiler/bigintWithLib.ts(52,12): error TS1351: An identifier cannot follow a numeric literal.
23+
tests/cases/compiler/bigintWithLib.ts(52,18): error TS1351: An identifier cannot follow a numeric literal.
24+
tests/cases/compiler/bigintWithLib.ts(53,11): error TS1351: An identifier cannot follow a numeric literal.
1025

1126

12-
==== tests/cases/compiler/bigintWithLib.ts (7 errors) ====
27+
==== tests/cases/compiler/bigintWithLib.ts (22 errors) ====
1328
// Test BigInt functions
1429
let bigintVal: bigint = BigInt(123);
1530
bigintVal = BigInt("456");
@@ -27,6 +42,12 @@ tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '12
2742
let bigIntArray: BigInt64Array = new BigInt64Array();
2843
bigIntArray = new BigInt64Array(10);
2944
bigIntArray = new BigInt64Array([1n, 2n, 3n]);
45+
~
46+
!!! error TS1351: An identifier cannot follow a numeric literal.
47+
~
48+
!!! error TS1351: An identifier cannot follow a numeric literal.
49+
~
50+
!!! error TS1351: An identifier cannot follow a numeric literal.
3051
bigIntArray = new BigInt64Array([1, 2, 3]); // should error
3152
~~~~~~~~~
3253
!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'.
@@ -44,6 +65,12 @@ tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '12
4465
let bigUintArray: BigUint64Array = new BigUint64Array();
4566
bigUintArray = new BigUint64Array(10);
4667
bigUintArray = new BigUint64Array([1n, 2n, 3n]);
68+
~
69+
!!! error TS1351: An identifier cannot follow a numeric literal.
70+
~
71+
!!! error TS1351: An identifier cannot follow a numeric literal.
72+
~
73+
!!! error TS1351: An identifier cannot follow a numeric literal.
4774
bigUintArray = new BigUint64Array([1, 2, 3]); // should error
4875
~~~~~~~~~
4976
!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'.
@@ -60,12 +87,20 @@ tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '12
6087
// Test added DataView methods
6188
const dataView = new DataView(new ArrayBuffer(80));
6289
dataView.setBigInt64(1, -1n);
90+
~
91+
!!! error TS1351: An identifier cannot follow a numeric literal.
6392
dataView.setBigInt64(1, -1n, true);
93+
~
94+
!!! error TS1351: An identifier cannot follow a numeric literal.
6495
dataView.setBigInt64(1, -1); // should error
6596
~~
6697
!!! error TS2345: Argument of type '-1' is not assignable to parameter of type 'bigint'.
6798
dataView.setBigUint64(2, 123n);
99+
~
100+
!!! error TS1351: An identifier cannot follow a numeric literal.
68101
dataView.setBigUint64(2, 123n, true);
102+
~
103+
!!! error TS1351: An identifier cannot follow a numeric literal.
69104
dataView.setBigUint64(2, 123); // should error
70105
~~~
71106
!!! error TS2345: Argument of type '123' is not assignable to parameter of type 'bigint'.
@@ -76,6 +111,16 @@ tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '12
76111

77112
// Test emitted declarations files
78113
const w = 12n; // should emit as const w = 12n
114+
~
115+
!!! error TS1351: An identifier cannot follow a numeric literal.
79116
const x = -12n; // should emit as const x = -12n
117+
~
118+
!!! error TS1351: An identifier cannot follow a numeric literal.
80119
const y: 12n = 12n; // should emit type 12n
81-
let z = 12n; // should emit type bigint in declaration file
120+
~
121+
!!! error TS1351: An identifier cannot follow a numeric literal.
122+
~
123+
!!! error TS1351: An identifier cannot follow a numeric literal.
124+
let z = 12n; // should emit type bigint in declaration file
125+
~
126+
!!! error TS1351: An identifier cannot follow a numeric literal.

0 commit comments

Comments
 (0)