Docs.rs
  • stack-graphs-0.14.1
    • stack-graphs 0.14.1
    • Permalink
    • Docs.rs crate page
    • MIT OR Apache-2.0
    • Links
    • Homepage
    • Repository
    • crates.io
    • Source
    • Owners
    • dcreager
    • patrickt
    • hendrikvanantwerpen
    • rewinfrey
    • Dependencies
      • bincode ^2.0.0-rc.3 normal optional
      • bitvec ^1.0.1 normal
      • controlled-option ^0.4.1 normal
      • either ^1.6 normal
      • enumset ^1.1 normal
      • fxhash ^0.2 normal
      • itertools ^0.10.2 normal
      • libc ^0.2 normal
      • lsp-positions ^0.3 normal
      • rusqlite ^0.28 normal optional
      • serde ^1.0 normal optional
      • serde_json ^1.0 normal optional
      • serde_with ^3.1 normal optional
      • smallvec ^1.6 normal
      • thiserror ^1.0 normal
      • assert-json-diff ^2 dev
      • maplit ^1.0 dev
      • pretty_assertions ^0.7 dev
      • serde_json ^1.0 dev
    • Versions
    • 59.07% of the crate is documented
  • Platform
    • i686-unknown-linux-gnu
    • x86_64-unknown-linux-gnu
  • Feature flags
  • docs.rs
    • About docs.rs
    • Privacy policy
  • Rust
    • Rust website
    • The Book
    • Standard Library API Reference
    • Rust by Example
    • The Cargo Guide
    • Clippy Documentation

Crate stack_graphs

stack_graphs0.14.1

  • All Items

Sections

  • Relationship to scope graphs

Crate Items

  • Modules
  • Macros
  • Structs
  • Traits

Crates

  • stack_graphs

Crate stack_graphs

Source
Expand description

Stack graphs provide a single framework for performing name resolution for any programming language, while abstracting away the specific name resolution rules for each of those languages. The basic idea is to represent the definitions and references in a program using graph. A name binding maps a reference to all of the possible definitions that the reference could refer to. Because we’ve represented definitions and references as a graph, bindings are represented by paths within that graph.

While searching for a path in an incremental stack graph, we keep track of two stacks: a symbol stack and a scope stack. Broadly speaking, the symbol stack keeps track of what symbols we’re trying to resolve, while the scope stack gives us control over which particular scopes we look for those symbols in.

§Relationship to scope graphs

Stack graphs are based in the scope graphs formalism from Eelco Visser’s group at TU Delft. Scope graphs also model the name binding structure of a program using a graph, and uses paths within that graph to represent which definitions a reference might refer to.

Stack graphs add incrementality to scope graphs. An incremental analysis is one where we can reuse analysis results for source code files that haven’t changed. In a non-incremental analysis, we have to reanalyze the entire contents of a repository or package when any file is changed.

As one example, the Scopes as Types paper presents some rewrite rules that let you handle field access in a record or object type — for instance, being able to resolve the foo part of A.foo. In Scopes as Types, we’d handle this by performing the path-finding algorithm when constructing the graph, to find out what A resolves to. Once we find its definition, we then attach the reference to foo to that result.

This is not incremental because the reference to foo “lives” over in some unrelated part of the graph. If A is defined in a different file (or worse, a different package), then we have to update that distant part of the graph with the node representing the reference. We end up cluttering the graph for a class definition with nodes representing all of its field references, which is especially problematic for popular packages with lots of downstream dependencies.

Our key insight is to recognize that when resolving A.foo, we have to “pause” the resolution of foo to start resolving A. Once we’ve found the binding for A, we can resume the original resolution of foo. This describes a stack! So instead of having our path-finding algorithm look for exactly one symbol, we can keep track of a stack of things to look for. To correctly resolve foo, we do still have to eventually make our way over to the part of the graph where A is defined. But by having a stack of path-finding targets, we can resolve the reference to A.foo with a single execution of the path-finding algorithm. And most importantly, each “chunk” of the overall graph only depends on “local” information from the original source file. (a.k.a., it’s incremental!)

Modules§

arena
Cache-friendly arena allocation for stack graph data.
assert
Defines assertions that can be run against a stack graph.
c
Defines a C API for working with stack graphs in other languages.
cycles
Detect and avoid cycles in our path-finding algorithm.
graph
Defines the structure of a stack graph.
partial
Partial paths are “snippets” of paths that we can precalculate for each file that we analyze.
paths
Paths represent name bindings in a source language.
serde
stats
stitching
Partial paths can be “stitched together” to produce name-binding paths.
storage
visualization

Macros§

copious_debugging

Structs§

CancelAfterDuration
CancellationError
NoCancellation

Traits§

CancellationFlag
Trait to signal that the execution is cancelled

Results

Settings
Help

Type "ScopedSymbol" not found. Showing results for closest type name "popscopedsymbol" instead.

    enum variant
    stack_graphs::graph::Node::PopScopedSymbol
    enum variant
    stack_graphs::serde::Node::PopScopedSymbol
    struct
    stack_graphs::graph::PopScopedSymbolNode
    Pops a scoped symbol from the symbol stack. If the top of …
    enum variant
    stack_graphs::graph::Node::PushScopedSymbol
    enum variant
    stack_graphs::serde::Node::PushScopedSymbol
    struct
    stack_graphs::graph::PushScopedSymbolNode
    Pushes a scoped symbol onto the symbol stack.
    method
    stack_graphs::graph::StackGraph::add_pop_scoped_symbol_node
    Adds a pop scoped symbol node to the stack graph.
    struct
    stack_graphs::partial::PartialScopedSymbol
    A symbol with an unknown, but possibly empty, list of …
    struct
    stack_graphs::serde::PartialScopedSymbol
    method
    stack_graphs::graph::StackGraph::add_push_scoped_symbol_node
    Adds a push scoped symbol node to the stack graph.
    struct
    stack_graphs::c::sg_partial_scoped_symbol
    A symbol with an unknown, but possibly empty, list of …
    method
    stack_graphs::serde::PartialScopedSymbol::to_partial_scoped_symbol
    method
    stack_graphs::serde::PartialScopedSymbol::from_partial_scoped_symbol
    enum variant
    stack_graphs::c::sg_node_kind::SG_NODE_KIND_POP_SCOPED_SYMBOL
    Pops a scoped symbol from the symbol stack. If the top of …
    enum variant
    stack_graphs::c::sg_node_kind::SG_NODE_KIND_PUSH_SCOPED_SYMBOL
    Pushes a scoped symbol onto the symbol stack.
    struct field
    stack_graphs::serde::Node::PopScopedSymbol::id
    PopScopedSymbol -> NodeID
    struct field
    stack_graphs::serde::Node::PopScopedSymbol::symbol
    PopScopedSymbol -> String
    struct field
    stack_graphs::serde::Node::PopScopedSymbol::debug_info
    PopScopedSymbol -> Option
    struct field
    stack_graphs::serde::Node::PopScopedSymbol::source_info
    PopScopedSymbol -> Option
    struct field
    stack_graphs::serde::Node::PopScopedSymbol::is_definition
    PopScopedSymbol -> bool
No results :(
Try on DuckDuckGo?

Or try looking in one of these:
  • The Rust Reference for technical details about the language.
  • Rust By Example for expository code examples.
  • The Rust Book for introductions to language features and the language itself.
  • Docs.rs for documentation of crates released on crates.io.