Skip to content

Commit 15e8aaa

Browse files
committed
rework how number types are made to fix node 0.10 octal literals
1 parent 4d931db commit 15e8aaa

File tree

3 files changed

+25
-22
lines changed

3 files changed

+25
-22
lines changed

src/compiler/checker.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ namespace ts {
183183
const intersectionTypes: Map<IntersectionType> = {};
184184
const stringLiteralTypes: Map<StringLiteralType> = {};
185185
const numericLiteralTypes: Map<NumericLiteralType> = {};
186-
const NaNLiteralType = getNumericLiteralTypeForText(NaN.toString());
187-
const InfinityLiteralType = getNumericLiteralTypeForText(Infinity.toString());
186+
const NaNLiteralType = getNumericLiteralTypeForNumber(NaN);
187+
const InfinityLiteralType = getNumericLiteralTypeForNumber(Infinity);
188188

189189
const resolutionTargets: TypeSystemEntity[] = [];
190190
const resolutionResults: boolean[] = [];
@@ -4944,9 +4944,10 @@ namespace ts {
49444944
function getNumericLiteralTypeForText(text: string): NumericLiteralType {
49454945
// Use +(string) rather than Number(string) to be consistient with what we use in the parser
49464946
const num = +(text);
4947-
if (typeof num !== "number") {
4948-
return NaNLiteralType;
4949-
}
4947+
return getNumericLiteralTypeForNumber(num, text);
4948+
}
4949+
4950+
function getNumericLiteralTypeForNumber(num: number, text: string = num.toString()): NumericLiteralType {
49504951
if (hasProperty(numericLiteralTypes, text)) {
49514952
return numericLiteralTypes[text];
49524953
}
@@ -4968,7 +4969,7 @@ namespace ts {
49684969
function getTypeFromNumericLiteralTypeNode(node: NumericLiteralTypeNode): Type {
49694970
const links = getNodeLinks(node);
49704971
if (!links.resolvedType) {
4971-
links.resolvedType = getNumericLiteralTypeForText(node.text);
4972+
links.resolvedType = getNumericLiteralTypeForNumber(node.number, node.text);
49724973
}
49734974
return links.resolvedType;
49744975
}
@@ -11206,13 +11207,13 @@ namespace ts {
1120611207
if (operandType.flags & TypeFlags.NumericLiteral) {
1120711208
const litType = operandType as NumericLiteralType;
1120811209
const newNumber = -litType.number;
11209-
return getNumericLiteralTypeForText(newNumber.toString());
11210+
return getNumericLiteralTypeForNumber(newNumber);
1121011211
}
1121111212
case SyntaxKind.TildeToken:
1121211213
if (operandType.flags & TypeFlags.NumericLiteral) {
1121311214
const litType = operandType as NumericLiteralType;
1121411215
const newNumber = ~litType.number;
11215-
return getNumericLiteralTypeForText(newNumber.toString());
11216+
return getNumericLiteralTypeForNumber(newNumber);
1121611217
}
1121711218
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
1121811219
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
@@ -11224,13 +11225,13 @@ namespace ts {
1122411225
if (operandType.flags & TypeFlags.NumericLiteral) {
1122511226
const litType = operandType as NumericLiteralType;
1122611227
const newNumber = litType.number + 1;
11227-
return getNumericLiteralTypeForText(newNumber.toString());
11228+
return getNumericLiteralTypeForNumber(newNumber);
1122811229
}
1122911230
case SyntaxKind.MinusMinusToken:
1123011231
if (operandType.flags & TypeFlags.NumericLiteral) {
1123111232
const litType = operandType as NumericLiteralType;
1123211233
const newNumber = litType.number - 1;
11233-
return getNumericLiteralTypeForText(newNumber.toString());
11234+
return getNumericLiteralTypeForNumber(newNumber);
1123411235
}
1123511236
const ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
1123611237
if (ok) {
@@ -11476,49 +11477,49 @@ namespace ts {
1147611477
case SyntaxKind.AsteriskEqualsToken:
1147711478
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1147811479
const newNumber = (leftType as NumericLiteralType).number * (rightType as NumericLiteralType).number;
11479-
return getNumericLiteralTypeForText(newNumber.toString());
11480+
return getNumericLiteralTypeForNumber(newNumber);
1148011481
}
1148111482
case SyntaxKind.AsteriskAsteriskToken:
1148211483
case SyntaxKind.AsteriskAsteriskEqualsToken:
1148311484
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1148411485
const newNumber = (leftType as NumericLiteralType).number ** (rightType as NumericLiteralType).number;
11485-
return getNumericLiteralTypeForText(newNumber.toString());
11486+
return getNumericLiteralTypeForNumber(newNumber);
1148611487
}
1148711488
case SyntaxKind.SlashToken:
1148811489
case SyntaxKind.SlashEqualsToken:
1148911490
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1149011491
const newNumber = (leftType as NumericLiteralType).number / (rightType as NumericLiteralType).number;
11491-
return getNumericLiteralTypeForText(newNumber.toString());
11492+
return getNumericLiteralTypeForNumber(newNumber);
1149211493
}
1149311494
case SyntaxKind.PercentToken:
1149411495
case SyntaxKind.PercentEqualsToken:
1149511496
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1149611497
const newNumber = (leftType as NumericLiteralType).number % (rightType as NumericLiteralType).number;
11497-
return getNumericLiteralTypeForText(newNumber.toString());
11498+
return getNumericLiteralTypeForNumber(newNumber);
1149811499
}
1149911500
case SyntaxKind.MinusToken:
1150011501
case SyntaxKind.MinusEqualsToken:
1150111502
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1150211503
const newNumber = (leftType as NumericLiteralType).number - (rightType as NumericLiteralType).number;
11503-
return getNumericLiteralTypeForText(newNumber.toString());
11504+
return getNumericLiteralTypeForNumber(newNumber);
1150411505
}
1150511506
case SyntaxKind.BarToken:
1150611507
case SyntaxKind.BarEqualsToken:
1150711508
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1150811509
const newNumber = (leftType as NumericLiteralType).number | (rightType as NumericLiteralType).number;
11509-
return getNumericLiteralTypeForText(newNumber.toString());
11510+
return getNumericLiteralTypeForNumber(newNumber);
1151011511
}
1151111512
case SyntaxKind.CaretToken:
1151211513
case SyntaxKind.CaretEqualsToken:
1151311514
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1151411515
const newNumber = (leftType as NumericLiteralType).number ^ (rightType as NumericLiteralType).number;
11515-
return getNumericLiteralTypeForText(newNumber.toString());
11516+
return getNumericLiteralTypeForNumber(newNumber);
1151611517
}
1151711518
case SyntaxKind.AmpersandToken:
1151811519
case SyntaxKind.AmpersandEqualsToken:
1151911520
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1152011521
const newNumber = (leftType as NumericLiteralType).number & (rightType as NumericLiteralType).number;
11521-
return getNumericLiteralTypeForText(newNumber.toString());
11522+
return getNumericLiteralTypeForNumber(newNumber);
1152211523
}
1152311524
case SyntaxKind.LessThanLessThanToken:
1152411525
case SyntaxKind.LessThanLessThanEqualsToken:
@@ -11558,7 +11559,7 @@ namespace ts {
1155811559
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1155911560
// TODO (weswig): add case for when 1 side is a string literal type and the other is a numeric literal, then cast as appropriate
1156011561
const newNumber = (leftType as NumericLiteralType).number + (rightType as NumericLiteralType).number;
11561-
return getNumericLiteralTypeForText(newNumber.toString());
11562+
return getNumericLiteralTypeForNumber(newNumber);
1156211563
}
1156311564
// TypeScript 1.0 spec (April 2014): 4.19.2
1156411565
// The binary + operator requires both operands to be of the Number primitive type or an enum type,

src/compiler/parser.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1905,9 +1905,10 @@ namespace ts {
19051905

19061906
function parseNumericLiteralTypeNode(): NumericLiteralTypeNode {
19071907
const node = createNode(SyntaxKind.NumericLiteralType) as NumericLiteralTypeNode;
1908-
// Get token text rather than value, this way number formatting is preserved
1909-
const text = scanner.getTokenText();
1910-
node.text = text;
1908+
// Get token text for node text rather than value, this way number formatting is preserved
1909+
node.text = scanner.getTokenText();
1910+
// But store the number on the node because we need it for comparisons later
1911+
node.number = +(scanner.getTokenValue());
19111912
return finishLiteralLikeNode(node);
19121913
}
19131914

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ namespace ts {
783783
// @kind(SyntaxKind.NumericLiteralTypeNode)
784784
export interface NumericLiteralTypeNode extends LiteralLikeNode, TypeNode {
785785
_numericLiteralTypeBrand: any;
786+
number: number; // The value of the number
786787
}
787788

788789
// @kind(SyntaxKind.StringLiteral)

0 commit comments

Comments
 (0)