diff --git a/muppet/puppet/ast.py b/muppet/puppet/ast.py index af2ccb152003c221d55012f9b31231b2f6e85a42..f30acaaf0c750eb65593146ca933bbe0ed2997b4 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 e4d345169d56cd264091f9b51ac242552d5d340a..046823c036cc246f30cc400f9a21b9f1ae99f2c1 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 4e8c5328e4c18441f1bdacb46b8418237a05f9dc..9230420b1d33520172729878604ac53b0552905b 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)