stack-graphs

repository·main·Indexed 21 days ago

https://github.com/github/stack-graphs

A Rust-based framework for defining efficient, incremental name resolution rules for programming languages, independent of existing build or analysis tools. It includes language definitions for Java, JavaScript, Python, and TypeScript, as well as the lsp-positions library for mapping UTF-8 byte positions to LSP-compatible UTF-16 code units.

Tokens
28.1K
Snippets
100
Records
132
Agent score
74%

What's inside stack-graphs

  1. Available stack-graphs name binding examples

    main

    The repository includes several examples demonstrating different name binding patterns. Each example directory contains a stack-graphs.tsg file describing the implemented behavior and a tests directory showcasing that behavior. Note that while these examples use Python syntax, they may not strictly implement Python semantics.

    Available examples:

    • nested-scope/: Demonstrates nested scoping.
    • sequential-definitions/: Demonstrates sequential definitions.
    • modules/: Demonstrates modules and imports.
  2. Understand stack graphs language definitions

    main

    The languages/ directory contains stack graphs definitions for specific programming languages. Each definition is packaged following a naming convention that combines the target tool and the language name.

    For example, tree-sitter-stack-graphs-typescript is the definition for TypeScript intended for use with tree-sitter-stack-graphs.

  3. What are stack graphs?

    main
    Stack graphs are a Rust implementation used to define name resolution rules for arbitrary programming languages. They are designed to be efficient and incremental, allowing for name resolution without requiring integration with existing build systems or program analysis tools. The implementation is heavily based on the scope graphs framework from TU Delft.
  4. Understand the stack graphs versioning scheme

    main

    Stack graphs definitions are versioned independently of the underlying grammar versions. They use an adapted semantic versioning (MAJOR.MINOR.PATCH) scheme based on the compatibility of the resulting resolutions:

    • MAJOR: Increment if the new stack graphs are incompatible with previous versions (i.e., some existing resolutions are missing when replacing old graphs with new ones).
    • MINOR: Increment if the new stack graphs are compatible with previous versions (i.e., all pre-existing resolutions remain, though new resolutions may be added).
    • PATCH: Increment for bug fixes.

    Note for 0.x.y versions: Increment the MINOR version for changes that are incompatible with the previous version.

    Dependency Rule: Versioned releases of stack graphs should only depend on versioned releases of the grammars they use.

  5. Writing TSG (Tree-sitter Graph) rules

    main

    Stack graph rules are written using the tree-sitter-graph syntax.

    • Rule Location: In this project, rules are defined in src/stack-graphs.tsg.
    • Builtins: Sources and configuration are in src/builtins.it and builtins.cfg.
    • Tooling: A VSCode extension is available for TSG syntax highlighting.
    • Examples: Refer to the stack-graphs examples for self-contained rules for specific language features.
  6. How lsp-positions handles character locations

    main

    The lsp-positions crate solves the problem of interoperating with the Language Server Protocol (LSP) when working with Rust source code.

    Rust strings are UTF-8 encoded and indexed by bytes, whereas LSP specifies character locations using UTF-16 code units. To bridge this gap, lsp-positions tracks each source code position using two distinct units:

    1. UTF-8 byte position: Used for indexing into standard Rust str and [u8] data.
    2. UTF-16 code unit position: Used within a line to generate Position values compatible with LSP specifications.

    This dual tracking ensures that tools analyzing source code can accurately map internal byte offsets to the character-based locations required by LSP clients and servers.

  7. Develop tree-sitter-stack-graphs from source

    main

    If you are contributing to the project or running it without installation, use the following commands. Note that the CLI features are gated behind the cli feature flag.

    • Run CLI from source: cargo run --features cli -- ARGS
    • Build: cargo build (use --features cli to include CLI binaries)
    • Test: cargo test (use --features cli to include CLI tests)
    • Format: cargo fmt
    # Run CLI with arguments
    cargo run --features cli -- <ARGS>
    
    # Build with CLI features
    cargo build --features cli
  8. Initialize a new language stack graph project

    main

    To start developing stack graph definitions for a new language, use the init command. This will launch an interactive prompt to collect information about the language, its grammar dependency, and the project structure, then generate a scaffold in the specified directory.

    tree-sitter-stack-graphs init PROJECT_DIR