11use crate :: core:: IntoTypeQualifier ;
2+ use crate :: core:: PosVisitor ;
23use crate :: core:: TypeResolverImpl ;
4+ use crate :: core:: VisitResult ;
5+ use crate :: core:: Visitor ;
36use crate :: core:: { LintError , LintErrorPos } ;
47use crate :: core:: { LintResult , ResolvedParamType } ;
58use crate :: pre_linter:: const_rules:: global_const;
@@ -26,7 +29,7 @@ pub fn pre_lint_program(program: &Program) -> Result<PreLinterResult, LintErrorP
2629 global_constants : Default :: default ( ) ,
2730 declaration_pos : Position :: start ( ) ,
2831 } ;
29- ctx . on_program ( program) ?;
32+ < MainContext as Visitor < Program > > :: visit ( & mut ctx , program) ?;
3033 ctx. functions . post_visit ( ) ?;
3134 ctx. subs . post_visit ( ) ?;
3235 Ok ( PreLinterResult :: new (
@@ -42,41 +45,70 @@ pub fn pre_lint_program(program: &Program) -> Result<PreLinterResult, LintErrorP
4245// FUNCTION/SUB -> depends on resolver for resolving bare names and on user_defined_types to ensure types exist
4346
4447impl MainContext {
45- fn on_program ( & mut self , program : & Program ) -> Result < ( ) , LintErrorPos > {
46- for Positioned { element, pos } in program {
47- self . declaration_pos = * pos;
48- match element {
49- GlobalStatement :: DefType ( def_type) => {
50- self . on_def_type ( def_type) ;
51- }
52- GlobalStatement :: FunctionDeclaration ( f) => {
53- self . on_function_declaration ( f) ?;
54- }
55- GlobalStatement :: FunctionImplementation ( f) => {
56- self . on_function_implementation ( f) ?;
57- }
58- GlobalStatement :: Statement ( s) => {
59- self . on_statement ( s) ?;
60- }
61- GlobalStatement :: SubDeclaration ( s) => {
62- self . on_sub_declaration ( s) ?;
63- }
64- GlobalStatement :: SubImplementation ( s) => {
65- self . on_sub_implementation ( s) ?;
66- }
67- GlobalStatement :: UserDefinedType ( user_defined_type) => {
68- self . on_user_defined_type ( user_defined_type, * pos) ?;
48+ fn on_parameters ( & self , parameters : & Parameters ) -> Result < ResolvedParamTypes , LintErrorPos > {
49+ parameters
50+ . iter ( )
51+ . map ( |p| self . on_parameter_pos ( p) )
52+ . collect ( )
53+ }
54+
55+ fn on_parameter_pos (
56+ & self ,
57+ parameter_pos : & ParameterPos ,
58+ ) -> Result < ResolvedParamType , LintErrorPos > {
59+ self . on_parameter ( & parameter_pos. element )
60+ . with_err_at ( parameter_pos)
61+ }
62+
63+ fn on_parameter ( & self , parameter : & Parameter ) -> Result < ResolvedParamType , LintError > {
64+ self . resolve_param_type ( & parameter. bare_name , & parameter. var_type )
65+ }
66+
67+ fn resolve_param_type (
68+ & self ,
69+ bare_name : & BareName ,
70+ param_type : & ParamType ,
71+ ) -> Result < ResolvedParamType , LintError > {
72+ match param_type {
73+ ParamType :: Bare => {
74+ let q = bare_name. qualify ( & self . resolver ) ;
75+ Ok ( ResolvedParamType :: BuiltIn ( q, BuiltInStyle :: Compact ) )
76+ }
77+ ParamType :: BuiltIn ( q, built_in_style) => {
78+ Ok ( ResolvedParamType :: BuiltIn ( * q, * built_in_style) )
79+ }
80+ ParamType :: UserDefined ( u) => {
81+ let type_name: & BareName = & u. element ;
82+ if self . user_defined_types . contains_key ( type_name) {
83+ Ok ( ResolvedParamType :: UserDefined ( type_name. clone ( ) ) )
84+ } else {
85+ Err ( LintError :: TypeNotDefined )
6986 }
7087 }
88+ ParamType :: Array ( element_type) => {
89+ let element_param_type =
90+ self . resolve_param_type ( bare_name, element_type. as_ref ( ) ) ?;
91+ Ok ( ResolvedParamType :: Array ( Box :: new ( element_param_type) ) )
92+ }
7193 }
72- Ok ( ( ) )
7394 }
95+ }
96+
97+ impl PosVisitor for MainContext {
98+ fn set_pos ( & mut self , pos : Position ) {
99+ self . declaration_pos = pos;
100+ }
101+ }
74102
75- fn on_def_type ( & mut self , def_type : & DefType ) {
103+ impl Visitor < DefType > for MainContext {
104+ fn visit ( & mut self , def_type : & DefType ) -> VisitResult {
76105 self . resolver . set ( def_type) ;
106+ Ok ( ( ) )
77107 }
108+ }
78109
79- fn on_function_declaration ( & mut self , f : & FunctionDeclaration ) -> Result < ( ) , LintErrorPos > {
110+ impl Visitor < FunctionDeclaration > for MainContext {
111+ fn visit ( & mut self , f : & FunctionDeclaration ) -> VisitResult {
80112 let FunctionDeclaration {
81113 name,
82114 parameters : params,
@@ -88,11 +120,10 @@ impl MainContext {
88120 . add_declaration ( bare_name, signature, self . declaration_pos )
89121 . with_err_at ( name)
90122 }
123+ }
91124
92- fn on_function_implementation (
93- & mut self ,
94- f : & FunctionImplementation ,
95- ) -> Result < ( ) , LintErrorPos > {
125+ impl Visitor < FunctionImplementation > for MainContext {
126+ fn visit ( & mut self , f : & FunctionImplementation ) -> VisitResult {
96127 let FunctionImplementation { name, params, .. } = f;
97128 let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
98129 let bare_name = name. element . bare_name ( ) ;
@@ -101,15 +132,10 @@ impl MainContext {
101132 . add_implementation ( bare_name, signature, self . declaration_pos )
102133 . with_err_at ( name)
103134 }
135+ }
104136
105- fn on_statement ( & mut self , s : & Statement ) -> Result < ( ) , LintErrorPos > {
106- match s {
107- Statement :: Const ( name, expr) => self . on_const ( name, expr) ,
108- _ => Ok ( ( ) ) ,
109- }
110- }
111-
112- fn on_sub_declaration ( & mut self , s : & SubDeclaration ) -> Result < ( ) , LintErrorPos > {
137+ impl Visitor < SubDeclaration > for MainContext {
138+ fn visit ( & mut self , s : & SubDeclaration ) -> VisitResult {
113139 let SubDeclaration {
114140 name,
115141 parameters : params,
@@ -121,8 +147,10 @@ impl MainContext {
121147 . add_declaration ( bare_name, signature, self . declaration_pos )
122148 . with_err_at ( name)
123149 }
150+ }
124151
125- fn on_sub_implementation ( & mut self , s : & SubImplementation ) -> Result < ( ) , LintErrorPos > {
152+ impl Visitor < SubImplementation > for MainContext {
153+ fn visit ( & mut self , s : & SubImplementation ) -> VisitResult {
126154 let SubImplementation { name, params, .. } = s;
127155 let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
128156 let bare_name = & name. element ;
@@ -131,69 +159,24 @@ impl MainContext {
131159 . add_implementation ( bare_name, signature, self . declaration_pos )
132160 . with_err_at ( name)
133161 }
162+ }
134163
135- fn on_user_defined_type (
136- & mut self ,
137- user_defined_type : & UserDefinedType ,
138- pos : Position ,
139- ) -> Result < ( ) , LintErrorPos > {
164+ impl Visitor < Statement > for MainContext {
165+ fn visit ( & mut self , s : & Statement ) -> VisitResult {
166+ match s {
167+ Statement :: Const ( name, expr) => global_const ( & mut self . global_constants , name, expr) ,
168+ _ => Ok ( ( ) ) ,
169+ }
170+ }
171+ }
172+
173+ impl Visitor < UserDefinedType > for MainContext {
174+ fn visit ( & mut self , user_defined_type : & UserDefinedType ) -> VisitResult {
140175 super :: user_defined_type_rules:: user_defined_type (
141176 & mut self . user_defined_types ,
142177 & self . global_constants ,
143178 user_defined_type,
144- pos ,
179+ self . declaration_pos ,
145180 )
146181 }
147-
148- fn on_const ( & mut self , name : & NamePos , expr : & ExpressionPos ) -> Result < ( ) , LintErrorPos > {
149- global_const ( & mut self . global_constants , name, expr)
150- }
151-
152- fn on_parameters ( & self , parameters : & Parameters ) -> Result < ResolvedParamTypes , LintErrorPos > {
153- parameters
154- . iter ( )
155- . map ( |p| self . on_parameter_pos ( p) )
156- . collect ( )
157- }
158-
159- fn on_parameter_pos (
160- & self ,
161- parameter_pos : & ParameterPos ,
162- ) -> Result < ResolvedParamType , LintErrorPos > {
163- self . on_parameter ( & parameter_pos. element )
164- . with_err_at ( parameter_pos)
165- }
166-
167- fn on_parameter ( & self , parameter : & Parameter ) -> Result < ResolvedParamType , LintError > {
168- self . resolve_param_type ( & parameter. bare_name , & parameter. var_type )
169- }
170-
171- fn resolve_param_type (
172- & self ,
173- bare_name : & BareName ,
174- param_type : & ParamType ,
175- ) -> Result < ResolvedParamType , LintError > {
176- match param_type {
177- ParamType :: Bare => {
178- let q = bare_name. qualify ( & self . resolver ) ;
179- Ok ( ResolvedParamType :: BuiltIn ( q, BuiltInStyle :: Compact ) )
180- }
181- ParamType :: BuiltIn ( q, built_in_style) => {
182- Ok ( ResolvedParamType :: BuiltIn ( * q, * built_in_style) )
183- }
184- ParamType :: UserDefined ( u) => {
185- let type_name: & BareName = & u. element ;
186- if self . user_defined_types . contains_key ( type_name) {
187- Ok ( ResolvedParamType :: UserDefined ( type_name. clone ( ) ) )
188- } else {
189- Err ( LintError :: TypeNotDefined )
190- }
191- }
192- ParamType :: Array ( element_type) => {
193- let element_param_type =
194- self . resolve_param_type ( bare_name, element_type. as_ref ( ) ) ?;
195- Ok ( ResolvedParamType :: Array ( Box :: new ( element_param_type) ) )
196- }
197- }
198- }
199182}
0 commit comments