-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
perf(es/compat): Merge regexp pass into Transformer
#11307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Code Review for PR #11307SummaryThis PR refactors the regexp compatibility pass by merging it into the 🐛 Critical BugLocation: unicode_sets_regex: config.unicode_regex, // ❌ BUG: Should be config.unicode_sets_regexThis line incorrectly assigns unicode_sets_regex: config.unicode_sets_regex,Impact: The ✅ Code Quality & Best PracticesPositive aspects:
Architecture improvements:
🔍 Code AnalysisDependency changes:
Implementation details:
🧪 Test CoverageConcern: No test modifications or additions were made in this PR. Recommendation:
🔒 Security ConsiderationsNo security concerns identified. The transformation logic remains the same, only the architecture changed. 📊 Performance ConsiderationsPositive:
Note: The actual performance benefit should be measurable in the benchmarks. Consider documenting the performance improvement in the PR description once benchmarks complete. 🎯 Action Items
Compliance with CLAUDE.md
Overall Assessment: Good refactoring with solid architectural improvements, but must fix the copy-paste bug before merging. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the regexp compatibility transformation by merging it into the Transformer architecture. The transformation logic is moved from swc_ecma_compat_common to swc_ecma_transformer and converted from a VisitMut pattern to a VisitMutHook pattern for better integration with the transformer pipeline.
- Moved regexp pass implementation from
swc_ecma_compat_commontoswc_ecma_transformer - Converted the implementation from
VisitMuttoVisitMutHookfor hook-based traversal - Added
into_pass()method toOptionsfor creating transformer passes
Reviewed Changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/swc_ecma_transformer/src/regexp.rs | Implements the regexp transformation logic using VisitMutHook pattern with exit_expr hook |
| crates/swc_ecma_transformer/src/lib.rs | Adds into_pass() method to Options for creating transformer passes |
| crates/swc_ecma_compat_common/src/regexp.rs | Updated to delegate to swc_ecma_transformer by constructing Options and calling into_pass() |
| crates/swc_ecma_transformer/Cargo.toml | Added swc_common dependency and reordered dependencies alphabetically |
| crates/swc_ecma_compat_common/Cargo.toml | Added swc_ecma_transformer dependency and reordered dependencies alphabetically |
| Cargo.lock | Updated lock file to reflect new dependency relationships |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| || (self.options.lookbehind_assertion && regex.exp.contains("(?<=") | ||
| || regex.exp.contains("(?<!")) |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logical operator precedence issue causes regex.exp.contains("(?<!") to always trigger transformation regardless of the lookbehind_assertion option. The condition should be:
|| (self.options.lookbehind_assertion && (regex.exp.contains("(?<=") || regex.exp.contains("(?<!")))This ensures both lookbehind patterns are only transformed when the option is enabled.
| || (self.options.lookbehind_assertion && regex.exp.contains("(?<=") | |
| || regex.exp.contains("(?<!")) | |
| || (self.options.lookbehind_assertion && (regex.exp.contains("(?<=") || regex.exp.contains("(?<!"))) |
| sticky_regex: config.sticky_regex, | ||
| unicode_property_regex: config.unicode_property_regex, | ||
| unicode_regex: config.unicode_regex, | ||
| unicode_sets_regex: config.unicode_regex, |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unicode_sets_regex field is being assigned the value of config.unicode_regex instead of config.unicode_sets_regex. This is a copy-paste error that will prevent the unicode sets regex transformation from working correctly when config.unicode_sets_regex is true.
| unicode_sets_regex: config.unicode_regex, | |
| unicode_sets_regex: config.unicode_sets_regex, |
CodSpeed Performance ReportMerging #11307 will not alter performanceComparing Summary
|
Code ReviewOverviewThis PR consolidates the regexp transformation pass into the new crate, moving away from the standalone visitor pattern to the hook-based architecture. This is a performance-oriented refactoring that reduces the number of AST traversals. ✅ Strengths
🔍 Observations
|
Code Review: PR #11307 - perf(es/compat): Merge
|
Binary Sizes
Commit: f4ebc8a |
Code Review: PR #11307 - perf(es/compat): Merge
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
regexp pass into Transfomerregexp pass into Transformer
Code Review: Performance Optimization - Merge
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| || (self.options.lookbehind_assertion && regex.exp.contains("(?<=") | ||
| || regex.exp.contains("(?<!")) |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Operator precedence issue: the condition for lookbehind_assertion is incorrectly grouped. Line 60's || regex.exp.contains(\"(?<!\") is not checked against self.options.lookbehind_assertion, so negative lookbehind patterns (?<!) will always be transformed regardless of the option setting. Add parentheses around the entire lookbehind check: || (self.options.lookbehind_assertion && (regex.exp.contains(\"(?<=\") || regex.exp.contains(\"(?<!\")))
| || (self.options.lookbehind_assertion && regex.exp.contains("(?<=") | |
| || regex.exp.contains("(?<!")) | |
| || (self.options.lookbehind_assertion && (regex.exp.contains("(?<=") || regex.exp.contains("(?<!"))) |
Code ReviewThank you for this performance optimization! This PR merges the pass into the to improve performance. Overall, the refactoring looks good, but there are several issues that need to be addressed before merging. 🐛 Critical Issues1. Compilation Error: Non-exhaustive StructLocation: The code fails to compile because Fix: Either:
2. Operator Precedence Bug in Lookbehind Assertion CheckLocation: || (self.options.lookbehind_assertion && regex.exp.contains("(?<=")
|| regex.exp.contains("(?<\!"))Due to operator precedence, this is parsed as: (self.options.lookbehind_assertion && regex.exp.contains("(?<=")) || regex.exp.contains("(?<\!")This means negative lookbehind Fix: Add parentheses: || (self.options.lookbehind_assertion && (regex.exp.contains("(?<=") || regex.exp.contains("(?<\!")))📝 Code Quality Issues3. Missing Unit TestsObservation: The PR doesn't add unit tests for the new Per CLAUDE.md instruction #5: "Write unit tests for your code." Recommendation: Add unit tests to verify:
4. Test Output ChangeLocation: The test expectation changed from: var c = RegExp(".", "imsuy");to: var c = new RegExp(".", "imsuy");Question: Is this intentional? Both are semantically equivalent, but the change should be explained. If this is a side effect of moving code, consider whether consistency with previous output is important. ✅ Positive Aspects
🔍 Performance ConsiderationsThe hook system adds a slight indirection through 🛡️ Security ConcernsNo security issues identified. The string matching for regexp patterns ( 📋 Recommendations
SummaryThis is a good performance optimization, but it cannot be merged due to the compilation error. After fixing the critical issues and adding tests, this should be ready to go. |
Code ReviewThank you for this performance optimization! This PR merges the 🐛 Critical Issues1. Compilation Error: Non-exhaustive StructLocation: The code fails to compile because Fix: Either:
2. Operator Precedence Bug in Lookbehind Assertion CheckLocation: || (self.options.lookbehind_assertion && regex.exp.contains("(?<=")
|| regex.exp.contains("(?<!"))Due to operator precedence, this is parsed as: (self.options.lookbehind_assertion && regex.exp.contains("(?<=")) || regex.exp.contains("(?<!")This means negative lookbehind Fix: Add parentheses: || (self.options.lookbehind_assertion && (regex.exp.contains("(?<=") || regex.exp.contains("(?<!")))📝 Code Quality Issues3. Missing Unit TestsObservation: The PR doesn't add unit tests for the new Per CLAUDE.md instruction #5: "Write unit tests for your code." Recommendation: Add unit tests to verify:
4. Test Output ChangeLocation: The test expectation changed from: var c = RegExp(".", "imsuy");to: var c = new RegExp(".", "imsuy");Question: Is this intentional? Both are semantically equivalent, but the change should be explained. If this is a side effect of moving code, consider whether consistency with previous output is important. ✅ Positive Aspects
🔍 Performance ConsiderationsThe hook system adds a slight indirection through 🛡️ Security ConcernsNo security issues identified. The string matching for regexp patterns ( 📋 Recommendations
SummaryThis is a good performance optimization, but it cannot be merged due to the compilation error. After fixing the critical issues and adding tests, this should be ready to go. |
ff84b7a to
6882d23
Compare
Code ReviewOverviewThis PR successfully merges the transformation pass into the new architecture using the hook system. This is a performance-oriented refactoring that consolidates transformation logic. Positive Aspects✅ Architecture Improvement: The migration to the hook-based system is well-executed and aligns with the project's direction of consolidating transformation passes. ✅ Code Organization: The regexp logic is cleanly moved to ✅ Dependency Management: Properly updated ✅ Test Coverage: Existing test updated to reflect the new output format. Issues & Concerns1. Logic Error in Lookbehind Assertion Check (crates/swc_ecma_transformer/src/regexp.rs:59-60)The lookbehind assertion condition has a subtle logic bug: || (self.options.lookbehind_assertion && regex.exp.contains("(?<=")
|| regex.exp.contains("(?<\!"))Problem: Due to operator precedence, Expected behavior: || (self.options.lookbehind_assertion
&& (regex.exp.contains("(?<=") || regex.exp.contains("(?<\!")))2. Inconsistent Test Output (crates/swc_ecma_preset_env/tests/fixtures/corejs3/usage-regexp/output.mjs:6)The test shows an unexpected change:
Questions:
The old code generated 3. Performance Consideration - String Contains ChecksThe current implementation uses multiple regex.exp.contains("(?<")
regex.exp.contains("(?<=")
regex.exp.contains("(?<\!")
regex.exp.contains("\\p{")
regex.exp.contains("\\P{")Per CLAUDE.md: "Write performant code. Always prefer performance over other things." Suggestion: For hot paths, consider:
However, this may be premature optimization - recommend measuring first. 4. Documentation GapMissing documentation for Suggestion: Add doc comments explaining: /// Transform pass that converts modern RegExp syntax to RegExp constructor calls
/// for compatibility with older JavaScript environments.
///
/// This pass handles various RegExp features like dotAll, unicode, sticky flags,
/// and advanced features like lookbehind assertions and unicode property escapes.
struct RegexpPass {
options: RegExpOptions,
}Minor Issues
Security✅ No security concerns identified. The transformation logic is straightforward AST manipulation. Test Coverage
RecommendationsMust Fix:
Should Address: Consider: Overall AssessmentThis is a well-structured refactoring that moves in the right direction architecturally. The main concern is the logic bug in the lookbehind assertion check that needs to be fixed. Once addressed, this should be good to merge. The code quality is generally high and follows the project's conventions, with room for improvement in documentation and test coverage. |
Code ReviewOverviewThis PR successfully merges the regexp transformation pass into the new Transformer architecture using the hook system. This is a performance-oriented refactoring that consolidates transformation logic. Positive Aspects✅ Architecture Improvement: The migration to the hook-based system is well-executed and aligns with the project's direction of consolidating transformation passes. ✅ Code Organization: The regexp logic is cleanly moved to swc_ecma_transformer while maintaining a backwards-compatible wrapper in swc_ecma_compat_common. ✅ Dependency Management: Properly updated Cargo.toml files to reflect the new architecture. ✅ Test Coverage: Existing test updated to reflect the new output format. Issues & Concerns1. Logic Error in Lookbehind Assertion CheckLocation: crates/swc_ecma_transformer/src/regexp.rs:59-60 The lookbehind assertion condition has a subtle logic bug: || (self.options.lookbehind_assertion && regex.exp.contains("(?<=")
|| regex.exp.contains("(?<!"))Problem: Due to operator precedence, Expected behavior: || (self.options.lookbehind_assertion
&& (regex.exp.contains("(?<=") || regex.exp.contains("(?<!")))2. Inconsistent Test OutputLocation: crates/swc_ecma_preset_env/tests/fixtures/corejs3/usage-regexp/output.mjs:6 The test shows an unexpected change:
Questions:
The old code generated 3. Performance Consideration - String Contains ChecksThe current implementation uses multiple regex.exp.contains("(?<")
regex.exp.contains("(?<=")
regex.exp.contains("(?<!")
regex.exp.contains("\\p{")
regex.exp.contains("\\P{")Per CLAUDE.md: "Write performant code. Always prefer performance over other things." Suggestion: For hot paths, consider:
However, this may be premature optimization - recommend measuring first. 4. Documentation GapMissing documentation for Suggestion: Add doc comments explaining: /// Transform pass that converts modern RegExp syntax to RegExp constructor calls
/// for compatibility with older JavaScript environments.
///
/// This pass handles various RegExp features like dotAll, unicode, sticky flags,
/// and advanced features like lookbehind assertions and unicode property escapes.
struct RegexpPass {
options: RegExpOptions,
}Minor Issues
Security✅ No security concerns identified. The transformation logic is straightforward AST manipulation. Test Coverage
RecommendationsMust Fix:
Should Address: Consider: Overall AssessmentThis is a well-structured refactoring that moves in the right direction architecturally. The main concern is the logic bug in the lookbehind assertion check that needs to be fixed. Once addressed, this should be good to merge. The code quality is generally high and follows the project conventions, with room for improvement in documentation and test coverage. |
Code Review: Merge
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var a = RegExp("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})", "u"); | ||
| var b = RegExp(".", "s"); | ||
| var c = RegExp(".", "imsuy"); | ||
| var c = new RegExp(".", "imsuy"); |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output shows inconsistent behavior where variable c is transformed to new RegExp(...) while variables a and b on lines 4-5 are transformed to RegExp(...) without the new keyword. Since the transformation code creates a CallExpr without new, this suggests an unintended change in behavior. Please verify that this test output is correct or investigate why the new keyword is being added for this specific case.
| var c = new RegExp(".", "imsuy"); | |
| var c = RegExp(".", "imsuy"); |
No description provided.