mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Merge pull request #28896 from JoshuaKGoldberg/n-identifier-after-numeric-literal-error
Better error message for invalid bigint literals ending with n
This commit is contained in:
@@ -1015,6 +1015,14 @@
|
||||
"category": "Error",
|
||||
"code": 1351
|
||||
},
|
||||
"A bigint literal cannot use exponential notation.": {
|
||||
"category": "Error",
|
||||
"code": 1352
|
||||
},
|
||||
"A bigint literal must be an integer.": {
|
||||
"category": "Error",
|
||||
"code": 1353
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -976,7 +976,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
|
||||
checkForIdentifierStartAfterNumericLiteral();
|
||||
checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific));
|
||||
return {
|
||||
type: SyntaxKind.NumericLiteral,
|
||||
value: "" + +result // if value is not an integer, it can be safely coerced to a number
|
||||
@@ -985,20 +985,31 @@ namespace ts {
|
||||
else {
|
||||
tokenValue = result;
|
||||
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
|
||||
checkForIdentifierStartAfterNumericLiteral();
|
||||
checkForIdentifierStartAfterNumericLiteral(start);
|
||||
return { type, value: tokenValue };
|
||||
}
|
||||
}
|
||||
|
||||
function checkForIdentifierStartAfterNumericLiteral() {
|
||||
function checkForIdentifierStartAfterNumericLiteral(numericStart: number, isScientific?: boolean) {
|
||||
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;
|
||||
|
||||
if (length === 1 && text[identifierStart] === "n") {
|
||||
if (isScientific) {
|
||||
error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
|
||||
pos = identifierStart;
|
||||
}
|
||||
}
|
||||
|
||||
function scanOctalDigits(): number {
|
||||
|
||||
@@ -9,10 +9,12 @@ tests/cases/compiler/identifierStartAfterNumericLiteral.ts(6,5): error TS1124: D
|
||||
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,1): error TS1352: A bigint literal cannot use exponential notation.
|
||||
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(9,5): error TS2538: Type 'null' cannot be used as an index type.
|
||||
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(10,1): error TS1352: A bigint literal cannot use exponential notation.
|
||||
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(10,7): error TS2538: Type 'null' cannot be used as an index type.
|
||||
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.
|
||||
@@ -35,7 +37,7 @@ tests/cases/compiler/identifierStartAfterNumericLiteral.ts(26,5): error TS1351:
|
||||
tests/cases/compiler/identifierStartAfterNumericLiteral.ts(26,5): error TS2304: Cannot find name 'abc'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/identifierStartAfterNumericLiteral.ts (35 errors) ====
|
||||
==== tests/cases/compiler/identifierStartAfterNumericLiteral.ts (37 errors) ====
|
||||
let valueIn = 3in[null];
|
||||
~~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
@@ -67,15 +69,19 @@ tests/cases/compiler/identifierStartAfterNumericLiteral.ts(26,5): error TS2304:
|
||||
~~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
3en[null]
|
||||
~~~
|
||||
!!! error TS1352: A bigint literal cannot use exponential notation.
|
||||
|
||||
!!! error TS1124: Digit expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'n'.
|
||||
~~~~
|
||||
!!! error TS2538: Type 'null' cannot be used as an index type.
|
||||
123en[null]
|
||||
~~~~~
|
||||
!!! error TS1352: A bigint literal cannot use exponential notation.
|
||||
|
||||
!!! error TS1124: Digit expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'n'.
|
||||
~~~~
|
||||
!!! error TS2538: Type 'null' cannot be used as an index type.
|
||||
1a
|
||||
~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
|
||||
@@ -37,10 +37,8 @@ a[null];
|
||||
123e[null];
|
||||
3 in [null];
|
||||
123 in [null];
|
||||
3e;
|
||||
n[null];
|
||||
123e;
|
||||
n[null];
|
||||
3en[null];
|
||||
123en[null];
|
||||
1;
|
||||
a;
|
||||
123;
|
||||
|
||||
@@ -41,15 +41,13 @@ let valueIn = 3in[null];
|
||||
>null : null
|
||||
|
||||
3en[null]
|
||||
>3e : 3
|
||||
>n[null] : any
|
||||
>n : any
|
||||
>3en[null] : any
|
||||
>3en : 3
|
||||
>null : null
|
||||
|
||||
123en[null]
|
||||
>123e : 123
|
||||
>n[null] : any
|
||||
>n : any
|
||||
>123en[null] : any
|
||||
>123en : 123
|
||||
>null : null
|
||||
|
||||
1a
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
tests/cases/compiler/parseBigInt.ts(51,20): error TS2736: Operator '+' cannot be applied to type '123n'.
|
||||
tests/cases/compiler/parseBigInt.ts(52,23): error TS2736: Operator '+' cannot be applied to type '291n'.
|
||||
tests/cases/compiler/parseBigInt.ts(56,25): error TS1005: ',' expected.
|
||||
tests/cases/compiler/parseBigInt.ts(57,25): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
tests/cases/compiler/parseBigInt.ts(58,22): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
tests/cases/compiler/parseBigInt.ts(59,28): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
tests/cases/compiler/parseBigInt.ts(57,22): error TS1352: A bigint literal cannot use exponential notation.
|
||||
tests/cases/compiler/parseBigInt.ts(58,19): error TS1353: A bigint literal must be an integer.
|
||||
tests/cases/compiler/parseBigInt.ts(59,26): error TS1353: A bigint literal must be an integer.
|
||||
tests/cases/compiler/parseBigInt.ts(60,23): error TS1177: Binary digit expected.
|
||||
tests/cases/compiler/parseBigInt.ts(61,20): error TS1178: Octal digit expected.
|
||||
tests/cases/compiler/parseBigInt.ts(62,20): error TS1125: Hexadecimal digit expected.
|
||||
@@ -81,14 +81,14 @@ tests/cases/compiler/parseBigInt.ts(70,72): error TS2345: Argument of type '3' i
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
{ const scientific = 1e2n; }
|
||||
~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
~~~~
|
||||
!!! error TS1352: A bigint literal cannot use exponential notation.
|
||||
{ const decimal = 4.1n; }
|
||||
~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
~~~~
|
||||
!!! error TS1353: A bigint literal must be an integer.
|
||||
{ const leadingDecimal = .1n; }
|
||||
~
|
||||
!!! error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
|
||||
~~~
|
||||
!!! error TS1353: A bigint literal must be an integer.
|
||||
const emptyBinary = 0bn; // should error but infer 0n
|
||||
|
||||
!!! error TS1177: Binary digit expected.
|
||||
|
||||
@@ -123,13 +123,13 @@ const unaryPlusHex = +0x123n;
|
||||
const legacyOct = 0123, n;
|
||||
}
|
||||
{
|
||||
const scientific = 1e2, n;
|
||||
const scientific = 1e2n;
|
||||
}
|
||||
{
|
||||
const decimal = 4.1, n;
|
||||
const decimal = 4.1n;
|
||||
}
|
||||
{
|
||||
const leadingDecimal = .1, n;
|
||||
const leadingDecimal = .1n;
|
||||
}
|
||||
const emptyBinary = 0n; // should error but infer 0n
|
||||
const emptyOct = 0n; // should error but infer 0n
|
||||
|
||||
@@ -131,15 +131,12 @@ const unaryPlusHex = +0x123n;
|
||||
|
||||
{ const scientific = 1e2n; }
|
||||
>scientific : Symbol(scientific, Decl(parseBigInt.ts, 56, 7))
|
||||
>n : Symbol(n, Decl(parseBigInt.ts, 56, 24))
|
||||
|
||||
{ const decimal = 4.1n; }
|
||||
>decimal : Symbol(decimal, Decl(parseBigInt.ts, 57, 7))
|
||||
>n : Symbol(n, Decl(parseBigInt.ts, 57, 21))
|
||||
|
||||
{ const leadingDecimal = .1n; }
|
||||
>leadingDecimal : Symbol(leadingDecimal, Decl(parseBigInt.ts, 58, 7))
|
||||
>n : Symbol(n, Decl(parseBigInt.ts, 58, 27))
|
||||
|
||||
const emptyBinary = 0bn; // should error but infer 0n
|
||||
>emptyBinary : Symbol(emptyBinary, Decl(parseBigInt.ts, 59, 5))
|
||||
|
||||
@@ -180,18 +180,15 @@ const unaryPlusHex = +0x123n;
|
||||
|
||||
{ const scientific = 1e2n; }
|
||||
>scientific : 100
|
||||
>1e2 : 100
|
||||
>n : any
|
||||
>1e2n : 100
|
||||
|
||||
{ const decimal = 4.1n; }
|
||||
>decimal : 4.1
|
||||
>4.1 : 4.1
|
||||
>n : any
|
||||
>4.1n : 4.1
|
||||
|
||||
{ const leadingDecimal = .1n; }
|
||||
>leadingDecimal : 0.1
|
||||
>.1 : 0.1
|
||||
>n : any
|
||||
>.1n : 0.1
|
||||
|
||||
const emptyBinary = 0bn; // should error but infer 0n
|
||||
>emptyBinary : 0n
|
||||
|
||||
Reference in New Issue
Block a user