Commit 054b6449 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Print warning when @link is ambiguous.

Like when {@link #foo} refers to either #method-foo or #event-foo.

Also add new warning type: link_ambiguous.
parent 239f0dbe
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -154,25 +154,33 @@ module JsDuck
      local_members
    end

    # Returns member by name.
    # Returns members by name. An array of one or more members, or
    # empty array when nothing matches.
    #
    # Optionally one can also specify type name to differenciate
    # between different types of members.
    def get_member(name, type_name=nil)
    def get_members(name, type_name=nil)
      # build hash of all members
      unless @members_map
        @members_map = {}
        [:members, :statics].each do |group|
          @doc[group].each_key do |type|
            members_hash(type, group).each_pair do |key, member|
              @members_map["#{type}-#{key}"] = member
              @members_map[key] = member
              members_map_add_key!("#{type}-#{key}", member)
              members_map_add_key!(key, member)
            end
          end
        end
      end

      @members_map[type_name ? "#{type_name}-#{name}" : name]
      @members_map[type_name ? "#{type_name}-#{name}" : name] || []
    end

    # Adds member to @members_map so that each key corresponse to one
    # or more actual members.
    def members_map_add_key!(key, value)
      old = @members_map[key]
      @members_map[key] = old ? old + [value] : [value]
    end

    # Returns all public members of class, including the inherited and mixed in ones
+44 −15
Original line number Diff line number Diff line
@@ -131,15 +131,39 @@ module JsDuck
        line = @doc_context[:linenr]
        if !@relations[cls]
          Logger.instance.warn(:link, "#{input} links to non-existing class", file, line)
          text
        elsif member && !get_member(cls, member, type)
          return text
        elsif member
          ms = get_members(cls, member, type)
          if ms.length == 0
            Logger.instance.warn(:link, "#{input} links to non-existing member", file, line)
          text
        elsif member && !public_member?(cls, member, type)
            return text
          end

          ms = ms.find_all {|m| !m[:private] }
          if ms.length == 0
            Logger.instance.warn(:link_private, "#{input} links to private member", file, line)
          text
            return text
          end

          if ms.length > 1
            # When multiple public members, see if there remains just
            # one when we ignore the static members. If there's more,
            # report ambiguity. If there's only static members, also
            # report ambiguity.
            instance_ms = ms.find_all {|m| !m[:attributes][:static] }
            if instance_ms.length > 1
              alternatives = instance_ms.map {|m| m[:tagname].to_s }.join(", ")
              Logger.instance.warn(:link_ambiguous, "#{input} is ambiguous: "+alternatives, file, line)
            elsif instance_ms.length == 0
              static_ms = ms.find_all {|m| m[:attributes][:static] }
              alternatives = static_ms.map {|m| "static " + m[:tagname].to_s }.join(", ")
              Logger.instance.warn(:link_ambiguous, "#{input} is ambiguous: "+alternatives, file, line)
            end
          end

          return link(cls, member, text, type)
        else
          link(cls, member, text, type)
          return link(cls, false, text, false)
        end
      end
    end
@@ -156,7 +180,7 @@ module JsDuck
        member = $4
        after = $5

        if @relations[cls] && (member ? public_member?(cls, member) : cls =~ /\./)
        if @relations[cls] && (member ? get_matching_member(cls, member) : cls =~ /\./)
          label = member ? cls+"."+member : cls
          before + link(cls, member, label) + after
        else
@@ -185,7 +209,7 @@ module JsDuck
      # Use the canonical class name for link (not some alternateClassName)
      cls = @relations[cls].full_name
      # prepend type name to member name
      member = member && get_member(cls, member, type)
      member = member && get_matching_member(cls, member, type)

      @link_tpl.gsub(/(%[\w#-])/) do
        case $1
@@ -205,13 +229,18 @@ module JsDuck
      end
    end

    def public_member?(cls, member, type=nil)
      m = get_member(cls, member, type)
      return m && !m[:private]
    def get_matching_member(cls, member, type=nil)
      ms = get_members(cls, member, type).find_all {|m| !m[:private] }
      if ms.length > 1
        instance_ms = ms.find_all {|m| !m[:attributes][:static] }
        instance_ms.length > 0 ? instance_ms[0] : ms.find_all {|m| m[:attributes][:static] }[0]
      else
        ms[0]
      end
    end

    def get_member(cls, member, type=nil)
      return @relations[cls] && @relations[cls].get_member(member, type)
    def get_members(cls, member, type=nil)
      @relations[cls] ? @relations[cls].get_members(member, type) : []
    end

    # Formats doc-comment for placement into HTML.
+2 −2
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ module JsDuck
          warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - class not found", context)
          return m
        end
        parent = parent_cls.get_member(inherit[:member], inherit[:type] || m[:tagname])
        parent = parent_cls.get_members(inherit[:member], inherit[:type] || m[:tagname])[0]
        unless parent
          warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - member not found", context)
          return m
@@ -52,7 +52,7 @@ module JsDuck
          warn("@inheritdoc - parent class not found", context)
          return m
        end
        parent = parent_cls.get_member(m[:name], m[:tagname])
        parent = parent_cls.get_members(m[:name], m[:tagname])[0]
        unless parent
          warn("@inheritdoc - parent member not found", context)
          return m
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ module JsDuck
        [:extend, "@extend or @mixin referring to unknown class"],
        [:link, "{@link} to unknown class or member"],
        [:link_private, "{@link} to private member"],
        [:link_ambiguous, "{@link} is ambiguous"],

        [:alt_name, "Name used as both classname and alternate classname"],
        [:name_missing, "Member or parameter has no name"],