Skip to content

Commit 731e083

Browse files
unhappychoiceclaude
andcommitted
feat: implement comprehensive Dart language extractor
- Add DartExtractor with support for classes, functions, methods, enums, mixins, extensions, and variables - Register Dart extractor in parser registry - Add comment detection support for Dart (// and ///) - Support extraction of: * Classes with constructors and methods * Top-level functions and lambda expressions * Enums with values and methods * Mixins with methods and properties * Extension methods on existing types * Variable declarations (final, var, const) * Async functions and Flutter patterns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 6fee1f4 commit 731e083

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

src/extractor/core/extractor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl CommonExtractor {
100100
Language::C => node_kind == "comment",
101101
Language::Cpp => node_kind == "comment",
102102
Language::Haskell => node_kind == "comment",
103+
Language::Dart => node_kind == "comment" || node_kind == "documentation_comment",
103104
}
104105
}
105106

src/extractor/parsers/dart.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use super::LanguageExtractor;
2+
use crate::extractor::models::{ChunkType, Language};
3+
use crate::{GitTypeError, Result};
4+
use tree_sitter::{Node, Parser};
5+
6+
pub struct DartExtractor;
7+
8+
impl LanguageExtractor for DartExtractor {
9+
fn language(&self) -> Language {
10+
Language::Dart
11+
}
12+
13+
fn file_extensions(&self) -> &[&str] {
14+
&["dart"]
15+
}
16+
17+
fn tree_sitter_language(&self) -> tree_sitter::Language {
18+
tree_sitter_dart::language()
19+
}
20+
21+
fn query_patterns(&self) -> &str {
22+
"
23+
(class_definition (identifier) @name) @class
24+
(enum_declaration (identifier) @name) @enum
25+
(mixin_declaration (identifier) @name) @mixin
26+
(extension_declaration (identifier) @name) @extension
27+
(lambda_expression (function_signature (identifier) @name)) @function
28+
(method_signature (function_signature (identifier) @name)) @method
29+
(local_variable_declaration (initialized_variable_definition (identifier) @name)) @variable
30+
"
31+
}
32+
33+
fn comment_query(&self) -> &str {
34+
"[(comment) (documentation_comment)] @comment"
35+
}
36+
37+
fn capture_name_to_chunk_type(&self, capture_name: &str) -> Option<ChunkType> {
38+
match capture_name {
39+
"function" => Some(ChunkType::Function),
40+
"method" => Some(ChunkType::Function),
41+
"class" => Some(ChunkType::Class),
42+
"enum" => Some(ChunkType::Enum),
43+
"mixin" => Some(ChunkType::Class),
44+
"extension" => Some(ChunkType::Class),
45+
"variable" => Some(ChunkType::Variable),
46+
_ => None,
47+
}
48+
}
49+
50+
fn extract_name(&self, node: Node, source_code: &str, _capture_name: &str) -> Option<String> {
51+
self.extract_name_from_node(node, source_code)
52+
}
53+
}
54+
55+
impl DartExtractor {
56+
fn extract_name_from_node(&self, node: Node, source_code: &str) -> Option<String> {
57+
// First try direct identifier children
58+
let mut cursor = node.walk();
59+
if cursor.goto_first_child() {
60+
loop {
61+
let child = cursor.node();
62+
if child.kind() == "identifier" {
63+
let start = child.start_byte();
64+
let end = child.end_byte();
65+
return Some(source_code[start..end].to_string());
66+
}
67+
68+
// For function signatures, recursively look for identifier
69+
if child.kind() == "function_signature" {
70+
if let Some(name) = self.extract_name_from_node(child, source_code) {
71+
return Some(name);
72+
}
73+
}
74+
75+
// For variable declarations, look deeper
76+
if child.kind() == "initialized_variable_definition" {
77+
if let Some(name) = self.extract_name_from_node(child, source_code) {
78+
return Some(name);
79+
}
80+
}
81+
82+
if !cursor.goto_next_sibling() {
83+
break;
84+
}
85+
}
86+
}
87+
None
88+
}
89+
90+
pub fn create_parser() -> Result<Parser> {
91+
let mut parser = Parser::new();
92+
parser
93+
.set_language(&tree_sitter_dart::language())
94+
.map_err(|e| {
95+
GitTypeError::ExtractionFailed(format!("Failed to set Dart language: {}", e))
96+
})?;
97+
Ok(parser)
98+
}
99+
}

src/extractor/parsers/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use tree_sitter::{Node, Parser, Query, Tree};
88
pub mod c;
99
pub mod cpp;
1010
pub mod csharp;
11+
pub mod dart;
1112
pub mod go;
1213
pub mod haskell;
1314
pub mod java;
@@ -116,6 +117,10 @@ impl ParserRegistry {
116117
|| Box::new(haskell::HaskellExtractor),
117118
);
118119

120+
registry.register(Language::Dart, dart::DartExtractor::create_parser, || {
121+
Box::new(dart::DartExtractor)
122+
});
123+
119124
registry
120125
}
121126

0 commit comments

Comments
 (0)