1use crate::{ContainerBody, Import, Language, LanguageSymbols};
4use tree_sitter::Node;
5
6pub struct Vhdl;
8
9impl Language for Vhdl {
10 fn name(&self) -> &'static str {
11 "VHDL"
12 }
13 fn extensions(&self) -> &'static [&'static str] {
14 &["vhd", "vhdl"]
15 }
16 fn grammar_name(&self) -> &'static str {
17 "vhdl"
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() != "use_clause" {
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: text.contains(".all"),
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 let names_to_use: Vec<&str> = names
43 .map(|n| n.to_vec())
44 .unwrap_or_else(|| import.names.iter().map(|s| s.as_str()).collect());
45 if import.is_wildcard || names_to_use.is_empty() {
46 format!("use {}.all;", import.module)
47 } else if names_to_use.len() == 1 {
48 format!("use {}.{};", import.module, names_to_use[0])
49 } else {
50 names_to_use
51 .iter()
52 .map(|n| format!("use {}.{};", import.module, n))
53 .collect::<Vec<_>>()
54 .join("\n")
55 }
56 }
57
58 fn container_body<'a>(&self, node: &'a Node<'a>) -> Option<Node<'a>> {
59 Some(*node)
61 }
62
63 fn analyze_container_body(
64 &self,
65 body_node: &Node,
66 content: &str,
67 inner_indent: &str,
68 ) -> Option<ContainerBody> {
69 crate::body::analyze_is_begin_end_body(body_node, content, inner_indent)
72 }
73}
74
75impl LanguageSymbols for Vhdl {}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::validate_unused_kinds_audit;
81
82 #[test]
83 fn unused_node_kinds_audit() {
84 #[rustfmt::skip]
85 let documented_unused: &[&str] = &[
86 "constant_declaration", "signal_declaration", "variable_declaration",
88 "shared_variable_declaration", "file_declaration", "alias_declaration",
89 "attribute_declaration", "attribute_specification", "component_declaration",
90 "group_template_declaration", "group_declaration", "subtype_declaration",
91 "incomplete_type_declaration", "disconnection_specification",
92 "configuration_specification", "configuration_declaration",
93 "enumeration_type_definition", "physical_type_definition",
95 "primary_unit_declaration", "secondary_unit_declaration", "record_type_definition",
96 "element_declaration", "access_type_definition", "file_type_definition",
97 "constrained_array_definition", "unbounded_array_definition",
98 "index_subtype_definition", "numeric_type_definition",
99 "protected_type_declaration", "protected_type_body",
101 "procedure_declaration", "function_declaration",
103 "procedure_instantiation_declaration", "function_instantiation_declaration",
104 "procedure_parameter_clause", "function_parameter_clause",
105 "procedure_call_statement",
106 "constant_interface_declaration", "signal_interface_declaration",
108 "variable_interface_declaration", "file_interface_declaration",
109 "type_interface_declaration", "procedure_interface_declaration",
110 "function_interface_declaration", "package_interface_declaration",
111 "interface_subprogram_default",
112 "process_statement", "concurrent_statement_part", "sequence_of_statements",
114 "wait_statement", "assertion_statement", "report_statement",
115 "next_statement", "exit_statement", "return_statement", "null_statement",
116 "simple_waveform_assignment", "conditional_waveform_assignment",
118 "selected_waveform_assignment", "simple_force_assignment",
119 "conditional_force_assignment", "selected_force_assignment",
120 "simple_variable_assignment", "conditional_variable_assignment",
121 "selected_variable_assignment", "simple_release_assignment",
122 "waveforms", "waveform_element", "conditional_waveforms",
124 "selected_waveforms", "alternative_selected_waveforms",
125 "alternative_conditional_waveforms",
126 "expression", "simple_expression", "shift_expression", "logical_expression",
128 "conditional_expression", "parenthesized_expression", "qualified_expression",
129 "alternative_conditional_expressions", "alternative_selected_expressions",
130 "conditional_expressions", "selected_expressions", "expression_list",
131 "string_expression", "time_expression", "severity_expression",
132 "inertial_expression", "default_expression", "relation",
133 "exponentiation", "concatenation", "reduction", "condition",
134 "for_generate_statement", "if_generate_statement", "case_generate_statement",
136 "if_generate", "elsif_generate", "else_generate", "case_generate_alternative",
137 "generate_statement_body", "generate_statement_element",
138 "block_statement", "block_header", "block_configuration", "block_specification",
140 "component_instantiation_statement", "verification_unit_binding_indication",
142 "verification_unit_list", "component_configuration", "binding_indication",
143 "port_map_aspect", "generic_map_aspect",
144 "entity_instantiation", "configuration_instantiation", "component_instantiation",
145 "instantiation_list", "all", "component_header", "component_map_aspect",
146 "context_clause", "library_clause", "generic_clause", "port_clause",
148 "file_open_information", "file_open_kind",
150 "identifier", "extended_identifier", "identifier_list", "operator_symbol",
152 "label", "simple_name", "extended_simple_name",
153 "external_signal_name", "external_constant_name", "external_variable_name",
154 "pathname_element", "relative_pathname", "package_pathname", "absolute_pathname",
155 "if", "elsif", "else", "return", "for_loop", "while_loop",
157 "case_statement_alternative",
159 "package_body", "package_instantiation_declaration", "context_declaration",
161 "package_header", "package_map_aspect",
162 "entity_specification", "entity_class", "entity_class_entry",
164 "entity_class_entry_list", "entity_header", "entity_name_list",
165 "entity_designator",
166 "type_mark", "subtype_indication", "resolution_function",
168 "range_constraint", "array_constraint", "record_constraint",
169 "record_element_constraint", "index_constraint", "array_element_constraint",
170 "parenthesized_resolution", "record_resolution", "record_element_resolution",
171 "guarded_signal_specification", "signal_list", "signal_kind",
173 "function_call",
175 "parameter_specification",
177 "association_list", "positional_association_element", "named_association_element",
179 "default",
180 "attribute_name", "slice_name", "selected_name", "ambiguous_name",
182 "predefined_designator",
183 "aggregate", "positional_element_association", "named_element_association",
185 "choices", "others",
186 "ascending_range", "descending_range",
188 "physical_literal", "string_literal", "bit_string_literal",
190 "character_literal", "integer_decimal", "real_decimal", "based_integer",
191 "based_real", "allocator", "null",
192 "sign", "factor", "term",
194 "signature", "tool_directive",
196 "design_unit", "design_file", "logical_name_list",
198 "context_reference", "context_list",
199 "subprogram_header", "subprogram_map_aspect",
201 "conditional_concurrent_signal_assignment",
203 "selected_concurrent_signal_assignment", "simple_concurrent_signal_assignment",
204 "group_constituent_list",
206 "force_mode", "declarative_part", "open", "semicolon",
208 "transport", "inertial", "unaffected", "delay_mechanism",
209 "sensitivity_list", "same", "any", "boolean", "comment",
210 "PSL_Verification_Unit_Body", "PSL_Property_Declaration",
212 "PSL_Sequence_Declaration", "PSL_Clock_Declaration",
213 "PSL_Built_In_Function_Call", "PSL_Union_Expression",
214 "PSL_Expression", "PSL_Identifier", "PSL_HDL_Type", "PSL_Any_Type",
215 "PSL_Type_Class", "PSL_Formal_Parameter", "PSL_Formal_Parameter_List",
216 "PSL_Parameters_Definition", "PSL_Parameter_Specification",
217 "PSL_Constant_Parameter_Specification", "PSL_Temporal_Parameter_Specification",
218 "PSL_Assert_Directive", "PSL_Assume_Directive", "PSL_Assume_Guarantee_Directive",
219 "PSL_Cover_Directive", "PSL_Restrict_Directive", "PSL_Restrict_Guarantee_Directive",
220 "PSL_Fairness_Directive", "PSL_Strong_Fairness_Directive",
221 "PSL_Property_Instance", "PSL_Sequence_Instance", "PSL_Actual_Parameter_List",
222 "PSL_Property_Replicator", "PSL_Count", "PSL_Number",
223 "PSL_Boolean", "PSL_Value_Set",
224 "PSL_Compound_SERE", "PSL_Repeated_SERE",
225 "PSL_Braced_SERE", "PSL_Clocked_SERE", "PSL_Simple_SERE",
226 "PSL_Parameterized_SERE", "PSL_Ambiguous_Instance",
227 "PSL_Parameterized_Property", "PSL_Index_Range",
228 "PSL_Actual_Parameter",
229 "PSL_Parenthesized_FL_Property", "PSL_Sequential_FL_Property",
230 "PSL_Clocked_FL_Property", "PSL_Invariant_FL_Property",
231 "PSL_Ocurrence_FL_Property", "PSL_Implication_FL_Property",
232 "PSL_Logical_FL_Property", "PSL_Factor_FL_Property",
233 "PSL_Extended_Ocurrence_FL_Property", "PSL_Termination_FL_Property",
234 "PSL_Bounding_FL_Property", "PSL_Suffix_Implication_FL_Property",
235 "PSL_VUnit", "PSL_VProp", "PSL_VMode",
236 "PSL_Hierarchical_HDL_Name", "PSL_Inherit_Spec",
237 "loop_statement",
239 "use_clause",
240 "case_statement",
241 "if_statement",
242 ];
243 validate_unused_kinds_audit(&Vhdl, documented_unused)
244 .expect("VHDL unused node kinds audit failed");
245 }
246}