program.rs
1 // Copyright (C) 2019-2025 ADnet Contributors 2 // This file is part of the ADL library. 3 4 // The ADL library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 9 // The ADL library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 14 // You should have received a copy of the GNU General Public License 15 // along with the ADL library. If not, see <https://www.gnu.org/licenses/>. 16 17 use super::NameValidationVisitor; 18 19 use adl_ast::*; 20 21 impl ProgramVisitor for NameValidationVisitor<'_> { 22 fn visit_program(&mut self, input: &Program) { 23 input.stubs.iter().for_each(|(_symbol, stub)| self.visit_stub(stub)); 24 input.modules.values().for_each(|module| self.visit_module(module)); 25 input.program_scopes.values().for_each(|scope| self.visit_program_scope(scope)); 26 } 27 28 fn visit_program_scope(&mut self, input: &ProgramScope) { 29 let program_name = input.program_id.name; 30 self.does_not_contain_reserved(program_name, "program"); 31 self.is_not_keyword(program_name, "program", &[]); 32 33 input.composites.iter().for_each(|(_, function)| self.visit_composite(function)); 34 input.functions.iter().for_each(|(_, function)| self.visit_function(function)); 35 } 36 37 fn visit_module(&mut self, input: &Module) { 38 input.composites.iter().for_each(|(_, function)| self.visit_composite(function)); 39 input.functions.iter().for_each(|(_, function)| self.visit_function(function)); 40 } 41 42 fn visit_stub(&mut self, input: &Stub) { 43 input.composites.iter().for_each(|(_, function)| self.visit_composite_stub(function)); 44 input.functions.iter().for_each(|(_, function)| self.visit_function_stub(function)); 45 } 46 47 fn visit_composite(&mut self, input: &Composite) { 48 let composite_name = input.identifier; 49 let item_type = if input.is_record { "record" } else { "struct" }; 50 self.is_not_keyword(composite_name, item_type, &[]); 51 if input.is_record { 52 self.does_not_contain_reserved(composite_name, item_type); 53 } 54 55 for Member { identifier: member_name, .. } in &input.members { 56 if input.is_record { 57 self.is_not_keyword(*member_name, "record member", &["owner"]); 58 self.does_not_contain_reserved(*member_name, "record member"); 59 } else { 60 self.is_not_keyword(*member_name, "struct member", &[]); 61 } 62 } 63 } 64 65 fn visit_function(&mut self, function: &Function) { 66 use Variant::*; 67 match function.variant { 68 Transition | AsyncTransition => self.is_not_keyword(function.identifier, "transition", &[]), 69 Function => self.is_not_keyword(function.identifier, "function", &[]), 70 Inline | AsyncFunction | Script => {} 71 } 72 } 73 74 fn visit_function_stub(&mut self, input: &FunctionStub) { 75 use Variant::*; 76 match input.variant { 77 Transition | AsyncTransition => self.is_not_keyword(input.identifier, "transition", &[]), 78 Function => self.is_not_keyword(input.identifier, "function", &[]), 79 Inline | AsyncFunction | Script => {} 80 } 81 } 82 83 fn visit_composite_stub(&mut self, input: &Composite) { 84 self.visit_composite(input); 85 } 86 }