1
1
use crate :: block:: { Block , BlockType } ;
2
+ use crate :: config:: { Config , Matchers } ;
3
+ use jwalk:: rayon:: str:: ParallelString ;
2
4
use std:: collections:: { HashMap , HashSet } ;
3
5
use std:: fs;
4
6
use std:: path:: Path ;
@@ -12,7 +14,7 @@ extern "C" {
12
14
// Add more language bindings here
13
15
}
14
16
15
- pub fn parse_file ( file_path : & Path , module_name : & str ) -> Vec < Block > {
17
+ pub fn parse_file ( file_path : & Path , module_name : & str , config : & Config ) -> Vec < Block > {
16
18
let code = fs:: read_to_string ( file_path) . unwrap ( ) ;
17
19
let language = tree_sitter_language ( file_path) ;
18
20
let mut parser = Parser :: new ( ) ;
@@ -33,6 +35,7 @@ pub fn parse_file(file_path: &Path, module_name: &str) -> Vec<Block> {
33
35
None ,
34
36
module_name,
35
37
& mut imports,
38
+ & config,
36
39
) ;
37
40
38
41
if !non_function_blocks. is_empty ( ) {
@@ -71,12 +74,14 @@ fn traverse_tree(
71
74
class_name : Option < String > ,
72
75
module_name : & str ,
73
76
imports : & mut HashMap < String , String > ,
77
+ config : & Config ,
74
78
) {
75
79
let node = cursor. node ( ) ;
76
80
let kind = node. kind ( ) ;
77
81
78
82
if is_import_statement ( kind, language) {
79
- if let Some ( ( module, alias) ) = parse_import_statement ( code, node, language) {
83
+ if let Some ( ( module, alias) ) = parse_import_statement ( code, node, language, config) {
84
+ println ! ( "Module: {}, Alias: {}" , module, alias) ;
80
85
imports. insert ( alias, module) ;
81
86
}
82
87
} else if is_class_definition ( kind, language) {
@@ -98,6 +103,7 @@ fn traverse_tree(
98
103
Some ( extracted_class_name. clone ( ) ) ,
99
104
module_name,
100
105
imports,
106
+ config,
101
107
) ;
102
108
if !cursor. goto_next_sibling ( ) {
103
109
break ;
@@ -145,6 +151,7 @@ fn traverse_tree(
145
151
class_name. clone ( ) ,
146
152
module_name,
147
153
imports,
154
+ & config,
148
155
) ;
149
156
if !cursor. goto_next_sibling ( ) {
150
157
break ;
@@ -225,36 +232,144 @@ fn is_import_statement(kind: &str, language: Language) -> bool {
225
232
lang if lang == unsafe { tree_sitter_python ( ) } => {
226
233
kind == "import_statement" || kind == "import_from_statement"
227
234
}
235
+ lang if lang == unsafe { tree_sitter_rust ( ) } => kind == "use_declaration" ,
228
236
// Add more language-specific checks here
229
237
_ => false ,
230
238
}
231
239
}
232
240
233
- fn parse_import_statement ( code : & str , node : Node , language : Language ) -> Option < ( String , String ) > {
241
+ fn filter_import_matchers (
242
+ child : Node ,
243
+ code : & str ,
244
+ matchers : & Matchers ,
245
+ ) -> ( Option < String > , Option < String > , Option < String > ) {
246
+ let module = child
247
+ . child_by_field_name ( & matchers. module_name . field_name )
248
+ . map ( |n| {
249
+ if n. kind ( ) == matchers. module_name . kind {
250
+ return n. utf8_text ( code. as_bytes ( ) ) . unwrap_or_default ( ) . to_owned ( ) ;
251
+ }
252
+
253
+ String :: default ( )
254
+ } ) ;
255
+
256
+ let name = child
257
+ . child_by_field_name ( & matchers. object_name . field_name )
258
+ . map ( |n| {
259
+ if n. kind ( ) == matchers. object_name . kind {
260
+ return n. utf8_text ( code. as_bytes ( ) ) . unwrap_or_default ( ) . to_owned ( ) ;
261
+ }
262
+
263
+ String :: default ( )
264
+ } ) ;
265
+
266
+ let alias = child
267
+ . child_by_field_name ( & matchers. alias . field_name )
268
+ . map ( |n| {
269
+ if n. kind ( ) == matchers. alias . kind {
270
+ return n. utf8_text ( code. as_bytes ( ) ) . unwrap_or_default ( ) . to_owned ( ) ;
271
+ }
272
+
273
+ String :: default ( )
274
+ } ) ;
275
+
276
+ ( module, name, alias)
277
+ }
278
+
279
+ fn parse_import_statement (
280
+ code : & str ,
281
+ node : Node ,
282
+ language : Language ,
283
+ config : & Config ,
284
+ ) -> Option < ( String , String ) > {
285
+ let mut module_name = String :: new ( ) ;
286
+ let mut object_name = String :: new ( ) ;
287
+ let mut alias_name = String :: new ( ) ;
288
+
234
289
match language {
235
290
lang if lang == unsafe { tree_sitter_python ( ) } => {
236
- if node. kind ( ) == "import_from_statement" {
237
- // Extract the module name from the 'module_name' field
238
- let module = node
239
- . child_by_field_name ( "module_name" )
240
- . map ( |n| n. utf8_text ( code. as_bytes ( ) ) . ok ( ) )
241
- . flatten ( )
242
- . unwrap_or_default ( )
243
- . to_string ( ) ;
244
-
245
- // Iterate over the names imported from the module
246
- let node_walk = & mut node. walk ( ) ;
247
- let imported_names = node. children_by_field_name ( "name" , node_walk) ;
248
- for imported_name in imported_names {
249
- let alias = imported_name
250
- . utf8_text ( code. as_bytes ( ) )
251
- . unwrap_or_default ( )
252
- . to_string ( ) ;
253
-
254
- // In this case, we assume that each import statement imports a single name,
255
- // so we return the first found. For handling multiple imports, this approach needs to be adjusted.
256
- return Some ( ( module. clone ( ) , alias) ) ;
291
+ let matchers = & config
292
+ . languages
293
+ . get ( "python" )
294
+ . expect ( "Failed to get Python matchers from config" )
295
+ . matchers ;
296
+
297
+ if node. kind ( ) == matchers. import_statement {
298
+ let result = filter_import_matchers ( node, code, matchers) ;
299
+ ( module_name, object_name, alias_name) = (
300
+ result. 0 . unwrap_or ( module_name) ,
301
+ result. 1 . unwrap_or ( object_name) ,
302
+ result. 2 . unwrap_or ( alias_name) ,
303
+ ) ;
304
+
305
+ let mut cursor = node. walk ( ) ;
306
+ for child in node. named_children ( & mut cursor) {
307
+ let result = filter_import_matchers ( child, code, matchers) ;
308
+ ( module_name, object_name, alias_name) = (
309
+ result. 0 . unwrap_or ( module_name) ,
310
+ result. 1 . unwrap_or ( object_name) ,
311
+ result. 2 . unwrap_or ( alias_name) ,
312
+ ) ;
313
+
314
+ let mut cursor2 = child. walk ( ) ;
315
+ for child2 in child. named_children ( & mut cursor2) {
316
+ let result = filter_import_matchers ( child2, code, matchers) ;
317
+ ( module_name, object_name, alias_name) = (
318
+ result. 0 . unwrap_or ( module_name) ,
319
+ result. 1 . unwrap_or ( object_name) ,
320
+ result. 2 . unwrap_or ( alias_name) ,
321
+ ) ;
322
+ }
323
+ }
324
+
325
+ println ! (
326
+ "Module: {}, Object: {}, Alias: {}" ,
327
+ module_name, object_name, alias_name
328
+ ) ;
329
+ return Some ( ( module_name, object_name) ) ;
330
+ }
331
+ None
332
+ } ,
333
+ lang if lang == unsafe { tree_sitter_rust ( ) } => {
334
+ let matchers = & config
335
+ . languages
336
+ . get ( "rust" )
337
+ . expect ( "Failed to get Python matchers from config" )
338
+ . matchers ;
339
+
340
+ if node. kind ( ) == matchers. import_statement {
341
+ let result = filter_import_matchers ( node, code, matchers) ;
342
+ ( module_name, object_name, alias_name) = (
343
+ result. 0 . unwrap_or ( module_name) ,
344
+ result. 1 . unwrap_or ( object_name) ,
345
+ result. 2 . unwrap_or ( alias_name) ,
346
+ ) ;
347
+
348
+ let mut cursor = node. walk ( ) ;
349
+ for child in node. named_children ( & mut cursor) {
350
+ let result = filter_import_matchers ( child, code, matchers) ;
351
+ ( module_name, object_name, alias_name) = (
352
+ result. 0 . unwrap_or ( module_name) ,
353
+ result. 1 . unwrap_or ( object_name) ,
354
+ result. 2 . unwrap_or ( alias_name) ,
355
+ ) ;
356
+
357
+ let mut cursor2 = child. walk ( ) ;
358
+ for child2 in child. named_children ( & mut cursor2) {
359
+ let result = filter_import_matchers ( child2, code, matchers) ;
360
+ ( module_name, object_name, alias_name) = (
361
+ result. 0 . unwrap_or ( module_name) ,
362
+ result. 1 . unwrap_or ( object_name) ,
363
+ result. 2 . unwrap_or ( alias_name) ,
364
+ ) ;
365
+ }
257
366
}
367
+
368
+ println ! (
369
+ "Module: {}, Object: {}, Alias: {}" ,
370
+ module_name, object_name, alias_name
371
+ ) ;
372
+ return Some ( ( module_name, object_name) ) ;
258
373
}
259
374
None
260
375
}
0 commit comments