Skip to content

Commit 96bef67

Browse files
Andaristjakebailey
andauthored
Disallow negative numbers in create numeric literal (take 2) (#56570)
Co-authored-by: Jake Bailey <[email protected]>
1 parent 8456dcc commit 96bef67

File tree

5 files changed

+17
-7
lines changed

5 files changed

+17
-7
lines changed

src/compiler/checker.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -48149,8 +48149,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4814948149
if (enumResult) return enumResult;
4815048150
const literalValue = (type as LiteralType).value;
4815148151
return typeof literalValue === "object" ? factory.createBigIntLiteral(literalValue) :
48152-
typeof literalValue === "number" ? factory.createNumericLiteral(literalValue) :
48153-
factory.createStringLiteral(literalValue);
48152+
typeof literalValue === "string" ? factory.createStringLiteral(literalValue) :
48153+
literalValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-literalValue)) :
48154+
factory.createNumericLiteral(literalValue);
4815448155
}
4815548156

4815648157
function createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker) {

src/compiler/factory/nodeFactory.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
CaseOrDefaultClause,
4545
cast,
4646
CatchClause,
47+
CharacterCodes,
4748
ClassDeclaration,
4849
ClassElement,
4950
ClassExpression,
@@ -1254,8 +1255,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
12541255

12551256
// @api
12561257
function createNumericLiteral(value: string | number, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral {
1258+
const text = typeof value === "number" ? value + "" : value;
1259+
Debug.assert(text.charCodeAt(0) !== CharacterCodes.minus, "Negative numbers should be created in combination with createPrefixUnaryExpression");
12571260
const node = createBaseDeclaration<NumericLiteral>(SyntaxKind.NumericLiteral);
1258-
node.text = typeof value === "number" ? value + "" : value;
1261+
node.text = text;
12591262
node.numericLiteralFlags = numericLiteralFlags;
12601263
if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015;
12611264
return node;

src/compiler/transformers/declarations.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1798,7 +1798,11 @@ export function transformDeclarations(context: TransformationContext) {
17981798
if (shouldStripInternal(m)) return;
17991799
// Rewrite enum values to their constants, if available
18001800
const constValue = resolver.getConstantValue(m);
1801-
return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m);
1801+
const newInitializer = constValue === undefined ? undefined
1802+
: typeof constValue === "string" ? factory.createStringLiteral(constValue)
1803+
: constValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-constValue))
1804+
: factory.createNumericLiteral(constValue);
1805+
return preserveJsDoc(factory.updateEnumMember(m, m.name, newInitializer), m);
18021806
})),
18031807
));
18041808
}

src/compiler/transformers/generators.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2524,7 +2524,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
25242524
labelExpressions = [];
25252525
}
25262526

2527-
const expression = factory.createNumericLiteral(-1);
2527+
const expression = factory.createNumericLiteral(Number.MAX_SAFE_INTEGER);
25282528
if (labelExpressions[label] === undefined) {
25292529
labelExpressions[label] = [expression];
25302530
}

src/compiler/transformers/ts.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1901,7 +1901,9 @@ export function transformTypeScript(context: TransformationContext) {
19011901
function transformEnumMemberDeclarationValue(member: EnumMember): Expression {
19021902
const value = resolver.getConstantValue(member);
19031903
if (value !== undefined) {
1904-
return typeof value === "string" ? factory.createStringLiteral(value) : factory.createNumericLiteral(value);
1904+
return typeof value === "string" ? factory.createStringLiteral(value) :
1905+
value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-value)) :
1906+
factory.createNumericLiteral(value);
19051907
}
19061908
else {
19071909
enableSubstitutionForNonQualifiedEnumMembers();
@@ -2687,7 +2689,7 @@ export function transformTypeScript(context: TransformationContext) {
26872689
// track the constant value on the node for the printer in mayNeedDotDotForPropertyAccess
26882690
setConstantValue(node, constantValue);
26892691
const substitute = typeof constantValue === "string" ? factory.createStringLiteral(constantValue) :
2690-
constantValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(constantValue))) :
2692+
constantValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-constantValue)) :
26912693
factory.createNumericLiteral(constantValue);
26922694

26932695
if (!compilerOptions.removeComments) {

0 commit comments

Comments
 (0)