Commit 3916999b authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Merge branch 'since-params'

parents 16a77bc7 657541ea
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -63,10 +63,11 @@ module JsDuck
      new_items
    end

    # Returns all members of a class that have been marked as new, or
    # have parameters marked as new.
    def filter_new_members(cls)
      members = []
      cls.all_local_members.each do |m|
        members << m if m[:new] && visible?(m)
      members = cls.all_local_members.find_all do |m|
        visible?(m) && (m[:new] || new_params?(m))
      end
      members = discard_accessors(members)
      members.sort! {|a, b| a[:name] <=> b[:name] }
@@ -76,6 +77,10 @@ module JsDuck
      !member[:private] && !member[:hide]
    end

    def new_params?(member)
      Array(member[:params]).any? {|p| p[:new] }
    end

    def discard_accessors(members)
      accessors = {}
      members.find_all {|m| m[:accessor] }.each do |cfg|
@@ -127,7 +132,15 @@ module JsDuck
      if m[:tagname] == :class
        @doc_formatter.link(m[:name], nil, m[:name])
      else
        @doc_formatter.link(m[:owner], m[:name], m[:name], m[:tagname], m[:static])
        @doc_formatter.link(m[:owner], m[:name], m[:name], m[:tagname], m[:static]) + params_note(m)
      end
    end

    def params_note(m)
      if !m[:new] && new_params?(m)
        " <small>+parameters</small>"
      else
        ""
      end
    end

+3 −0
Original line number Diff line number Diff line
@@ -182,6 +182,9 @@ module JsDuck
        # definitions multiple times.
        TagRegistry.instance
      end

      # The tooltip of @new can now be configured.
      TagRegistry.get_by_name(:new).init_tooltip!(self)
    end

    private
+5 −2
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@ module JsDuck
      private

      def current_version
        Util::NullObject.new(:[] => Util::NullObject.new(:[] => true))
        JsDuck::Util::NullObject.new(
          :[] => JsDuck::Util::NullObject.new( # class
            :[] => JsDuck::Util::NullObject.new( # member
              :length => 1.0 / 0))) # params count == Infinity
      end

      # Reads in data from all .json files in directory
@@ -61,7 +64,7 @@ module JsDuck
      def members_id_index(json)
        index = {}
        json["members"].each do |m|
          index[m["id"]] = true
          index[m["id"]] = m["params"] ? m["params"].map {|p| p["name"] } : true
        end
        index
      end
+84 −50
Original line number Diff line number Diff line
require 'jsduck/process/importer'
require 'jsduck/tag_registry'

module JsDuck
  module Process
@@ -7,76 +6,65 @@ module JsDuck
    # Generates @since and @new tags by importing JSDuck exports of
    # older versions of the same project and looking in which version
    # a class or method first appeared.
    #
    # Additionally here the tooltip text for @new tag gets injected.
    class Versions
      def initialize(relations, opts={}, importer=nil)
      def initialize(relations, opts={}, importer=Process::Importer.new)
        @relations = relations
        @opts = opts
        # Allow different importer to be injected for testing
        @importer = importer || Process::Importer.new
        @importer = importer
      end

      # Loads in exported docs and generates @since and @new tags.
      def process_all!
        init_new_tag_tooltip!

        if @opts[:imports].length > 0
          generate_since_tags(@importer.import(@opts[:imports]))
          @versions = @importer.import(@opts[:imports])
          add_since_tags
        end
      end

      private

      # Initializes the tooltip text for the signature of @new tag.
      def init_new_tag_tooltip!
        signature = TagRegistry.get_by_name(:new).signature
        if @opts[:new_since]
          signature[:tooltip] = "New since #{@opts[:new_since]}"
        elsif @opts[:imports].length > 0
          signature[:tooltip] = "New since #{@opts[:imports].last[:version]}"
        end
      end
      # classes...

      # Using the imported versions data, adds @since tags to all
      # classes/members.
      def generate_since_tags(versions)
        new_versions = build_new_versions_map(versions)

      # classes/members/params.
      def add_since_tags
        @relations.each do |cls|
          v = cls[:since] || class_since(versions, cls)
          v = cls[:since] || class_since(cls)
          cls[:since] = v
          cls[:new] = true if new_versions[v]
          cls[:new] = true if is_new?(v)

          cls.all_local_members.each do |m|
            v = m[:since] || member_since(versions, cls, m)
            m[:since] = v
            m[:new] = true if new_versions[v]
          end
          add_members_since_tags(cls)
        end
      end

      # Generates a lookup table of versions that we are going to label
      # with @new tags.  By default we use the latest version, otherwise
      # use all versions since the latest.
      def build_new_versions_map(versions)
        new_versions = {}

        if @opts[:new_since]
          versions.map {|v| v[:version] }.each do |v|
            if v == @opts[:new_since] || !new_versions.empty?
              new_versions[v] = true
      # Returns name of the version since which the class is available
      def class_since(cls)
        @versions.each do |ver|
          return ver[:version] if ver[:classes][cls[:name]]
          cls[:alternateClassNames].each do |name|
            return ver[:version] if ver[:classes][name]
          end
        end
        else
          new_versions[versions.last[:version]] = true
      end

        new_versions
      # members...

      def add_members_since_tags(cls)
        cls.all_local_members.each do |m|
          # Remember the initial explicit @since tag value
          # to disable params processing when it's present.
          explicit_since = m[:since]

          v = m[:since] || member_since(cls, m)
          m[:since] = v
          m[:new] = true if is_new?(v)

          add_params_since_tags(cls, m, v) unless explicit_since
        end
      end

      def member_since(versions, cls, m)
        versions.each do |ver|
      def member_since(cls, m)
        @versions.each do |ver|
          c = ver[:classes][cls[:name]]
          return ver[:version] if c && c[m[:id]]
          cls[:alternateClassNames].each do |name|
@@ -86,16 +74,62 @@ module JsDuck
        end
      end

      # Returns name of the version since which the class is available
      def class_since(versions, cls)
        versions.each do |ver|
          return ver[:version] if ver[:classes][cls[:name]]
      # params...

      def add_params_since_tags(cls, member, member_version)
        Array(member[:params]).each_with_index do |p, i|
          v = param_since(cls, member, i)
          if v != member_version
            p[:since] = v
            p[:new] = true if is_new?(v)
          end
        end
      end

      def param_since(cls, m, i)
        @versions.each do |ver|
          c = ver[:classes][cls[:name]]
          return ver[:version] if c && has_param?(c[m[:id]], i)
          cls[:alternateClassNames].each do |name|
            return ver[:version] if ver[:classes][name]
            c = ver[:classes][name]
            return ver[:version] if c && has_param?(c[m[:id]], i)
          end
        end
      end

      # Because parameters can be renamed between versions, only
      # consider parameter count.
      def has_param?(member, param_index)
        member && member.respond_to?(:length) && member.length > param_index
      end

      # helpers...

      # Should items introduced in given version be marked as new?
      def is_new?(version_nr)
        @new_versions = new_versions_map unless @new_versions
        @new_versions[version_nr]
      end

      # Generates a lookup table of versions that we are going to label
      # with @new tags.  By default we use the latest version, otherwise
      # use all versions since the latest.
      def new_versions_map
        new_versions = {}

        if @opts[:new_since]
          @versions.map {|v| v[:version] }.each do |v|
            if v == @opts[:new_since] || !new_versions.empty?
              new_versions[v] = true
            end
          end
        else
          new_versions[@versions.last[:version]] = true
        end

        new_versions
      end

    end

  end
+18 −0
Original line number Diff line number Diff line
require 'jsduck/util/html'
require 'jsduck/util/singleton'
require 'jsduck/tag_registry'

module JsDuck
  module Render
@@ -54,15 +55,32 @@ module JsDuck
            "<span class='pre'>#{p[:name]}</span> : ",
            p[:html_type],
            p[:optional] ? " (optional)" : "",
            p[:new] ? render_new : "",
            "<div class='sub-desc'>",
              p[:doc],
              p[:default] ? "<p>Defaults to: <code>#{Util::HTML.escape(p[:default])}</code></p>" : "",
              p[:since] ? render_since(p) : "",
              p[:properties] && p[:properties].length > 0 ? render(p) : "",
            "</div>",
          "</li>",
        ]
      end

      def render_new
        signature = TagRegistry.get_by_name(:new).signature
        return [
          "<span class='signature'>",
            "<span class='new' title='#{signature[:tooltip]}'>",
              signature[:long],
            "</span>",
          "</span>",
        ]
      end

      def render_since(param)
        TagRegistry.get_by_name(:since).to_html(param)
      end

      def render_return(ret)
        return [
          "<h3 class='pa'>Returns</h3>",
Loading