Skip to content

Commit

Permalink
Merge pull request #930 from ruby/fix-locator
Browse files Browse the repository at this point in the history
Fix RBS::Locator
  • Loading branch information
soutaro committed Mar 20, 2022
2 parents 222a2e4 + 0c67a77 commit 3d6e8c7
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 16 deletions.
3 changes: 2 additions & 1 deletion ext/rbs_extension/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,6 @@ VALUE parse_type_params(parserstate *state, range *rg, bool module_type_params)

parser_advance_assert(state, tUIDENT);
name_range = state->current_token.range;
param_range.end = state->current_token.range.end;

ID id = INTERN_TOKEN(state, state->current_token);
name = ID2SYM(id);
Expand All @@ -1065,6 +1064,8 @@ VALUE parse_type_params(parserstate *state, range *rg, bool module_type_params)
}
}

param_range.end = state->current_token.range.end;

VALUE location = rbs_new_location(state->buffer, param_range);
rbs_loc *loc = rbs_check_location(location);
rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
Expand Down
39 changes: 24 additions & 15 deletions lib/rbs/locator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ def find_in_decl(pos, decl:, array:)
case decl
when AST::Declarations::Class
decl.type_params.each do |param|
if test_loc(pos, location: param.location)
array.unshift(param)
find_in_loc(pos, array: array, location: param.location)
return true
end
find_in_type_param(pos, type_param: param, array: array) and return true
end

if super_class = decl.super_class
Expand All @@ -66,11 +62,7 @@ def find_in_decl(pos, decl:, array:)

when AST::Declarations::Module
decl.type_params.each do |param|
if test_loc(pos, location: param.location)
array.unshift(param)
find_in_loc(pos, array: array, location: param.location)
return true
end
find_in_type_param(pos, type_param: param, array: array) and return true
end

decl.self_types.each do |self_type|
Expand All @@ -91,11 +83,7 @@ def find_in_decl(pos, decl:, array:)

when AST::Declarations::Interface
decl.type_params.each do |param|
if test_loc(pos, location: param.location)
array.unshift(param)
find_in_loc(pos, array: array, location: param.location)
return true
end
find_in_type_param(pos, type_param: param, array: array) and return true
end

decl.members.each do |member|
Expand Down Expand Up @@ -144,6 +132,10 @@ def find_in_method_type(pos, method_type:, array:)
if test_loc(pos, location: method_type.location)
array.unshift(method_type)

method_type.type_params.each do |param|
find_in_type_param(pos, type_param: param, array: array) and return true
end

method_type.each_type do |type|
find_in_type(pos, array: array, type: type) and break
end
Expand All @@ -154,6 +146,23 @@ def find_in_method_type(pos, method_type:, array:)
end
end

def find_in_type_param(pos, type_param:, array:)
if test_loc(pos, location: type_param.location)
array.unshift(type_param)

if upper_bound = type_param.upper_bound
find_in_type(pos, type: upper_bound, array: array) or
find_in_loc(pos, location: type_param.location, array: array)
else
find_in_loc(pos, location: type_param.location, array: array)
end

true
else
false
end
end

def find_in_type(pos, type:, array:)
if test_loc(pos, location: type.location)
array.unshift(type)
Expand Down
2 changes: 2 additions & 0 deletions sig/locator.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ module RBS

def find_in_type: (Integer pos, type: Types::t, array: Array[component]) -> bool

def find_in_type_param: (Integer pos, type_param: AST::TypeParam, array: Array[component]) -> bool

def find_in_loc: (Integer pos, location: Location[untyped, untyped]?, array: Array[component]) -> bool

def test_loc: (Integer pos, location: Location[untyped, untyped]?) -> bool
Expand Down
26 changes: 26 additions & 0 deletions test/rbs/locator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,30 @@ module Foo[A] : Array[A], _Foo
assert_instance_of AST::Declarations::Module, cs[2]
end
end

def test_find_upper_bound
locator = locator(<<RBS)
module Foo[A < Baz]
def bar: [X < Numeric] () -> X
end
RBS

locator.find(line: 1, column: 17).tap do |cs|
assert_equal 4, cs.size
assert_equal :name, cs[0]
assert_instance_of Types::ClassInstance, cs[1]
assert_instance_of AST::TypeParam, cs[2]
assert_instance_of AST::Declarations::Module, cs[3]
end

locator.find(line: 2, column: 18).tap do |cs|
assert_equal 6, cs.size
assert_equal :name, cs[0]
assert_instance_of Types::ClassInstance, cs[1]
assert_instance_of AST::TypeParam, cs[2]
assert_instance_of MethodType, cs[3]
assert_instance_of AST::Members::MethodDefinition, cs[4]
assert_instance_of AST::Declarations::Module, cs[5]
end
end
end

0 comments on commit 3d6e8c7

Please sign in to comment.