use crate::parse::traits::{CodeIntelligence, ComplexityMetrics, Error, Graph, Result, SignatureInfo};
use crate::parse::traits::{Block, Edge, EdgeType, Parameter, Visibility};
use tree_sitter::Parser;
pub struct SwiftParser;
impl Default for SwiftParser {
fn default() -> Self { Self::new() }
}
impl SwiftParser {
pub fn new() -> Self { Self }
}
impl CodeIntelligence for SwiftParser {
fn get_signatures(&self, source: &[u8]) -> Result<Vec<SignatureInfo>> {
let mut parser = Parser::new();
parser.set_language(&crate::parse::traits::languages::swift::language())
.map_err(|e| Error::ParseFailed(e.to_string()))?;
let tree = parser.parse(source, None)
.ok_or_else(|| Error::ParseFailed("Failed to parse Swift source".to_string()))?;
let mut signatures = Vec::new();
fn visit(node: &tree_sitter::Node, source: &[u8], sigs: &mut Vec<SignatureInfo>) {
match node.kind() {
"function_declaration" | "method_declaration" => {
if let Some(name) = node.child_by_field_name("name").and_then(|n| n.utf8_text(source).ok()) {
sigs.push(SignatureInfo {
name: name.to_string(),
qualified_name: name.to_string(),
parameters: vec![],
return_type: node.child_by_field_name("return_type").and_then(|r| r.utf8_text(source).ok()).map(|s| s.trim().to_string()),
visibility: Visibility::Public,
is_async: node.children(&mut node.walk()).any(|c| c.utf8_text(source).ok().map_or(false, |t| t.contains("async"))),
is_method: node.kind() == "method_declaration",
docstring: None,
calls: vec![],
imports: vec![],
byte_range: (0, 0),
cyclomatic_complexity: 0,
});
}
}
_ => { let mut c = node.walk(); for ch in node.children(&mut c) { visit(&ch, source, sigs); } }
}
}
visit(&tree.root_node(), source, &mut signatures);
Ok(signatures)
}
fn compute_cfg(&self, source: &[u8], _node_id: usize) -> Result<Graph<Block, Edge>> {
let mut parser = Parser::new();
parser.set_language(&crate::parse::traits::languages::swift::language())
.map_err(|e| Error::ParseFailed(e.to_string()))?;
parser.parse(source, None).ok_or_else(|| Error::ParseFailed("Failed to parse".to_string()))?;
Ok(Graph { blocks: vec![], edges: vec![], entry_block: 0, exit_blocks: vec![] })
}
fn extract_complexity(&self, node: &tree_sitter::Node) -> ComplexityMetrics {
ComplexityMetrics { cyclomatic: 1, nesting_depth: 0, line_count: 1, token_count: node.child_count() }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_swift_function() {
let source = b"func greet(_ name: String) -> String { \"Hello, \\(name)\" }";
let parser = SwiftParser::new();
assert!(parser.get_signatures(source).unwrap().len() > 0);
}
}