@@ -61,39 +61,123 @@ impl Parser {
6161 pub fn parse < P : AsRef < Path > > ( & self , path : P ) -> Result < ParseResult > {
6262 let path = path. as_ref ( ) ;
6363 let content = std:: fs:: read_to_string ( path) ?;
64- let lang = Language :: from_path ( path)
64+ let _lang = Language :: from_path ( path)
6565 . ok_or_else ( || AcpError :: UnsupportedLanguage (
6666 path. extension ( )
6767 . map ( |e| e. to_string_lossy ( ) . to_string ( ) )
6868 . unwrap_or_default ( )
6969 ) ) ?;
7070
71- // TODO: Implement actual tree-sitter parsing
72- // For now, return a basic result with file metadata
7371 let lines = content. lines ( ) . count ( ) ;
7472 let file_name = path. file_stem ( )
7573 . map ( |s| s. to_string_lossy ( ) . to_string ( ) )
7674 . unwrap_or_default ( ) ;
75+ let file_path = path. to_string_lossy ( ) . to_string ( ) ;
76+
77+ // Parse @acp: annotations from source
78+ let annotations = self . parse_annotations ( & content) ;
79+
80+ // Extract file-level metadata from annotations
81+ let mut module_name = file_name. clone ( ) ;
82+ let mut domains = vec ! [ ] ;
83+ let mut layer = None ;
84+ let mut symbols = vec ! [ ] ;
85+ let mut symbol_names = vec ! [ ] ;
86+ let mut calls = vec ! [ ] ;
87+
88+ // Track current symbol context for multi-line annotations
89+ let mut current_symbol: Option < SymbolBuilder > = None ;
90+
91+ for ann in & annotations {
92+ match ann. name . as_str ( ) {
93+ "module" => {
94+ if let Some ( val) = & ann. value {
95+ module_name = val. trim_matches ( '"' ) . to_string ( ) ;
96+ }
97+ }
98+ "domain" => {
99+ if let Some ( val) = & ann. value {
100+ domains. push ( val. trim_matches ( '"' ) . to_string ( ) ) ;
101+ }
102+ }
103+ "layer" => {
104+ if let Some ( val) = & ann. value {
105+ layer = Some ( val. trim_matches ( '"' ) . to_string ( ) ) ;
106+ }
107+ }
108+ "symbol" => {
109+ // Save previous symbol if exists
110+ if let Some ( builder) = current_symbol. take ( ) {
111+ let sym = builder. build ( & file_path) ;
112+ symbol_names. push ( sym. name . clone ( ) ) ;
113+ symbols. push ( sym) ;
114+ }
115+ // Start new symbol
116+ if let Some ( val) = & ann. value {
117+ current_symbol = Some ( SymbolBuilder :: new (
118+ val. trim_matches ( '"' ) . to_string ( ) ,
119+ ann. line ,
120+ ) ) ;
121+ }
122+ }
123+ "summary" => {
124+ if let Some ( ref mut builder) = current_symbol {
125+ if let Some ( val) = & ann. value {
126+ builder. summary = Some ( val. trim_matches ( '"' ) . to_string ( ) ) ;
127+ }
128+ }
129+ }
130+ "calls" => {
131+ if let Some ( ref mut builder) = current_symbol {
132+ if let Some ( val) = & ann. value {
133+ let callees: Vec < String > = val
134+ . split ( ',' )
135+ . map ( |s| s. trim ( ) . trim_matches ( '"' ) . to_string ( ) )
136+ . collect ( ) ;
137+ builder. calls . extend ( callees) ;
138+ }
139+ }
140+ }
141+ _ => { }
142+ }
143+ }
144+
145+ // Save last symbol
146+ if let Some ( builder) = current_symbol {
147+ let sym = builder. build ( & file_path) ;
148+ if !sym. calls . is_empty ( ) {
149+ calls. push ( ( sym. name . clone ( ) , sym. calls . clone ( ) ) ) ;
150+ }
151+ symbol_names. push ( sym. name . clone ( ) ) ;
152+ symbols. push ( sym) ;
153+ }
154+
155+ // Build call edges for earlier symbols
156+ for sym in & symbols {
157+ if !sym. calls . is_empty ( ) {
158+ calls. push ( ( sym. name . clone ( ) , sym. calls . clone ( ) ) ) ;
159+ }
160+ }
77161
78162 let file = FileEntry {
79- path : path . to_string_lossy ( ) . to_string ( ) ,
80- module : file_name . clone ( ) ,
163+ path : file_path ,
164+ module : module_name ,
81165 lines,
82- domains : vec ! [ ] ,
83- layer : None ,
166+ domains,
167+ layer,
84168 stability : Stability :: Active ,
85169 depends : vec ! [ ] ,
86- exports : vec ! [ ] ,
87- symbols : vec ! [ ] ,
170+ exports : symbol_names . clone ( ) ,
171+ symbols : symbol_names ,
88172 keywords : vec ! [ ] ,
89173 hash : Some ( format ! ( "{:x}" , md5:: compute( & content) ) ) ,
90174 guardrails : None ,
91175 } ;
92176
93177 Ok ( ParseResult {
94178 file,
95- symbols : vec ! [ ] ,
96- calls : vec ! [ ] ,
179+ symbols,
180+ calls,
97181 } )
98182 }
99183
@@ -128,4 +212,42 @@ pub struct Annotation {
128212 pub name : String ,
129213 pub value : Option < String > ,
130214 pub line : usize ,
215+ }
216+
217+ /// Helper to build SymbolEntry from annotations
218+ struct SymbolBuilder {
219+ name : String ,
220+ line : usize ,
221+ summary : Option < String > ,
222+ calls : Vec < String > ,
223+ }
224+
225+ impl SymbolBuilder {
226+ fn new ( name : String , line : usize ) -> Self {
227+ Self {
228+ name,
229+ line,
230+ summary : None ,
231+ calls : vec ! [ ] ,
232+ }
233+ }
234+
235+ fn build ( self , file_path : & str ) -> SymbolEntry {
236+ SymbolEntry {
237+ name : self . name ,
238+ fqn : None ,
239+ symbol_type : SymbolType :: Fn ,
240+ file : file_path. to_string ( ) ,
241+ lines : [ self . line , self . line + 10 ] , // Approximate
242+ summary : self . summary ,
243+ signature : None ,
244+ exported : true ,
245+ async_fn : false ,
246+ calls : self . calls ,
247+ throws : vec ! [ ] ,
248+ flags : vec ! [ ] ,
249+ side_effects : vec ! [ ] ,
250+ complexity : None ,
251+ }
252+ }
131253}
0 commit comments