Skip to content

Commit

Permalink
fix(cfc): Call statements for function blocks (PLC-lang#1006)
Browse files Browse the repository at this point in the history
Whenever we encountered a CFC block element, we previously created call statements based on it's typeName. While this is correct for function calls, it is incorrect for function block calls where it should have been the instanceName. To better illustrate the issue, here's the culprit <block localId="4" width="137" height="80" typeName="myFb" instanceName="fb0" executionOrderId="0">.

This issue has been fixed by using the instanceName before falling back to the typeName.
  • Loading branch information
volsa authored Nov 7, 2023
1 parent 11ed699 commit bc1c805
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/plc_xml/src/xml_parser/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl<'xml> Block<'xml> {
.collect();

AstFactory::create_call_to(
self.type_name.to_string(),
self.instance_name.as_ref().unwrap_or(&self.type_name).to_string(),
parameters,
session.next_id(),
session.next_id(),
Expand Down
2 changes: 2 additions & 0 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,10 +565,12 @@ impl AnnotationMapImpl {

/// annotates the given statement (using it's `get_id()`) with the given type-name
pub fn annotate(&mut self, s: &AstNode, annotation: StatementAnnotation) {
log::trace!("Annotation: {annotation:?} @ {s:?}");
self.type_map.insert(s.get_id(), annotation);
}

pub fn annotate_type_hint(&mut self, s: &AstNode, annotation: StatementAnnotation) {
log::trace!("Annotation (type-hint): {annotation:?} @ {s:?}");
self.type_hint_map.insert(s.get_id(), annotation);
}

Expand Down
1 change: 1 addition & 0 deletions tests/integration/cfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ fn connection_sink_source() {
// THEN the result will have double the value of the initial value
assert_eq!(res, 4);
}

#[test]
fn jump_to_label_with_true() {
let cfc_file = get_test_file("cfc/jump_true.cfc");
Expand Down
26 changes: 26 additions & 0 deletions tests/integration/cfc/resolver_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,29 @@ fn action_variables_annotated() {
};
assert_debug_snapshot!(annotations.get(left));
}

#[test]
fn function_block_calls_are_annotated_correctly() {
let main = get_test_file("cfc/function_block_call_main.cfc");
let fb = get_test_file("cfc/function_block_call_fb.cfc");

let main = main.load_source(None).unwrap();
let fb = fb.load_source(None).unwrap();

let annotated_project = parse_and_annotate("plc", vec![main, fb]).unwrap();
let annotations = &annotated_project.annotations;
let (unit, ..) = &annotated_project.units[0];

let call_annotation = annotations.get(&unit.implementations[0].statements[0]).unwrap().clone();
assert_debug_snapshot!(call_annotation, @r###"
Variable {
resulting_type: "myFb",
qualified_name: "main.fb0",
constant: false,
argument_type: ByVal(
Local,
),
is_auto_deref: false,
}
"###);
}
32 changes: 32 additions & 0 deletions tests/integration/data/cfc/function_block_call_fb.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<pou xmlns="http://www.plcopen.org/xml/tc6_0201" name="myFb" pouType="functionBlock">
<interface>
<localVars/>
<addData>
<data name="www.bachmann.at/plc/plcopenxml" handleUnknown="implementation">
<textDeclaration>
<content>
FUNCTION_BLOCK myFb
VAR_INPUT
in1 : DINT;
in2 : DINT;
END_VAR

VAR_OUTPUT
out1 : DINT;
out2 : DINT;
out3 : DINT;
END_VAR

VAR

END_VAR
</content>
</textDeclaration>
</data>
</addData>
</interface>
<body>
<FBD/>
</body>
</pou>
55 changes: 55 additions & 0 deletions tests/integration/data/cfc/function_block_call_main.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<pou xmlns="http://www.plcopen.org/xml/tc6_0201" name="main" pouType="program">
<interface>
<localVars/>
<addData>
<data name="www.bachmann.at/plc/plcopenxml" handleUnknown="implementation">
<textDeclaration>
<content>
PROGRAM main
VAR
fb0 : myFb;
END_VAR
</content>
</textDeclaration>
</data>
</addData>
</interface>
<body>
<FBD>
<block localId="4" width="137" height="80" typeName="myFb" instanceName="fb0" executionOrderId="0">
<position x="200" y="110"/>
<inputVariables>
<variable formalParameter="in1" negated="false">
<connectionPointIn>
<relPosition x="0" y="30"/>
</connectionPointIn>
</variable>
<variable formalParameter="in2" negated="false">
<connectionPointIn>
<relPosition x="0" y="50"/>
</connectionPointIn>
</variable>
</inputVariables>
<inOutVariables/>
<outputVariables>
<variable formalParameter="out1" negated="false">
<connectionPointOut>
<relPosition x="137" y="30"/>
</connectionPointOut>
</variable>
<variable formalParameter="out2" negated="false">
<connectionPointOut>
<relPosition x="137" y="50"/>
</connectionPointOut>
</variable>
<variable formalParameter="out3" negated="false">
<connectionPointOut>
<relPosition x="137" y="70"/>
</connectionPointOut>
</variable>
</outputVariables>
</block>
</FBD>
</body>
</pou>

0 comments on commit bc1c805

Please sign in to comment.