Skip to content

Report bundler-eliminated (tree-shaken) functions as uncovered - #27

Merged
NullVoxPopuli merged 1 commit into
NullVoxPopuli:mainfrom
NullVoxPopuli-ai-agent:store-unused-function
Aug 7, 2026
Merged

NullVoxPopuli merged 1 commit into
NullVoxPopuli:mainfrom
NullVoxPopuli-ai-agent:store-unused-function

Conversation

@NullVoxPopuli-ai-agent

Copy link
Copy Markdown
Contributor

Fixes the remaining false positives from #22 (jagthedrummer's follow-up comments: unusedTestFunction in the store service and a top-level unusedNonClassFunction in a component both still showed as covered).

Root cause

Both functions are unexported and unreferenced, so rollup/vite tree-shakes them out of the build entirely — the bundles are byte-identical with or without them (the names only survive in .map sourcesContent). With no compiled code, V8 never sees them, the source map has no segments for their lines, and v8-to-istanbul defaults unmapped original lines to covered. Not platform-specific this time — reproduced on Linux with the exact shapes from the screenshots.

Fix

While processing each bundle, the report now records which original-source lines have at least one source-map segment. After merging, each reported original file is parsed with acorn and function-like declaration spans are collected (function/class declarations, function/arrow variable initializers). A span with no mapped lines in any bundle was eliminated by the bundler: its statement counts are zeroed and an uncovered function entry is added. A span with even one mapped line is left alone — the bundle kept it, so real V8 data (or the synthetic-method pass) already decides its coverage.

To parse original .gjs/.gts files, <template>…</template> spans are blanked to an offset-preserving 0 placeholder and decorators (@tracked, @action('x'), …) are blanked to spaces — parse-validity is all that matters. Files that still fail to parse are skipped rather than guessed at.

Scenario changes

vite-app-using-v2-addon-js now contains both shapes from the issue report, replicated from the screenshots:

  • app/services/store.js — unusedTestFunction() (unexported, never called)
  • app/components/counter.gjs — unusedNonClassFunction() (top-level, outside the class)

Before this fix both reported 100% covered; now store.js reports 0/1 functions with its lines uncovered, and counter.gjs reports the function uncovered alongside the two never-called class methods. Regression assertions added for both, plus the store.js entry itself.

All 22 tests across the three scenarios pass, lint clean.

🤖 Generated with Claude Code

An unexported, unreferenced function is tree-shaken by rollup/vite: no
compiled code exists, so V8 never sees it, the source map has no
segments for its lines, and v8-to-istanbul defaults those lines to
covered — a false positive (second report on issue NullVoxPopuli#22, where an
unusedTestFunction in a service and a top-level unusedNonClassFunction
in a component both showed as 100% covered).

The report step now records which original-source lines have at least
one mapping segment in any bundle's source map, parses each reported
original file with acorn, and collects function-like declaration spans
(function/class declarations, function/arrow variable initializers). A
span with no mapped lines anywhere was eliminated from the build; its
statement counts are zeroed and an uncovered function entry is added.
Spans with even one mapped line are left to the existing V8-data and
synthetic-method paths.

To make original .gjs/.gts app files parseable by acorn, template tags
are blanked to an offset-preserving "0" placeholder and decorators are
blanked to spaces; any file that still fails to parse is skipped rather
than guessed at.

The vite-app-using-v2-addon-js scenario now contains both shapes from
the issue report — unusedTestFunction in app/services/store.js and
unusedNonClassFunction in app/components/counter.gjs — with regression
assertions that they are reported as uncovered.

Fixes the remaining false positives from NullVoxPopuli#22

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NullVoxPopuli NullVoxPopuli added the bug Something isn't working label Aug 7, 2026
@NullVoxPopuli
NullVoxPopuli merged commit 5380ae8 into NullVoxPopuli:main Aug 7, 2026
5 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants