Skip to content

[medium] Nested functions inflate their enclosing function's complexity #11

Description

@gingercakedev-bot

Nested functions inflate their enclosing function's complexity

Severity medium
Confidence 99% (confirmed)
Kind logic-bug
Location src/parsers/shared/metrics-base.tscomputeComplexity
Module src/parsers/shared
Finding ID f-097c56

Failure scenario

A Python function containing a nested function with an if is reported with complexity 2 even when the outer function has no decisions. The recursive walk enters the nested function_definition and attributes its decisions to the outer function; the same boundary problem applies to Go function literals and Rust closures.

Evidence

src/parsers/shared/metrics-base.ts:11-17 defines an unrestricted recursive walk: if (decisionTypes.has(n.type)) complexity++;, followed by for (const child of n.namedChildren || []) walk(child);, then starts it at the enclosing callable's body with if (body) walk(body);. src/parsers/python/py-metrics.ts:11-24 counts if_statement and delegates directly to this walker. src/parsers/python/py-parser.ts:269 assigns that result to the outer function via complexity: computePyComplexity(funcNode). No nested-callable boundary is checked.

Reproduction

Generate a codemap for Python containing def outer():\n def inner(x):\n if x:\n return 1\n return inner. The outer function receives complexity 2, although its own control flow has no decision and should produce the baseline complexity 1.

Suggested fix direction

Stop the shared traversal when it reaches a nested callable boundary, using the relevant tree-sitter node types for each language (Python function_definition, Go func_literal, Rust closure_expression). Keep traversing the original function body and add one focused regression test covering an outer function with a conditional only inside a nested callable.

Why this matters here

Accurate per-function complexity is necessary for trustworthy relationship maps, health scores, and hotspot reporting.

Suggested test

Parse def outer():\n def inner(x):\n if x:\n return 1\n return inner and assert that outer has complexity 1, not 2.


How to work this issue

Open a Claude Code session in this repo and say
"work the dev-cli finding f-097c56 in src/parsers/shared/metrics-base.ts".

Start from the evidence above rather than re-investigating: it was produced by reading this
exact commit. Done means the suggested test fails before your change and passes after, and the
next scan marks the finding fixed.

If this is not a real defect, close the issue with the false-positive label — dev-cli
records the fingerprint and will never raise it again. Closing it without that label marks the
finding fixed instead.

Raised by dev-cli · repo codemap-cli · branch main · commit c8cf294 · scan 2026-08-15T14-12-31 · fingerprint 097c56c73143

Metadata

Metadata

Assignees

No one assigned

    Labels

    dev-cliRaised by dev-cli automated scan

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions