Skip to main content

normalize_languages/
glsl.rs

1//! GLSL (OpenGL Shading Language) support.
2
3use crate::{ContainerBody, Language, LanguageSymbols};
4use tree_sitter::Node;
5
6/// GLSL language support.
7pub struct Glsl;
8
9impl Language for Glsl {
10    fn name(&self) -> &'static str {
11        "GLSL"
12    }
13    fn extensions(&self) -> &'static [&'static str] {
14        &["glsl", "vert", "frag", "geom", "comp", "tesc", "tese"]
15    }
16    fn grammar_name(&self) -> &'static str {
17        "glsl"
18    }
19
20    fn as_symbols(&self) -> Option<&dyn LanguageSymbols> {
21        Some(self)
22    }
23
24    fn container_body<'a>(&self, node: &'a Node<'a>) -> Option<Node<'a>> {
25        node.child_by_field_name("body")
26    }
27
28    fn analyze_container_body(
29        &self,
30        body_node: &Node,
31        content: &str,
32        inner_indent: &str,
33    ) -> Option<ContainerBody> {
34        crate::body::analyze_brace_body(body_node, content, inner_indent)
35    }
36
37    fn node_name<'a>(&self, node: &Node, content: &'a str) -> Option<&'a str> {
38        node.child_by_field_name("declarator")
39            .and_then(|d| d.child_by_field_name("declarator"))
40            .map(|n| &content[n.byte_range()])
41            .or_else(|| {
42                node.child_by_field_name("name")
43                    .map(|n| &content[n.byte_range()])
44            })
45    }
46}
47
48impl LanguageSymbols for Glsl {}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use crate::validate_unused_kinds_audit;
54
55    #[test]
56    fn unused_node_kinds_audit() {
57        #[rustfmt::skip]
58        let documented_unused: &[&str] = &[
59            "abstract_function_declarator", "alignas_qualifier", "alignof_expression",
60            "assignment_expression", "attribute_declaration", "attribute_specifier",
61            "attributed_statement", "binary_expression", "bitfield_clause", "break_statement",
62            "call_expression", "cast_expression", "comma_expression", "compound_literal_expression",
63            "continue_statement", "declaration", "declaration_list", "do_statement",
64            "else_clause", "enum_specifier", "enumerator", "enumerator_list",
65            "expression_statement", "extension_expression", "extension_storage_class",
66            "field_declaration", "field_declaration_list", "field_expression", "field_identifier",
67            "function_declarator", "generic_expression", "gnu_asm_expression", "gnu_asm_qualifier",
68            "goto_statement", "identifier", "labeled_statement", "layout_qualifiers",
69            "layout_specification", "linkage_specification", "macro_type_specifier",
70            "ms_based_modifier", "ms_call_modifier", "ms_declspec_modifier",
71            "ms_pointer_modifier", "ms_restrict_modifier", "ms_signed_ptr_modifier",
72            "ms_unaligned_ptr_modifier", "ms_unsigned_ptr_modifier", "offsetof_expression",
73            "parameter_declaration", "parenthesized_expression", "pointer_expression",
74            "preproc_elif", "preproc_elifdef", "preproc_else", "preproc_function_def",
75            "preproc_if", "preproc_ifdef", "primitive_type", "qualifier", "return_statement",
76            "seh_except_clause", "seh_finally_clause", "seh_leave_statement", "seh_try_statement",
77            "sizeof_expression", "sized_type_specifier", "statement_identifier",
78            "storage_class_specifier", "subscript_expression", "type_definition",
79            "type_descriptor", "type_identifier", "type_qualifier", "unary_expression",
80            "union_specifier", "update_expression",
81            // control flow — not extracted as symbols
82            "switch_statement",
83            "if_statement",
84            "while_statement",
85            "for_statement",
86            "conditional_expression",
87            "compound_statement",
88            "case_statement",
89        ];
90        validate_unused_kinds_audit(&Glsl, documented_unused)
91            .expect("GLSL unused node kinds audit failed");
92    }
93}