Skip to content

Commit

Permalink
Disallow negative numbers in create numeric literal (take 2) (#56570)
Browse files Browse the repository at this point in the history
Co-authored-by: Jake Bailey <[email protected]>
  • Loading branch information
Andarist and jakebailey authored Dec 7, 2023
1 parent 8456dcc commit 96bef67
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48149,8 +48149,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (enumResult) return enumResult;
const literalValue = (type as LiteralType).value;
return typeof literalValue === "object" ? factory.createBigIntLiteral(literalValue) :
typeof literalValue === "number" ? factory.createNumericLiteral(literalValue) :
factory.createStringLiteral(literalValue);
typeof literalValue === "string" ? factory.createStringLiteral(literalValue) :
literalValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-literalValue)) :
factory.createNumericLiteral(literalValue);
}

function createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker) {
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
CaseOrDefaultClause,
cast,
CatchClause,
CharacterCodes,
ClassDeclaration,
ClassElement,
ClassExpression,
Expand Down Expand Up @@ -1254,8 +1255,10 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode

// @api
function createNumericLiteral(value: string | number, numericLiteralFlags: TokenFlags = TokenFlags.None): NumericLiteral {
const text = typeof value === "number" ? value + "" : value;
Debug.assert(text.charCodeAt(0) !== CharacterCodes.minus, "Negative numbers should be created in combination with createPrefixUnaryExpression");
const node = createBaseDeclaration<NumericLiteral>(SyntaxKind.NumericLiteral);
node.text = typeof value === "number" ? value + "" : value;
node.text = text;
node.numericLiteralFlags = numericLiteralFlags;
if (numericLiteralFlags & TokenFlags.BinaryOrOctalSpecifier) node.transformFlags |= TransformFlags.ContainsES2015;
return node;
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/transformers/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1798,7 +1798,11 @@ export function transformDeclarations(context: TransformationContext) {
if (shouldStripInternal(m)) return;
// Rewrite enum values to their constants, if available
const constValue = resolver.getConstantValue(m);
return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m);
const newInitializer = constValue === undefined ? undefined
: typeof constValue === "string" ? factory.createStringLiteral(constValue)
: constValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-constValue))
: factory.createNumericLiteral(constValue);
return preserveJsDoc(factory.updateEnumMember(m, m.name, newInitializer), m);
})),
));
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transformers/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,7 @@ export function transformGenerators(context: TransformationContext): (x: SourceF
labelExpressions = [];
}

const expression = factory.createNumericLiteral(-1);
const expression = factory.createNumericLiteral(Number.MAX_SAFE_INTEGER);
if (labelExpressions[label] === undefined) {
labelExpressions[label] = [expression];
}
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/transformers/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1901,7 +1901,9 @@ export function transformTypeScript(context: TransformationContext) {
function transformEnumMemberDeclarationValue(member: EnumMember): Expression {
const value = resolver.getConstantValue(member);
if (value !== undefined) {
return typeof value === "string" ? factory.createStringLiteral(value) : factory.createNumericLiteral(value);
return typeof value === "string" ? factory.createStringLiteral(value) :
value < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-value)) :
factory.createNumericLiteral(value);
}
else {
enableSubstitutionForNonQualifiedEnumMembers();
Expand Down Expand Up @@ -2687,7 +2689,7 @@ export function transformTypeScript(context: TransformationContext) {
// track the constant value on the node for the printer in mayNeedDotDotForPropertyAccess
setConstantValue(node, constantValue);
const substitute = typeof constantValue === "string" ? factory.createStringLiteral(constantValue) :
constantValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(constantValue))) :
constantValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-constantValue)) :
factory.createNumericLiteral(constantValue);

if (!compilerOptions.removeComments) {
Expand Down

0 comments on commit 96bef67

Please sign in to comment.