Skip to content

Commit 659d2e0

Browse files
committed
rework how number types are made to fix node 0.10 octal literals
1 parent e346855 commit 659d2e0

File tree

3 files changed

+25
-22
lines changed

3 files changed

+25
-22
lines changed

Diff for: src/compiler/checker.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ namespace ts {
193193
const intersectionTypes: Map<IntersectionType> = {};
194194
const stringLiteralTypes: Map<StringLiteralType> = {};
195195
const numericLiteralTypes: Map<NumericLiteralType> = {};
196-
const NaNLiteralType = getNumericLiteralTypeForText(NaN.toString());
197-
const InfinityLiteralType = getNumericLiteralTypeForText(Infinity.toString());
196+
const NaNLiteralType = getNumericLiteralTypeForNumber(NaN);
197+
const InfinityLiteralType = getNumericLiteralTypeForNumber(Infinity);
198198

199199
const resolutionTargets: TypeSystemEntity[] = [];
200200
const resolutionResults: boolean[] = [];
@@ -5110,9 +5110,10 @@ namespace ts {
51105110
function getNumericLiteralTypeForText(text: string): NumericLiteralType {
51115111
// Use +(string) rather than Number(string) to be consistient with what we use in the parser
51125112
const num = +(text);
5113-
if (typeof num !== "number") {
5114-
return NaNLiteralType;
5115-
}
5113+
return getNumericLiteralTypeForNumber(num, text);
5114+
}
5115+
5116+
function getNumericLiteralTypeForNumber(num: number, text: string = num.toString()): NumericLiteralType {
51165117
if (hasProperty(numericLiteralTypes, text)) {
51175118
return numericLiteralTypes[text];
51185119
}
@@ -5134,7 +5135,7 @@ namespace ts {
51345135
function getTypeFromNumericLiteralTypeNode(node: NumericLiteralTypeNode): Type {
51355136
const links = getNodeLinks(node);
51365137
if (!links.resolvedType) {
5137-
links.resolvedType = getNumericLiteralTypeForText(node.text);
5138+
links.resolvedType = getNumericLiteralTypeForNumber(node.number, node.text);
51385139
}
51395140
return links.resolvedType;
51405141
}
@@ -11877,13 +11878,13 @@ namespace ts {
1187711878
if (operandType.flags & TypeFlags.NumericLiteral) {
1187811879
const litType = operandType as NumericLiteralType;
1187911880
const newNumber = -litType.number;
11880-
return getNumericLiteralTypeForText(newNumber.toString());
11881+
return getNumericLiteralTypeForNumber(newNumber);
1188111882
}
1188211883
case SyntaxKind.TildeToken:
1188311884
if (operandType.flags & TypeFlags.NumericLiteral) {
1188411885
const litType = operandType as NumericLiteralType;
1188511886
const newNumber = ~litType.number;
11886-
return getNumericLiteralTypeForText(newNumber.toString());
11887+
return getNumericLiteralTypeForNumber(newNumber);
1188711888
}
1188811889
if (maybeTypeOfKind(operandType, TypeFlags.ESSymbol)) {
1188911890
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
@@ -11895,14 +11896,14 @@ namespace ts {
1189511896
if (operandType.flags & TypeFlags.NumericLiteral) {
1189611897
const litType = operandType as NumericLiteralType;
1189711898
const newNumber = litType.number + 1;
11898-
return getNumericLiteralTypeForText(newNumber.toString());
11899+
return getNumericLiteralTypeForNumber(newNumber);
1189911900
}
1190011901
// Intentional fallthrough
1190111902
case SyntaxKind.MinusMinusToken:
1190211903
if (operandType.flags & TypeFlags.NumericLiteral) {
1190311904
const litType = operandType as NumericLiteralType;
1190411905
const newNumber = litType.number - 1;
11905-
return getNumericLiteralTypeForText(newNumber.toString());
11906+
return getNumericLiteralTypeForNumber(newNumber);
1190611907
}
1190711908
const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType),
1190811909
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
@@ -12161,49 +12162,49 @@ namespace ts {
1216112162
case SyntaxKind.AsteriskEqualsToken:
1216212163
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1216312164
const newNumber = (leftType as NumericLiteralType).number * (rightType as NumericLiteralType).number;
12164-
return getNumericLiteralTypeForText(newNumber.toString());
12165+
return getNumericLiteralTypeForNumber(newNumber);
1216512166
}
1216612167
case SyntaxKind.AsteriskAsteriskToken:
1216712168
case SyntaxKind.AsteriskAsteriskEqualsToken:
1216812169
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1216912170
const newNumber = (leftType as NumericLiteralType).number ** (rightType as NumericLiteralType).number;
12170-
return getNumericLiteralTypeForText(newNumber.toString());
12171+
return getNumericLiteralTypeForNumber(newNumber);
1217112172
}
1217212173
case SyntaxKind.SlashToken:
1217312174
case SyntaxKind.SlashEqualsToken:
1217412175
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1217512176
const newNumber = (leftType as NumericLiteralType).number / (rightType as NumericLiteralType).number;
12176-
return getNumericLiteralTypeForText(newNumber.toString());
12177+
return getNumericLiteralTypeForNumber(newNumber);
1217712178
}
1217812179
case SyntaxKind.PercentToken:
1217912180
case SyntaxKind.PercentEqualsToken:
1218012181
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1218112182
const newNumber = (leftType as NumericLiteralType).number % (rightType as NumericLiteralType).number;
12182-
return getNumericLiteralTypeForText(newNumber.toString());
12183+
return getNumericLiteralTypeForNumber(newNumber);
1218312184
}
1218412185
case SyntaxKind.MinusToken:
1218512186
case SyntaxKind.MinusEqualsToken:
1218612187
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1218712188
const newNumber = (leftType as NumericLiteralType).number - (rightType as NumericLiteralType).number;
12188-
return getNumericLiteralTypeForText(newNumber.toString());
12189+
return getNumericLiteralTypeForNumber(newNumber);
1218912190
}
1219012191
case SyntaxKind.BarToken:
1219112192
case SyntaxKind.BarEqualsToken:
1219212193
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1219312194
const newNumber = (leftType as NumericLiteralType).number | (rightType as NumericLiteralType).number;
12194-
return getNumericLiteralTypeForText(newNumber.toString());
12195+
return getNumericLiteralTypeForNumber(newNumber);
1219512196
}
1219612197
case SyntaxKind.CaretToken:
1219712198
case SyntaxKind.CaretEqualsToken:
1219812199
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1219912200
const newNumber = (leftType as NumericLiteralType).number ^ (rightType as NumericLiteralType).number;
12200-
return getNumericLiteralTypeForText(newNumber.toString());
12201+
return getNumericLiteralTypeForNumber(newNumber);
1220112202
}
1220212203
case SyntaxKind.AmpersandToken:
1220312204
case SyntaxKind.AmpersandEqualsToken:
1220412205
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1220512206
const newNumber = (leftType as NumericLiteralType).number & (rightType as NumericLiteralType).number;
12206-
return getNumericLiteralTypeForText(newNumber.toString());
12207+
return getNumericLiteralTypeForNumber(newNumber);
1220712208
}
1220812209
case SyntaxKind.LessThanLessThanToken:
1220912210
case SyntaxKind.LessThanLessThanEqualsToken:
@@ -12246,7 +12247,7 @@ namespace ts {
1224612247
if (leftType.flags & rightType.flags & TypeFlags.NumericLiteral) {
1224712248
// TODO (weswig): add case for when 1 side is a string literal type and the other is a numeric literal, then cast as appropriate
1224812249
const newNumber = (leftType as NumericLiteralType).number + (rightType as NumericLiteralType).number;
12249-
return getNumericLiteralTypeForText(newNumber.toString());
12250+
return getNumericLiteralTypeForNumber(newNumber);
1225012251
}
1225112252
// TypeScript 1.0 spec (April 2014): 4.19.2
1225212253
// The binary + operator requires both operands to be of the Number primitive type or an enum type,

Diff for: src/compiler/parser.ts

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

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

Diff for: src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ namespace ts {
787787
// @kind(SyntaxKind.NumericLiteralTypeNode)
788788
export interface NumericLiteralTypeNode extends LiteralLikeNode, TypeNode {
789789
_numericLiteralTypeBrand: any;
790+
number: number; // The value of the number
790791
}
791792

792793
// @kind(SyntaxKind.StringLiteral)

0 commit comments

Comments
 (0)