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