Skip to content

Commit 576fdf9

Browse files
authored
Merge pull request #25886 from calebsander/feature/bigint
BigInt support
2 parents f37101e + bb99c41 commit 576fdf9

File tree

264 files changed

+11275
-5548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

264 files changed

+11275
-5548
lines changed

src/compiler/binder.ts

+6
Original file line numberDiff line numberDiff line change
@@ -3702,6 +3702,10 @@ namespace ts {
37023702
}
37033703
break;
37043704

3705+
case SyntaxKind.BigIntLiteral:
3706+
transformFlags |= TransformFlags.AssertESNext;
3707+
break;
3708+
37053709
case SyntaxKind.ForOfStatement:
37063710
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
37073711
if ((<ForOfStatement>node).awaitModifier) {
@@ -3718,6 +3722,7 @@ namespace ts {
37183722

37193723
case SyntaxKind.AnyKeyword:
37203724
case SyntaxKind.NumberKeyword:
3725+
case SyntaxKind.BigIntKeyword:
37213726
case SyntaxKind.NeverKeyword:
37223727
case SyntaxKind.ObjectKeyword:
37233728
case SyntaxKind.StringKeyword:
@@ -3926,6 +3931,7 @@ namespace ts {
39263931
return TransformFlags.MethodOrAccessorExcludes;
39273932
case SyntaxKind.AnyKeyword:
39283933
case SyntaxKind.NumberKeyword:
3934+
case SyntaxKind.BigIntKeyword:
39293935
case SyntaxKind.NeverKeyword:
39303936
case SyntaxKind.StringKeyword:
39313937
case SyntaxKind.ObjectKeyword:

src/compiler/checker.ts

+226-66
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ namespace ts {
4444
["esnext.array", "lib.esnext.array.d.ts"],
4545
["esnext.symbol", "lib.esnext.symbol.d.ts"],
4646
["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"],
47-
["esnext.intl", "lib.esnext.intl.d.ts"]
47+
["esnext.intl", "lib.esnext.intl.d.ts"],
48+
["esnext.bigint", "lib.esnext.bigint.d.ts"]
4849
];
4950

5051
/**
@@ -583,6 +584,12 @@ namespace ts {
583584
category: Diagnostics.Experimental_Options,
584585
description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
585586
},
587+
{
588+
name: "experimentalBigInt",
589+
type: "boolean",
590+
category: Diagnostics.Experimental_Options,
591+
description: Diagnostics.Enables_experimental_support_for_ESNext_BigInt_literals
592+
},
586593

587594
// Advanced
588595
{

src/compiler/diagnosticMessages.json

+19-3
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,10 @@
10111011
"category": "Message",
10121012
"code": 1350
10131013
},
1014+
"Experimental support for BigInt is a feature that is subject to change in a future release. Set the 'experimentalBigInt' option to remove this warning.": {
1015+
"category": "Error",
1016+
"code": 1351
1017+
},
10141018

10151019
"Duplicate identifier '{0}'.": {
10161020
"category": "Error",
@@ -1236,7 +1240,7 @@
12361240
"category": "Error",
12371241
"code": 2355
12381242
},
1239-
"An arithmetic operand must be of type 'any', 'number' or an enum type.": {
1243+
"An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.": {
12401244
"category": "Error",
12411245
"code": 2356
12421246
},
@@ -1260,11 +1264,11 @@
12601264
"category": "Error",
12611265
"code": 2361
12621266
},
1263-
"The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
1267+
"The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
12641268
"category": "Error",
12651269
"code": 2362
12661270
},
1267-
"The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
1271+
"The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
12681272
"category": "Error",
12691273
"code": 2363
12701274
},
@@ -2497,6 +2501,14 @@
24972501
"category": "Error",
24982502
"code": 2735
24992503
},
2504+
"Operator '{0}' cannot be applied to type '{1}'.": {
2505+
"category": "Error",
2506+
"code": 2736
2507+
},
2508+
"BigInt literals are not available when targetting lower than ESNext.": {
2509+
"category": "Error",
2510+
"code": 2737
2511+
},
25002512

25012513
"Import declaration '{0}' is using private name '{1}'.": {
25022514
"category": "Error",
@@ -3905,6 +3917,10 @@
39053917
"category": "Error",
39063918
"code": 6370
39073919
},
3920+
"Enables experimental support for ESNext BigInt literals.": {
3921+
"category": "Message",
3922+
"code": 6371
3923+
},
39083924

39093925
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
39103926
"category": "Message",

src/compiler/emitter.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,8 @@ namespace ts {
905905
switch (node.kind) {
906906
// Literals
907907
case SyntaxKind.NumericLiteral:
908-
return emitNumericLiteral(<NumericLiteral>node);
908+
case SyntaxKind.BigIntLiteral:
909+
return emitNumericOrBigIntLiteral(<NumericLiteral | BigIntLiteral>node);
909910

910911
case SyntaxKind.StringLiteral:
911912
case SyntaxKind.RegularExpressionLiteral:
@@ -1068,7 +1069,8 @@ namespace ts {
10681069
//
10691070

10701071
// SyntaxKind.NumericLiteral
1071-
function emitNumericLiteral(node: NumericLiteral) {
1072+
// SyntaxKind.BigIntLiteral
1073+
function emitNumericOrBigIntLiteral(node: NumericLiteral | BigIntLiteral) {
10721074
emitLiteral(node);
10731075
}
10741076

src/compiler/factory.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,16 @@ namespace ts {
6868
/* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // tslint:disable-line unified-signatures
6969
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
7070
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
71-
export function createLiteral(value: number): NumericLiteral;
71+
export function createLiteral(value: number | PseudoBigInt): NumericLiteral;
7272
export function createLiteral(value: boolean): BooleanLiteral;
73-
export function createLiteral(value: string | number | boolean): PrimaryExpression;
74-
export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
73+
export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression;
74+
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
7575
if (typeof value === "number") {
7676
return createNumericLiteral(value + "");
7777
}
78+
if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
79+
return createBigIntLiteral(pseudoBigIntToString(value) + "n");
80+
}
7881
if (typeof value === "boolean") {
7982
return value ? createTrue() : createFalse();
8083
}
@@ -93,6 +96,12 @@ namespace ts {
9396
return node;
9497
}
9598

99+
export function createBigIntLiteral(value: string): BigIntLiteral {
100+
const node = <BigIntLiteral>createSynthesizedNode(SyntaxKind.BigIntLiteral);
101+
node.text = value;
102+
return node;
103+
}
104+
96105
export function createStringLiteral(text: string): StringLiteral {
97106
const node = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
98107
node.text = text;
@@ -3467,6 +3476,7 @@ namespace ts {
34673476
return cacheIdentifiers;
34683477
case SyntaxKind.ThisKeyword:
34693478
case SyntaxKind.NumericLiteral:
3479+
case SyntaxKind.BigIntLiteral:
34703480
case SyntaxKind.StringLiteral:
34713481
return false;
34723482
case SyntaxKind.ArrayLiteralExpression:

src/compiler/parser.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -2247,8 +2247,7 @@ namespace ts {
22472247

22482248
function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode {
22492249
const node = <LiteralExpression>createNode(kind);
2250-
const text = scanner.getTokenValue();
2251-
node.text = text;
2250+
node.text = scanner.getTokenValue();
22522251

22532252
if (scanner.hasExtendedUnicodeEscape()) {
22542253
node.hasExtendedUnicodeEscape = true;
@@ -2892,8 +2891,9 @@ namespace ts {
28922891
return finishNode(node);
28932892
}
28942893

2895-
function nextTokenIsNumericLiteral() {
2896-
return nextToken() === SyntaxKind.NumericLiteral;
2894+
function nextTokenIsNumericOrBigIntLiteral() {
2895+
nextToken();
2896+
return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral;
28972897
}
28982898

28992899
function parseNonArrayType(): TypeNode {
@@ -2902,6 +2902,7 @@ namespace ts {
29022902
case SyntaxKind.UnknownKeyword:
29032903
case SyntaxKind.StringKeyword:
29042904
case SyntaxKind.NumberKeyword:
2905+
case SyntaxKind.BigIntKeyword:
29052906
case SyntaxKind.SymbolKeyword:
29062907
case SyntaxKind.BooleanKeyword:
29072908
case SyntaxKind.UndefinedKeyword:
@@ -2922,11 +2923,12 @@ namespace ts {
29222923
case SyntaxKind.NoSubstitutionTemplateLiteral:
29232924
case SyntaxKind.StringLiteral:
29242925
case SyntaxKind.NumericLiteral:
2926+
case SyntaxKind.BigIntLiteral:
29252927
case SyntaxKind.TrueKeyword:
29262928
case SyntaxKind.FalseKeyword:
29272929
return parseLiteralTypeNode();
29282930
case SyntaxKind.MinusToken:
2929-
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
2931+
return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
29302932
case SyntaxKind.VoidKeyword:
29312933
case SyntaxKind.NullKeyword:
29322934
return parseTokenNode<TypeNode>();
@@ -2960,6 +2962,7 @@ namespace ts {
29602962
case SyntaxKind.UnknownKeyword:
29612963
case SyntaxKind.StringKeyword:
29622964
case SyntaxKind.NumberKeyword:
2965+
case SyntaxKind.BigIntKeyword:
29632966
case SyntaxKind.BooleanKeyword:
29642967
case SyntaxKind.SymbolKeyword:
29652968
case SyntaxKind.UniqueKeyword:
@@ -2977,6 +2980,7 @@ namespace ts {
29772980
case SyntaxKind.NewKeyword:
29782981
case SyntaxKind.StringLiteral:
29792982
case SyntaxKind.NumericLiteral:
2983+
case SyntaxKind.BigIntLiteral:
29802984
case SyntaxKind.TrueKeyword:
29812985
case SyntaxKind.FalseKeyword:
29822986
case SyntaxKind.ObjectKeyword:
@@ -2990,7 +2994,7 @@ namespace ts {
29902994
case SyntaxKind.FunctionKeyword:
29912995
return !inStartOfParameter;
29922996
case SyntaxKind.MinusToken:
2993-
return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
2997+
return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
29942998
case SyntaxKind.OpenParenToken:
29952999
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
29963000
// or something that starts a type. We don't want to consider things like '(1)' a type.
@@ -3215,6 +3219,7 @@ namespace ts {
32153219
case SyntaxKind.TrueKeyword:
32163220
case SyntaxKind.FalseKeyword:
32173221
case SyntaxKind.NumericLiteral:
3222+
case SyntaxKind.BigIntLiteral:
32183223
case SyntaxKind.StringLiteral:
32193224
case SyntaxKind.NoSubstitutionTemplateLiteral:
32203225
case SyntaxKind.TemplateHead:
@@ -4624,6 +4629,7 @@ namespace ts {
46244629
function parsePrimaryExpression(): PrimaryExpression {
46254630
switch (token()) {
46264631
case SyntaxKind.NumericLiteral:
4632+
case SyntaxKind.BigIntLiteral:
46274633
case SyntaxKind.StringLiteral:
46284634
case SyntaxKind.NoSubstitutionTemplateLiteral:
46294635
return parseLiteralNode();
@@ -5139,7 +5145,7 @@ namespace ts {
51395145

51405146
function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
51415147
nextToken();
5142-
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
5148+
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
51435149
}
51445150

51455151
function isDeclaration(): boolean {

0 commit comments

Comments
 (0)