Skip to main content

agentic_codebase/parse/
mod.rs

1//! Multi-language parsing engine using tree-sitter.
2//!
3//! Converts source code into raw syntax information. One module per language.
4//! No semantic analysis here — just syntax extraction.
5
6pub mod cpp;
7pub mod go;
8pub mod parser;
9pub mod python;
10pub mod rust;
11pub mod treesitter;
12pub mod typescript;
13
14pub use parser::{ParseOptions, ParseResult, ParseStats, Parser};
15
16use std::collections::HashMap;
17use std::path::{Path, PathBuf};
18
19use crate::types::{AcbResult, CodeUnitType, Language, Span, Visibility};
20
21/// A code unit extracted from parsing, before semantic analysis.
22#[derive(Debug, Clone)]
23pub struct RawCodeUnit {
24    /// Temporary ID (reassigned during graph building).
25    pub temp_id: u64,
26    /// Type of code unit.
27    pub unit_type: CodeUnitType,
28    /// Programming language.
29    pub language: Language,
30    /// Simple name.
31    pub name: String,
32    /// Qualified name (may be partial, completed by semantic).
33    pub qualified_name: String,
34    /// Source file path.
35    pub file_path: PathBuf,
36    /// Location in source.
37    pub span: Span,
38    /// Type signature (raw, may need resolution).
39    pub signature: Option<String>,
40    /// Documentation.
41    pub doc: Option<String>,
42    /// Visibility.
43    pub visibility: Visibility,
44    /// Is async.
45    pub is_async: bool,
46    /// Is generator.
47    pub is_generator: bool,
48    /// Cyclomatic complexity.
49    pub complexity: u32,
50    /// Raw references found (names, not resolved IDs).
51    pub references: Vec<RawReference>,
52    /// Children temp_ids (for containers like modules, classes).
53    pub children: Vec<u64>,
54    /// Parent temp_id (for nested items).
55    pub parent: Option<u64>,
56    /// Language-specific metadata.
57    pub metadata: HashMap<String, String>,
58}
59
60impl RawCodeUnit {
61    /// Create a new raw code unit with minimal required fields.
62    pub fn new(
63        unit_type: CodeUnitType,
64        language: Language,
65        name: String,
66        file_path: PathBuf,
67        span: Span,
68    ) -> Self {
69        let qualified_name = name.clone();
70        Self {
71            temp_id: 0,
72            unit_type,
73            language,
74            name,
75            qualified_name,
76            file_path,
77            span,
78            signature: None,
79            doc: None,
80            visibility: Visibility::Unknown,
81            is_async: false,
82            is_generator: false,
83            complexity: 0,
84            references: Vec::new(),
85            children: Vec::new(),
86            parent: None,
87            metadata: HashMap::new(),
88        }
89    }
90}
91
92/// A raw reference found during parsing.
93#[derive(Debug, Clone)]
94pub struct RawReference {
95    /// The name being referenced.
96    pub name: String,
97    /// The kind of reference.
98    pub kind: ReferenceKind,
99    /// Where in the source.
100    pub span: Span,
101}
102
103/// The kind of a raw reference.
104#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub enum ReferenceKind {
106    /// Import statement.
107    Import,
108    /// Function call.
109    Call,
110    /// Type usage.
111    TypeUse,
112    /// Inheritance.
113    Inherit,
114    /// Interface implementation.
115    Implement,
116    /// Attribute/field access.
117    Access,
118}
119
120/// Parse error with severity.
121#[derive(Debug, Clone)]
122pub struct ParseFileError {
123    /// File path.
124    pub path: PathBuf,
125    /// Location in source.
126    pub span: Option<Span>,
127    /// Error message.
128    pub message: String,
129    /// Severity level.
130    pub severity: Severity,
131}
132
133/// Severity of a parse issue.
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
135pub enum Severity {
136    /// Could not parse at all.
137    Error,
138    /// Parsed but something odd.
139    Warning,
140    /// Informational.
141    Info,
142}
143
144/// Trait for language-specific parsers.
145pub trait LanguageParser: Send + Sync {
146    /// Extract code units from a parsed tree.
147    fn extract_units(
148        &self,
149        tree: &tree_sitter::Tree,
150        source: &str,
151        file_path: &Path,
152    ) -> AcbResult<Vec<RawCodeUnit>>;
153
154    /// Check if a file is a test file.
155    fn is_test_file(&self, path: &Path, source: &str) -> bool;
156}