Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion graphify/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
_EXTRACTOR_VERSION = "unknown"

# Bump when AST cache-key semantics change independently of the package version.
_AST_CACHE_SCHEMA = 17 # Batch: Python pytest-fixture markers (`_py_fixture`/`_python_fixture_param`, #4332) and module-level class-id collision salting (#2810); TS `this.field` typed from any method incl. static (#4473); Solidity callables carry `metadata.arity` + inherited-call/`super`/modifier raw calls (#4379); Go type-decl and Rust file-item case-distinct node ids (#4444); prior (16): Rust `use` edges carry the imported name as written (`_rust_use_name`, #4439); (15): Go generic receiver types normalized (`Box[T]` -> `Box`) so methods attach to the type node; prior (14): C# receiver resolution for nameless/`new X()`/`foreach` receivers (defer + receiver-chain markers) and `_`/case-distinct node ids (underscore-salted); prior (13): Kotlin/Scala/C++/Swift generic & template type params no longer mint sourceless stubs; Objective-C NS_ENUM/NS_OPTIONS extraction and `_callable`/`_callable_class` markers; Go and PHP receiver-typed member calls park cross-repo (`go_type_table`/`php_type_table`, receiver fields); prior (12): Java inherited-supertype (`receiver_unbound`) and chained/new/cast receiver typing (`java_receiver_chain`, `_java_ret`); C/C++ quoted cross-directory include provenance (`include_kind`); JS external imports anchored to the package, not the path leaf; prior (11): Python property-accessor decorators / `Self`, Swift `Self`, Go generic type params, Python forward type-hint file node, PowerShell dot-source, C# verbatim-interpolated string recovery; (10): C# partial types carry `type_path`; (9): Python property-read raw calls and `_py_property` nodes; (8): Rust `use`-group per-binding edges; (7): Python opaque-base/super(args) markers + nested-class enclosing ids.
_AST_CACHE_SCHEMA = 18 # package.json dependency entries link to their ref node (`declares`) and are labelled `name@range` (#4569); prior (17): Python pytest-fixture markers (`_py_fixture`/`_python_fixture_param`, #4332) and module-level class-id collision salting (#2810); TS `this.field` typed from any method incl. static (#4473); Solidity callables carry `metadata.arity` + inherited-call/`super`/modifier raw calls (#4379); Go type-decl and Rust file-item case-distinct node ids (#4444); prior (16): Rust `use` edges carry the imported name as written (`_rust_use_name`, #4439); (15): Go generic receiver types normalized (`Box[T]` -> `Box`) so methods attach to the type node; prior (14): C# receiver resolution for nameless/`new X()`/`foreach` receivers (defer + receiver-chain markers) and `_`/case-distinct node ids (underscore-salted); prior (13): Kotlin/Scala/C++/Swift generic & template type params no longer mint sourceless stubs; Objective-C NS_ENUM/NS_OPTIONS extraction and `_callable`/`_callable_class` markers; Go and PHP receiver-typed member calls park cross-repo (`go_type_table`/`php_type_table`, receiver fields); prior (12): Java inherited-supertype (`receiver_unbound`) and chained/new/cast receiver typing (`java_receiver_chain`, `_java_ret`); C/C++ quoted cross-directory include provenance (`include_kind`); JS external imports anchored to the package, not the path leaf; prior (11): Python property-accessor decorators / `Self`, Swift `Self`, Go generic type params, Python forward type-hint file node, PowerShell dot-source, C# verbatim-interpolated string recovery; (10): C# partial types carry `type_path`; (9): Python property-read raw calls and `_py_property` nodes; (8): Rust `use`-group per-binding edges; (7): Python opaque-base/super(args) markers + nested-class enclosing ids.


# Per-process memo: distributions() scans site-packages metadata, which is
Expand Down
26 changes: 25 additions & 1 deletion graphify/extractors/json_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def walk_object(obj_node, parent_nid: str, parent_key: str | None,
if ref_nid:
add_edge(parent_nid, ref_nid, "references", line)

elif parent_key in _DEP_KEYS and val_text:
elif parent_key in _DEP_KEYS and val_text.strip():
# Two defects fixed here, both from the #1764 shape:
#
# 1. The edge ran `key_nid -> dep_nid`, and both nodes carry
Expand All @@ -253,10 +253,34 @@ def walk_object(obj_node, parent_nid: str, parent_key: str | None,
# `types` could then be collapsed onto a same-named local
# module by build.py's alias index -- the #1638 failure
# mode reached through a different door.
#
# 3. Moving that edge to the manifest also cut the only link between the
# dependency's key node (its manifest entry, reached through
# `dependencies --contains-->`) and its ref node, so the entry and
# the code that imports the package landed in different communities
# (#4569). `key_nid --declares--> dep_nid` reconnects them, and the
# entry is relabelled `name@range` so the two nodes no longer share a
# label: a same-label edge is the `react -> react` view #1764
# removed, and two `react` nodes made `explain`/`affected`
# ambiguous. The ref node keeps the bare name, which is what
# `import "react"` resolves to. The range is one line, capped at 40
# characters; a blank one links nothing (like an empty one) and the
# entry keeps its bare name.
dep_nid = _make_id("ref", key)
if dep_nid:
add_node(dep_nid, key, line, file_type="concept")
add_edge(file_nid, dep_nid, "imports", line, context="import")
add_edge(key_nid, dep_nid, "declares", line)
version = " ".join(val_text.split())
if len(version) > 40:
version = version[:37] + "..."
# `add_node` kept the first node under this id (the same key under
# two sibling blocks shares it), so relabel only the pair that
# node's line belongs to: label and line then name one entry.
for node in nodes:
if node["id"] == key_nid and node["source_location"] == f"L{line}":
node["label"] = f"{key}@{version}"
break

# Entry: find root document → object
doc = root
Expand Down
Loading
Loading