normalize_languages/
json.rs1use crate::{Language, LanguageSymbols};
4use tree_sitter::Node;
5
6pub struct Json;
8
9impl Language for Json {
10 fn name(&self) -> &'static str {
11 "JSON"
12 }
13 fn extensions(&self) -> &'static [&'static str] {
14 &["json", "jsonc"]
15 }
16 fn grammar_name(&self) -> &'static str {
17 "json"
18 }
19
20 fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
21 Some(self)
22 }
23
24 fn refine_kind(
25 &self,
26 node: &Node,
27 _content: &str,
28 tag_kind: crate::SymbolKind,
29 ) -> crate::SymbolKind {
30 if node.kind() == "pair"
32 && let Some(value) = node.child_by_field_name("value")
33 && value.kind() == "object"
34 {
35 return crate::SymbolKind::Module;
36 }
37 tag_kind
38 }
39
40 fn node_name<'a>(&self, node: &Node, content: &'a str) -> Option<&'a str> {
41 if node.kind() == "pair"
43 && let Some(key) = node.child_by_field_name("key")
44 {
45 let mut cursor = key.walk();
46 for child in key.children(&mut cursor) {
47 if child.kind() == "string_content" {
48 return Some(&content[child.byte_range()]);
49 }
50 }
51 }
52 None
53 }
54
55 fn container_body<'a>(&self, node: &'a Node<'a>) -> Option<Node<'a>> {
56 if node.kind() == "pair"
57 && let Some(value) = node.child_by_field_name("value")
58 && value.kind() == "object"
59 {
60 return Some(value);
61 }
62 None
63 }
64
65 fn build_signature(&self, node: &Node, content: &str) -> String {
66 if node.kind() == "pair"
67 && let Some(key) = self.node_name(node, content)
68 {
69 if let Some(value) = node.child_by_field_name("value") {
70 return match value.kind() {
71 "object" => format!("{}: {{}}", key),
72 "array" => format!("{}: []", key),
73 _ => {
74 let val_text = &content[value.byte_range()];
75 if val_text.len() > 40 {
76 format!("{}: {}…", key, &val_text[..37])
77 } else {
78 format!("{}: {}", key, val_text)
79 }
80 }
81 };
82 }
83 return key.to_string();
84 }
85 content[node.byte_range()]
86 .lines()
87 .next()
88 .unwrap_or("")
89 .trim()
90 .to_string()
91 }
92}
93
94impl LanguageSymbols for Json {}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use crate::validate_unused_kinds_audit;
100
101 #[test]
102 fn unused_node_kinds_audit() {
103 let documented_unused: &[&str] = &[];
105 validate_unused_kinds_audit(&Json, documented_unused)
106 .expect("JSON unused node kinds audit failed");
107 }
108}