lib/ruby_indexer/lib/ruby_indexer/entry.rb in ruby-lsp-0.17.4 vs lib/ruby_indexer/lib/ruby_indexer/entry.rb in ruby-lsp-0.17.5
- old
+ new
@@ -20,10 +20,12 @@
attr_reader :file_path
sig { returns(RubyIndexer::Location) }
attr_reader :location
+ alias_method :name_location, :location
+
sig { returns(T::Array[String]) }
attr_reader :comments
sig { returns(Visibility) }
attr_accessor :visibility
@@ -56,10 +58,20 @@
RubyIndexer::Location,
)
end
sig { returns(T::Boolean) }
+ def public?
+ visibility == Visibility::PUBLIC
+ end
+
+ sig { returns(T::Boolean) }
+ def protected?
+ visibility == Visibility::PROTECTED
+ end
+
+ sig { returns(T::Boolean) }
def private?
visibility == Visibility::PRIVATE
end
sig { returns(String) }
@@ -82,35 +94,53 @@
end
end
class Include < ModuleOperation; end
class Prepend < ModuleOperation; end
- class Extend < ModuleOperation; end
class Namespace < Entry
extend T::Sig
extend T::Helpers
abstract!
sig { returns(T::Array[String]) }
attr_reader :nesting
+ # Returns the location of the constant name, excluding the parent class or the body
+ sig { returns(Location) }
+ attr_reader :name_location
+
sig do
params(
nesting: T::Array[String],
file_path: String,
location: T.any(Prism::Location, RubyIndexer::Location),
+ name_location: T.any(Prism::Location, Location),
comments: T::Array[String],
).void
end
- def initialize(nesting, file_path, location, comments)
+ def initialize(nesting, file_path, location, name_location, comments)
@name = T.let(nesting.join("::"), String)
# The original nesting where this namespace was discovered
@nesting = nesting
super(@name, file_path, location, comments)
+
+ @name_location = T.let(
+ if name_location.is_a?(Prism::Location)
+ Location.new(
+ name_location.start_line,
+ name_location.end_line,
+ name_location.start_column,
+ name_location.end_column,
+ )
+ else
+ name_location
+ end,
+ RubyIndexer::Location,
+ )
end
sig { returns(T::Array[String]) }
def mixin_operation_module_names
mixin_operations.map(&:module_name)
@@ -144,16 +174,17 @@
sig do
params(
nesting: T::Array[String],
file_path: String,
location: T.any(Prism::Location, RubyIndexer::Location),
+ name_location: T.any(Prism::Location, Location),
comments: T::Array[String],
parent_class: T.nilable(String),
).void
end
- def initialize(nesting, file_path, location, comments, parent_class)
- super(nesting, file_path, location, comments)
+ def initialize(nesting, file_path, location, name_location, comments, parent_class) # rubocop:disable Metrics/ParameterLists
+ super(nesting, file_path, location, name_location, comments)
@parent_class = parent_class
end
sig { override.returns(Integer) }
def ancestor_hash
@@ -162,19 +193,25 @@
end
class SingletonClass < Class
extend T::Sig
- sig { params(location: Prism::Location, comments: T::Array[String]).void }
- def update_singleton_information(location, comments)
+ sig { params(location: Prism::Location, name_location: Prism::Location, comments: T::Array[String]).void }
+ def update_singleton_information(location, name_location, comments)
# Create a new RubyIndexer::Location object from the Prism location
@location = Location.new(
location.start_line,
location.end_line,
location.start_column,
location.end_column,
)
+ @name_location = Location.new(
+ name_location.start_line,
+ name_location.end_line,
+ name_location.start_column,
+ name_location.end_column,
+ )
@comments.concat(comments)
end
end
class Constant < Entry
@@ -264,10 +301,15 @@
abstract!
sig { returns(T.nilable(Entry::Namespace)) }
attr_reader :owner
+ sig { returns(T::Array[RubyIndexer::Entry::Parameter]) }
+ def parameters
+ T.must(signatures.first).parameters
+ end
+
sig do
params(
name: String,
file_path: String,
location: T.any(Prism::Location, RubyIndexer::Location),
@@ -280,51 +322,76 @@
super(name, file_path, location, comments)
@visibility = visibility
@owner = owner
end
- sig { abstract.returns(T::Array[Parameter]) }
- def parameters; end
+ sig { abstract.returns(T::Array[Entry::Signature]) }
+ def signatures; end
- # Returns a string with the decorated names of the parameters of this member. E.g.: `(a, b = 1, c: 2)`
sig { returns(String) }
def decorated_parameters
- "(#{parameters.map(&:decorated_name).join(", ")})"
+ first_signature = signatures.first
+ return "()" unless first_signature
+
+ "(#{first_signature.format})"
end
end
class Accessor < Member
extend T::Sig
- sig { override.returns(T::Array[Parameter]) }
- def parameters
- params = []
- params << RequiredParameter.new(name: name.delete_suffix("=").to_sym) if name.end_with?("=")
- params
+ sig { override.returns(T::Array[Signature]) }
+ def signatures
+ @signatures ||= T.let(
+ begin
+ params = []
+ params << RequiredParameter.new(name: name.delete_suffix("=").to_sym) if name.end_with?("=")
+ [Entry::Signature.new(params)]
+ end,
+ T.nilable(T::Array[Signature]),
+ )
end
end
class Method < Member
extend T::Sig
- sig { override.returns(T::Array[Parameter]) }
- attr_reader :parameters
+ sig { override.returns(T::Array[Signature]) }
+ attr_reader :signatures
+ # Returns the location of the method name, excluding parameters or the body
+ sig { returns(Location) }
+ attr_reader :name_location
+
sig do
params(
name: String,
file_path: String,
location: T.any(Prism::Location, RubyIndexer::Location),
+ name_location: T.any(Prism::Location, Location),
comments: T::Array[String],
- parameters: T::Array[Parameter],
+ signatures: T::Array[Signature],
visibility: Visibility,
owner: T.nilable(Entry::Namespace),
).void
end
- def initialize(name, file_path, location, comments, parameters, visibility, owner) # rubocop:disable Metrics/ParameterLists
+ def initialize(name, file_path, location, name_location, comments, signatures, visibility, owner) # rubocop:disable Metrics/ParameterLists
super(name, file_path, location, comments, visibility, owner)
- @parameters = parameters
+ @signatures = signatures
+ @name_location = T.let(
+ if name_location.is_a?(Prism::Location)
+ Location.new(
+ name_location.start_line,
+ name_location.end_line,
+ name_location.start_column,
+ name_location.end_column,
+ )
+ else
+ name_location
+ end,
+ RubyIndexer::Location,
+ )
end
end
# An UnresolvedAlias points to a constant alias with a right hand side that has not yet been resolved. For
# example, if we find
@@ -435,10 +502,13 @@
extend T::Sig
sig { returns(T.any(Member, MethodAlias)) }
attr_reader :target
+ sig { returns(T.nilable(Entry::Namespace)) }
+ attr_reader :owner
+
sig { params(target: T.any(Member, MethodAlias), unresolved_alias: UnresolvedMethodAlias).void }
def initialize(target, unresolved_alias)
full_comments = ["Alias for #{target.name}\n"]
full_comments.concat(unresolved_alias.comments)
full_comments << "\n"
@@ -450,24 +520,41 @@
unresolved_alias.location,
full_comments,
)
@target = target
+ @owner = T.let(unresolved_alias.owner, T.nilable(Entry::Namespace))
end
- sig { returns(T.nilable(Entry::Namespace)) }
- def owner
- @target.owner
- end
-
sig { returns(T::Array[Parameter]) }
def parameters
@target.parameters
end
sig { returns(String) }
def decorated_parameters
@target.decorated_parameters
+ end
+ end
+
+ # Ruby doesn't support method overloading, so a method will have only one signature.
+ # However RBS can represent the concept of method overloading, with different return types based on the arguments
+ # passed, so we need to store all the signatures.
+ class Signature
+ extend T::Sig
+
+ sig { returns(T::Array[Parameter]) }
+ attr_reader :parameters
+
+ sig { params(parameters: T::Array[Parameter]).void }
+ def initialize(parameters)
+ @parameters = parameters
+ end
+
+ # Returns a string with the decorated names of the parameters of this member. E.g.: `(a, b = 1, c: 2)`
+ sig { returns(String) }
+ def format
+ @parameters.map(&:decorated_name).join(", ")
end
end
end
end