fix(extract): add origin_file to cross-file stubs in the six dedicated extractors (#1515)
The #1462 same-label cross-file stub disambiguation (the origin_file key) only existed in the generic extractor, so the six dedicated extractors — Julia, Fortran, Go, Rust, PowerShell, ObjC — still collapsed same-named imported-type stubs from different files into one conflated bare-id node (a false cross-package link). Each now sets origin_file on its sourceless stub, identical to the generic extractor; the generic _node_disambiguation_source_key consumes it, so two files importing the same type stay distinct while source_file stays empty (the #1402 rewire onto a real definition is unchanged). Ported from PR #1515 by @TPAteeq. Must ship with #1516: this widens origin_file to six more languages, and #1516 is what strips it from graph.json. Verified: a 2-file Go corpus now yields 2 distinct Widget stubs AND graph.json carries no origin_file. Resolved a test-insertion conflict with #1516 by keeping both tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
safishamsi
co-authored by
Claude Opus 4.8
parent
afa4aded2e
commit
d177f04270
@@ -22,6 +22,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
|
||||
- Fix: imported type stubs with the same label no longer falsely merge across files when there is no project definition to rewire onto (#1462, thanks @jiangyq9). Two files that both `from pathlib import Path` and use `Path` as a type previously collapsed into one node; the referencing file is now kept as an internal disambiguator (`origin_file`) used only when splitting colliding ids, while `source_file` stays empty so a real project definition can still be rewired onto (the #1402 path is unaffected).
|
||||
- Feat: resolve C# cross-file type references and extract `enum`/`struct`/`record` declarations (#1466, thanks @TheFedaikin). A new `_resolve_csharp_type_references` (the C# counterpart to the Java resolver) re-points dangling `inherits`/`implements`/`references` edges from no-source "shadow" stubs to their real definitions, disambiguating same-named types in different namespaces via the referencing file's `using` directives and enclosing namespace; ambiguous matches are refused rather than guessed. `enum`/`struct`/`record` types are now extracted as definitions so those references resolve too. Advances #1318 for C#.
|
||||
- Fix: the Go AST extractor no longer creates phantom duplicate nodes for cross-file type references — the Go copy of `ensure_named_node` still used the older sourced-stub fallback; it now emits a sourceless stub like the other extractors, extending the #1402 fix to Go (#1500, thanks @TPAteeq).
|
||||
- Fix: cross-file references to a same-named type now stay distinct across the six dedicated AST extractors (Go, Rust, Julia, Fortran, PowerShell, ObjC) instead of conflating into one shared node — #1462's `origin_file` stub-disambiguation had only been applied to the generic extractor; it now covers all seven.
|
||||
|
||||
## 0.8.50 (2026-06-27)
|
||||
|
||||
|
||||
@@ -5967,6 +5967,7 @@ def extract_julia(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
@@ -6263,6 +6264,7 @@ def extract_fortran(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
@@ -6512,6 +6514,7 @@ def extract_go(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
@@ -6866,6 +6869,7 @@ def extract_rust(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
@@ -7169,6 +7173,7 @@ def extract_powershell(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
@@ -9481,6 +9486,7 @@ def extract_objc(path: Path) -> dict:
|
||||
"file_type": "code",
|
||||
"source_file": "",
|
||||
"source_location": "",
|
||||
"origin_file": str_path,
|
||||
})
|
||||
return nid
|
||||
|
||||
|
||||
@@ -201,6 +201,28 @@ def test_origin_file_is_not_serialized_into_extract_output(tmp_path):
|
||||
assert len({node["id"] for node in path_nodes}) == 2
|
||||
|
||||
|
||||
def test_go_imported_type_stubs_do_not_collide_across_source_files(tmp_path):
|
||||
"""#1462 (dedicated extractors): the imported-type-stub disambiguation (the
|
||||
``origin_file`` key) landed only in the generic extractor, so the six dedicated
|
||||
extractors (Go, Rust, Julia, Fortran, PowerShell, ObjC) still collapsed same-label
|
||||
cross-file stubs into one conflated bare-id node — a false cross-package link.
|
||||
They must stay distinct per file while keeping ``source_file`` empty so the #1402
|
||||
rewire still collapses them onto a real definition when one exists."""
|
||||
first = tmp_path / "a/use_a.go"
|
||||
second = tmp_path / "b/use_b.go"
|
||||
first.parent.mkdir(parents=True)
|
||||
second.parent.mkdir(parents=True)
|
||||
first.write_text('package a\n\nimport "ext"\n\nfunc UseA(w ext.Widget) {}\n', encoding="utf-8")
|
||||
second.write_text('package b\n\nimport "ext"\n\nfunc UseB(w ext.Widget) {}\n', encoding="utf-8")
|
||||
|
||||
result = extract([first, second], cache_root=tmp_path)
|
||||
widget_nodes = [node for node in result["nodes"] if node["label"] == "Widget"]
|
||||
|
||||
assert len(widget_nodes) == 2
|
||||
assert len({node["id"] for node in widget_nodes}) == 2
|
||||
assert all(not node.get("source_file") for node in widget_nodes)
|
||||
|
||||
|
||||
def test_extract_updates_raw_call_callers_after_duplicate_id_disambiguation(tmp_path):
|
||||
first = tmp_path / "apps/api/Program.cs"
|
||||
second = tmp_path / "tools/api/Program.cs"
|
||||
|
||||
Reference in New Issue
Block a user