@@ -6,8 +6,8 @@ use itertools::Itertools;
6
6
use rustc_hash:: { FxHashSet , FxHasher } ;
7
7
8
8
use plc_ast:: ast:: {
9
- AstId , AstNode , AstStatement , ConfigVariable , DirectAccessType , GenericBinding , HardwareAccessType ,
10
- Identifier , Interface , LinkageType , PouType , TypeNature ,
9
+ AstId , AstNode , AstStatement , ConfigVariable , DeclarationKind , DirectAccessType , GenericBinding ,
10
+ HardwareAccessType , Identifier , Interface , LinkageType , PouType , TypeNature ,
11
11
} ;
12
12
use plc_diagnostics:: diagnostics:: Diagnostic ;
13
13
use plc_source:: source_location:: SourceLocation ;
@@ -491,48 +491,117 @@ impl ImplementationType {
491
491
}
492
492
}
493
493
494
- #[ derive( PartialEq , Eq ) ]
494
+ #[ derive( PartialEq , Eq , Hash ) ]
495
495
pub struct InterfaceIndexEntry {
496
- /// The interface name
497
- pub name : String ,
496
+ /// The interface identifier, consisting of its name and name-location
497
+ pub identifier : Identifier ,
498
498
499
499
/// The location of the interface as a whole
500
500
pub location : SourceLocation ,
501
501
502
- /// The location of the interface name
503
- pub location_name : SourceLocation ,
504
-
505
502
/// A list of qualified names of the methods in this interface; the actual methods are located in
506
503
/// [`Index::pous`]
507
504
pub methods : Vec < String > ,
505
+
506
+ /// A list of other interfaces this interface extends
507
+ pub extensions : Vec < Identifier > ,
508
508
}
509
509
510
510
impl InterfaceIndexEntry {
511
- /// Returns a list of methods defined in this interface
512
- pub fn get_methods < ' idx > ( & self , index : & ' idx Index ) -> Vec < & ' idx PouIndexEntry > {
511
+ pub fn get_name ( & self ) -> & str {
512
+ self . identifier . name . as_str ( )
513
+ }
514
+
515
+ pub fn get_name_location ( & self ) -> & SourceLocation {
516
+ & self . identifier . location
517
+ }
518
+
519
+ pub fn get_location ( & self ) -> & SourceLocation {
520
+ & self . location
521
+ }
522
+
523
+ /// Returns a list of methods this interface declared
524
+ pub fn get_declared_methods < ' idx > ( & self , index : & ' idx Index ) -> Vec < & ' idx PouIndexEntry > {
513
525
self . methods
514
526
. iter ( )
515
527
. map ( |name| index. find_pou ( name) . expect ( "must exist because of present InterfaceIndexEntry" ) )
516
528
. collect ( )
517
529
}
530
+
531
+ /// Returns a list of methods this interface inherited
532
+ pub fn get_derived_methods < ' idx > ( & ' idx self , index : & ' idx Index ) -> Vec < & ' idx PouIndexEntry > {
533
+ self . get_derived_methods_recursive ( index, & mut FxHashSet :: default ( ) )
534
+ }
535
+
536
+ /// Returns a list of methods defined in this interface, including inherited methods from derived interfaces
537
+ pub fn get_methods < ' idx > ( & ' idx self , index : & ' idx Index ) -> Vec < & ' idx PouIndexEntry > {
538
+ self . get_methods_recursive ( index, & mut FxHashSet :: default ( ) )
539
+ }
540
+
541
+ /// Returns a list of interfaces this interface implements
542
+ pub fn get_extensions ( & self ) -> Vec < & Identifier > {
543
+ self . extensions . iter ( ) . collect ( )
544
+ }
545
+
546
+ /// Returns a list of interfaces this interface inherited
547
+ pub fn get_derived_interfaces < ' idx > (
548
+ & self ,
549
+ index : & ' idx Index ,
550
+ ) -> Vec < Result < & ' idx InterfaceIndexEntry , Identifier > > {
551
+ self . extensions
552
+ . iter ( )
553
+ . flat_map ( |id| index. find_interface ( & id. name ) . map ( Result :: Ok ) . or ( Some ( Err ( id. to_owned ( ) ) ) ) )
554
+ . collect ( )
555
+ }
556
+
557
+ fn get_methods_recursive < ' idx > (
558
+ & ' idx self ,
559
+ index : & ' idx Index ,
560
+ seen : & mut FxHashSet < & ' idx str > ,
561
+ ) -> Vec < & ' idx PouIndexEntry > {
562
+ seen. insert ( self . get_name ( ) ) ;
563
+ self . get_declared_methods ( index)
564
+ . into_iter ( )
565
+ . chain ( self . get_derived_methods_recursive ( index, seen) )
566
+ . collect_vec ( )
567
+ }
568
+
569
+ fn get_derived_methods_recursive < ' idx > (
570
+ & ' idx self ,
571
+ index : & ' idx Index ,
572
+ seen : & mut FxHashSet < & ' idx str > ,
573
+ ) -> Vec < & ' idx PouIndexEntry > {
574
+ self . get_derived_interfaces ( index)
575
+ . iter ( )
576
+ . filter_map ( |it| it. as_ref ( ) . ok ( ) )
577
+ . flat_map ( |it| {
578
+ if !seen. contains ( it. get_name ( ) ) {
579
+ it. get_methods_recursive ( index, seen)
580
+ } else {
581
+ vec ! [ ]
582
+ }
583
+ } )
584
+ . collect ( )
585
+ }
518
586
}
519
587
520
588
impl std:: fmt:: Debug for InterfaceIndexEntry {
521
589
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
522
590
f. debug_struct ( "InterfaceIndexEntry" )
523
- . field ( "name" , & self . name )
591
+ . field ( "name" , & self . get_name ( ) )
524
592
. field ( "methods" , & self . methods )
593
+ . field ( "extensions" , & self . extensions )
525
594
. finish ( )
526
595
}
527
596
}
528
597
529
598
impl From < & Interface > for InterfaceIndexEntry {
530
599
fn from ( interface : & Interface ) -> Self {
531
600
InterfaceIndexEntry {
532
- name : interface. name . clone ( ) ,
601
+ identifier : interface. identifier . clone ( ) ,
533
602
location : interface. location . clone ( ) ,
534
- location_name : interface. location_name . clone ( ) ,
535
603
methods : interface. methods . iter ( ) . map ( |method| method. name . clone ( ) ) . collect ( ) ,
604
+ extensions : interface. extensions . clone ( ) ,
536
605
}
537
606
}
538
607
}
@@ -574,15 +643,16 @@ pub enum PouIndexEntry {
574
643
} ,
575
644
Method {
576
645
name : String ,
577
- parent_pou_name : String ,
646
+ parent_name : String ,
647
+ declaration_kind : DeclarationKind ,
578
648
return_type : String ,
579
649
instance_struct_name : String ,
580
650
linkage : LinkageType ,
581
651
location : SourceLocation ,
582
652
} ,
583
653
Action {
584
654
name : String ,
585
- parent_pou_name : String ,
655
+ parent_name : String ,
586
656
instance_struct_name : String ,
587
657
linkage : LinkageType ,
588
658
location : SourceLocation ,
@@ -693,7 +763,7 @@ impl PouIndexEntry {
693
763
) -> PouIndexEntry {
694
764
PouIndexEntry :: Action {
695
765
name : qualified_name. into ( ) ,
696
- parent_pou_name : pou_name. into ( ) ,
766
+ parent_name : pou_name. into ( ) ,
697
767
instance_struct_name : pou_name. into ( ) ,
698
768
linkage,
699
769
location,
@@ -729,12 +799,14 @@ impl PouIndexEntry {
729
799
name : & str ,
730
800
return_type : & str ,
731
801
owner_class : & str ,
802
+ declaration_kind : DeclarationKind ,
732
803
linkage : LinkageType ,
733
804
location : SourceLocation ,
734
805
) -> PouIndexEntry {
735
806
PouIndexEntry :: Method {
736
807
name : name. into ( ) ,
737
- parent_pou_name : owner_class. into ( ) ,
808
+ parent_name : owner_class. into ( ) ,
809
+ declaration_kind,
738
810
instance_struct_name : name. into ( ) ,
739
811
return_type : return_type. into ( ) ,
740
812
linkage,
@@ -775,14 +847,21 @@ impl PouIndexEntry {
775
847
776
848
pub fn get_parent_pou_name ( & self ) -> Option < & str > {
777
849
match self {
778
- PouIndexEntry :: Method { parent_pou_name , .. } | PouIndexEntry :: Action { parent_pou_name , .. } => {
779
- Some ( parent_pou_name . as_str ( ) )
850
+ PouIndexEntry :: Method { parent_name , .. } | PouIndexEntry :: Action { parent_name , .. } => {
851
+ Some ( parent_name . as_str ( ) )
780
852
}
781
853
782
854
_ => None ,
783
855
}
784
856
}
785
857
858
+ pub fn get_declaration_kind ( & self ) -> Option < DeclarationKind > {
859
+ match self {
860
+ PouIndexEntry :: Method { declaration_kind, .. } => Some ( * declaration_kind) ,
861
+ _ => None ,
862
+ }
863
+ }
864
+
786
865
/// returns the name of the struct-type used to store the POUs state
787
866
/// (interface-variables)
788
867
pub fn get_instance_struct_type_name ( & self ) -> Option < & str > {
@@ -819,8 +898,8 @@ impl PouIndexEntry {
819
898
| PouIndexEntry :: FunctionBlock { .. }
820
899
| PouIndexEntry :: Class { .. }
821
900
| PouIndexEntry :: Function { .. } => self . get_name ( ) ,
822
- PouIndexEntry :: Action { parent_pou_name , .. } | PouIndexEntry :: Method { parent_pou_name , .. } => {
823
- parent_pou_name . as_str ( )
901
+ PouIndexEntry :: Action { parent_name , .. } | PouIndexEntry :: Method { parent_name , .. } => {
902
+ parent_name . as_str ( )
824
903
}
825
904
}
826
905
}
@@ -1925,11 +2004,11 @@ impl Index {
1925
2004
1926
2005
/// Returns all methods declared on container, or its parents.
1927
2006
/// If a method is declared in the container the parent method is not included
1928
- pub fn find_methods ( & self , container : & str ) -> Vec < & PouIndexEntry > {
1929
- self . find_method_recursive ( container, vec ! [ ] , & mut FxHashSet :: default ( ) )
2007
+ pub fn get_methods ( & self , container : & str ) -> Vec < & PouIndexEntry > {
2008
+ self . get_methods_recursive ( container, vec ! [ ] , & mut FxHashSet :: default ( ) )
1930
2009
}
1931
2010
1932
- fn find_method_recursive < ' b > (
2011
+ fn get_methods_recursive < ' b > (
1933
2012
& ' b self ,
1934
2013
container : & str ,
1935
2014
current_methods : Vec < & ' b PouIndexEntry > ,
@@ -1952,7 +2031,7 @@ impl Index {
1952
2031
if !seen. insert ( super_class) {
1953
2032
return res;
1954
2033
} ;
1955
- self . find_method_recursive ( super_class, res, seen)
2034
+ self . get_methods_recursive ( super_class, res, seen)
1956
2035
} else {
1957
2036
res
1958
2037
}
0 commit comments