Skip to main content

Crate thread_ast_engine

Crate thread_ast_engine 

Source
Expand description

§thread-ast-engine

Core AST engine for Thread: parsing, matching, and transforming code using AST patterns.

§Overview

thread-ast-engine provides powerful tools for working with Abstract Syntax Trees (ASTs). Forked from ast-grep-core, it offers language-agnostic APIs for code analysis and transformation.

§What You Can Do

  • Parse source code into ASTs using tree-sitter
  • Search for code patterns using flexible meta-variables (like $VAR)
  • Transform code by replacing matched patterns with new code
  • Navigate AST nodes with intuitive tree traversal methods

Perfect for building code linters, refactoring tools, and automated code modification systems.

§Quick Start

Add to your Cargo.toml:

[dependencies]
thread-ast-engine = { version = "0.1.0", features = ["parsing", "matching"] }

§Basic Example: Find and Replace Variables

use thread_ast_engine::Language;
use thread_ast_engine::tree_sitter::LanguageExt;

// Parse JavaScript/TypeScript code
let mut ast = Language::Tsx.ast_grep("var a = 1; var b = 2;");

// Replace all 'var' declarations with 'let'
ast.replace("var $NAME = $VALUE", "let $NAME = $VALUE")?;

// Get the transformed code
println!("{}", ast.generate());
// Output: "let a = 1; let b = 2;"

§Finding Code Patterns

use thread_ast_engine::matcher::MatcherExt;

let ast = Language::Tsx.ast_grep("function add(a, b) { return a + b; }");
let root = ast.root();

// Find all function declarations
if let Some(func) = root.find("function $NAME($$$PARAMS) { $$$BODY }") {
    println!("Function name: {}", func.get_env().get_match("NAME").unwrap().text());
}

// Find all return statements
for ret_stmt in root.find_all("return $EXPR") {
    println!("Returns: {}", ret_stmt.get_env().get_match("EXPR").unwrap().text());
}

§Working with Meta-Variables

Meta-variables capture parts of the matched code:

  • $VAR - Captures a single AST node
  • $$$ITEMS - Captures multiple consecutive nodes (ellipsis)
  • $_ - Matches any node but doesn’t capture it
let ast = Language::Tsx.ast_grep("console.log('Hello', 'World', 123)");
let root = ast.root();

if let Some(call) = root.find("console.log($$$ARGS)") {
    let args = call.get_env().get_multiple_matches("ARGS");
    println!("Found {} arguments", args.len()); // Output: Found 3 arguments
}

§Core Components

§Node - AST Navigation

Navigate and inspect AST nodes with methods like Node::children, Node::parent, and Node::find.

§Pattern - Code Matching

Match code structures using tree-sitter patterns with meta-variables.

§MetaVarEnv - Variable Capture

Store and retrieve captured meta-variables from pattern matches.

§[Replacer] - Code Transformation

Replace matched code with new content, supporting template-based replacement.

§Language - Language Support

Abstract interface for different programming languages via tree-sitter grammars.

§Feature Flags

  • parsing - Enables tree-sitter parsing (includes tree-sitter dependency)
  • matching - Enables pattern matching and node replacement/transformation engine.

Use default-features = false to opt out of all features and enable only what you need:

[dependencies]
thread-ast-engine = { version = "0.1.0", default-features = false, features = ["matching"] }

§Advanced Examples

§Custom Pattern Matching

use thread_ast_engine::ops::Op;

// Combine multiple patterns with logical operators
let pattern = Op::either("let $VAR = $VALUE")
    .or("const $VAR = $VALUE")
    .or("var $VAR = $VALUE");

let ast = Language::Tsx.ast_grep("const x = 42;");
let root = ast.root();

if let Some(match_) = root.find(pattern) {
    println!("Found variable declaration");
}

§Tree Traversal

let ast = Language::Tsx.ast_grep("if (condition) { doSomething(); } else { doOther(); }");
let root = ast.root();

// Traverse all descendants
for node in root.dfs() {
    if node.kind() == "identifier" {
        println!("Identifier: {}", node.text());
    }
}

// Check relationships between nodes
if let Some(if_stmt) = root.find("if ($COND) { $$$THEN }") {
    println!("If statement condition: {}",
        if_stmt.get_env().get_match("COND").unwrap().text());
}

§License

Original ast-grep code is licensed under the MIT license, all changes introduced in this project are licensed under the AGPL-3.0-or-later.

See VENDORED.md for more information on our fork, changes, and reasons.

Re-exports§

pub use source::Doc;
pub use matcher::MatchAll;
pub use matcher::MatchNone;
pub use matcher::Matcher;
pub use matcher::MatcherExt;
pub use matcher::NodeMatch;
pub use matcher::Pattern;
pub use matcher::PatternBuilder;
pub use matcher::PatternError;
pub use matcher::PatternNode;
pub use meta_var::MetaVarEnv;
pub use language::Language;

Modules§

language
Language Abstraction for AST Parsing
matcher
Pattern Matching Engine
meta_var
Meta-variable Environment and Utilities
ops
replacer
Code Replacement and Transformation
source
Document and Content Abstraction
tree_sitter
Tree-sitter Integration and AST Backend

Structs§

Node
A single node in an Abstract Syntax Tree.
Position
Represents a position in source code.
Root
Root of an AST tree that owns the source code and parsed tree structure.

Enums§

MatchStrictness
Controls how precisely patterns must match AST structure.

Type Aliases§

AstGrep