extract-const-value: fold arithmetic BinaryExpression and UnaryExpression#92932
Open
yogeshwaran-c wants to merge 1 commit intovercel:canaryfrom
Open
extract-const-value: fold arithmetic BinaryExpression and UnaryExpression#92932yogeshwaran-c wants to merge 1 commit intovercel:canaryfrom
yogeshwaran-c wants to merge 1 commit intovercel:canaryfrom
Conversation
…sion
`export const revalidate = 60 * 5` failed `next build` with
Unsupported node type "BinaryExpression" at "revalidate"
forcing users to inline the result by hand. The const-value extractor
walked literals, arrays, objects, regexp, template literals, identifiers
(only `undefined`), and TS-only type wrappers — but had no case for
`BinaryExpression` or `UnaryExpression`, so any compile-time arithmetic
or string-concat expression bailed out.
Add cases for `BinaryExpression` and `UnaryExpression` restricted to a
small set of pure operators that have no side-effect or short-circuit
semantics:
- Binary: `+ - * / % **`
- Unary: `- + ~`
Logical (`&& || ??`), comparison (`< > == ===` etc.), and `!` / `typeof`
/ `void` / `delete` are intentionally left as `unsupported` — they
either short-circuit (changing what we'd extract) or evaluate runtime
semantics that don't belong in a build-time constant.
Added unit tests covering the regression case from vercel#72365 plus
nested folding, string concatenation, unary forms, the exponentiation
operator, and rejection cases for unsupported operators and identifiers
inside an otherwise-foldable expression.
Fixes vercel#72365
Contributor
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Make
next buildrecognize compile-time arithmetic in segment-config exports likeToday these fail with
forcing users to inline the result by hand.
Why?
extract-const-value.tswalks the SWC AST of an exportedconstinitializer and folds it down to a runtime value. It already handled literals (null,boolean,string,number,regexp, template literals with no expressions),Array/Objectexpressions, theundefinedidentifier, and TS-only wrappers (as,satisfies, type/const assertions). It had no case forBinaryExpressionorUnaryExpression, so any compound expression — even a trivially constant one like60 * 5or-42— bailed out as unsupported.This is reported as #72365, and a few callsites in the wild use the obvious pattern (e.g.
60 * 60 * 24for a 1-day revalidate window).How?
Added cases for
BinaryExpressionandUnaryExpression, restricted to a small set of pure operators with no side-effect or short-circuit semantics:+ - * / % **- + ~Logical (
&&,||,??), comparison (<,>,==,===,!=,!==,<=,>=), and unary!,typeof,void,deleteare intentionally not added — they either short-circuit (which would change what the extractor sees as "the value") or invoke runtime semantics that don't belong in a build-time constant. They keep returningunsupported.Recursion handles nesting naturally (
60 * 60 * 24→ folds left-to-right;100 + -42works because-42is aUnaryExpression(NumericLiteral(42))per the SWC AST).Test plan
Added
test/unit/extract-const-value.test.tswith 11 cases:60 * 5.BinaryExpression.60 * 60 * 24).'edge' + '').-42.100 + -42).2 ** 10).&&(binary).!(unary).1 + foo— confirms an unfoldable identifier in one operand still propagates the original "Unknown identifier" error rather than getting masked by the new code path.npx jest test/unit/extract-const-value.test.ts→ 11 passed locally.The test uses the same
installBindings()+parseModulesetup as the existingparse-page-static-info.test.tsto exercise real SWC parsing.Fixes #72365