Skip to content

Commit 20a03b9

Browse files
committed
Merge remote-tracking branch 'origin/master' into debug_fixes
2 parents 2ac4497 + da17446 commit 20a03b9

21 files changed

+2292
-330
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ pub struct Pou {
4949

5050
#[derive(Debug, PartialEq)]
5151
pub struct Interface {
52-
pub name: String,
52+
pub id: AstId,
53+
pub identifier: Identifier,
5354
pub methods: Vec<Pou>,
5455
pub location: SourceLocation,
55-
pub location_name: SourceLocation,
56+
pub extensions: Vec<Identifier>,
5657
}
5758

58-
#[derive(Debug, PartialEq, Clone)]
59+
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
5960
pub struct Identifier {
6061
pub name: String,
6162
pub location: SourceLocation,
@@ -311,6 +312,22 @@ pub enum AccessModifier {
311312
Internal,
312313
}
313314

315+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
316+
pub enum DeclarationKind {
317+
Abstract,
318+
Concrete,
319+
}
320+
321+
impl DeclarationKind {
322+
pub fn is_abstract(&self) -> bool {
323+
matches!(self, DeclarationKind::Abstract)
324+
}
325+
326+
pub fn is_concrete(&self) -> bool {
327+
matches!(self, DeclarationKind::Concrete)
328+
}
329+
}
330+
314331
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
315332
pub enum PouType {
316333
Program,
@@ -324,6 +341,8 @@ pub enum PouType {
324341

325342
/// The fully qualified name of the property this GET or SET method represents
326343
property: Option<String>,
344+
345+
declaration_kind: DeclarationKind,
327346
},
328347
Init,
329348
ProjectInit,
@@ -1351,7 +1370,7 @@ impl Operator {
13511370

13521371
#[cfg(test)]
13531372
mod tests {
1354-
use crate::ast::{ArgumentProperty, PouType, VariableBlockType};
1373+
use crate::ast::{ArgumentProperty, DeclarationKind, PouType, VariableBlockType};
13551374

13561375
#[test]
13571376
fn display_pou() {
@@ -1360,7 +1379,15 @@ mod tests {
13601379
assert_eq!(PouType::FunctionBlock.to_string(), "FunctionBlock");
13611380
assert_eq!(PouType::Action.to_string(), "Action");
13621381
assert_eq!(PouType::Class.to_string(), "Class");
1363-
assert_eq!(PouType::Method { parent: String::new(), property: None }.to_string(), "Method");
1382+
assert_eq!(
1383+
PouType::Method {
1384+
parent: String::new(),
1385+
property: None,
1386+
declaration_kind: DeclarationKind::Concrete
1387+
}
1388+
.to_string(),
1389+
"Method"
1390+
);
13641391
}
13651392

13661393
#[test]

compiler/plc_lowering/src/inheritance.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ mod units_tests {
20952095

20962096
let (_, project) = parse_and_annotate("test", vec![src]).unwrap();
20972097
let unit = &project.units[0].get_unit().units[3];
2098-
assert_debug_snapshot!(unit, @r###"
2098+
assert_debug_snapshot!(unit, @r#"
20992099
POU {
21002100
name: "child.foo",
21012101
variable_blocks: [
@@ -2142,11 +2142,12 @@ mod units_tests {
21422142
pou_type: Method {
21432143
parent: "child",
21442144
property: None,
2145+
declaration_kind: Concrete,
21452146
},
21462147
return_type: None,
21472148
interfaces: [],
21482149
}
2149-
"###);
2150+
"#);
21502151
}
21512152

21522153
#[test]
@@ -2168,14 +2169,15 @@ mod units_tests {
21682169

21692170
let (_, project) = parse_and_annotate("test", vec![src]).unwrap();
21702171
let unit = &project.units[0].get_unit().implementations[1];
2171-
assert_debug_snapshot!(unit, @r###"
2172+
assert_debug_snapshot!(unit, @r#"
21722173
Implementation {
21732174
name: "bar.set0",
21742175
type_name: "bar.set0",
21752176
linkage: Internal,
21762177
pou_type: Method {
21772178
parent: "bar",
21782179
property: None,
2180+
declaration_kind: Concrete,
21792181
},
21802182
statements: [
21812183
Assignment {
@@ -2255,7 +2257,7 @@ mod units_tests {
22552257
Protected,
22562258
),
22572259
}
2258-
"###);
2260+
"#);
22592261
}
22602262
}
22612263

src/index.rs

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use itertools::Itertools;
66
use rustc_hash::{FxHashSet, FxHasher};
77

88
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,
1111
};
1212
use plc_diagnostics::diagnostics::Diagnostic;
1313
use plc_source::source_location::SourceLocation;
@@ -491,48 +491,117 @@ impl ImplementationType {
491491
}
492492
}
493493

494-
#[derive(PartialEq, Eq)]
494+
#[derive(PartialEq, Eq, Hash)]
495495
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,
498498

499499
/// The location of the interface as a whole
500500
pub location: SourceLocation,
501501

502-
/// The location of the interface name
503-
pub location_name: SourceLocation,
504-
505502
/// A list of qualified names of the methods in this interface; the actual methods are located in
506503
/// [`Index::pous`]
507504
pub methods: Vec<String>,
505+
506+
/// A list of other interfaces this interface extends
507+
pub extensions: Vec<Identifier>,
508508
}
509509

510510
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> {
513525
self.methods
514526
.iter()
515527
.map(|name| index.find_pou(name).expect("must exist because of present InterfaceIndexEntry"))
516528
.collect()
517529
}
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+
}
518586
}
519587

520588
impl std::fmt::Debug for InterfaceIndexEntry {
521589
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
522590
f.debug_struct("InterfaceIndexEntry")
523-
.field("name", &self.name)
591+
.field("name", &self.get_name())
524592
.field("methods", &self.methods)
593+
.field("extensions", &self.extensions)
525594
.finish()
526595
}
527596
}
528597

529598
impl From<&Interface> for InterfaceIndexEntry {
530599
fn from(interface: &Interface) -> Self {
531600
InterfaceIndexEntry {
532-
name: interface.name.clone(),
601+
identifier: interface.identifier.clone(),
533602
location: interface.location.clone(),
534-
location_name: interface.location_name.clone(),
535603
methods: interface.methods.iter().map(|method| method.name.clone()).collect(),
604+
extensions: interface.extensions.clone(),
536605
}
537606
}
538607
}
@@ -574,15 +643,16 @@ pub enum PouIndexEntry {
574643
},
575644
Method {
576645
name: String,
577-
parent_pou_name: String,
646+
parent_name: String,
647+
declaration_kind: DeclarationKind,
578648
return_type: String,
579649
instance_struct_name: String,
580650
linkage: LinkageType,
581651
location: SourceLocation,
582652
},
583653
Action {
584654
name: String,
585-
parent_pou_name: String,
655+
parent_name: String,
586656
instance_struct_name: String,
587657
linkage: LinkageType,
588658
location: SourceLocation,
@@ -693,7 +763,7 @@ impl PouIndexEntry {
693763
) -> PouIndexEntry {
694764
PouIndexEntry::Action {
695765
name: qualified_name.into(),
696-
parent_pou_name: pou_name.into(),
766+
parent_name: pou_name.into(),
697767
instance_struct_name: pou_name.into(),
698768
linkage,
699769
location,
@@ -729,12 +799,14 @@ impl PouIndexEntry {
729799
name: &str,
730800
return_type: &str,
731801
owner_class: &str,
802+
declaration_kind: DeclarationKind,
732803
linkage: LinkageType,
733804
location: SourceLocation,
734805
) -> PouIndexEntry {
735806
PouIndexEntry::Method {
736807
name: name.into(),
737-
parent_pou_name: owner_class.into(),
808+
parent_name: owner_class.into(),
809+
declaration_kind,
738810
instance_struct_name: name.into(),
739811
return_type: return_type.into(),
740812
linkage,
@@ -775,14 +847,21 @@ impl PouIndexEntry {
775847

776848
pub fn get_parent_pou_name(&self) -> Option<&str> {
777849
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())
780852
}
781853

782854
_ => None,
783855
}
784856
}
785857

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+
786865
/// returns the name of the struct-type used to store the POUs state
787866
/// (interface-variables)
788867
pub fn get_instance_struct_type_name(&self) -> Option<&str> {
@@ -819,8 +898,8 @@ impl PouIndexEntry {
819898
| PouIndexEntry::FunctionBlock { .. }
820899
| PouIndexEntry::Class { .. }
821900
| 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()
824903
}
825904
}
826905
}
@@ -1925,11 +2004,11 @@ impl Index {
19252004

19262005
/// Returns all methods declared on container, or its parents.
19272006
/// 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())
19302009
}
19312010

1932-
fn find_method_recursive<'b>(
2011+
fn get_methods_recursive<'b>(
19332012
&'b self,
19342013
container: &str,
19352014
current_methods: Vec<&'b PouIndexEntry>,
@@ -1952,7 +2031,7 @@ impl Index {
19522031
if !seen.insert(super_class) {
19532032
return res;
19542033
};
1955-
self.find_method_recursive(super_class, res, seen)
2034+
self.get_methods_recursive(super_class, res, seen)
19562035
} else {
19572036
res
19582037
}

src/index/indexer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ impl AstVisitor for SymbolIndexer {
6767
self.visit_pou(method);
6868
}
6969

70-
self.index.interfaces.insert(interface.name.clone(), InterfaceIndexEntry::from(interface));
70+
self.index
71+
.interfaces
72+
.insert(interface.identifier.name.to_owned(), InterfaceIndexEntry::from(interface));
7173
}
7274
}

0 commit comments

Comments
 (0)