gbf_core/decompiler/ast/
func_call.rs1#![deny(missing_docs)]
2
3use gbf_macros::AstNodeTransform;
4use serde::{Deserialize, Serialize};
5
6use super::{
7 AstKind, AstVisitable, array_kind::ArrayKind, expr::ExprKind, ptr::P, visitors::AstVisitor,
8};
9
10#[derive(Debug, Clone, Serialize, Deserialize, Eq, AstNodeTransform)]
12#[convert_to(ExprKind::FunctionCall, AstKind::Expression)]
13pub struct FunctionCallNode {
14 pub arguments: ArrayKind,
16}
17
18impl FunctionCallNode {
19 pub fn new(arguments: ArrayKind) -> Self {
24 Self { arguments }
25 }
26}
27
28impl AstVisitable for P<FunctionCallNode> {
29 fn accept<V: AstVisitor>(&self, visitor: &mut V) -> V::Output {
30 visitor.visit_function_call(self)
31 }
32}
33
34impl PartialEq for FunctionCallNode {
36 fn eq(&self, other: &Self) -> bool {
37 self.arguments == other.arguments
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use crate::decompiler::ast::{
44 AstNodeError, emit, new_fn_call_normal, new_id, new_member_access,
45 };
46
47 #[test]
48 fn test_call_emit() -> Result<(), AstNodeError> {
49 let call = new_fn_call_normal(new_id("echo"), vec![new_id("hello").into()]);
50 assert_eq!(emit(call), "echo(hello)");
51
52 let ma = new_member_access(new_id("foo"), new_id("bar"))?;
54 let call = new_fn_call_normal(ma, vec![new_id("baz").into()]);
55 assert_eq!(emit(call), "foo.bar(baz)");
56 Ok(())
57 }
58
59 #[test]
60 fn test_call_equality() {
61 let call1 = new_fn_call_normal(new_id("echo"), vec![new_id("hello").into()]);
62 let call2 = new_fn_call_normal(new_id("echo"), vec![new_id("hello").into()]);
63 assert_eq!(call1, call2);
64
65 let call3 = new_fn_call_normal(new_id("echo"), vec![new_id("world").into()]);
66 assert_ne!(call1, call3);
67 }
68
69 #[test]
70 fn test_nested_call_emit() {
71 let call = new_fn_call_normal(
72 new_id("foo"),
73 vec![new_fn_call_normal(new_id("bar"), vec![new_id("baz").into()]).into()],
74 );
75 assert_eq!(emit(call), "foo(bar(baz))");
76 }
77}