Class: RBS::Locator
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rbs/locator.rb |
Class Method Summary
- .new(buffer:, dirs:, decls:) ⇒ Locator constructor
Instance Attribute Summary
Instance Method Summary
- #find(line:, column:)
- #find2(line:, column:)
- #find_in_decl(pos, decl:, array:)
- #find_in_directive(pos, dir, array)
- #find_in_loc(pos, location:, array:)
- #find_in_member(pos, member:, array:)
- #find_in_method_type(pos, method_type:, array:)
- #find_in_type(pos, type:, array:)
- #find_in_type_param(pos, type_param:, array:)
- #test_loc(pos, location:)
Constructor Details
.new(buffer:, dirs:, decls:) ⇒ Locator
Instance Attribute Details
#buffer (readonly)
[ GitHub ]#decls (readonly)
[ GitHub ]#dirs (readonly)
[ GitHub ]Instance Method Details
#find(line:, column:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 13
def find(line:, column:) pos = buffer.loc_to_pos([line, column]) dirs.each do |dir| array = [] #: Array[component] find_in_directive(pos, dir, array) and return array end decls.each do |decl| array = [] #: Array[component] find_in_decl(pos, decl: decl, array: array) and return array end [] end
#find2(line:, column:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 29
def find2(line:, column:) path = find(line: line, column: column) return if path.empty? hd, *tl = path if hd.is_a?(Symbol) [hd, tl] else [nil, path] end end
#find_in_decl(pos, decl:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 58
def find_in_decl(pos, decl:, array:) if test_loc(pos, location: decl.location) array.unshift(decl) case decl when AST::Declarations::Class decl.type_params.each do |param| find_in_type_param(pos, type_param: param, array: array) and return true end if super_class = decl.super_class if test_loc(pos, location: super_class.location) array.unshift(super_class) find_in_loc(pos, array: array, location: super_class.location) return true end end decl.each_decl do |decl_| find_in_decl(pos, decl: decl_, array: array) and return true end decl.each_member do |member| find_in_member(pos, array: array, member: member) and return true end when AST::Declarations::Module decl.type_params.each do |param| find_in_type_param(pos, type_param: param, array: array) and return true end decl.self_types.each do |self_type| if test_loc(pos, location: self_type.location) array.unshift(self_type) find_in_loc(pos, array: array, location: self_type.location) return true end end decl.each_decl do |decl_| find_in_decl(pos, decl: decl_, array: array) and return true end decl.each_member do |member| find_in_member(pos, array: array, member: member) and return true end when AST::Declarations::Interface decl.type_params.each do |param| find_in_type_param(pos, type_param: param, array: array) and return true end decl.members.each do |member| find_in_member(pos, array: array, member: member) and return true end when AST::Declarations::Constant, AST::Declarations::Global find_in_type(pos, array: array, type: decl.type) and return true when AST::Declarations::TypeAlias find_in_type(pos, array: array, type: decl.type) and return true end find_in_loc(pos, location: decl.location, array: array) true else false end end
#find_in_directive(pos, dir, array)
[ GitHub ]# File 'lib/rbs/locator.rb', line 42
def find_in_directive(pos, dir, array) if test_loc(pos, location: dir.location) array.unshift(dir) dir.clauses.each do |clause| if test_loc(pos, location: clause.location) array.unshift(clause) find_in_loc(pos, location: clause.location, array: array) return true end end end false end
#find_in_loc(pos, location:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 203
def find_in_loc(pos, location:, array:) if test_loc(pos, location: location) if location.is_a?(Location) location.each_optional_key do |key| if loc = location[key] if loc.range === pos array.unshift(key) return true end end end location.each_required_key do |key| loc = location[key] or raise if loc.range === pos array.unshift(key) return true end end end true else false end end
#find_in_member(pos, member:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 129
def find_in_member(pos, member:, array:) if test_loc(pos, location: member.location) array.unshift(member) case member when AST::Members::MethodDefinition member.overloads.each do |overload| find_in_method_type(pos, array: array, method_type: overload.method_type) and return true end when AST::Members::InstanceVariable, AST::Members::ClassInstanceVariable, AST::Members::ClassVariable find_in_type(pos, array: array, type: member.type) and return true when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor find_in_type(pos, array: array, type: member.type) and return true end find_in_loc(pos, location: member.location, array: array) true else false end end
#find_in_method_type(pos, method_type:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 152
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 true else false end end
#find_in_type(pos, type:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 187
def find_in_type(pos, type:, array:) if test_loc(pos, location: type.location) array.unshift(type) type.each_type do |type_| find_in_type(pos, array: array, type: type_) and return true end find_in_loc(pos, array: array, location: type.location) true else false end end
#find_in_type_param(pos, type_param:, array:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 170
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
#test_loc(pos, location:)
[ GitHub ]# File 'lib/rbs/locator.rb', line 230
def test_loc(pos, location:) if location location.range === pos else false end end