Skip to main content

CodeAnalyzer

Trait CodeAnalyzer 

Source
pub trait CodeAnalyzer<D: Doc + Send + Sync>: Send + Sync {
    // Required methods
    fn find_pattern<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        document: &'life1 ParsedDocument<D>,
        pattern: &'life2 str,
        context: &'life3 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait;
    fn find_all_patterns<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
        &'life0 self,
        document: &'life1 ParsedDocument<D>,
        patterns: &'life2 [&'life3 str],
        context: &'life4 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait;
    fn replace_pattern<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
        &'life0 self,
        document: &'life1 mut ParsedDocument<D>,
        pattern: &'life2 str,
        replacement: &'life3 str,
        context: &'life4 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<usize>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait;
    fn analyze_cross_file_relationships<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        documents: &'life1 [ParsedDocument<D>],
        context: &'life2 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CrossFileRelationship>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn capabilities(&self) -> AnalyzerCapabilities;

    // Provided methods
    fn find_nodes_by_kind<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        document: &'life1 ParsedDocument<D>,
        node_kind: &'life2 str,
        context: &'life3 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait { ... }
    fn validate_pattern(&self, pattern: &str) -> ServiceResult<()> { ... }
    fn batch_analyze<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
        &'life0 self,
        documents: &'life1 [ParsedDocument<D>],
        patterns: &'life2 [&'life3 str],
        context: &'life4 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<Vec<CodeMatch<'_, D>>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait { ... }
    fn extract_symbols<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        _document: &'life1 mut ParsedDocument<D>,
        _context: &'life2 AnalysisContext,
    ) -> Pin<Box<dyn Future<Output = ServiceResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait { ... }
}
Expand description

Core analyzer service trait that abstracts ast-grep analysis functionality.

This trait provides both single-file analysis (preserving all ast-grep matching and replacement capabilities) and codebase-level analysis (adding graph intelligence and cross-file relationships).

§Design Philosophy

  • Preserve Power: All ast-grep Matcher and Replacer functionality accessible
  • Bridge Levels: Connect file-level AST operations to codebase-level graph intelligence
  • Enable Intelligence: Add cross-file relationships and codebase-wide analysis
  • Abstract Execution: Support different execution environments and strategies

§Examples

§File-Level Pattern Matching (preserves ast-grep power)

let analyzer = MyAnalyzer;
let context = AnalysisContext::default();

// Find all function declarations - preserves ast-grep pattern power
let matches = analyzer.find_pattern(
    &document,
    "fn $NAME($$$PARAMS) { $$$BODY }",
    &context
).await?;

for match_result in matches {
    // Access ast-grep NodeMatch functionality
    let node_match = match_result.ast_node_match();
    let env = node_match.get_env();

    if let Some(name) = env.get_match("NAME") {
        println!("Function: {}", name.text());
    }

    // Plus codebase-level context
    for relationship in match_result.relationships() {
        println!("Cross-file relationship: {:?}", relationship.kind);
    }
}

§Codebase-Level Analysis

let analyzer = MyAnalyzer;
let mut context = AnalysisContext::default();
context.scope = ExecutionScope::Codebase;

// Analyze relationships across entire codebase
let relationships = analyzer.analyze_cross_file_relationships(
    &documents,
    &context
).await?;

// Build intelligence on top of ast-grep file-level analysis
for rel in relationships {
    match rel.kind {
        thread_services::types::RelationshipKind::Calls => {
            println!("{} calls {} ({}->{})",
                rel.source_symbol, rel.target_symbol,
                rel.source_file.display(), rel.target_file.display());
        },
        thread_services::types::RelationshipKind::Imports => {
            println!("{} imports from {}",
                rel.source_file.display(), rel.target_file.display());
        },
        _ => {}
    }
}

Required Methods§

Source

fn find_pattern<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, document: &'life1 ParsedDocument<D>, pattern: &'life2 str, context: &'life3 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Find matches for a pattern in a document.

Preserves all ast-grep pattern matching power while adding codebase-level context. Returns CodeMatch instances that wrap NodeMatch and add cross-file relationship information.

§Arguments
  • document - ParsedDocument to search in
  • pattern - AST pattern using ast-grep meta-variable syntax (e.g., “$VAR”)
  • context - Analysis context for execution configuration
§Returns

Vector of CodeMatch instances with both ast-grep functionality and codebase context

Source

fn find_all_patterns<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, document: &'life1 ParsedDocument<D>, patterns: &'life2 [&'life3 str], context: &'life4 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Find matches for multiple patterns efficiently.

Optimizes for multiple pattern searches by batching operations and reusing AST traversals where possible.

§Arguments
  • document - ParsedDocument to search in
  • patterns - Slice of AST patterns to match
  • context - Analysis context for execution configuration
§Returns

Vector of CodeMatch instances for all pattern matches

Source

fn replace_pattern<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, document: &'life1 mut ParsedDocument<D>, pattern: &'life2 str, replacement: &'life3 str, context: &'life4 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<usize>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Replace matches for a pattern with replacement content.

Preserves all ast-grep replacement power including template-based replacement with meta-variable substitution and structural replacement.

§Arguments
  • document - ParsedDocument to perform replacements in (modified in-place)
  • pattern - AST pattern to match for replacement
  • replacement - Replacement template or content
  • context - Analysis context for execution configuration
§Returns

Number of replacements made

Source

fn analyze_cross_file_relationships<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, documents: &'life1 [ParsedDocument<D>], context: &'life2 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CrossFileRelationship>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Analyze relationships across multiple files.

This is where Thread extends ast-grep from file-level to codebase-level. Builds graph intelligence on top of ast-grep’s powerful file-level analysis.

§Arguments
  • documents - Collection of ParsedDocuments to analyze
  • context - Analysis context with scope and execution configuration
§Returns

Vector of CrossFileRelationship instances representing codebase-level connections

Source

fn capabilities(&self) -> AnalyzerCapabilities

Get analyzer capabilities and configuration.

Provided Methods§

Source

fn find_nodes_by_kind<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, document: &'life1 ParsedDocument<D>, node_kind: &'life2 str, context: &'life3 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<CodeMatch<'_, D>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Find specific AST node types efficiently.

Default implementation uses pattern matching, but implementations can override for more efficient node type searches.

Source

fn validate_pattern(&self, pattern: &str) -> ServiceResult<()>

Validate pattern syntax before analysis.

Default implementation performs basic validation. Implementations can override for language-specific validation.

Source

fn batch_analyze<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, documents: &'life1 [ParsedDocument<D>], patterns: &'life2 [&'life3 str], context: &'life4 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<Vec<Vec<CodeMatch<'_, D>>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Perform batch analysis operations efficiently.

Optimizes for analyzing multiple documents with multiple patterns by batching operations and using appropriate execution strategies.

Source

fn extract_symbols<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _document: &'life1 mut ParsedDocument<D>, _context: &'life2 AnalysisContext, ) -> Pin<Box<dyn Future<Output = ServiceResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Extract symbols and metadata from documents.

Bridges ast-grep file-level analysis to codebase-level intelligence by extracting symbols, imports, exports, and other metadata.

Implementors§