diff --git a/spec/compiler/formatter/formatter_spec.cr b/spec/compiler/formatter/formatter_spec.cr index fdd2b9012996..c0ae07674033 100644 --- a/spec/compiler/formatter/formatter_spec.cr +++ b/spec/compiler/formatter/formatter_spec.cr @@ -1387,6 +1387,7 @@ describe Crystal::Formatter do assert_format "macro foo\n %foo\nend" assert_format "macro foo\n %foo{x.id+2}\nend", "macro foo\n %foo{x.id + 2}\nend" assert_format "macro foo\n %foo{x,y}\nend", "macro foo\n %foo{x, y}\nend" + assert_format "macro foo;%var{}end", "macro foo\n%var{}end" assert_format "def foo : Int32\n 1\nend" assert_format "class Foo\n macro foo\n 1\n end\nend" assert_format " {{ 1 + 2 }}", "{{ 1 + 2 }}" diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr index 408bfda6668f..2e657e8a91eb 100644 --- a/spec/compiler/parser/parser_spec.cr +++ b/spec/compiler/parser/parser_spec.cr @@ -146,7 +146,7 @@ module Crystal it_parses %(macro foo\n%q(%t{)\nend), Macro.new("foo", body: Expressions.from(["%q(%t".macro_literal, "{)\n".macro_literal] of ASTNode)) it_parses %(macro foo\n%(%t{)\nend), Macro.new("foo", body: Expressions.from(["%(%t".macro_literal, "{)\n".macro_literal] of ASTNode)) - assert_syntax_error %({% begin %}\n%q(%t{})\n{% end %}), %(unexpected token: "}") # #16772 + it_parses %({% begin %}\n%q(%t{})\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n%q(".macro_literal, MacroVar.new("t", exps: [] of ASTNode), ")\n".macro_literal] of ASTNode)) it_parses %({% begin %}\n%(%t{})\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n%(%t".macro_literal, "{})\n".macro_literal] of ASTNode)) assert_syntax_error %({% begin %}\n%q(%t{)\n{% end %}), %{unexpected token: ")"} it_parses %({% begin %}\n%(%t{)\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n%(%t".macro_literal, "{)\n".macro_literal] of ASTNode)) @@ -1484,6 +1484,7 @@ module Crystal it_parses "macro foo;%var;end", Macro.new("foo", [] of Arg, Expressions.from([MacroVar.new("var"), MacroLiteral.new(";")] of ASTNode)) it_parses "macro foo;%var{1, x} = hello;end", Macro.new("foo", [] of Arg, Expressions.from([MacroVar.new("var", [1.int32, "x".var] of ASTNode), MacroLiteral.new(" = hello;")] of ASTNode)) + it_parses "macro foo;%var{}end", Macro.new("foo", [] of Arg, Expressions.from([MacroVar.new("var", [] of ASTNode)] of ASTNode)) # #4087 describe "suffix `if`/`unless` in macros after macro var" do diff --git a/spec/compiler/parser/to_s_spec.cr b/spec/compiler/parser/to_s_spec.cr index d5db72d0a9de..060ed87e9835 100644 --- a/spec/compiler/parser/to_s_spec.cr +++ b/spec/compiler/parser/to_s_spec.cr @@ -59,6 +59,7 @@ describe "ASTNode#to_s" do expect_to_s %(macro foo\n %bar = 1\nend) expect_to_s %(macro foo\n %bar = 1; end) expect_to_s %(macro foo\n %bar{1, x} = 1\nend) + expect_to_s %(macro foo\n %bar{}\nend) expect_to_s %({% foo %}) expect_to_s %({{ foo }}) expect_to_s %({% if foo %}\n foo_then\n{% end %}) diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr index a5f449351fba..36ac881a2f38 100644 --- a/src/compiler/crystal/syntax/parser.cr +++ b/src/compiler/crystal/syntax/parser.cr @@ -3325,15 +3325,12 @@ module Crystal next_token exps = [] of ASTNode - while true + while !@token.type.op_rcurly? exps << parse_expression_inside_macro skip_space case @token.type when .op_comma? next_token_skip_space - if @token.type.op_rcurly? - break - end when .op_rcurly? break else