@@ -199,7 +199,7 @@ impl VariableIndexEntry {
199199 self . data_type_name . as_str ( )
200200 }
201201
202- pub fn get_location_in_parent ( & self ) -> u32 {
202+ pub fn get_position ( & self ) -> u32 {
203203 self . location_in_parent
204204 }
205205
@@ -1551,30 +1551,31 @@ impl Index {
15511551 } )
15521552 }
15531553
1554- fn truly_find_local_member ( & self , pou : & str , name : & str ) -> Option < & VariableIndexEntry > {
1555- self . type_index . find_type ( pou) . and_then ( |it| it. find_member ( name) )
1556- }
1554+ // XXX: This is super specific and currently only being used in the context of argument annotations.
1555+ // Should we move this to the resolver.rs file?
1556+ /// Finds a member in the specified POU, traversing the inheritance chain if necessary. Returns the
1557+ /// [`VariableIndexEntry`] along with the inheritance depth from the given POU to where the member
1558+ /// was declared.
1559+ pub fn find_pou_member_and_depth ( & self , pou : & str , name : & str ) -> Option < ( & VariableIndexEntry , usize ) > {
1560+ fn find < ' a > ( index : & ' a Index , pou : & str , name : & str ) -> Option < & ' a VariableIndexEntry > {
1561+ index. type_index . find_type ( pou) . and_then ( |pou| pou. find_member ( name) )
1562+ }
15571563
1558- // TODO: Own type?
1559- /// Given some POU name and one of its members' name, returns the member and the position including its
1560- /// inheritance level. For example If we have `A { localVarA }, B extends A { localVarB }`, then
1561- /// `find_member_with_path("B", "localVarA")` will return `(localVarA, 0, 1)`
1562- pub fn find_member_with_path ( & self , pou : & str , name : & str ) -> Option < ( String , & VariableIndexEntry , u32 ) > {
15631564 // Check if the POU has the member locally
1564- if let Some ( entry) = self . truly_find_local_member ( pou, name) {
1565- return Some ( ( pou . to_string ( ) , entry, 0 ) ) ;
1565+ if let Some ( entry) = find ( self , pou, name) {
1566+ return Some ( ( entry, 0 ) ) ;
15661567 }
15671568
15681569 // ..and if not walk the inheritance chain and re-try
1569- let mut level = 1 ;
1570+ let mut depth = 1 ;
15701571 let mut current_pou = pou;
15711572
1572- while let Some ( parent) = self . find_pou ( current_pou) . and_then ( |it| it . get_super_class ( ) ) {
1573- if let Some ( entry) = self . truly_find_local_member ( parent, name) {
1574- return Some ( ( parent . to_string ( ) , entry, level ) ) ;
1573+ while let Some ( parent) = self . find_pou ( current_pou) . and_then ( PouIndexEntry :: get_super_class) {
1574+ if let Some ( entry) = find ( self , parent, name) {
1575+ return Some ( ( entry, depth ) ) ;
15751576 }
15761577
1577- level += 1 ;
1578+ depth += 1 ;
15781579 current_pou = parent;
15791580 }
15801581
@@ -1731,21 +1732,32 @@ impl Index {
17311732 self . get_pou_types ( ) . get ( & pou_name. to_lowercase ( ) )
17321733 }
17331734
1734- pub fn get_declared_parameters ( & self , pou_name : & str ) -> Vec < & VariableIndexEntry > {
1735- self . get_pou_members ( pou_name )
1736- . iter ( )
1737- . filter ( |it| it . is_parameter ( ) && !it . is_variadic ( ) )
1738- . collect :: < Vec < _ > > ( )
1735+ /// Returns the parameter for the given POU by its location, if it exists.
1736+ ///
1737+ /// A parameter is defined as a `VAR_INPUT`, `VAR_OUTPUT` or `VAR_IN_OUT` variable.
1738+ pub fn get_declared_parameter ( & self , pou_name : & str , index : u32 ) -> Option < & VariableIndexEntry > {
1739+ self . type_index . find_pou_type ( pou_name ) . and_then ( |it| it . find_declared_parameter_by_location ( index ) )
17391740 }
17401741
1741- /// Returns all declared parameters of a POU, including those defined in super-classes
1742- pub fn get_declared_parameters_2nd ( & self , pou : & str ) -> Vec < & VariableIndexEntry > {
1743- let mut pou = pou;
1744- let mut parameters = self . get_declared_parameters ( pou) ;
1742+ /// Returns all declared parameters of a POU, including those defined in super-classes,
1743+ /// in intuitive order: base class parameters first, then derived.
1744+ pub fn get_declared_parameters ( & self , pou : & str ) -> Vec < & VariableIndexEntry > {
1745+ // Collect all POU names in the inheritance chain from base to derived
1746+ let mut chain = Vec :: new ( ) ;
1747+ let mut current = Some ( pou) ;
1748+ let mut parameters = Vec :: new ( ) ;
17451749
1746- while let Some ( parent) = self . find_pou ( pou) . and_then ( PouIndexEntry :: get_super_class) {
1747- parameters. extend ( self . get_declared_parameters ( parent) ) ;
1748- pou = parent;
1750+ // Walk the inheritance chain and collect its POU names; only has an effect on function block calls
1751+ while let Some ( pou_name) = current {
1752+ chain. push ( pou_name) ;
1753+ current = self . find_pou ( pou_name) . and_then ( PouIndexEntry :: get_super_class) ;
1754+ }
1755+
1756+ // Then, reverse the chain to start at the root and collect its parameters
1757+ for & name in chain. iter ( ) . rev ( ) {
1758+ parameters. extend (
1759+ self . get_pou_members ( name) . iter ( ) . filter ( |var| var. is_parameter ( ) && !var. is_variadic ( ) ) ,
1760+ ) ;
17491761 }
17501762
17511763 parameters
@@ -1755,13 +1767,6 @@ impl Index {
17551767 self . get_pou_members ( pou_name) . iter ( ) . any ( |member| member. is_parameter ( ) && member. is_variadic ( ) )
17561768 }
17571769
1758- /// returns some if the current index is a VAR_INPUT, VAR_IN_OUT or VAR_OUTPUT that is not a variadic argument
1759- /// In other words it returns some if the member variable at `index` of the given container is a possible parameter in
1760- /// the call to it
1761- pub fn get_declared_parameter ( & self , pou_name : & str , index : u32 ) -> Option < & VariableIndexEntry > {
1762- self . type_index . find_pou_type ( pou_name) . and_then ( |it| it. find_declared_parameter_by_location ( index) )
1763- }
1764-
17651770 pub fn get_variadic_member ( & self , pou_name : & str ) -> Option < & VariableIndexEntry > {
17661771 self . type_index . find_pou_type ( pou_name) . and_then ( |it| it. find_variadic_member ( ) )
17671772 }
0 commit comments