lib/inch/code_object/proxy/base.rb in inch-0.2.3 vs lib/inch/code_object/proxy/base.rb in inch-0.3.0.rc1

- old
+ new

@@ -4,210 +4,203 @@ module CodeObject module Proxy # @abstract class Base extend Forwardable - include NodocHelper - # @return [YARD::CodeObjects::Base] the actual (YARD) code object - attr_reader :object - # @return [Symbol] # when objects are assigned to GradeLists, this grade is set to # enable easier querying for objects of a certain grade attr_writer :grade - # Tags considered by wrapper methods like {#has_code_example?} - CONSIDERED_YARD_TAGS = %w(api example param private return) + # @return [#find] + # an object that responds to #find to look up objects by their + # full name + attr_accessor :object_lookup - # convenient shortcuts to (YARD) code object - def_delegators :object, :type, :path, :name, :namespace, :source, :source_type, :signature, :group, :dynamic, :visibility, :docstring - # convenient shortcuts to evalution object def_delegators :evaluation, :score, :roles, :priority - # @param object [YARD::CodeObjects::Base] the actual (YARD) code object - def initialize(object) - @object = object + def initialize(attributes) + @attributes = attributes end - def api_tag? - !api_tag.nil? + # Returns the attribute for the given +key+ + # + # @param key [Symbol] + def [](key) + @attributes[key] end - def api_tag - tag(:api) || (parent && parent.api_tag) + # @return [Evaluation::Base] + def evaluation + @evaluation ||= Evaluation::Proxy.for(self) end - # To be overridden - # @see Proxy::NamespaceObject - # @return [CodeObject::Proxy::Base,nil] the child inside the current object or +nil+ - def child(name) - nil + # @return [Symbol] + def grade + @grade ||= Evaluation.new_grade_lists.detect { |range| + range.scores.include?(score) + }.grade end - # To be overridden - # @see Proxy::NamespaceObject - # @return [Array,nil] the children of the current object or +nil+ + # @return [Boolean] +true+ if the object has an @api tag + def api_tag? + self[:api_tag?] + end + + # @return [Array] the children of the current object def children - nil + @children ||= self[:children_fullnames].map do |fullname| + object_lookup.find(fullname) + end end + # @return [Boolean] +true+ if the object represents a constant + def constant? + self[:constant?] + end + + def core? + self[:api_tag?] + end + + # The depth of the following is 4: + # + # Foo::Bar::Baz#initialize + # ^ ^ ^ ^ + # 1 << 2 << 3 << 4 + # + # +depth+ answers the question "how many layers of code objects are + # above this one?" + # + # @note top-level counts, that's why Foo has depth 1! + # + # @param i [Fixnum] a counter for recursive method calls + # @return [Fixnum] the depth of the object in terms of namespace + def depth + self[:depth] + end + # @return [Docstring] def docstring - @docstring ||= Docstring.new(object.docstring) + self[:docstring] end - # @return [Evaluation::Base] - def evaluation - @evaluation ||= Evaluation.for(self) + def files + self[:files] end # Returns the name of the file where the object is declared first # @return [String] a filename def filename # just checking the first file (which is the file where an object # is first declared) - files.size > 0 ? files[0][0] : nil + files.first end - # @return [Symbol] - def grade - @grade ||= Evaluation.new_grade_lists.detect { |range| - range.scores.include?(score) - }.grade + # @return [String] the name of an object, e.g. + # "Docstring" + def name + self[:name] end + # @return [String] the fully qualified name of an object, e.g. + # "Inch::CodeObject::Provider::YARD::Docstring" + def fullname + self[:fullname] + end + def has_alias? - !object.aliases.empty? + self[:has_alias?] end + def has_children? + self[:has_children?] + end + def has_code_example? - !tags(:example).empty? || - docstring.contains_code_example? + self[:has_code_example?] end def has_doc? - !docstring.empty? + self[:has_doc?] end def has_multiple_code_examples? - if tags(:example).size > 1 || docstring.code_examples.size > 1 - true - else - if tag = tag(:example) - multi_code_examples?(tag.text) - elsif text = docstring.code_examples.first - multi_code_examples?(text) - else - false - end - end + self[:has_multiple_code_examples?] end def has_unconsidered_tags? - !unconsidered_tags.empty? + self[:has_unconsidered_tags?] end def in_root? - depth == 1 + self[:in_root?] end - # The depth of the following is 4: - # - # Foo::Bar::Baz#initialize - # ^ ^ ^ ^ - # 1 << 2 << 3 << 4 - # - # +depth+ answers the question "how many layers of code objects are - # above this one?" - # - # @note top-level counts, that's why Foo has depth 1! - # - # @param i [Fixnum] a counter for recursive method calls - # @return [Fixnum] the depth of the object in terms of namespace - def depth(i = 0) - if parent - parent.depth(i+1) - else - i - end - end - # @return [Boolean] +true+ if the object represents a method def method? - false + self[:method?] end # @return [Boolean] +true+ if the object represents a namespace def namespace? - false + self[:namespace?] end + # @return [Boolean] +true+ if the object was tagged not to be documented + def nodoc? + self[:nodoc?] + end + # @return [Array,nil] the parent of the current object or +nil+ def parent - Proxy.for(object.parent) if object.parent + object_lookup.find( self[:parent_fullname] ) end def private? - visibility == :private + self[:private?] end # @return [Boolean] # +true+ if the object or its parent is tagged as @private def private_tag? - !private_tag.nil? + self[:private_tag?] end - def private_tag - tag(:private) || (parent && parent.private_tag) - end - def private_api_tag? - api_tag && api_tag.text == 'private' + self[:private_api_tag?] end def protected? - visibility == :protected + self[:protected?] end def public? - visibility == :public + self[:public?] end + def source + self[:source] + end + # @return [Boolean] +true+ if the object has no documentation at all def undocumented? - docstring.empty? && tags.empty? + self[:undocumented?] end - # @return [Array] - # YARD tags that are not already covered by other wrapper methods - def unconsidered_tags - @unconsidered_tags ||= tags.reject do |tag| - CONSIDERED_YARD_TAGS.include?(tag.tag_name) - end + # @return [Fixnum] the amount of tags not considered for this object + def unconsidered_tag_count + self[:unconsidered_tag_count] end - def inspect - "#<#{self.class.to_s}: #{path}>" + def visibility + self[:visibility] end - protected - - def multi_code_examples?(text) - text.scan(/\b(#{Regexp.escape(name)})[^_0-9\!\?]/m).size > 1 - end - - def tag(name) - tags(name).first - end - - def tags(name = nil) - object.tags(name) - rescue YARD::CodeObjects::ProxyMethodError - # this error is raised by YARD - # see broken.rb in test fixtures - [] + def inspect + "#<#{self.class.to_s}: #{fullname}>" end end end end end