Skip to content

feat(es_parser): complete internal parser wiring without ecma runtime dep#11622

Merged
kdy1 merged 2 commits intomainfrom
kdy1/swc-es-parser-internal-complete
Mar 6, 2026
Merged

feat(es_parser): complete internal parser wiring without ecma runtime dep#11622
kdy1 merged 2 commits intomainfrom
kdy1/swc-es-parser-internal-complete

Conversation

@kdy1
Copy link
Copy Markdown
Member

@kdy1 kdy1 commented Mar 5, 2026

Summary

  • complete internal swc_es_parser option wiring without introducing runtime dependency on swc_ecma_parser
  • add Syntax accessors and connect parser behavior for decorators_before_export, export_default_from, allow_super_outside_method, dts, and disallow_ambiguous_jsx_like
  • tighten super context handling and fix export default from branch regression (export default from; remains expression export)
  • remove stale fixture skip/ignore entries, normalize parity expectations for known invalid super span fixtures, and refresh impacted snapshots
  • extend runtime non-dependency checks (src/tests/examples/benches, Cargo.toml, and cargo tree graph)
  • sync parser docs (README.md, AGENTS.md) with runtime non-dependency and fixture-reuse policy

Verification

  • git submodule update --init --recursive
  • cargo fmt --all
  • cargo clippy --all --all-targets -- -D warnings
  • cargo test -p swc_es_parser

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 5, 2026

⚠️ No Changeset found

Latest commit: 88f10aa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 5, 2026

Binary Sizes

File Size
swc.linux-x64-gnu.node 28M (28744264 bytes)

Commit: 0a5c1bb

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 5, 2026

Merging this PR will not alter performance

✅ 192 untouched benchmarks


Comparing kdy1/swc-es-parser-internal-complete (88f10aa) with main (325170f)

Open in CodSpeed

@kdy1 kdy1 marked this pull request as ready for review March 6, 2026 09:11
@kdy1 kdy1 requested a review from a team as a code owner March 6, 2026 09:11
Copilot AI review requested due to automatic review settings March 6, 2026 09:11
@kdy1 kdy1 changed the title feat(swc_es_parser): complete internal parser wiring without ecma runtime dep feat(es_parser): complete internal parser wiring without ecma runtime dep Mar 6, 2026
@kdy1 kdy1 merged commit 1c51891 into main Mar 6, 2026
197 checks passed
@kdy1 kdy1 deleted the kdy1/swc-es-parser-internal-complete branch March 6, 2026 09:11
@github-actions github-actions Bot added this to the Planned milestone Mar 6, 2026
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 6, 2026

PR Review: feat(es_parser): complete internal parser wiring without ecma runtime dep

Overall this is a solid PR that systematically wires syntax options (decorators_before_export, export_default_from, allow_super_outside_method, dts, disallow_ambiguous_jsx_like) into swc_es_parser and tightens super context handling. The test coverage is good and the approach aligns with parity goals against swc_ecma_parser.

Code Quality

Good:

  • The export default from disambiguation logic at parser.rs:489-494 is well-designed — checking for Str after from to distinguish export default from 'mod' from export default from; (expression).
  • The ALLOW_DIRECT_SUPER context flag follows the same pattern as swc_ecma_parser's AllowDirectSuper: set in class/object methods, removed in regular function bodies.
  • Extracting contains_swc_ecma_parser_import helper in no_ecma_dependency.rs reduces duplication.
  • The typescript.rs change to use matches!(ext, "cts" | "mts") instead of file_name.contains(...) is more precise and avoids false positives from directory names.

Nits:

  • parity_suite.rs:215-221 — The matches!(path.as_str(), p if p.ends_with(...) || ...) pattern is valid but a bit unusual. Since the pattern p is an irrefutable catch-all that always binds, all filtering happens in the guard. A simple let p = path.as_str(); p.ends_with(...) || ... reads more naturally and avoids reader confusion about what the matches! is actually pattern-matching on.

Potential Issues

  1. super inside object shorthand methodsparse_class_method_function sets ALLOW_DIRECT_SUPER and is called for both class methods and object literal shorthand methods (line 3714). This is correct for super property access in shorthand object methods (which is valid ES6+), but worth documenting since the function name says "class_method" while it's shared with object methods. Consider a comment or rename for clarity.

  2. parse_class_method_function context before params — The context change (line 3554-3562) now sets IN_FUNCTION, ALLOW_DIRECT_SUPER, IN_ASYNC, IN_GENERATOR before parsing parameters. The original code set context only before the body. This means parameter default expressions are now parsed with ALLOW_DIRECT_SUPER set, which would allow super.foo inside parameter defaults of class methods. Verify this matches swc_ecma_parser behavior — in the ecma parser, AllowDirectSuper is set at the do_inside_of_context call site which wraps the entire method parse including params, so this should be fine, but it's a subtle semantic change worth double-checking.

  3. expr_is_super_reference traverses through parens — At line 5166, (super) is treated as a super reference. This correctly matches the test262 fail case 5864c96b99472ffc.js (function f() { (super)() }). Good.

Performance

  • The ensure_super_property_or_call_allowed check is called on every member access and call expression (lines 2857, 2877, 2952, 2967). Since it's a simple flag check that short-circuits on non-super expressions via expr_is_super_reference (which is typically a single match arm), the overhead is negligible.

Test Coverage

  • Good coverage for all five syntax options with dedicated unit tests.
  • Parity suite correctly marks the super span fixtures as expected failures.
  • Dependency guard tests properly verify no runtime dependency on swc_ecma_parser.
  • The removed skip entries (stale fixture ignores) indicate these cases now pass, which is a good sign of parser maturation.

Minor Suggestions

  • The export default, * as ns from error message (around line 532) mentions the AST limitation. This is fine as a diagnostic but consider whether this should be a TODO for future AST model extension.
  • The error message "decorators before export are disabled by syntax option" could be slightly more actionable: "decorators must appear after export (set decorators_before_export to allow this)".

LGTM with the minor suggestions above. The behavioral changes around super handling are well-motivated and align with swc_ecma_parser semantics.

Copy link
Copy Markdown
Contributor

Copilot AI left a 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 finishes wiring several swc_es_parser syntax options end-to-end (including diagnostics/snapshots) while reinforcing the “fixture reuse is test-only” contract to avoid any runtime dependency on swc_ecma_parser.

Changes:

  • Add Syntax accessors and connect parser behavior for decorators_before_export, export_default_from, allow_super_outside_method, dts, and disallow_ambiguous_jsx_like.
  • Tighten super handling and refresh parity harness expectations/snapshots for fixtures that intentionally exercise invalid super usage.
  • Strengthen and document the no-runtime-swc_ecma_parser dependency policy (tests + docs), and prune stale skip/ignore entries.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/swc_es_parser/src/parser.rs Wires new syntax options into parsing behavior, adds super context enforcement, and adds targeted unit tests.
crates/swc_es_parser/src/syntax.rs Adds new Syntax accessors (decorators_before_export, export_default_from, dts, disallow_ambiguous_jsx_like).
crates/swc_es_parser/src/context.rs Introduces new context flags used by the parser (IN_DECLARE, ALLOW_DIRECT_SUPER).
crates/swc_es_parser/tests/no_ecma_dependency.rs Refactors/extends test-only checks intended to prevent swc_ecma_parser dependency usage.
crates/swc_es_parser/tests/parity_suite.rs Marks known-invalid super span fixtures as expected failures to normalize parity expectations.
crates/swc_es_parser/tests/typescript.rs Improves TS fixture option inference using file extensions (tsx, cts/mts).
crates/swc_es_parser/tests/test262.rs Updates ignore-list comments and removes stale ignored entries.
crates/swc_es_parser/tests/common/ecma_reuse.rs Removes stale tsc skip/ignore patterns.
crates/swc_es_parser/tests/snapshots/** Updates stderr snapshots for new diagnostics / adjusted failure classification.
crates/swc_es_parser/README.md Documents runtime non-dependency and enumerates wired syntax options.
crates/swc_es_parser/AGENTS.md Updates contributor-facing notes for the non-dependency and option coverage contracts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 2856 to 2860
TokenKind::Dot => {
self.ensure_super_property_or_call_allowed(expr)?;
let start = self.cur.span.lo;
self.bump();
let is_private = self.cur.kind == TokenKind::Hash;
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_super_property_or_call_allowed is only invoked for member access/calls (., ?., [], ()). Other postfix forms like tagged templates (super as a tag) and update expressions (super++ / super--) can still be parsed without triggering the super-context restriction. Consider invoking the same check for TokenKind::Template and the PlusPlus/MinusMinus branches (or representing super as a distinct AST node and validating all non-SuperProperty/SuperCall uses).

Copilot uses AI. Check for mistakes.
fn contains_swc_ecma_parser_import(source: &str) -> bool {
source.contains("use swc_ecma_parser")
|| source.contains("extern crate swc_ecma_parser")
|| source.contains("::swc_ecma_parser::")
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains_swc_ecma_parser_import does not currently match direct crate-path references like swc_ecma_parser::Parser (without a leading ::). If the goal is to forbid any test-time dependency usage, consider also checking for "swc_ecma_parser::" to avoid false negatives.

Suggested change
|| source.contains("::swc_ecma_parser::")
|| source.contains("::swc_ecma_parser::")
|| source.contains("swc_ecma_parser::")

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88f10aa93b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3554 to +3557
let old_ctx = self.ctx;
self.ctx.insert(Context::IN_FUNCTION);
self.ctx.insert(Context::ALLOW_DIRECT_SUPER);
if is_async {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore method parsing context before propagating errors

parse_class_method_function now mutates self.ctx before any of the fallible header parsing (expect('('), parameter parsing, return type parsing), but the old context is only restored after successfully parsing the body. If a malformed method signature returns early via ?, the parser keeps IN_FUNCTION/ALLOW_DIRECT_SUPER set, so subsequent statements are parsed under the wrong context (for example in TypeScript no_early_errors mode where parsing continues after fatal errors), which can suppress or misclassify later diagnostics.

Useful? React with 👍 / 👎.

@github-actions github-actions Bot modified the milestones: Planned, 1.15.21 Mar 22, 2026
@swc-project swc-project locked as resolved and limited conversation to collaborators Apr 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants