Avatar for the swc-project user
swc-project
swc
BlogDocsChangelog

Performance History

Latest Results

fix(es/parser): Retry ambiguous Program parsing (#12142) **Description:** `parse_program` could classify a source as a Module too early when a top-level `await` token also had a valid Script interpretation. For example, in the following code, `await` should be parsed as an identifier and the second import argument should remain a normal call expression: ```js function await() {} import("./fixture.js", await(undefined)); ``` This PR updates unambiguous Program parsing to: - initially parse using the Module `Await` grammar; - retry as Script when `await` has a distinct valid Script interpretation and no definitive module syntax was found; - retain the Module result when imports, exports, or unambiguous module-only syntax determine the parse goal; - restore lexer diagnostics and token state when retrying; - defer publishing comments until a parse result is selected, preventing duplicated comments; - preserve the grammar boundaries of functions, parameters, class fields, and static blocks. The regular lexer/parser checkpoint remains unchanged. Non-ambiguous valid programs still use a single parsing pass; reparsing is limited to ambiguous or failed probes. Regression coverage includes: - ambiguous `await` unary, binary, call, member, assignment, arrow, and `for...of` forms; - TypeScript `as` and `satisfies` expressions; - nested function and class-field grammar contexts; - comment preservation across retries; - parser fixtures and resolver output for the dynamic-import case. **Related issue (if exists):** N/A
main
5 seconds ago
ci: validate workspace manifests in change detection
kdy1/ci-detect-changes
2 minutes ago
fix(es/minifier): Don't replace value-used console.*.bind() calls with undefined (#12138) **Description:** With `drop_console`, every call rooted at `console` is replaced with `undefined`, including calls whose result is used: ```js // input const err = console.error.bind(console); err("boom"); // output with drop_console: true const err = void 0; err("boom"); // TypeError: err is not a function ``` This breaks real-world code at runtime, e.g. Emscripten prologues (`var err = console.error.bind(console)`) and `@sqlite.org/sqlite-wasm`. Now `bind`/`toString`/`valueOf` (written as `.bind` or `["bind"]`) invoked directly on a known console method keep their result by replacing only the console method, the same way terser does since terser/terser#323: `console.error.bind(console)` -> `(()=>{}).bind()`. With `ecma` >= 2015 the noop is an arrow, which - like the native console methods - is not a constructor; ES5 keeps `function () {}`. A `?.` in the callee keeps its per-hop short-circuiting: - `console.debug?.bind(x)` -> `(console.debug && noop)?.bind()`: a nullish method still yields `undefined`. - `console?.error.bind(x)` -> `console == null ? void 0 : (console.error && noop).bind()`: a nullish `console` still yields `undefined`, while a nullish `console.error` still throws at the `.bind` access. Everything else is unchanged and still collapses to `undefined`: direct calls, `.call`/`.apply` (whose results are `undefined` anyway), custom properties on `console` or its methods (`console.state.valueOf(...)`, `console.log.capture(...)`), and deeper chains like `console.a.b.c(...)`. Also, only the unresolved global `console` is matched now, so a local binding that happens to be named `console` is no longer dropped (matches terser's `is_undeclared_ref` guard). Notes: - A chained call in statement position (`console.error.bind(console);`) now leaves `(()=>{}).bind();` instead of being erased, since value usage isn't known at this site and the substitution must be safe in any position. - Local invariants beyond the documented assumptions, each with a code comment per the AGENTS.md guidance: under ES5, constructing a dropped bound method succeeds instead of throwing (non-constructibility is not expressible in ES5); own overrides of `bind`/`toString`/`valueOf` on a console method are not preserved (names are matched statically, as terser does); and the hoisted `console == null` check reads the global twice, assuming a stable binding rather than a side-effectful accessor. All scenarios are covered by executing fixture suites (`tests/fixture/issues/drop-console-*`) with checked-in `expected.stdout`. --------- Co-authored-by: Hugo Striedinger <6549408+striedinger@users.noreply.github.com>
main
10 minutes ago
ci: refresh rust-toolchain action pin
kdy1/ci-detect-changes
18 minutes ago
Merge branch 'main' into fix/parse-unambiguous
fix/parse-unambiguous
35 minutes ago
ci: remove commit message filters
kdy1/ci-detect-changes
37 minutes ago
ci: gate jobs with detected changes
kdy1:kdy1/ci-detect-changes
39 minutes ago

Latest Branches

CodSpeed Performance Gauge
0%
ci: Gate jobs with detected changes#12147
22 minutes ago
7322f01
kdy1/ci-detect-changes
CodSpeed Performance Gauge
0%
fix(es/parser): Retry ambiguous Program parsing#12142
38 minutes ago
18c7608
fix/parse-unambiguous
CodSpeed Performance Gauge
0%
ci: Gate jobs with detected changes#12146
47 minutes ago
dcea7ee
kdy1:kdy1/ci-detect-changes
© 2026 CodSpeed Technology
Home Terms Privacy Docs