Pre-flight checks
What happened?
The Dart extractor only links the default URI of a configurable (conditional) import/export directive. Every if (...) alternative is dropped:
// lib/service.dart
export 'service_stub.dart'
if (dart.library.io) 'service_io.dart';
produces a single exports edge to service_stub.dart; there is no edge to service_io.dart.
This is the standard Flutter facade pattern for platform-specific code, and the stub is usually an empty placeholder while the real implementation lives in the if branch. As a result the implementation file becomes unreachable through the facade: everything that imports service.dart appears to depend only on the stub, and explain/path on the implementation file see no link from the facade or its importers.
Expected: one edge per URI in the directive - the default one plus each conditional alternative (service_stub.dart and service_io.dart above). The same applies to conditional import directives.
Cause: both patterns in graphify/extractors/dart.py (section "6. Imports and Exports") match only the first quoted string after import/export:
r"""^\s*export\s+['"]([^'"]+)['"]"""
Note that a condition may itself contain a string literal (if (app.flavor == 'prod') 'flags_prod.dart'), so a naive "all quoted strings in the directive" approach would mint a bogus prod node.
Steps to reproduce
mkdir -p repro/lib && cd repro
printf "export 'service_stub.dart'\n if (dart.library.io) 'service_io.dart';\n" > lib/service.dart
printf "class Service {}\n" > lib/service_stub.dart
printf "class Service {\n void connect() {}\n}\n" > lib/service_io.dart
python - <<'PY'
from pathlib import Path
from graphify.extract import extract_dart
for e in extract_dart(Path("lib/service.dart"))["edges"]:
print(e["relation"], "->", e["target"])
PY
Error output or graph output
exports -> service_stub_dart
Expected:
exports -> service_stub_dart
exports -> service_io_dart
On a real Flutter app (~300 Dart files) all four such facades in the project were affected: the graph had no edge from any facade to its *_io.dart implementation.
Graphify version
0.9.73 (reproduced on v8 @ e10df08 / 0.9.74 as well - the Dart extractor is unchanged there)
Operating System
macOS
Python Version
3.13
Installation Method
uv tool install (recommended)
Additional Environment Details
No provider environment variables are needed - this is pure AST/regex extraction. Reproduced from a clean checkout of v8.
Pre-flight checks
What happened?
The Dart extractor only links the default URI of a configurable (conditional)
import/exportdirective. Everyif (...)alternative is dropped:produces a single
exportsedge toservice_stub.dart; there is no edge toservice_io.dart.This is the standard Flutter facade pattern for platform-specific code, and the stub is usually an empty placeholder while the real implementation lives in the
ifbranch. As a result the implementation file becomes unreachable through the facade: everything that importsservice.dartappears to depend only on the stub, andexplain/pathon the implementation file see no link from the facade or its importers.Expected: one edge per URI in the directive - the default one plus each conditional alternative (
service_stub.dartandservice_io.dartabove). The same applies to conditionalimportdirectives.Cause: both patterns in
graphify/extractors/dart.py(section "6. Imports and Exports") match only the first quoted string afterimport/export:r"""^\s*export\s+['"]([^'"]+)['"]"""Note that a condition may itself contain a string literal (
if (app.flavor == 'prod') 'flags_prod.dart'), so a naive "all quoted strings in the directive" approach would mint a bogusprodnode.Steps to reproduce
Error output or graph output
Expected:
On a real Flutter app (~300 Dart files) all four such facades in the project were affected: the graph had no edge from any facade to its
*_io.dartimplementation.Graphify version
0.9.73 (reproduced on
v8@ e10df08 / 0.9.74 as well - the Dart extractor is unchanged there)Operating System
macOS
Python Version
3.13
Installation Method
uv tool install (recommended)
Additional Environment Details
No provider environment variables are needed - this is pure AST/regex extraction. Reproduced from a clean checkout of
v8.