Skip to content

refactor: remove dead code and redundant work#1263

Closed
Boshen wants to merge 1 commit into
mainfrom
refactor/cleanup
Closed

refactor: remove dead code and redundant work#1263
Boshen wants to merge 1 commit into
mainfrom
refactor/cleanup

Conversation

@Boshen

@Boshen Boshen commented Jul 2, 2026

Copy link
Copy Markdown
Member

Behavior-preserving cleanup pass across the crate (+74/−145). Verified with clippy (all features/targets), cargo test + --all-features, s390x check, docs with -D warnings, Node tests, and the Yarn PnP fixture tests.

Dead code

  • package_target_resolve: the i == targets.len() branch could never execute (i comes from enumerate() so it maxes out at len − 1), meaning errors from array entries always fall through to the next entry. Removed the branch and corrected the comment to describe the actual behavior. If the original intent was Node's lastException semantics (propagate the last entry's error), that would be i + 1 == targets.len() — deliberately not done here to keep this PR behavior-preserving.
  • impl BitOr for Extensions in the dts resolver: never invoked, all unions go through .union().
  • dts_resolve_tsconfig_paths: unused _cached_path parameter.
  • napi EnforceExtension::{is_auto,is_enabled,is_disabled}: zero callers and not #[napi]-exported.
  • A no-op let _ = meta; in the metadata test.

Redundant work

  • fallback aliases are now compiled once at construction into ResolverImpl.fallback (mirroring alias) instead of compile_alias re-running on every failed resolution; load_alias_by_options is deleted.
  • Cache::get_tsconfig no longer deep-clones the TsConfig on the non-root (extends) path, where the clone was immediately dropped. The clone only ever mattered for the root branch because build() consumes self.

Simplifications

  • The byte-identical typings/types/main entry-selection block duplicated twice in dts_resolve_as_directory is factored into dts_package_entry, and the nested if let collapsed into a let-chain.
  • clone_with_options: (a && !b) || (!a && b) → plain == comparison; its stale #[allow(clippy::unused_self)] is removed.
  • Resolution uses #[derive(Clone)] (the manual impl was field-for-field identical), the two identical #[cold] error constructors in Specifier::parse are merged, require_hash uses ok_or_else instead of map_or_else(|| Err(..), Ok), plus a redundant .as_ref() on file_name() and a Some(x).as_deref().unwrap() dance are gone.
  • Stale doc on TsConfig::root fixed: template-variable substitution is driven by should_build now, not root.

Noticed but intentionally not changed (behavior changes, separate discussion)

  • The escaped-\0# path in Specifier::parse_query_fragment rebuilds the string with s.push(b as char) over raw bytes, which garbles multi-byte UTF-8 on that rare branch.
  • The project-references extends loop in extend_tsconfig skips the with_extended_file circular-extend guard that load_tsconfig applies.

- Remove the never-true `i == targets.len()` branch in
  `package_target_resolve` array handling (`i` comes from `enumerate()`
  so it maxes out at `len - 1`) and correct the comment to describe the
  actual fall-through behavior.
- Compile `fallback` aliases once at construction instead of running
  `compile_alias` on every failed resolution; delete the now-unused
  `load_alias_by_options`.
- Skip the `TsConfig` deep clone in `Cache::get_tsconfig` on the
  non-root (`extends`) path where it was dropped unused.
- Factor the duplicated typings/types/main entry selection in
  `dts_resolve_as_directory` into `dts_package_entry`.
- Remove dead code: `impl BitOr for Extensions`, unused `_cached_path`
  parameter, napi `EnforceExtension` helpers with no callers, a no-op
  `let _ = meta` in a test.
- Simplify: derive `Resolution::clone`, merge duplicate #[cold] error
  constructors in `Specifier::parse`, `ok_or_else` in `require_hash`,
  plain equality for the yarn_pnp cache check in `clone_with_options`,
  drop a redundant `.as_ref()` and a `Some(x).as_deref().unwrap()` dance.
- Fix stale doc comment on `TsConfig::root` (template variable
  substitution is driven by `should_build` now).
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.42857% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.96%. Comparing base (4837a2e) to head (19ad4ce).

Files with missing lines Patch % Lines
src/dts_resolver.rs 93.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1263      +/-   ##
==========================================
+ Coverage   93.85%   93.96%   +0.10%     
==========================================
  Files          21       21              
  Lines        4313     4272      -41     
==========================================
- Hits         4048     4014      -34     
+ Misses        265      258       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented Jul 2, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 4.23%

❌ 3 regressed benchmarks
✅ 18 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
pm/npm-flat 898.6 µs 949.5 µs -5.37%
pm/bun-isolated 1 ms 1.1 ms -3.8%
pm/bun-flat 902.6 µs 935.4 µs -3.51%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing refactor/cleanup (19ad4ce) with main (4837a2e)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Boshen

Boshen commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Split into #1264 (fallback alias precompilation), #1265 (tsconfig clone skip), #1266 (dts cleanups), #1267 (dead array-target branch), and #1268 (misc small cleanups).

@Boshen Boshen closed this Jul 2, 2026
@Boshen
Boshen deleted the refactor/cleanup branch July 2, 2026 06:25
Boshen added a commit that referenced this pull request Jul 2, 2026
`load_alias_by_options` re-ran `compile_alias` (allocating and cloning
every `AliasValue`) on **every failed resolution**, while the primary
`alias` list is compiled once at construction. This compiles `fallback`
once into a `ResolverImpl.fallback` field, uses `load_alias` directly at
the fallback call site, and deletes `load_alias_by_options` (its only
caller). `compile_alias` is pure over the post-`sanitize` options, so
behavior is identical; with an empty fallback list the new field is an
empty box + 32 zero bytes.

Also tidies `clone_with_options` while touching it: the `(a && !b) ||
(!a && b)` yarn_pnp cache check becomes a plain `==` comparison, and the
stale `#[allow(clippy::unused_self)]` is removed (both cfg branches use
`self`).

Split out of #1263.
Boshen added a commit that referenced this pull request Jul 2, 2026
)

`Cache::get_tsconfig` deep-cloned every parsed `TsConfig` before
branching on `root`, but the clone only matters in the root branch,
where `TsConfig::build(mut self)` consumes the value after the raw
version is cached. On the non-root path — taken once per `extends` entry
— the original local was dropped unused, so the clone
(`CompilerOptions`, three `Option<Vec<PathBuf>>`s, references, paths)
was pure waste.

The raw cache still stores the `should_build = false` version and the
built cache still stores the built version; returned `Arc`s share the
cached instances exactly as before.

Split out of #1263.
Boshen added a commit that referenced this pull request Jul 2, 2026
…de (#1266)

- Factor the byte-identical 14-line `typings`/`types`/`main`
entry-selection block, which appeared twice in
`dts_resolve_as_directory` (once in the `typesVersions` branch, once in
the types/typings/main branch), into a `dts_package_entry` helper, and
collapse the resulting nested `if let` into a let-chain.
- Remove `impl BitOr for Extensions`: the `|` operator is never invoked
on this private type — every union goes through `.union()` (`BitAnd` is
used and stays).
- Drop the unused `_cached_path` parameter from
`dts_resolve_tsconfig_paths` (private method, single caller).

Split out of #1263.
Boshen added a commit that referenced this pull request Jul 2, 2026
A batch of tiny, independent cleanups:

- Derive `Clone` for `Resolution` — the manual impl was field-for-field
identical to what the derive produces (`Debug`/`PartialEq` stay manual,
they're genuinely custom).
- Merge the two byte-identical `#[cold]` empty-error constructors in
`Specifier::parse` into one.
- `require_hash`: `.ok_or_else(..)` instead of `.map_or_else(|| Err(..),
Ok)`.
- Remove a pointless `Some(owned).as_deref().unwrap()` dance in the
legacy `jest-runner-../..` fallback path.
- Drop a redundant `.as_ref()` on `file_name()` in `Cache::value`
(`&OsStr == &str` already works via `OsStr: PartialEq<str>`).
- Remove the napi `EnforceExtension::{is_auto,is_enabled,is_disabled}`
helpers — zero callers anywhere in the repo and not `#[napi]`-exported,
so they never reached JS.
- Remove a no-op `let _ = meta;` in the `metadata` test.
- Fix the stale doc comment on `TsConfig::root` / `root()": it claimed
the field drives final template-variable substitution, but that's keyed
off `should_build` now; `root` just records whether the config is the
caller's (vs loaded through `extends`).

Split out of #1263.
Boshen added a commit that referenced this pull request Jul 2, 2026
)

The "return the last array entry's error" branch in
`package_target_resolve` was dead code: `i` comes from `enumerate()`, so
`i == targets.len()` could never be true. Errors from array entries were
always swallowed like `undefined`, so an invalid target in the last
fallback entry surfaced as a generic `PackagePathNotExported` instead of
the specific error — despite the comment right below claiming "Return or
throw the last fallback resolution null return or error".

This fixes the off-by-one (`i + 1 == targets.len()`) so the last entry's
error now propagates, matching the documented intent and Node's
`lastException` behavior for arrays.

One deliberate exemption: `ResolveError::NotFound` still falls through.
It only arises from re-resolving a bare `imports` target (e.g. `\"#a\":
[{\"import\": [\"#b/import.js\"]}]`) through the module system, and
enhanced-resolve treats an unresolvable candidate there as a soft
failure, not a hard error — the ported "Direct and conditional mapping
#4" test pins that behavior. Node would actually throw immediately on
any non-`ERR_INVALID_PACKAGE_TARGET` error inside the array loop, which
is stricter than enhanced-resolve; the exemption keeps us compatible
with the latter.

Adds two imports-field tests: an invalid target in the **last** array
entry now errors (previously `Ok(None)`), and an invalid target in a
**non-last** entry still falls through to the next entry.

Split out of #1263.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant