@@ -51,7 +51,7 @@ impl Visitor<FunctionDeclaration> for MainContext {
5151 name : Positioned { element : name, .. } ,
5252 parameters : params,
5353 } = f;
54- let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
54+ let param_types: ResolvedParamTypes = self . resolve_parameters ( params) ?;
5555 let bare_name = name. bare_name ( ) ;
5656 let q = name. qualify ( & self . resolver ) ;
5757 let signature = Signature :: new_function ( q, param_types) ;
@@ -67,7 +67,7 @@ impl Visitor<FunctionImplementation> for MainContext {
6767 params,
6868 ..
6969 } = f;
70- let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
70+ let param_types: ResolvedParamTypes = self . resolve_parameters ( params) ?;
7171 let bare_name = name. bare_name ( ) ;
7272 let q = name. qualify ( & self . resolver ) ;
7373 let signature = Signature :: new_function ( q, param_types) ;
@@ -84,7 +84,7 @@ impl Visitor<SubDeclaration> for MainContext {
8484 } ,
8585 parameters : params,
8686 } = s;
87- let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
87+ let param_types: ResolvedParamTypes = self . resolve_parameters ( params) ?;
8888 let signature = Signature :: new_sub ( param_types) ;
8989 self . subs
9090 . add_declaration ( bare_name. clone ( ) , signature. at_pos ( self . declaration_pos ) )
@@ -100,7 +100,7 @@ impl Visitor<SubImplementation> for MainContext {
100100 params,
101101 ..
102102 } = s;
103- let param_types: ResolvedParamTypes = self . on_parameters ( params) ?;
103+ let param_types: ResolvedParamTypes = self . resolve_parameters ( params) ?;
104104 let signature = Signature :: new_sub ( param_types) ;
105105 self . subs
106106 . add_implementation ( bare_name. clone ( ) , signature. at_pos ( self . declaration_pos ) )
@@ -131,33 +131,36 @@ impl MainContext {
131131 )
132132 }
133133
134- // TODO the remaining logic regarding parameters is a different kind of Visitor
135- // with a possible signature visit(&mut self, element: &T) -> Result<U, LintErrorPos>
136-
137- fn on_parameters ( & self , parameters : & Parameters ) -> Result < ResolvedParamTypes , LintErrorPos > {
138- parameters
139- . iter ( )
140- . map ( |p| self . on_parameter_pos ( p) )
141- . collect ( )
134+ fn resolve_parameters (
135+ & mut self ,
136+ parameters : & Parameters ,
137+ ) -> Result < ResolvedParamTypes , LintErrorPos > {
138+ self . ref_to_value_visit ( parameters) . map ( |v| v. no_pos ( ) )
142139 }
143140
144- fn on_parameter_pos (
145- & self ,
146- parameter_pos : & ParameterPos ,
147- ) -> Result < ResolvedParamType , LintErrorPos > {
148- self . on_parameter ( & parameter_pos. element )
149- . with_err_at ( parameter_pos)
141+ fn post_visit_functions ( & self ) -> Result < ( ) , LintErrorPos > {
142+ self . functions . ensure_declarations_are_implemented ( ) ?;
143+ self . functions
144+ . ensure_does_not_clash_with_built_in ( |name| BuiltInFunction :: try_parse ( name) . is_some ( ) )
150145 }
151146
152- fn on_parameter ( & self , parameter : & Parameter ) -> Result < ResolvedParamType , LintError > {
153- self . resolve_param_type ( parameter. bare_name ( ) , parameter. var_type ( ) )
147+ fn post_visit_subs ( & self ) -> Result < ( ) , LintErrorPos > {
148+ // not checking if declarations are present, because in MONEY.BAS there
149+ // are two SUBs declared but not implemented (and not called either)
150+ self . subs . ensure_does_not_clash_with_built_in ( |name| {
151+ BuiltInSub :: parse_non_keyword_sub ( name. as_ref ( ) ) . is_some ( )
152+ } )
154153 }
154+ }
155+
156+ impl < T > RefToValueVisitor < T , ResolvedParamType , LintError > for MainContext
157+ where
158+ T : AsRef < BareName > + AsRef < ParamType > ,
159+ {
160+ fn ref_to_value_visit ( & mut self , element : & T ) -> Result < ResolvedParamType , LintError > {
161+ let bare_name: & BareName = element. as_ref ( ) ;
162+ let param_type: & ParamType = element. as_ref ( ) ;
155163
156- fn resolve_param_type (
157- & self ,
158- bare_name : & BareName ,
159- param_type : & ParamType ,
160- ) -> Result < ResolvedParamType , LintError > {
161164 match param_type {
162165 ParamType :: Bare => {
163166 let q = bare_name. qualify ( & self . resolver ) ;
@@ -175,24 +178,28 @@ impl MainContext {
175178 }
176179 }
177180 ParamType :: Array ( element_type) => {
178- let element_param_type =
179- self . resolve_param_type ( bare_name , element_type . as_ref ( ) ) ?;
181+ let temp = RefParamName ( bare_name , element_type ) ;
182+ let element_param_type = self . ref_to_value_visit ( & temp ) ?;
180183 Ok ( ResolvedParamType :: Array ( Box :: new ( element_param_type) ) )
181184 }
182185 }
183186 }
187+ }
184188
185- fn post_visit_functions ( & self ) -> Result < ( ) , LintErrorPos > {
186- self . functions . ensure_declarations_are_implemented ( ) ?;
187- self . functions
188- . ensure_does_not_clash_with_built_in ( |name| BuiltInFunction :: try_parse ( name) . is_some ( ) )
189+ /// This is the same as [Parameter],
190+ /// but the memebers are references.
191+ /// It's needed due to the recursive implementation of `RefToValueVisitor`
192+ /// and the recursive (`Box`) implementation of `ParamType::Array`.
193+ struct RefParamName < ' a > ( & ' a BareName , & ' a ParamType ) ;
194+
195+ impl < ' a > AsRef < BareName > for RefParamName < ' a > {
196+ fn as_ref ( & self ) -> & BareName {
197+ self . 0
189198 }
199+ }
190200
191- fn post_visit_subs ( & self ) -> Result < ( ) , LintErrorPos > {
192- // not checking if declarations are present, because in MONEY.BAS there
193- // are two SUBs declared but not implemented (and not called either)
194- self . subs . ensure_does_not_clash_with_built_in ( |name| {
195- BuiltInSub :: parse_non_keyword_sub ( name. as_ref ( ) ) . is_some ( )
196- } )
201+ impl < ' a > AsRef < ParamType > for RefParamName < ' a > {
202+ fn as_ref ( & self ) -> & ParamType {
203+ self . 1
197204 }
198205}
0 commit comments