fix: add symbol-level IMPORTS edges for named imports#137
Conversation
|
Someone is attempting to deploy a commit to the NexusCore Team on Vercel. A member of the Team first needs to authorize it. |
…odes - Add definition.instance query to PYTHON_QUERIES, anchored to module scope with call on right-hand side - Add definition.instance to DEFINITION_CAPTURE_KEYS and label maps in both sequential (parsing-processor.ts) and worker (parse-worker.ts) paths - Compose with abhigyanpatwari#137: instances are now linkable targets for File->Symbol IMPORTS edges created by symbol-level import resolution
|
Verified on a Python project (~180 files). Before: all IMPORTS edges were file-level only — \ returned 0 upstream callers for any named import target. After: +53 symbol-level edges created correctly. Aliased imports (\ → resolves to ) and wildcard/bare module skipping both behave correctly. Worker path serialization handles the optional \ field cleanly via structured clone. One thing worth confirming before merge: downstream consumers of \ across worker boundaries handle \ fields — they do, structured clone omits them and all callers check \ before use. No issues found. Solid fix, hope it gets merged. |
|
This will be covered as part of #238 as it requires semantic resolution. Thank you for your contribution! |
Glad it’s being looked at! I did find an issue with it not working for all languages, just an FYI. |
|
These are the feature we are planning to support and cover in my PR Per-Language Feature Coverage Matrix
¹ Go/Rust use struct literal I'm still actively working on it. |
NOTE: This was fixed by AI and I am by no means a programmer. Please let me know if you have any issues with this.
Problem
The ingestion pipeline only creates file-to-file IMPORTS edges. When a file uses a named import like:
The graph only records:
The specific symbol (
validate_userfunction) being imported is lost. This means:impact("validate_user")can't trace what depends on this function via importscontext("validate_user")doesn't show importing files in its incoming referencesSolution
Add symbol-level IMPORTS edges alongside existing file-level ones by leveraging the
SymbolTable(already populated during parsing) to resolve named imports to their target nodes.After this fix, the graph contains both:
What's affected
from X import foo, bar(Python)import { foo, bar } from 'X'(JS/TS)from X import foo as alias(Python)import X(Python bare import)import X from 'Y'(JS default import)from X import *(Python wildcard)Changes
src/core/ingestion/workers/parse-worker.tsextractImportedSymbolNames()— walks the import AST node to extract named symbols from Pythonimport_from_statementand JS/TSnamed_importsnodessymbolNamesarray to theExtractedImportinterface for the worker data pathsrc/core/ingestion/import-processor.tsaddSymbolImportEdges()helper in bothprocessImports(sequential path) andprocessImportsFromExtracted(worker path)symbolTable.lookupExact(resolvedPath, name)to find the target Function/Class nodesymbolTableparameter (no breaking change — undefined falls through gracefully)src/core/ingestion/pipeline.tssymbolTableas a new argument toprocessImports()andprocessImportsFromExtracted()Design decisions
symbolTableis undefined or a symbol isn't found, the code silently skips. No errors for unresolved symbols.sourceIdis the importing File node (not a symbol within it), since Python/JS import statements are module-level, not scoped to a function.lookupExactonly — matches symbol by (filePath, name) pair. No fuzzy matching, keeping confidence at 1.0.Testing
Verified on a Python LangGraph project (84 nodes). Before: 179 edges (all file-level). After: 179 file-level edges + ~40 new symbol-level IMPORTS edges correctly linking files to the specific Function/Class nodes they import.
Example results from
impact("supervisor")targeting a Function node:graph.py (File) --IMPORTS--> supervisor (Function)at depth 1, with correct transitive trace through files that importgraph.pyat depth 2