Commit 3f916406 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Turn :autodetected field into hash.

Inside Ast auto-detection store there :tagname flag.
Inside @param and @type merging store the :params and :type flags.

Create Tag::Autodetected to do the merging of :autodetected fields
from code and docs.
parent f4a90991
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -7,16 +7,23 @@ module JsDuck
  class DocsCodeComparer
    include Util::Singleton

    # When docs has the key, returns value from there.
    # When code has the key and matches with docs, gets value from there.
    # Otherwise returns nil.
    def merge_if_matches(key, docs, code)
    # Sets the value of a field in result hash based on its value in
    # docs and code hashes.
    #
    # - When docs has the key, gets value from there.
    #
    # - When code has the key and matches with docs, gets value from
    #   there, and also remembers the fact that we're using
    #   auto-detected value by recording it in :autodetected field.
    #
    def merge_if_matches(h, key, docs, code)
      if docs[key]
        docs[key]
        h[key] = docs[key]
      elsif code[key] && matches?(docs, code)
        code[key]
        h[key] = code[key]
        mark_autodetected(h, key)
      else
        nil
        # nothing
      end
    end

@@ -26,6 +33,12 @@ module JsDuck
      return docs[:name] == nil || docs[:name] == code[:name]
    end

    # Stores the key as flag into h[:autodetcted]
    def mark_autodetected(h, key)
      h[:autodetected] = {} unless h[:autodetected]
      h[:autodetected][key] = true
    end

  end

end
+1 −1
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ module JsDuck
          else
            m[:private] = true
          end
          m[:autodetected] = true
          m[:autodetected] = {:tagname => m[:tagname]}
        end

        if docset
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ module JsDuck
      # values default to being public.
      def strip_inheritdoc(cls)
        cls[:members].each do |p|
          p[:inheritdoc] = nil if p[:autodetected]
          p[:inheritdoc] = nil if p[:autodetected] && p[:autodetected][:tagname]
        end
      end

+38 −11
Original line number Diff line number Diff line
@@ -35,18 +35,14 @@ module JsDuck
        end

        if m[:inheritdoc] && parent
          m[:doc] = parent[:doc] if m[:doc].empty?
          m[:params] = parent[:params] unless m[:params] && m[:params].length > 0
          m[:return] = parent[:return] unless m[:return]
          m[:throws] = parent[:throws] unless m[:throws] && m[:throws].length > 0
          m[:type] = parent[:type] unless m[:type] && m[:type] != "Object"
          inherit(m, parent)

          if m[:autodetected]
          if autodetected?(m)
            m[:deprecated] = parent[:deprecated] if parent[:deprecated] && !m[:deprecated]
          end

          # remember properties that have changed to configs
          if m[:autodetected] && m[:tagname] != parent[:tagname]
          if autodetected?(m) && m[:tagname] != parent[:tagname]
            new_cfgs << m
          end
        end
@@ -56,6 +52,32 @@ module JsDuck
        m[:inheritdoc] = nil
      end

      def inherit(m, parent)
        m[:doc] = parent[:doc] if m[:doc].empty?

        # Don't inherit params from parent when:
        # - member itself has params and these are not auto-detected
        # - or the params in parent are auto-detected.
        unless m[:params] && m[:params].length > 0 && !auto?(m, :params) || auto?(parent, :params)
          m[:params] = parent[:params]
        end

        m[:return] = parent[:return] unless m[:return]
        m[:throws] = parent[:throws] unless m[:throws] && m[:throws].length > 0

        # Don't inherit type from parent when:
        # - member itself has type and it's not auto-detected
        # - or the type in parent is auto-detected.
        unless m[:type] && m[:type] != "Object" && !auto?(m, :type) || auto?(parent, :type)
          m[:type] = parent[:type]
        end
      end

      # True when specific field of member has been auto-detected
      def auto?(m, key)
        m[:autodetected] && m[:autodetected][key]
      end

      # Changes given properties into configs within class
      def move_cfgs(cls, members)
        members.each do |m|
@@ -68,7 +90,7 @@ module JsDuck
      # For auto-detected members/classes (which have @private == :inherit)
      # Use the visibility from parent class (defaulting to private when no parent).
      def resolve_visibility(m, parent)
        if m[:autodetected] && !JsDuck::Class.constructor?(m)
        if autodetected?(m) && !JsDuck::Class.constructor?(m)
          if !parent || parent[:private]
            m[:private] = true
          end
@@ -104,7 +126,7 @@ module JsDuck

          # Warn when no parent or mixins at all
          if !parent_cls && mixins.length == 0
            warn("parent class not found", m) unless m[:autodetected]
            warn("parent class not found", m) unless autodetected?(m)
            return nil
          end

@@ -123,7 +145,7 @@ module JsDuck

          # Only when both parent and mixins fail, throw warning
          if !parent
            warn("parent member not found", m) unless m[:autodetected]
            warn("parent member not found", m) unless autodetected?(m)
            return nil
          end
        end
@@ -137,7 +159,7 @@ module JsDuck
        tagname = inherit[:type] || m[:tagname]
        static = inherit[:static] || m[:static]

        if m[:autodetected]
        if autodetected?(m)
          # Auto-detected properties can override either a property or a
          # config. So look for both types.
          if tagname == :property
@@ -192,6 +214,11 @@ module JsDuck
        return parent
      end

      # True when the entire member was auto-detected
      def autodetected?(m)
        m[:autodetected] && m[:autodetected][:tagname]
      end

      def warn(msg, item)
        i_member = item[:inheritdoc][:member]

+21 −0
Original line number Diff line number Diff line
require "jsduck/tag/tag"
require "jsduck/docs_code_comparer"

module JsDuck::Tag
  # There is no @autodetected tag.
  #
  # This tag class exists to take care of the merging of :autodetected
  # field.
  class Autodetected < Tag
    def initialize
      @tagname = :autodetected
      @merge_context = [:class, :member]
    end

    def merge(h, docs, code)
      if docs[:autodetected] || code[:autodetected]
        h[:autodetected] = (code[:autodetected] || {}).merge(docs[:autodetected] || {})
      end
    end
  end
end
Loading