lib/inch/language/ruby/provider/yard/object/method_object.rb
require 'inch/language/ruby/provider/yard/object/method_signature'
module Inch
module Language
module Ruby
module Provider
module YARD
module Object
# Proxy class for methods
class MethodObject < Base
UNUSABLE_RETURN_VALUES = %w(nil nothing undefined void)
def aliases_fullnames
object.aliases.map(&:path)
end
def bang_name?
name =~ /\!$/
end
def constructor?
name == :initialize
end
def getter?
attr_info = object.attr_info || {}
read_info = attr_info[:read]
if read_info
read_info.path == fullname
else
parent.child(:"#{name}=")
end
end
def has_code_example?
signatures.any? { |s| s.has_code_example? }
end
def has_doc?
signatures.any? { |s| s.has_doc? }
end
def method?
true
end
def parameters
@parameters ||= signatures.map(&:parameters).flatten
end
def parameter(name)
parameters.find { |p| p.name == name.to_s }
end
# Returns the original docstring unless it was generated by YARD.
# @return [String]
def original_docstring
implicit_docstring? ? "" : super
end
def overridden?
!!object.overridden_method
end
def overridden_method
return unless overridden?
@overridden_method ||= YARD::Object.for(object.overridden_method)
end
def overridden_method_fullname
return unless overridden?
overridden_method.fullname
end
# Returns +true+ if a return value is described by it's type or
# mentioned in the docstring (e.g. "Returns a String").
def return_mentioned?
return_tags.any? do |t|
!t.types.nil? && !t.types.empty? &&
!YARD.implicit_tag?(t, self)
end || docstring.mentions_return? && !implicit_docstring?
end
# Returns +true+ if a return value is described by words.
def return_described?
return_described_via_tag? ||
docstring.describes_return? && !implicit_docstring?
end
def return_typed?
return_mentioned?
end
def setter?
name =~ /\=$/ && parameters.size == 1
end
def signatures
base = MethodSignature.new(self, nil)
overloaded = overload_tags.map do |tag|
MethodSignature.new(self, tag)
end
if overloaded.any? { |s| s.same?(base) }
overloaded
else
[base] + overloaded
end
end
def questioning_name?
name =~ /\?$/
end
private
# Returns @return tags that are assigned to the getter
# corresponding to this setter.
#
# @return [Array<::YARD::Tag>]
def attributed_return_tags
if setter? && object.tags(:return).empty?
method = corresponding_getter
return method.object.tags(:return) if method
end
[]
end
# @return [MethodObject,nil]
def corresponding_getter
clean_name = name.to_s.gsub(/(\=)$/, '')
parent.child(clean_name.to_sym)
end
# Returns +true+ if the docstring was generated by YARD.
def implicit_docstring?
YARD.implicit_docstring?(docstring, self)
end
# @return [Array<::YARD::Tag>]
def overload_tags
object.tags(:overload)
end
# @return [Array<::YARD::Tag>]
def overloaded_return_tags
overload_tags.map do |overload_tag|
overload_tag.tag(:return)
end.compact
end
# @return [Array<::YARD::Tag>]
def return_tags
object.tags(:return) +
overloaded_return_tags +
attributed_return_tags
end
# Returns +true+ if a return value is described via tags.
def return_described_via_tag?
return_tags.any? do |t|
return_tag_describes_unusable_value?(t) ||
!t.text.to_s.empty? && !YARD.implicit_tag?(t, self)
end
end
def return_tag_describes_unusable_value?(t)
return false if t.types.nil?
t.types.size == 1 &&
UNUSABLE_RETURN_VALUES.include?(t.types.first)
end
end
end
end
end
end
end
end