@@ -16,6 +16,7 @@ use crate::hash::compute_file_hash;
1616pub enum Language {
1717 C ,
1818 Rust ,
19+ Python ,
1920}
2021
2122impl Language {
@@ -26,6 +27,7 @@ impl Language {
2627 . and_then ( |ext| match ext {
2728 "c" | "h" | "cpp" | "cc" | "cxx" | "hpp" => Some ( Language :: C ) ,
2829 "rs" => Some ( Language :: Rust ) ,
30+ "py" => Some ( Language :: Python ) ,
2931 _ => None ,
3032 } )
3133 }
@@ -53,8 +55,10 @@ struct LanguageQueries {
5355pub struct TreeSitterAnalyzer {
5456 c_parser : Parser ,
5557 rust_parser : Parser ,
58+ python_parser : Parser ,
5659 c_queries : LanguageQueries ,
5760 rust_queries : LanguageQueries ,
61+ python_queries : LanguageQueries ,
5862}
5963
6064impl TreeSitterAnalyzer {
@@ -69,17 +73,27 @@ impl TreeSitterAnalyzer {
6973 let mut rust_parser = Parser :: new ( ) ;
7074 rust_parser. set_language ( & rust_language) ?;
7175
76+ // Initialize Python parser and queries
77+ let python_language = tree_sitter_python:: LANGUAGE . into ( ) ;
78+ let mut python_parser = Parser :: new ( ) ;
79+ python_parser. set_language ( & python_language) ?;
80+
7281 // Create C queries
7382 let c_queries = Self :: create_c_queries ( & c_language) ?;
7483
7584 // Create Rust queries
7685 let rust_queries = Self :: create_rust_queries ( & rust_language) ?;
7786
87+ // Create Python queries
88+ let python_queries = Self :: create_python_queries ( & python_language) ?;
89+
7890 Ok ( TreeSitterAnalyzer {
7991 c_parser,
8092 rust_parser,
93+ python_parser,
8194 c_queries,
8295 rust_queries,
96+ python_queries,
8397 } )
8498 }
8599
@@ -293,6 +307,75 @@ impl TreeSitterAnalyzer {
293307 } )
294308 }
295309
310+ fn create_python_queries ( language : & tree_sitter:: Language ) -> Result < LanguageQueries > {
311+ // Query for function definitions (including methods)
312+ let function_query = Query :: new (
313+ language,
314+ r#"
315+ (function_definition
316+ name: (identifier) @function_name
317+ parameters: (parameters) @parameters
318+ return_type: (_)? @return_type
319+ body: (block) @body
320+ ) @function
321+ "# ,
322+ ) ?;
323+
324+ // Query for comments
325+ let comment_query = Query :: new (
326+ language,
327+ r#"
328+ (comment) @comment
329+ "# ,
330+ ) ?;
331+
332+ // Query for class definitions
333+ let type_query = Query :: new (
334+ language,
335+ r#"
336+ (class_definition
337+ name: (identifier) @type_name
338+ body: (block) @body
339+ ) @class
340+ "# ,
341+ ) ?;
342+
343+ // Python doesn't have traditional macros, but we can track decorators
344+ let macro_query = Query :: new (
345+ language,
346+ r#"
347+ (decorator
348+ (identifier) @macro_name
349+ ) @decorator
350+ "# ,
351+ ) ?;
352+
353+ // Query for function calls
354+ let call_query = Query :: new (
355+ language,
356+ r#"
357+ (call
358+ function: (identifier) @function_name
359+ ) @call
360+
361+ (call
362+ function: (attribute
363+ attribute: (identifier) @function_name
364+ )
365+ ) @method_call
366+ "# ,
367+ ) ?;
368+
369+ Ok ( LanguageQueries {
370+ function_query,
371+ comment_query,
372+ type_query,
373+ typedef_query : None , // Python doesn't have typedefs
374+ macro_query,
375+ call_query,
376+ } )
377+ }
378+
296379 /// Helper method to convert absolute path to relative path based on source root
297380 fn make_relative_path ( & self , file_path : & Path , source_root : Option < & Path > ) -> String {
298381 if let Some ( root) = source_root {
@@ -310,6 +393,7 @@ impl TreeSitterAnalyzer {
310393 match language {
311394 Language :: C => & mut self . c_parser ,
312395 Language :: Rust => & mut self . rust_parser ,
396+ Language :: Python => & mut self . python_parser ,
313397 }
314398 }
315399
@@ -318,6 +402,7 @@ impl TreeSitterAnalyzer {
318402 match language {
319403 Language :: C => & self . c_queries ,
320404 Language :: Rust => & self . rust_queries ,
405+ Language :: Python => & self . python_queries ,
321406 }
322407 }
323408
@@ -945,6 +1030,14 @@ impl TreeSitterAnalyzer {
9451030 line_start = node. start_position ( ) . row as u32 + 1 ;
9461031 }
9471032 }
1033+ "class" => {
1034+ kind = "class" . to_string ( ) ;
1035+ type_start_byte = node. start_byte ( ) ;
1036+ type_end_byte = node. end_byte ( ) ;
1037+ if line_start == 0 {
1038+ line_start = node. start_position ( ) . row as u32 + 1 ;
1039+ }
1040+ }
9481041 _ => { }
9491042 }
9501043 }
0 commit comments