Repository navigation
Conversation
Janther
force-pushed
the
parser-is-not-used
branch
from
October 12, 2026 02:32
8e35c09 to
35f32a1
Compare
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.
Slang's
inferLanguageVersionsinternally parses the whole file using the latest parser they have and fetches allVersionExpressionSetsto then return an array of matching versions.The way we were parsing, we were doing the work twice, once for inference and once for the actual parse.
By parsing directly with the latest parser and collecting the pragmas, we can use a much smaller input to infer the same array of versions and then if we happen to match with the latest version, we have an output ready to go.
As an example for OpenZeppelin v3.4's
TimelockController.sol(301 lines), the inference receives only:The highest version these pragmas allow is
0.7.6, not the latest, so we parse again with0.7.6. That's the same two parses as before, plus collecting the pragmas through calls from JavaScript into Slang instead of entirely inside Slang. That overhead is small enough to be lost in the noise here (15.2 ms → 15.1 ms).Pragmas anywhere in the file are found, which matters for flattened files. For OpenZeppelin's
ERC20flattened with its dependencies (604 lines, 7 contracts), it receives only:Here the highest allowed version is the latest one (
0.8.37), so the parse we already have is the result: 1 parse instead of an inference plus a parse (12.5 ms → 6.7 ms).In the worst case, the inferred array will force us to parse again with an older version which is roughly the same amount of work we were originally doing.
main0.8.26), or the latest version can't parse the file (syntax from before 0.8.0)createParseralso now returns{ version, parseOutput }instead of theParser, since callers only ever readparser.languageVersion.The name
createParseris not accurate anymore, since we return{ version, parseOutput }, so I would be changing it in a PR after this since it touches a few files in testing as well. I'm thinking aboutparseSourceUnit()since that describes better what it does. Welcoming suggestions @fvictorioBenchmark
Formatting OpenZeppelin v5.7.0's
contracts/(368 files) with Prettier 3.9.9 on Node 26 (Apple M3 Pro):main1.31× faster.