Skip to content

Commit

Permalink
Apply changes from crystal-lang#15305
Browse files Browse the repository at this point in the history
  • Loading branch information
Blacksmoke16 committed Dec 21, 2024
1 parent 453e84d commit 131c7f0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 86 deletions.
83 changes: 2 additions & 81 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ private def node_source(string, node)
source_between(string, node.location, node.end_location)
end

private def assert_location(node : ASTNode, line_number : Int32, column_number : Int32)
location = node.location.should_not be_nil
location.line_number.should eq line_number
location.column_number.should eq column_number
end

private def assert_end_location(source, line_number = 1, column_number = source.size, file = __FILE__, line = __LINE__)
it "gets corrects end location for #{source.inspect}", file, line do
string = "#{source}; 1"
Expand Down Expand Up @@ -1124,7 +1118,7 @@ module Crystal
it_parses "puts {{**1}}", Call.new(nil, "puts", MacroExpression.new(DoubleSplat.new(1.int32)))
it_parses "{{a = 1 if 2}}", MacroExpression.new(If.new(2.int32, Assign.new("a".var, 1.int32)))
it_parses "{% a = 1 %}", MacroExpression.new(Assign.new("a".var, 1.int32), output: false)
it_parses "{%\na = 1\n%}", MacroExpression.new(Assign.new("a".var, 1.int32), output: false, multiline: true)
it_parses "{%\na = 1\n%}", MacroExpression.new(Assign.new("a".var, 1.int32), output: false)
it_parses "{% a = 1 if 2 %}", MacroExpression.new(If.new(2.int32, Assign.new("a".var, 1.int32)), output: false)
it_parses "{% if 1; 2; end %}", MacroExpression.new(If.new(1.int32, 2.int32), output: false)
it_parses "{%\nif 1; 2; end\n%}", MacroExpression.new(If.new(1.int32, 2.int32), output: false)
Expand All @@ -1134,7 +1128,7 @@ module Crystal
it_parses "{% unless 1; 2; else 3; end %}", MacroExpression.new(Unless.new(1.int32, 2.int32, 3.int32), output: false)
it_parses "{% unless 1\n x\nend %}", MacroExpression.new(Unless.new(1.int32, "x".var), output: false)
it_parses "{% x unless 1 %}", MacroExpression.new(Unless.new(1.int32, "x".var), output: false)
it_parses "{%\n1\n2\n3\n%}", MacroExpression.new(Expressions.new([1.int32, 2.int32, 3.int32] of ASTNode), output: false, multiline: true)
it_parses "{%\n1\n2\n3\n%}", MacroExpression.new(Expressions.new([1.int32, 2.int32, 3.int32] of ASTNode), output: false)

assert_syntax_error "{% unless 1; 2; elsif 3; 4; end %}"
assert_syntax_error "{% unless 1 %} 2 {% elsif 3 %} 3 {% end %}"
Expand Down Expand Up @@ -2778,79 +2772,6 @@ module Crystal
else_node_location.line_number.should eq 7
end

it "sets the correct location for MacroExpressions in a MacroVerbatim in a finished hook with significant whitespace" do
parser = Parser.new(<<-CR)
macro finished
{% verbatim do %}
{%
10
# Foo
20
30
# Bar
40
%}
{%
50
60
%}
{% end %}
end
CR

node = parser.parse.should be_a Macro

assert_location node, 1, 1

macro_body = node.body.should be_a Expressions
verbatim_node = macro_body[1].should be_a MacroVerbatim

expressions = verbatim_node.exp.as(Expressions).expressions
expressions.size.should eq 5

expressions[0].should eq MacroLiteral.new("\n ")
expression = expressions[1].should be_a MacroExpression

macro_expression = expression.exp.as(Expressions).expressions
macro_expression.size.should eq 10
macro_expression.select(MacroLiteral).size.should eq 6

num = macro_expression[0].should be_a NumberLiteral
num.value.should eq "10"
assert_location num, 4, 7

num = macro_expression[4].should be_a NumberLiteral
num.value.should eq "20"
assert_location num, 8, 7

num = macro_expression[5].should be_a NumberLiteral
num.value.should eq "30"
assert_location num, 9, 7

num = macro_expression[9].should be_a NumberLiteral
num.value.should eq "40"
assert_location num, 13, 7

expression = expressions[3].should be_a MacroExpression

macro_expression = expression.exp.as(Expressions).expressions
macro_expression.size.should eq 2
macro_expression.select(MacroLiteral).size.should eq 0

num = macro_expression[0].should be_a NumberLiteral
num.value.should eq "50"
assert_location num, 17, 7

num = macro_expression[1].should be_a NumberLiteral
num.value.should eq "60"
assert_location num, 18, 7
end

it "sets correct location of Begin within another node" do
parser = Parser.new(<<-CR)
macro finished
Expand Down
25 changes: 20 additions & 5 deletions src/compiler/crystal/syntax/to_s.cr
Original file line number Diff line number Diff line change
Expand Up @@ -728,14 +728,29 @@ module Crystal
end

def visit(node : MacroExpression)
@str << (node.output? ? "{{" : "{% ")
@str << ' ' if node.output?
newline if node.multiline?
@str << (node.output? ? "{{ " : node.multiline? ? "{%" : "{% ")

if node.multiline?
newline
@indent += 1
end

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
append_indent
end

node.exp.accept self
end
@str << ' ' if node.output?
@str << (node.output? ? "}}" : " %}")

if node.multiline?
@indent -= 1
newline if !node.exp.is_a? Expressions
end

@str << (node.output? ? " }}" : node.multiline? ? "%}" : " %}")
false
end

Expand Down

0 comments on commit 131c7f0

Please sign in to comment.