Skip to content

fix: report nested JavaScript function declarations once - #196

Merged
DaisukeYoda merged 2 commits into
ludo-technologies:mainfrom
HarshRajSinghania:fix/js-nested-function-cfgs
Oct 10, 2026
Merged

DaisukeYoda merged 2 commits into
ludo-technologies:mainfrom
HarshRajSinghania:fix/js-nested-function-cfgs

Conversation

@HarshRajSinghania

Copy link
Copy Markdown
Contributor

Summary

  • Nested JavaScript function declarations are now reported once by the complexity CFG builder.
  • A declaration nested in another function declaration is kept, and a declaration nested in an arrow, method, or exported function is no longer emitted a second time as name_<line>.

Motivation
Fixes #135. Complexity analysis dropped inNamed-style declarations and duplicated inArrow / inMethod / inExported, which also inflated summary.total_functions.

Implementation

  • processStatement now keeps CFGs built for declarations inside the function it just analyzed. Those nodes are already on the child CFG, so BuildAll will not rebuild them.
  • When BuildAll sees a function span it already recorded, it stops the walk instead of descending. The AST walk visits the same statement from both Children and Body, and the previous return true walked into the body and minted the name_<line> duplicate.
  • Nested function locations are marked after a function is built so a later walk of the same span is skipped.

Testing

The ASCII-only name suffix path is unchanged for genuinely distinct functions that share a name.

Nested function declarations were either dropped or emitted twice as name_<line>, which skewed complexity totals.

Fixes ludo-technologies#135
@DaisukeYoda
DaisukeYoda self-requested a review October 9, 2026 15:16

@DaisukeYoda DaisukeYoda left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for picking up #135. markFunctionLocations fixes the duplicate on its own, but returning false from the BuildAll walk causes a regression.

Callbacks inside function bodies are dropped

The walk no longer enters function bodies, so function expressions inside them are never found:

function top(items) {
  return items.map((x) => { if (x) { return 1; } return 0; });
}

main reports anonymous_2, but this branch does not. Returning true in both places fixes it. With that change, #135 stays fixed and go test ./internal/js/... passes. Please also add a callback case to the new test.

Minor (optional)

When two functions each contain a nested function h(), absorbNestedFunctionCFGs drops the second h. This is not a regression, so a follow-up PR is fine.

Returning false from the BuildAll walk skipped callbacks and other function
expressions nested inside already-discovered functions. Always return true so
the walk continues (markFunctionLocations still prevents duplicates) and add a
callback case to the nested-declaration test.

Fixes the regression noted in the review of ludo-technologies#196.
@HarshRajSinghania

Copy link
Copy Markdown
Contributor Author

Thanks for the review @DaisukeYoda.

Addressed the regression: the BuildAll walk now returns true in both places so it continues into function bodies and discovers nested callbacks / function expressions. markFunctionLocations still prevents the name_<line> duplicates.

Also added the callback case from your example to TestCFGBuilder_BuildAll_NestedFunctionDeclarations.

Verified with go test ./internal/js/analyzer/ -count=1 (pass).

The optional absorbNestedFunctionCFGs name-collision note is left for a follow-up as suggested.

@DaisukeYoda
DaisukeYoda self-requested a review October 10, 2026 11:15

@DaisukeYoda DaisukeYoda left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@DaisukeYoda
DaisukeYoda merged commit ace7b87 into ludo-technologies:main Oct 10, 2026
4 checks passed
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.

[BUG][auto] js/js-nested-function-declaration-dropped-or-duplicated: nested function declarations are reported twice (name, name_<line>) or not at all

2 participants