normalize_languages/
idris.rs1use crate::{ContainerBody, Import, Language, LanguageSymbols};
4use tree_sitter::Node;
5
6pub struct Idris;
8
9impl Language for Idris {
10 fn name(&self) -> &'static str {
11 "Idris"
12 }
13 fn extensions(&self) -> &'static [&'static str] {
14 &["idr", "lidr"]
15 }
16 fn grammar_name(&self) -> &'static str {
17 "idris"
18 }
19
20 fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
21 Some(self)
22 }
23
24 fn extract_imports(&self, node: &Node, content: &str) -> Vec<Import> {
25 if node.kind() != "import" {
26 return Vec::new();
27 }
28
29 let text = &content[node.byte_range()];
30 vec![Import {
31 module: text.trim().to_string(),
32 names: Vec::new(),
33 alias: None,
34 is_wildcard: false,
35 is_relative: false,
36 line: node.start_position().row + 1,
37 }]
38 }
39
40 fn format_import(&self, import: &Import, _names: Option<&[&str]>) -> String {
41 format!("import {}", import.module)
43 }
44
45 fn is_test_symbol(&self, symbol: &crate::Symbol) -> bool {
46 let name = symbol.name.as_str();
47 match symbol.kind {
48 crate::SymbolKind::Function | crate::SymbolKind::Method => name.starts_with("test_"),
49 crate::SymbolKind::Module => name == "tests" || name == "test",
50 _ => false,
51 }
52 }
53
54 fn container_body<'a>(&self, node: &'a Node<'a>) -> Option<Node<'a>> {
55 let mut c = node.walk();
57 for child in node.children(&mut c) {
58 if matches!(child.kind(), "data_body" | "record_body" | "interface_body") {
59 return Some(child);
60 }
61 }
62 None
63 }
64
65 fn analyze_container_body(
66 &self,
67 body_node: &Node,
68 content: &str,
69 inner_indent: &str,
70 ) -> Option<ContainerBody> {
71 match body_node.kind() {
74 "interface_body" => {
75 crate::body::analyze_keyword_end_body(body_node, content, inner_indent)
76 }
77 _ => crate::body::analyze_end_body(body_node, content, inner_indent),
78 }
79 }
80}
81
82impl LanguageSymbols for Idris {}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::validate_unused_kinds_audit;
88
89 #[test]
90 fn unused_node_kinds_audit() {
91 #[rustfmt::skip]
92 let documented_unused: &[&str] = &[
93 "exp_else", "exp_with", "exp_lambda", "exp_lambda_case",
95 "exp_list_comprehension", "lambda_exp", "lambda_args",
96 "type_signature", "type_parens", "type_braces", "type_var", "forall",
98 "parameters_body", "namespace_body", "mutual_body", "data_body",
100 "record_body", "interface_body", "implementation_body",
101 "interface_name", "module",
103 "function",
105 "operator", "qualified_operator", "qualified_dot_operators", "dot_operator",
107 "ticked_operator", "tuple_operator",
108 "qualified_loname", "qualified_caname",
110 "constructor", "statement", "declarations",
112 "with", "with_pat", "with_arg",
113 "pragma_export", "pragma_foreign", "pragma_foreign_impl", "pragma_transform",
115 "exp_if",
117 "exp_case",
118 "import",
119 ];
120 validate_unused_kinds_audit(&Idris, documented_unused)
121 .expect("Idris unused node kinds audit failed");
122 }
123}