mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-18 22:02:49 +08:00
fix(dart): a library links the files its part directives name (#2391)
A Dart `part 'x.g.dart';` now mints an `import` node (name = the URI,
signature = the directive) and an `imports` ref from the library's file
node, in both extractors. The ref resolves through `dartDirectiveFile` by
the rules an import or export follows, so the library's file links the
part's file. A library and its parts are one library, so a change to a
part, generated or hand-written, now reaches the library and what imports
it in `codegraph affected` and the files listed as using the part. Before,
neither `part` nor `part of` left a trace, and the two files were joined
only by whatever symbol edges happened to cross between them: riverpod's
framework.dart, which holds nothing but `part` lines, by none.
`part of` still records nothing: the library's edge already joins the two
files, and a part -> library edge would list every pair on both import
rails of both files and make each a file 2-cycle.
The kernel's directive arm now goes on into the directive's children, as
the TS ladder does. Its `import_or_export` arm used to return first, so an
annotated directive's arguments (`@Tag(f) import 'a.dart';`) were fn-ref
candidates on the wasm path only.
Validation on rrousselGit/riverpod @4ba1be2 and felangel/bloc @b9be1e2
with the kernel loaded, base 837a1866:
- bloc: +53 import nodes, +53 contains, +53 imports (library -> part).
- riverpod: +294 import nodes, +294 contains, +258 imports, +36 refs left
unresolved (generated parts that are not committed).
- Nothing removed; kernel and wasm dumps byte-identical; parity sweeps
0 diffs. Every added edge sits on a `part` line whose URI names the
target, and the target's `part of` names the library back (311/311).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -826,9 +826,13 @@ impl<'t> Walker<'t> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
"import_or_export" => {
|
||||
// importTypes (dart.ts): `import` / `export`, and `part
|
||||
// 'x.g.dart';`, which links the library to the part's file. The
|
||||
// TS ladder goes on into the directive's children, so this does
|
||||
// too: an annotation's arguments are fn-ref capture points
|
||||
// (`@Tag(bar) import 'a.dart';` captures `bar`).
|
||||
"import_or_export" | "part_directive" => {
|
||||
self.extract_import(node);
|
||||
return;
|
||||
}
|
||||
"new_expression" => {
|
||||
// INSTANTIATION_KINDS row — from the FILE/CLASS on the
|
||||
@@ -1036,7 +1040,7 @@ impl<'t> Walker<'t> {
|
||||
false
|
||||
}
|
||||
|
||||
// --- extractImport (:3170; hook dart.ts:261-304) ----------------------
|
||||
// --- extractImport (:3170; hook dart.ts extractImport) -----------------
|
||||
|
||||
fn extract_import(&mut self, node: Node<'t>) {
|
||||
let find_child = |parent: Node<'t>, kind: &str| -> Option<Node<'t>> {
|
||||
@@ -1050,6 +1054,12 @@ impl<'t> Walker<'t> {
|
||||
find_child(uri, "string_literal")
|
||||
};
|
||||
let mut module: Option<String> = None;
|
||||
// A part: `part 'x.g.dart';` holds its `uri` directly.
|
||||
if node.kind() == "part_directive" {
|
||||
if let Some(sl) = find_child(node, "uri").and_then(|uri| find_child(uri, "string_literal")) {
|
||||
module = Some(self.text(sl).replace(['\'', '"'], ""));
|
||||
}
|
||||
}
|
||||
if let Some(li) = find_child(node, "library_import") {
|
||||
if let Some(spec) = find_child(li, "import_specification") {
|
||||
if let Some(sl) = uri_of(spec) {
|
||||
|
||||
Reference in New Issue
Block a user