Skip to content

--deps / --importers / blast-radius report coverage: complete on languages with no file-level imports #148

Description

@JordanCoin

Version: 4.4.2 (Homebrew) · macOS · ast-grep installed

Summary

In languages where files inside a module do not import each other by path — Swift is the clearest case, but the same applies to C#, Java within a package, and Kotlin — the dependency graph comes back essentially empty, yet the JSON still declares the analysis authoritative and complete.

Repro

Any single-module Swift app (~290 source files in my test):

codemap --deps --json .

Actual

"coverage": {"status": "complete", "sources": [{"name": "ast-grep", "status": "authoritative"}], "issues": []}

Two edges found across the whole project. blast-radius on a 50-file change in the same project reports:

files_with_dependents=0
impacted_outside_diff=0/0
dependency_context_outside_diff=0/0

Expected

Either real edges, or an honest degraded status.

Why this is the worst of the bugs

Parsing is fine — 1068 functions were extracted correctly. The edge model is what doesn't apply: every import in that project resolves to a framework (SwiftUI, Foundation, …), never to another file in the project. So the graph is structurally empty, not wrong-by-accident.

The damage comes from pairing that with status: complete. A consumer — especially an automated one feeding an LLM — reads "complete" plus "0 dependents" and concludes the change is isolated. In my test the changed set included a type with 40 referencing files and another with 33. Reported impact: zero, with full confidence.

A tool that says "I found nothing" is useful. A tool that says "I checked everything and there is nothing" when it cannot check is worse than not running.

Suggested fix

  1. When a language's import graph yields ~0 internal edges across a large file count, set coverage.status = "degraded" with an issue explaining that the language needs symbol-reference resolution rather than import resolution.
  2. Longer term, resolve edges for these languages by type name → declaring file. ast-grep already extracts the declarations; the missing step is matching references to them. A plain ranking of type name → count of other files referencing it took 1.8s on the same repo and produced exactly the signal blast-radius reported as zero.

Related false positives

The two edges it does find look like filename-against-directory-name matches:

VendorSDK  ───▶ src/Integrations/VendorSDK
OtherSDK   ───▶ src/Integrations/OtherSDK

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions