Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle properly stringifying multiline macro expressions #15305

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions spec/compiler/crystal/tools/expand_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ describe "expand" do
{% end %}
CRYSTAL

assert_expand_simple code, "1\n2\n3\n"
assert_expand_simple code, "1\n\n2\n\n3\n"
end

it "expands macro control {% for %} with cursor inside it" do
Expand All @@ -167,7 +167,7 @@ describe "expand" do
{% end %}
CRYSTAL

assert_expand_simple code, "1\n2\n3\n"
assert_expand_simple code, "1\n\n2\n\n3\n"
end

it "expands macro control {% for %} with cursor at end of it" do
Expand All @@ -177,7 +177,7 @@ describe "expand" do
‸{% end %}
CRYSTAL

assert_expand_simple code, "1\n2\n3\n"
assert_expand_simple code, "1\n\n2\n\n3\n"
end

it "expands macro control {% for %} with indent" do
Expand All @@ -195,7 +195,7 @@ describe "expand" do
{% end %}
CRYSTAL

assert_expand_simple code, original: original, expanded: "1\n2\n3\n"
assert_expand_simple code, original: original, expanded: "1\n\n2\n\n3\n"
end

it "expands simple macro" do
Expand Down Expand Up @@ -258,7 +258,7 @@ describe "expand" do
‸foo
CRYSTAL

assert_expand_simple code, original: "foo", expanded: %("if true"\n"1"\n"2"\n"3"\n)
assert_expand_simple code, original: "foo", expanded: %("if true"\n\n\n"1"\n\n"2"\n\n"3"\n)
end

it "expands macros with 2 level" do
Expand Down Expand Up @@ -615,6 +615,7 @@ describe "expand" do
def hello_str
"hello"
end

# symbol of hello
def hello_sym
:hello
Expand Down
140 changes: 140 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,146 @@ module Crystal
location.line_number.should eq 8
end

it "sets correct location for output macro expression in for loop" do
parser = Parser.new(<<-CR)
{% for foo in bar %}
{{ if true
foo
bar
end }}
{% end %}
CR

node = parser.parse.should be_a MacroFor
node = node.body.should be_a Expressions

node = node.expressions[1].should be_a MacroExpression

location = node.location.should_not be_nil
location.line_number.should eq 2
location = node.end_location.should_not be_nil
location.line_number.should eq 5

node = node.exp.should be_a If

location = node.location.should_not be_nil
location.line_number.should eq 2
location = node.end_location.should_not be_nil
location.line_number.should eq 5
end

it "sets correct location for single node within another node" do
parser = Parser.new(<<-CR)
macro finished
{% verbatim do %}
{%

a = 1 %}
{% end %}
end
CR

node = parser.parse.should be_a Macro
node = node.body.should be_a Expressions
node = node.expressions[1].should be_a MacroVerbatim
node = node.exp.should be_a Expressions
node = node.expressions[1].should be_a MacroExpression

location = node.location.should_not be_nil
location.line_number.should eq 3
location = node.end_location.should_not be_nil
location.line_number.should eq 5

assign = node.exp.should be_a Assign

location = assign.location.should_not be_nil
location.line_number.should eq 5
location = assign.end_location.should_not be_nil
location.line_number.should eq 5

target = assign.target.should be_a Var

location = target.location.should_not be_nil
location.line_number.should eq 5
location = target.end_location.should_not be_nil
location.line_number.should eq 5

value = assign.value.should be_a NumberLiteral

location = value.location.should_not be_nil
location.line_number.should eq 5
location = value.end_location.should_not be_nil
location.line_number.should eq 5
end

it "sets correct location for multiple nodes within another node" do
parser = Parser.new(<<-CR)
macro finished
{% verbatim do %}
{%


a = 1
b = 2 %}
{% end %}
end
CR

node = parser.parse.should be_a Macro
node = node.body.should be_a Expressions
node = node.expressions[1].should be_a MacroVerbatim
node = node.exp.should be_a Expressions
node = node.expressions[1].should be_a MacroExpression

location = node.location.should_not be_nil
location.line_number.should eq 3
location = node.end_location.should_not be_nil
location.line_number.should eq 7

node = node.exp.should be_a Expressions
assign = node.expressions[0].should be_a Assign

location = assign.location.should_not be_nil
location.line_number.should eq 6
location = assign.end_location.should_not be_nil
location.line_number.should eq 6

target = assign.target.should be_a Var

location = target.location.should_not be_nil
location.line_number.should eq 6
location = target.end_location.should_not be_nil
location.line_number.should eq 6

value = assign.value.should be_a NumberLiteral

location = value.location.should_not be_nil
location.line_number.should eq 6
location = value.end_location.should_not be_nil
location.line_number.should eq 6

assign = node.expressions[1].should be_a Assign

location = assign.location.should_not be_nil
location.line_number.should eq 7
location = assign.end_location.should_not be_nil
location.line_number.should eq 7

target = assign.target.should be_a Var

location = target.location.should_not be_nil
location.line_number.should eq 7
location = target.end_location.should_not be_nil
location.line_number.should eq 7

value = assign.value.should be_a NumberLiteral

location = value.location.should_not be_nil
location.line_number.should eq 7
location = value.end_location.should_not be_nil
location.line_number.should eq 7
end

it "sets correct location of trailing ensure" do
parser = Parser.new("foo ensure bar")
node = parser.parse.as(ExceptionHandler)
Expand Down
Loading