Skip to content

Import Traversal

Last verified end to end: 2026-07-14 (query_code schema version 2).

Import traversal starts with an indexed project declaration, not an import spelling. Convert that declaration to its file with file-of, then follow either a forward (imports-of) or reverse (importers-of) direct project-local edge. This keeps the result honest: Bifrost reports the files connected by a resolved import, not a guess that every importer calls a particular member.

For a project-local callable named target and an importing callable named consume, these RQL pipelines have the following roles:

; The declaration that contains a structural call match.
(enclosing-decl
(language <language> (call :callee (name "target"))))
; The file that declares target.
(file-of
(language <language> (callable :name "target")))
; The direct project-local file imported by consume's file.
(imports-of
(file-of (language <language> (callable :name "consume"))))
; Every project file that directly imports target's file.
(importers-of
(file-of (language <language> (callable :name "target"))))

For MCP or saved JSON queries, replace the last expression with the same structural match and ordered steps:

{
"languages": ["<language>"],
"match": {"kind": "callable", "name": "target"},
"steps": [
{"op": "file_of"},
{"op": "importers_of"}
]
}

<language> is the query_code filter label shown below. cpp deliberately covers both C and C++.

For example, the Ruby form is directly runnable as RQL or JSON:

(importers-of
(file-of (language ruby (callable :name "target"))))
{"languages":["ruby"],"match":{"kind":"callable","name":"target"},"steps":[{"op":"file_of"},{"op":"importers_of"}]}

The same reverse pipeline above is verified against a target declaration and one direct importer for every adapter that provides structured import-file analysis.

Query labelTarget declarationDirect importer
pythondef target(): pass in target.pyfrom target import target
javapublic static void target() {} in example/Target.javaimport example.Target;
javascriptexport function target() {} in target.jsimport { target } from './target.js';
typescriptexport function target(): void {} in target.tsimport { target } from './target';
gofunc Target() {} in target/target.goimport "example.com/project/target"
cppinline int target() { return 0; } in target.h#include "target.h"
rustpub fn target() {} in src/shared.rsuse crate::shared::target;
scaladef target(): Unit = () in example/Target.scalaimport example.Target
csharppublic static void target() {} in Target.csusing Example;
rubydef target; end in target.rbrequire_relative 'target'

The query does not need to duplicate each language’s import grammar. The language adapter obtains the structured import facts, and the shared pipeline only sees project files and direct edges.

Boundary: External Libraries And Member Uses

Section titled “Boundary: External Libraries And Member Uses”

The table intentionally uses project-local targets. An import of an out-of-scope package can be observed structurally with an import pattern, but it has no indexed project declaration or file to start this traversal. Bifrost does not create a synthetic declaration for that package, its types, or its methods.

PHP currently supports structural import matching and the declaration/file steps, but does not provide structured import-file analysis. imports-of and importers-of therefore return a diagnostic for affected PHP files instead of silently guessing.

Likewise, a reverse edge says that a file imports the target file—not that it calls target. Use Reference Traversal to traverse an indexed declaration to exact reference sites or semantic users. Because reference sites compose with file-of, a proven symbol edge can also feed imports-of or importers-of without turning the import relationship into a synthetic symbol identity.