From 79641c7ac6291ab709470ff0fdb22364b534b807 Mon Sep 17 00:00:00 2001 From: George Dietrich Date: Mon, 23 Dec 2024 10:37:19 -0500 Subject: [PATCH] Handle emitting significant whitespace as well --- spec/compiler/parser/to_s_spec.cr | 15 +++++++++------ src/compiler/crystal/syntax/to_s.cr | 27 ++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/spec/compiler/parser/to_s_spec.cr b/spec/compiler/parser/to_s_spec.cr index ed28ecd55dd1..3ea28be4e46e 100644 --- a/spec/compiler/parser/to_s_spec.cr +++ b/spec/compiler/parser/to_s_spec.cr @@ -1,7 +1,7 @@ require "../../support/syntax" -private def expect_to_s(original, expected = original, emit_doc = false, file = __FILE__, line = __LINE__) - it "does to_s of #{original.inspect}", file, line do +private def expect_to_s(original, expected = original, emit_doc = false, file = __FILE__, line = __LINE__, focus = false) + it "does to_s of #{original.inspect}", file, line, focus: focus do str = IO::Memory.new expected.bytesize source = original @@ -262,8 +262,7 @@ 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' + expect_to_s <<-'CR', <<-CR macro finished {% verbatim do %} {% @@ -280,14 +279,16 @@ describe "ASTNode#to_s" do {% verbatim do %} {% 10 + + + 20 %} {% end %} end CR - # FIXME: Should respect significant whitespace - expect_to_s <<-'CR', <<-'CR' + expect_to_s <<-'CR', <<-CR macro finished {% verbatim do %} {% @@ -303,6 +304,8 @@ describe "ASTNode#to_s" do {% verbatim do %} {% 10 + + 20 %} {% end %} diff --git a/src/compiler/crystal/syntax/to_s.cr b/src/compiler/crystal/syntax/to_s.cr index d30e2dd52d7f..5d8d28820c68 100644 --- a/src/compiler/crystal/syntax/to_s.cr +++ b/src/compiler/crystal/syntax/to_s.cr @@ -55,6 +55,21 @@ module Crystal true end + private def add_whitespace_around(first_node_location : Location?, second_node_location : Location?, &) : Nil + # If any location information is missing, don't add any extra newlines. + if !first_node_location || !second_node_location + yield + return + end + + # Only emit extra newlines. I.e. those more than the first handled via the Expressions visitor. + ((second_node_location.line_number - 1) - first_node_location.line_number).times do + newline + end + + yield + end + def visit(node : Nop) false end @@ -221,11 +236,17 @@ module Crystal if @inside_macro > 0 node.expressions.each &.accept self else + last_node = node.expressions.first + node.expressions.each_with_index do |exp, i| unless exp.nop? - append_indent unless node.keyword.paren? && i == 0 - exp.accept self - newline unless node.keyword.paren? && i == node.expressions.size - 1 + self.add_whitespace_around last_node.end_location, exp.location do + append_indent unless node.keyword.paren? && i == 0 + exp.accept self + newline unless node.keyword.paren? && i == node.expressions.size - 1 + end + + last_node = exp end end end