fix: reduce Dart extraction noise - #2249
Conversation
8638e4a to
d149ba6
Compare
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
This PR reworks the Dart extractor (graphify/extractors/dart.py) to add more careful type-name handling and part-file resolution. Key changes include: - A new _resolve_part_parent helper that resolves package: URIs in Dart part of declarations by locating the nearest pubspec.yaml, so part files map to the parent library stem rather than a local path. - A new _clean_type_name helper (plus supporting sets/helpers for SDK "noise" types, declaration modifiers, and balanced-generic stripping) that normalizes type fragments before creating nodes, applied across inheritance, mixins, interfaces, typedefs, extensions, and variable-type relations. - Assorted parsing adjustments such as skipping bare _ names, handling extension type const, and guarding the variable regex against declaration keywords. The large set of touched test files (tests/test_extract, tests/test_dart, and many rationale-numbered tests) indicates accompanying test additions/updates covering these extraction behaviors.
Worth a look
- _clean_type_name splits on '.' before stripping generics, mangling qualified generic types —
graphify/extractors/dart.py· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review Execution auto-disposal is off for this run; enable it (with sandbox isolation) to have Graphify try to confirm or refute this automatically.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 358 functions depend on the 358 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
extract_dart()— 9 callers, 8 callees
Verification — 358 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 358 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify extract\_dart.
The verifier did not have enough to check extract\_dart, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
· 1 more finding(s) on lines outside this diff (see the check run).
What changed
This PR makes Dart extraction stricter about parser noise. It keeps the current regex-based approach, but avoids creating graph nodes from syntax fragments that are not project entities.
The patch covers a few cases that showed up in real Flutter code:
part of 'package:...'files now resolve throughpubspec.yamlto the parent file underlib/_and_$Foono longer become graph nodesString get,bool get,static const,static finalare filtered outFutureOr,Never,MapEntry,Iterator,Comparable,StackTrace,Exceptionare filtered from noisy type referencesextension on String/List/Map/Set/Iterable/Future/Streamand SDK typedef targets are filtered as noiseIterable<T>from an extension typeimplementsclause is filtered as noise_with MyMixinstill emitsmixes_inThis is not a Dart analyzer rewrite. It only removes false positives that showed up in real projects.
The SDK filter is intentionally conservative. It covers common
dart:coreanddart:asyncnoise, but does not try to mirror the full Dart SDK. Graphify filters by short name here, so a very broad SDK list could hide project classes with the same names.Why
The old extractor sometimes treated syntax fragments as project entities. On a real Flutter monorepo I saw nodes like:
Those nodes are not useful graph facts. They make traversal noisier because they look like real classes, methods, or types.
Real project check
I also ran the extractor against a Flutter monorepo with
1552Dart files. Extraction errors stayed at0.Noise comparison:
_labelsString getlabelsbool getlabelsstatic const/finallabelsMocknodeString/List/Map/Iterable/FuturelabelsMost structural relations stayed stable:
The two drops are intentional.
extendsdrops because SDK targets from ordinary Dart extensions are now filtered; project extension targets still remain.implementsdrops because one SDKIterable<T>edge from an extension type is now filtered.Migration note
If you already have a graph for a Dart or Flutter project, run a forced rebuild once after updating:
graphify . --forceOlder
graphify-out/graph.jsonfiles may already contain the parser-noise nodes removed here. A forced rebuild removes those stale nodes instead of carrying them through an incremental update.Notes
The new tests focus on regression cases, not every Dart grammar rule. They cover the bugs above plus Dart 3 syntax that previously had a good chance of creating fake graph nodes.