@@ -40,6 +40,12 @@ private def node_source(string, node)
40
40
source_between(string, node.location, node.end_location)
41
41
end
42
42
43
+ private def assert_location (node : ASTNode , line_number : Int32 , column_number : Int32 )
44
+ location = node.location.should_not be_nil
45
+ location.line_number.should eq line_number
46
+ location.column_number.should eq column_number
47
+ end
48
+
43
49
private def assert_end_location (source , line_number = 1 , column_number = source.size, file = __FILE__ , line = __LINE__ )
44
50
it " gets corrects end location for #{ source.inspect } " , file, line do
45
51
string = " #{ source } ; 1"
@@ -1118,7 +1124,7 @@ module Crystal
1118
1124
it_parses " puts {{**1}}" , Call .new(nil , " puts" , MacroExpression .new(DoubleSplat .new(1 .int32)))
1119
1125
it_parses " {{a = 1 if 2}}" , MacroExpression .new(If .new(2 .int32, Assign .new(" a" .var, 1 .int32)))
1120
1126
it_parses " {% a = 1 %}" , MacroExpression .new(Assign .new(" a" .var, 1 .int32), output: false )
1121
- it_parses " {%\n a = 1\n %}" , MacroExpression .new(Assign .new(" a" .var, 1 .int32), output: false )
1127
+ it_parses " {%\n a = 1\n %}" , MacroExpression .new(Assign .new(" a" .var, 1 .int32), output: false , multiline: true )
1122
1128
it_parses " {% a = 1 if 2 %}" , MacroExpression .new(If .new(2 .int32, Assign .new(" a" .var, 1 .int32)), output: false )
1123
1129
it_parses " {% if 1; 2; end %}" , MacroExpression .new(If .new(1 .int32, 2 .int32), output: false )
1124
1130
it_parses " {%\n if 1; 2; end\n %}" , MacroExpression .new(If .new(1 .int32, 2 .int32), output: false )
@@ -1128,7 +1134,7 @@ module Crystal
1128
1134
it_parses " {% unless 1; 2; else 3; end %}" , MacroExpression .new(Unless .new(1 .int32, 2 .int32, 3 .int32), output: false )
1129
1135
it_parses " {% unless 1\n x\n end %}" , MacroExpression .new(Unless .new(1 .int32, " x" .var), output: false )
1130
1136
it_parses " {% x unless 1 %}" , MacroExpression .new(Unless .new(1 .int32, " x" .var), output: false )
1131
- it_parses " {%\n 1\n 2\n 3\n %}" , MacroExpression .new(Expressions .new([1 .int32, 2 .int32, 3 .int32] of ASTNode ), output: false )
1137
+ it_parses " {%\n 1\n 2\n 3\n %}" , MacroExpression .new(Expressions .new([1 .int32, 2 .int32, 3 .int32] of ASTNode ), output: false , multiline: true )
1132
1138
1133
1139
assert_syntax_error " {% unless 1; 2; elsif 3; 4; end %}"
1134
1140
assert_syntax_error " {% unless 1 %} 2 {% elsif 3 %} 3 {% end %}"
@@ -2772,6 +2778,79 @@ module Crystal
2772
2778
else_node_location.line_number.should eq 7
2773
2779
end
2774
2780
2781
+ it " sets the correct location for MacroExpressions in a MacroVerbatim in a finished hook with significant whitespace" do
2782
+ parser = Parser .new(<<-CR )
2783
+ macro finished
2784
+ {% verbatim do %}
2785
+ {%
2786
+ 10
2787
+
2788
+ # Foo
2789
+
2790
+ 20
2791
+ 30
2792
+
2793
+ # Bar
2794
+
2795
+ 40
2796
+ %}
2797
+
2798
+ {%
2799
+ 50
2800
+ 60
2801
+ %}
2802
+ {% end %}
2803
+ end
2804
+ CR
2805
+
2806
+ node = parser.parse.should be_a Macro
2807
+
2808
+ assert_location node, 1 , 1
2809
+
2810
+ macro_body = node.body.should be_a Expressions
2811
+ verbatim_node = macro_body[1 ].should be_a MacroVerbatim
2812
+
2813
+ expressions = verbatim_node.exp.as(Expressions ).expressions
2814
+ expressions.size.should eq 5
2815
+
2816
+ expressions[0 ].should eq MacroLiteral .new(" \n " )
2817
+ expression = expressions[1 ].should be_a MacroExpression
2818
+
2819
+ macro_expression = expression.exp.as(Expressions ).expressions
2820
+ macro_expression.size.should eq 10
2821
+ macro_expression.select(MacroLiteral ).size.should eq 6
2822
+
2823
+ num = macro_expression[0 ].should be_a NumberLiteral
2824
+ num.value.should eq " 10"
2825
+ assert_location num, 4 , 7
2826
+
2827
+ num = macro_expression[4 ].should be_a NumberLiteral
2828
+ num.value.should eq " 20"
2829
+ assert_location num, 8 , 7
2830
+
2831
+ num = macro_expression[5 ].should be_a NumberLiteral
2832
+ num.value.should eq " 30"
2833
+ assert_location num, 9 , 7
2834
+
2835
+ num = macro_expression[9 ].should be_a NumberLiteral
2836
+ num.value.should eq " 40"
2837
+ assert_location num, 13 , 7
2838
+
2839
+ expression = expressions[3 ].should be_a MacroExpression
2840
+
2841
+ macro_expression = expression.exp.as(Expressions ).expressions
2842
+ macro_expression.size.should eq 2
2843
+ macro_expression.select(MacroLiteral ).size.should eq 0
2844
+
2845
+ num = macro_expression[0 ].should be_a NumberLiteral
2846
+ num.value.should eq " 50"
2847
+ assert_location num, 17 , 7
2848
+
2849
+ num = macro_expression[1 ].should be_a NumberLiteral
2850
+ num.value.should eq " 60"
2851
+ assert_location num, 18 , 7
2852
+ end
2853
+
2775
2854
it " sets correct location of Begin within another node" do
2776
2855
parser = Parser .new(<<-CR )
2777
2856
macro finished
0 commit comments