diff --git a/spec/compiler/parser/to_s_spec.cr b/spec/compiler/parser/to_s_spec.cr index a339b120d328..276e0380b9fb 100644 --- a/spec/compiler/parser/to_s_spec.cr +++ b/spec/compiler/parser/to_s_spec.cr @@ -246,7 +246,13 @@ describe "ASTNode#to_s" do expect_to_s "1.+(&block)" expect_to_s "1.//(2, a: 3)" expect_to_s "1.//(2, &block)" - expect_to_s %({% verbatim do %}\n 1{{ 2 }}\n 3{{ 4 }}\n{% end %}) + expect_to_s <<-'CR' + {% verbatim do %} + 1{{ 2 }} + 3{{ 4 }} + {% end %} + CR + expect_to_s %({% for foo in bar %}\n {{ if true\n foo\n bar\nend }}\n{% end %}) expect_to_s "{% a = 1 %}" expect_to_s "{{ a = 1 }}" @@ -256,6 +262,64 @@ describe "ASTNode#to_s" do expect_to_s "{%\n a = 1 %}", "{%\n a = 1\n%}" expect_to_s "{% a = 1\n%}", "{% a = 1 %}" + # FIXME: Should respect significant whitespace + expect_to_s <<-'CR', <<-'CR' + macro finished + {% verbatim do %} + {% + 10 + + # Foo + + 20 + %} + {% end %} + end + CR + macro finished + {% verbatim do %} + {% + 10 + 20 + %} + {% end %} + end + CR + + # FIXME: Should respect significant whitespace + expect_to_s <<-'CR', <<-'CR' + macro finished + {% verbatim do %} + {% + 10 + + # Foo + 20 + %} + {% end %} + end + CR + macro finished + {% verbatim do %} + {% + 10 + 20 + %} + {% end %} + end + CR + + expect_to_s <<-'CR' # , focus: true + macro finished + {% verbatim do %} + {% + 10 + 20 + %} + {% end %} + end + CR + expect_to_s %(asm("nop" ::::)) expect_to_s %(asm("nop" : "a"(1), "b"(2) : "c"(3), "d"(4) : "e", "f" : "volatile", "alignstack", "intel")) expect_to_s %(asm("nop" :: "c"(3), "d"(4) ::)) diff --git a/src/compiler/crystal/syntax/to_s.cr b/src/compiler/crystal/syntax/to_s.cr index a6537027ce5e..8206f92053d2 100644 --- a/src/compiler/crystal/syntax/to_s.cr +++ b/src/compiler/crystal/syntax/to_s.cr @@ -223,7 +223,9 @@ module Crystal else node.expressions.each_with_index do |exp, i| unless exp.nop? - append_indent unless node.keyword.paren? && i == 0 + if !exp.is_a?(MacroLiteral) || !exp.value.blank? + append_indent unless node.keyword.paren? && i == 0 + end exp.accept self newline unless node.keyword.paren? && i == node.expressions.size - 1 end @@ -717,9 +719,11 @@ module Crystal end newline + @indent += 1 inside_macro do accept node.body end + @indent -= 1 # newline append_indent @@ -738,7 +742,7 @@ module Crystal outside_macro do # If the MacroExpression consists of a single node we need to manually handle appending indent and trailing newline if #multiline? # Otherwise, the Expressions logic handles that for us - if !node.exp.is_a? Expressions + if node.multiline? && !node.exp.is_a?(Expressions) append_indent end @@ -747,6 +751,7 @@ module Crystal if node.multiline? @indent -= 1 + append_indent newline if !node.exp.is_a? Expressions end @@ -806,9 +811,13 @@ module Crystal def visit(node : MacroVerbatim) @str << "{% verbatim do %}" + + @indent += 1 inside_macro do node.exp.accept self end + @indent -= 1 + @str << "{% end %}" false end