Skip to content

Commit af3f440

Browse files
committed
resolver: Annotate named arguments in function pointer call
1 parent 7d2d504 commit af3f440

File tree

2 files changed

+209
-7
lines changed

2 files changed

+209
-7
lines changed

src/resolver.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ impl StatementAnnotation {
751751
match self {
752752
StatementAnnotation::Variable { qualified_name, .. }
753753
| StatementAnnotation::Function { qualified_name, .. }
754+
| StatementAnnotation::FunctionPointer { qualified_name, .. }
754755
| StatementAnnotation::Program { qualified_name } => Some(qualified_name.as_str()),
755756

756757
_ => None,
@@ -2249,6 +2250,9 @@ impl<'i> TypeAnnotator<'i> {
22492250
StatementAnnotation::Function { qualified_name, call_name, .. } => {
22502251
call_name.as_ref().cloned().or_else(|| Some(qualified_name.clone()))
22512252
}
2253+
StatementAnnotation::FunctionPointer { qualified_name, .. } => {
2254+
Some(qualified_name.clone())
2255+
}
22522256
StatementAnnotation::Program { qualified_name } => Some(qualified_name.clone()),
22532257
StatementAnnotation::Variable { resulting_type, .. } => {
22542258
self.index

src/resolver/tests/fnptr.rs

Lines changed: 205 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use plc_ast::{
2-
ast::{AstStatement, CallStatement, ReferenceAccess, ReferenceExpr},
2+
ast::{Assignment, AstStatement, CallStatement, ReferenceAccess, ReferenceExpr},
33
provider::IdProvider,
44
};
55

@@ -78,17 +78,21 @@ fn function_pointer_method_with_arguments() {
7878
VAR
7979
echoPtr: POINTER TO Fb.echo := ADR(Fb.echo);
8080
localIn, localOut, localInOut: DINT;
81+
instanceFb: Fb;
8182
END_VAR
8283
8384
echoPtr^();
84-
echoPtr^(in := localIn, out => localOut, inout := localInOut);
85+
echoPtr^(instanceFb, localIn, localOut, localInOut);
86+
echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
8587
END_FUNCTION
8688
",
8789
ids.clone(),
8890
);
8991

9092
let (annotations, ..) = TypeAnnotator::visit_unit(&index, &unit, ids);
9193
let statements = &unit.implementations.iter().find(|imp| imp.name == "main").unwrap().statements;
94+
95+
// echoPtr^();
9296
{
9397
let AstStatement::CallStatement(CallStatement { operator, .. }) = statements[0].get_stmt() else {
9498
unreachable!();
@@ -110,12 +114,95 @@ fn function_pointer_method_with_arguments() {
110114
insta::assert_debug_snapshot!(annotations.get(&statements[0]), @"None");
111115
}
112116

117+
// echoPtr^(instanceFb, localIn, localOut, localInOut);
118+
{
119+
let AstStatement::CallStatement(CallStatement { operator, parameters: Some(parameters) }) =
120+
statements[1].get_stmt()
121+
else {
122+
unreachable!();
123+
};
124+
125+
// echoPtr^(instanceFb, localIn, localOut, localInOut);
126+
// ^^^^^^^^
127+
insta::assert_debug_snapshot!(annotations.get(operator), @r#"
128+
Some(
129+
FunctionPointer {
130+
return_type: "DINT",
131+
qualified_name: "Fb.echo",
132+
},
133+
)
134+
"#);
135+
136+
// echoPtr^(instanceFb, localIn, localOut, localInOut);
137+
// ^^^^^^^
138+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
139+
unreachable!();
140+
};
141+
142+
insta::assert_debug_snapshot!(annotations.get(&arguments[1]), @r#"
143+
Some(
144+
Variable {
145+
resulting_type: "DINT",
146+
qualified_name: "main.localIn",
147+
constant: false,
148+
argument_type: ByVal(
149+
Local,
150+
),
151+
auto_deref: None,
152+
},
153+
)
154+
"#);
155+
156+
// echoPtr^(instanceFb, localIn, localOut, localInOut);
157+
// ^^^^^^^^
158+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
159+
unreachable!();
160+
};
161+
162+
insta::assert_debug_snapshot!(annotations.get(&arguments[2]), @r#"
163+
Some(
164+
Variable {
165+
resulting_type: "DINT",
166+
qualified_name: "main.localOut",
167+
constant: false,
168+
argument_type: ByVal(
169+
Local,
170+
),
171+
auto_deref: None,
172+
},
173+
)
174+
"#);
175+
176+
// echoPtr^(instanceFb, localIn, localOut, localInOut);
177+
// ^^^^^^^^^^
178+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
179+
unreachable!();
180+
};
181+
182+
insta::assert_debug_snapshot!(annotations.get(&arguments[3]), @r#"
183+
Some(
184+
Variable {
185+
resulting_type: "DINT",
186+
qualified_name: "main.localInOut",
187+
constant: false,
188+
argument_type: ByVal(
189+
Local,
190+
),
191+
auto_deref: None,
192+
},
193+
)
194+
"#);
195+
}
196+
197+
// echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
113198
{
114-
let AstStatement::CallStatement(CallStatement { operator, .. }) = statements[1].get_stmt() else {
199+
let AstStatement::CallStatement(CallStatement { operator, parameters: Some(parameters) }) =
200+
statements[2].get_stmt()
201+
else {
115202
unreachable!();
116203
};
117204

118-
// echoPtr^(in := localIn, out => localOut, inout := localInOut);
205+
// echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
119206
// ^^^^^^^^
120207
insta::assert_debug_snapshot!(annotations.get(operator), @r#"
121208
Some(
@@ -126,9 +213,120 @@ fn function_pointer_method_with_arguments() {
126213
)
127214
"#);
128215

129-
// echoPtr^(in := localIn, out => localOut, inout := localInOut);
130-
// ^^^^^^^^^^^^^
131-
// TODO:
216+
// echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
217+
// ^^^^^^^^^^^^^
218+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
219+
unreachable!();
220+
};
221+
222+
let AstStatement::Assignment(Assignment { left, right }) = &arguments[1].stmt else {
223+
unreachable!();
224+
};
225+
insta::assert_debug_snapshot!(annotations.get(&arguments[1]), @"None");
226+
insta::assert_debug_snapshot!(annotations.get(&left), @r#"
227+
Some(
228+
Variable {
229+
resulting_type: "DINT",
230+
qualified_name: "Fb.echo.in",
231+
constant: false,
232+
argument_type: ByVal(
233+
Input,
234+
),
235+
auto_deref: None,
236+
},
237+
)
238+
"#);
239+
insta::assert_debug_snapshot!(annotations.get(&right), @r#"
240+
Some(
241+
Variable {
242+
resulting_type: "DINT",
243+
qualified_name: "main.localIn",
244+
constant: false,
245+
argument_type: ByVal(
246+
Local,
247+
),
248+
auto_deref: None,
249+
},
250+
)
251+
"#);
252+
253+
// echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
254+
// ^^^^^^^^^^^^^^^
255+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
256+
unreachable!();
257+
};
258+
259+
let AstStatement::OutputAssignment(Assignment { left, right }) = &arguments[2].stmt else {
260+
unreachable!();
261+
};
262+
insta::assert_debug_snapshot!(annotations.get(&arguments[2]), @"None");
263+
insta::assert_debug_snapshot!(annotations.get(&left), @r#"
264+
Some(
265+
Variable {
266+
resulting_type: "DINT",
267+
qualified_name: "Fb.echo.out",
268+
constant: false,
269+
argument_type: ByRef(
270+
Output,
271+
),
272+
auto_deref: Some(
273+
Default,
274+
),
275+
},
276+
)
277+
"#);
278+
insta::assert_debug_snapshot!(annotations.get(&right), @r#"
279+
Some(
280+
Variable {
281+
resulting_type: "DINT",
282+
qualified_name: "main.localOut",
283+
constant: false,
284+
argument_type: ByVal(
285+
Local,
286+
),
287+
auto_deref: None,
288+
},
289+
)
290+
"#);
291+
292+
// echoPtr^(instanceFb, in := localIn, out => localOut, inout := localInOut);
293+
// ^^^^^^^^^^^^^^^^^^^
294+
let AstStatement::ExpressionList(arguments) = &parameters.stmt else {
295+
unreachable!();
296+
};
297+
298+
let AstStatement::Assignment(Assignment { left, right }) = &arguments[3].stmt else {
299+
unreachable!();
300+
};
301+
insta::assert_debug_snapshot!(annotations.get(&arguments[3]), @"None");
302+
insta::assert_debug_snapshot!(annotations.get(&left), @r#"
303+
Some(
304+
Variable {
305+
resulting_type: "DINT",
306+
qualified_name: "Fb.echo.inout",
307+
constant: false,
308+
argument_type: ByRef(
309+
InOut,
310+
),
311+
auto_deref: Some(
312+
Default,
313+
),
314+
},
315+
)
316+
"#);
317+
insta::assert_debug_snapshot!(annotations.get(&right), @r#"
318+
Some(
319+
Variable {
320+
resulting_type: "DINT",
321+
qualified_name: "main.localInOut",
322+
constant: false,
323+
argument_type: ByVal(
324+
Local,
325+
),
326+
auto_deref: None,
327+
},
328+
)
329+
"#);
132330
}
133331
}
134332

0 commit comments

Comments
 (0)