From 6fa4f56bc4f2a063ee7eb05c187059ff27aae8db Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Sun, 3 Oct 2021 18:06:36 +0200 Subject: [PATCH] - lexer.rl: Fix handling of beginless ranges at start of line This fixes an issue where beginless ranges at the start of a line would be interpreted as continuing an expression starting on the previous line. Unlike leading dots for method calls, `..` and `...` at the start of a line do not continue an expression from the previous line. --- lib/parser/lexer.rl | 22 ++++++++++++++++++++++ test/test_lexer.rb | 26 ++++++++++++++++++++++++++ test/test_parser.rb | 23 +++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/lib/parser/lexer.rl b/lib/parser/lexer.rl index 718c1d8bf..ef3772dbd 100644 --- a/lib/parser/lexer.rl +++ b/lib/parser/lexer.rl @@ -2513,6 +2513,28 @@ class Parser::Lexer end }; + c_space* '..' + => { + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + fhold; fnext line_begin; fbreak; + else + emit(:tBDOT2) + fnext expr_beg; fbreak; + end + }; + + c_space* '...' + => { + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + fhold; fnext line_begin; fbreak; + else + emit(:tBDOT3) + fnext expr_beg; fbreak; + end + }; + c_space* %{ tm = p } ('.' | '&.') => { p = tm - 1; fgoto expr_end; }; diff --git a/test/test_lexer.rb b/test/test_lexer.rb index 192247718..e0c296dfd 100644 --- a/test/test_lexer.rb +++ b/test/test_lexer.rb @@ -602,10 +602,36 @@ def test_dot def test_dot2 assert_scanned "..", :tDOT2, "..", [0, 2] + refute_scanned("foo\n..42", + :tIDENTIFIER, "foo", [0, 3], + :tNL, nil, [3, 4]) + end + + def test_dot2_27 + setup_lexer 27 + assert_scanned "..", :tBDOT2, "..", [0, 2] + assert_scanned("foo\n..42", + :tIDENTIFIER, "foo", [0, 3], + :tNL, nil, [3, 4], + :tBDOT2, "..", [4, 6], + :tINTEGER, 42, [6, 8]) end def test_dot3 assert_scanned "...", :tDOT3, "...", [0, 3] + refute_scanned("foo\n...42", + :tIDENTIFIER, "foo", [0, 3], + :tNL, nil, [3, 4]) + end + + def test_dot3_27 + setup_lexer 27 + assert_scanned "...", :tBDOT3, "...", [0, 3] + assert_scanned("foo\n...42", + :tIDENTIFIER, "foo", [0, 3], + :tNL, nil, [3, 4], + :tBDOT3, "...", [4, 7], + :tINTEGER, 42, [7, 9]) end def test_equals diff --git a/test/test_parser.rb b/test/test_parser.rb index 2b0cdb509..d195e682f 100644 --- a/test/test_parser.rb +++ b/test/test_parser.rb @@ -911,6 +911,29 @@ def test_beginless_range ) end + def test_beginless_irange_after_newline + assert_parses( + s(:begin, + s(:lvar, :foo), + s(:irange, nil, + s(:int, 100))), + %Q{foo\n..100}, + %q{}, + SINCE_2_7 + ) + end + + def test_beginless_erange_after_newline + assert_parses( + s(:begin, + s(:lvar, :foo), + s(:erange, nil, + s(:int, 100))), + %Q{foo\n...100}, + %q{}, + SINCE_2_7 + ) + end # # Access #