Skip to content
Merged
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
20 changes: 10 additions & 10 deletions lib/error_highlight/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def spot_call_for_name
nd_recv, mid, nd_args = @node.children
lineno = nd_recv.last_lineno
lines = @fetch[lineno, @node.last_lineno]
if mid == :[] && lines.match(/\G\s*(\[(?:\s*\])?)/, nd_recv.last_column)
if mid == :[] && lines.match(/\G[\s)]*(\[(?:\s*\])?)/, nd_recv.last_column)
@beg_column = $~.begin(1)
@snippet = lines[/.*\n/]
@beg_lineno = @end_lineno = lineno
Expand All @@ -143,11 +143,11 @@ def spot_call_for_name
@end_column = $~.end(0)
end
else
if lines.match(/\G\s*?\[\s*\]/, nd_recv.last_column)
if lines.match(/\G[\s)]*?\[\s*\]/, nd_recv.last_column)
@end_column = $~.end(0)
end
end
elsif lines.match(/\G\s*?(\&?\.)(\s*?)(#{ Regexp.quote(mid) }).*\n/, nd_recv.last_column)
elsif lines.match(/\G[\s)]*?(\&?\.)(\s*?)(#{ Regexp.quote(mid) }).*\n/, nd_recv.last_column)
lines = $` + $&
@beg_column = $~.begin($2.include?("\n") ? 3 : 1)
@end_column = $~.end(3)
Expand Down Expand Up @@ -193,16 +193,16 @@ def spot_attrasgn_for_name
nd_recv, mid, nd_args = @node.children
*nd_args, _nd_last_arg, _nil = nd_args.children
fetch_line(nd_recv.last_lineno)
if mid == :[]= && @snippet.match(/\G\s*(\[)/, nd_recv.last_column)
if mid == :[]= && @snippet.match(/\G[\s)]*(\[)/, nd_recv.last_column)
@beg_column = $~.begin(1)
args_last_column = $~.end(0)
if nd_args.last && nd_recv.last_lineno == nd_args.last.last_lineno
args_last_column = nd_args.last.last_column
end
if @snippet.match(/\s*\]\s*=/, args_last_column)
if @snippet.match(/[\s)]*\]\s*=/, args_last_column)
@end_column = $~.end(0)
end
elsif @snippet.match(/\G\s*(\.\s*#{ Regexp.quote(mid.to_s.sub(/=\z/, "")) }\s*=)/, nd_recv.last_column)
elsif @snippet.match(/\G[\s)]*(\.\s*#{ Regexp.quote(mid.to_s.sub(/=\z/, "")) }\s*=)/, nd_recv.last_column)
@beg_column = $~.begin(1)
@end_column = $~.end(1)
end
Expand All @@ -218,7 +218,7 @@ def spot_attrasgn_for_name
def spot_attrasgn_for_args
nd_recv, mid, nd_args = @node.children
fetch_line(nd_recv.last_lineno)
if mid == :[]= && @snippet.match(/\G\s*\[/, nd_recv.last_column)
if mid == :[]= && @snippet.match(/\G[\s)]*\[/, nd_recv.last_column)
@beg_column = $~.end(0)
if nd_recv.last_lineno == nd_args.last_lineno
@end_column = nd_args.last_column
Expand All @@ -240,7 +240,7 @@ def spot_opcall_for_name
fetch_line(nd_recv.last_lineno)
if nd_arg
# binary operator
if @snippet.match(/\G\s*(#{ Regexp.quote(op) })/, nd_recv.last_column)
if @snippet.match(/\G[\s)]*(#{ Regexp.quote(op) })/, nd_recv.last_column)
@beg_column = $~.begin(1)
@end_column = $~.end(1)
end
Expand Down Expand Up @@ -316,7 +316,7 @@ def spot_vcall
def spot_op_asgn1_for_name
nd_recv, op, nd_args, _nd_rhs = @node.children
fetch_line(nd_recv.last_lineno)
if @snippet.match(/\G\s*(\[)/, nd_recv.last_column)
if @snippet.match(/\G[\s)]*(\[)/, nd_recv.last_column)
bracket_beg_column = $~.begin(1)
args_last_column = $~.end(0)
if nd_args && nd_recv.last_lineno == nd_args.last_lineno
Expand Down Expand Up @@ -363,7 +363,7 @@ def spot_op_asgn1_for_args
def spot_op_asgn2_for_name
nd_recv, _qcall, attr, op, _nd_rhs = @node.children
fetch_line(nd_recv.last_lineno)
if @snippet.match(/\G\s*(\.)\s*#{ Regexp.quote(attr) }()\s*(#{ Regexp.quote(op) })(=)/, nd_recv.last_column)
if @snippet.match(/\G[\s)]*(\.)\s*#{ Regexp.quote(attr) }()\s*(#{ Regexp.quote(op) })(=)/, nd_recv.last_column)
case @name
when attr
@beg_column = $~.begin(1)
Expand Down
162 changes: 161 additions & 1 deletion test/test_error_highlight.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ def test_CALL_noarg_3
end
end

def test_CALL_noarg_4
assert_error_message(NoMethodError, <<~END) do
undefined method `foo' for nil:NilClass

(nil).foo + 1
^^^^
END

(nil).foo + 1
end
end

def test_CALL_arg_1
assert_error_message(NoMethodError, <<~END) do
undefined method `foo' for nil:NilClass
Expand Down Expand Up @@ -221,6 +233,18 @@ def test_CALL_aref_4
end
end

def test_CALL_aref_5
assert_error_message(NoMethodError, <<~END) do
undefined method `[]' for nil:NilClass

(nil)[ ]
^^^
END

(nil)[ ]
end
end

def test_CALL_aset
assert_error_message(NoMethodError, <<~END) do
undefined method `[]=' for nil:NilClass
Expand Down Expand Up @@ -312,6 +336,30 @@ def test_ATTRASGN_3
end
end

def test_ATTRASGN_4
assert_error_message(NoMethodError, <<~END) do
undefined method `[]=' for nil:NilClass

(nil)[0] = 42
^^^^^
END

(nil)[0] = 42
end
end

def test_ATTRASGN_5
assert_error_message(NoMethodError, <<~END) do
undefined method `foo=' for nil:NilClass

(nil).foo = 42
^^^^^^
END

(nil).foo = 42
end
end

def test_OPCALL_binary_1
assert_error_message(NoMethodError, <<~END) do
undefined method `+' for nil:NilClass
Expand All @@ -337,7 +385,19 @@ def test_OPCALL_binary_2
end
end

def test_OPCALL_unary
def test_OPCALL_binary_3
assert_error_message(NoMethodError, <<~END) do
undefined method `+' for nil:NilClass

(nil) + 42
^
END

(nil) + 42
end
end

def test_OPCALL_unary_1
assert_error_message(NoMethodError, <<~END) do
undefined method `+@' for nil:NilClass

Expand All @@ -349,6 +409,18 @@ def test_OPCALL_unary
end
end

def test_OPCALL_unary_2
assert_error_message(NoMethodError, <<~END) do
undefined method `+@' for nil:NilClass

+(nil)
^
END

+(nil)
end
end

def test_FCALL_1
assert_error_message(NoMethodError, <<~END) do
undefined method `foo' for nil:NilClass
Expand Down Expand Up @@ -428,6 +500,20 @@ def test_OP_ASGN1_aref_3
end
end

def test_OP_ASGN1_aref_4
v = nil

assert_error_message(NoMethodError, <<~END) do
undefined method `[]' for nil:NilClass

(v)[0] += 42
^^^
END

(v)[0] += 42
end
end

def test_OP_ASGN1_op_1
v = Object.new
def v.[](x); nil; end
Expand Down Expand Up @@ -474,6 +560,21 @@ def v.[](x); nil; end
end
end

def test_OP_ASGN1_op_4
v = Object.new
def v.[](x); nil; end

assert_error_message(NoMethodError, <<~END) do
undefined method `+' for nil:NilClass

(v)[0] += 42
^
END

(v)[0] += 42
end
end

def test_OP_ASGN1_aset_1
v = Object.new
def v.[](x); 1; end
Expand Down Expand Up @@ -520,6 +621,21 @@ def v.[](x); 1; end
end
end

def test_OP_ASGN1_aset_4
v = Object.new
def v.[](x); 1; end

assert_error_message(NoMethodError, <<~END) do
undefined method `[]=' for #{ v.inspect }

(v)[0] += 42
^^^^^^
END

(v)[0] += 42
end
end

def test_OP_ASGN2_read_1
v = nil

Expand Down Expand Up @@ -549,6 +665,20 @@ def test_OP_ASGN2_read_2
end
end

def test_OP_ASGN2_read_3
v = nil

assert_error_message(NoMethodError, <<~END) do
undefined method `foo' for nil:NilClass

(v).foo += 42
^^^^
END

(v).foo += 42
end
end

def test_OP_ASGN2_op_1
v = Object.new
def v.foo; nil; end
Expand Down Expand Up @@ -580,6 +710,21 @@ def v.foo; nil; end
end
end

def test_OP_ASGN2_op_3
v = Object.new
def v.foo; nil; end

assert_error_message(NoMethodError, <<~END) do
undefined method `+' for nil:NilClass

(v).foo += 42
^
END

(v).foo += 42
end
end

def test_OP_ASGN2_write_1
v = Object.new
def v.foo; 1; end
Expand Down Expand Up @@ -611,6 +756,21 @@ def v.foo; 1; end
end
end

def test_OP_ASGN2_write_3
v = Object.new
def v.foo; 1; end

assert_error_message(NoMethodError, <<~END) do
undefined method `foo=' for #{ v.inspect }

(v).foo += 42
^^^^^^^
END

(v).foo += 42
end
end

def test_CONST
assert_error_message(NameError, <<~END) do
uninitialized constant ErrorHighlightTest::NotDefined
Expand Down