From 0750675f2fd1b534e544a848bd60cc85f6e65986 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Tue, 19 Sep 2023 14:56:21 +0200
Subject: [PATCH] Fix syscalls with lambda after them.

---
 muppet/puppet/ast.py           |  6 ++++++
 muppet/puppet/format/parser.py |  1 +
 tests/test_parse_elsif.py      | 30 ++++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/muppet/puppet/ast.py b/muppet/puppet/ast.py
index af2ccb1..f30acaa 100644
--- a/muppet/puppet/ast.py
+++ b/muppet/puppet/ast.py
@@ -384,6 +384,7 @@ class PuppetInvoke(Puppet):
 
     func: Puppet
     args: list[Puppet]
+    block: Optional[Puppet] = None
 
 
 @dataclass
@@ -677,6 +678,11 @@ def build_ast(form: Any) -> Puppet:
         case ['unless', {'test': test}]:
             return PuppetUnless(build_ast(test), [])
 
+        case ['invoke', {'functor': func, 'args': args, 'block': block}]:
+            return PuppetInvoke(build_ast(func),
+                                [build_ast(x) for x in args],
+                                build_ast(block))
+
         case ['invoke', {'functor': func, 'args': args}]:
             return PuppetInvoke(build_ast(func), [build_ast(x) for x in args])
 
diff --git a/muppet/puppet/format/parser.py b/muppet/puppet/format/parser.py
index e4d3451..046823c 100644
--- a/muppet/puppet/format/parser.py
+++ b/muppet/puppet/format/parser.py
@@ -434,6 +434,7 @@ class ParserFormatter(Serializer[ParseDirective]):
                 for x in xs:
                     parser &= ws & ',' & ws & self.s(x)
         parser &= optional(ws & ',') & optional(ws & ')')
+        parser &= optional(ws & self.s(it.block))
         return tag('invoke', parser)
 
     @override
diff --git a/tests/test_parse_elsif.py b/tests/test_parse_elsif.py
index 4e8c532..9230420 100644
--- a/tests/test_parse_elsif.py
+++ b/tests/test_parse_elsif.py
@@ -121,3 +121,33 @@ def test_invoke_inside_if():
     print("parser:\n" + str(parser))
     match_objects = ParserCombinator(s, "s").get(parser)
     pprint(match_objects)
+
+
+def test_funcall_with_block():
+    s = """
+    assert_type(A::B, $name) |$_expected, $actual | {
+      fail("msg")
+    }
+    """
+    ast = build_ast(puppet_parser(s))
+    pprint(ast)
+    parser = ParserFormatter(s, "s").serialize(ast)
+    print("parser:\n" + str(parser))
+    match_objects = ParserCombinator(s, "s").get(parser)
+    pprint(match_objects)
+
+
+def test_funcall_with_block_inner():
+    s = """
+    if $facts['package_provider'] == 'pkg' and $version =~ Undef {
+      assert_type(A::B, $name) |$_expected, $actual | {
+        fail("msg")
+      }
+    }
+    """
+    ast = build_ast(puppet_parser(s))
+    pprint(ast)
+    parser = ParserFormatter(s, "s").serialize(ast)
+    print("parser:\n" + str(parser))
+    match_objects = ParserCombinator(s, "s").get(parser)
+    pprint(match_objects)
-- 
GitLab