Commit dbce16de authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Change how class members are internally stored.

Instead of storing members in two hashes - :members & :statics -
the members are now stored in simple :members array.

Lots of refactoring, but in the end the unit tests are all passing
and running JSDuck against ExtJS SDK works fine.  More work is needed
though as now JSDuck::Class contains several methods and algorithms
that are inappropriate in the context of new data structure.

Here I'm only changing the internals - export format is still the same
and so is the data structure given to generated Docs app.
parent 867ae12a
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -9,37 +9,39 @@ module JsDuck
    # not added.
    def create(cls)
      # Grab all configs tagged as @accessor
      accessors = cls[:members][:cfg].find_all {|cfg| cfg[:accessor] }
      accessors = cls[:members].find_all {|m| m[:tagname] == :cfg && m[:accessor] }

      # Build lookup tables of method and event names
      methods = build_lookup_table(cls[:members][:method])
      events = build_lookup_table(cls[:members][:event])
      methods = build_lookup_table(cls[:members], :method)
      events = build_lookup_table(cls[:members], :event)

      accessors.each do |cfg|
        # add getter if no method with same name exists
        get = create_getter(cfg)
        if !methods[get[:name]]
          cls[:members][:method] << get
          cls[:members] << get
        end
        # add setter if no method with same name exists
        set = create_setter(cfg)
        if !methods[set[:name]]
          cls[:members][:method] << set
          cls[:members] << set
        end
        # for evented accessors
        if cfg[:evented]
          # add event if no event with same name exists
          ev = create_event(cfg)
          if !events[ev[:name]]
            cls[:members][:event] << ev
            cls[:members] << ev
          end
        end
      end
    end

    def build_lookup_table(members)
    def build_lookup_table(members, tagname)
      map = {}
      members.each {|m| map[m[:name]] = m }
      members.each do |m|
        map[m[:name]] = m if m[:tagname] == tagname
      end
      map
    end

+6 −6
Original line number Diff line number Diff line
@@ -106,8 +106,7 @@ module JsDuck
      end
      old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc]
      # Additionally the doc-comment can contain configs and constructor
      old[:members][:cfg] += new[:members][:cfg]
      old[:members][:method] += new[:members][:method]
      old[:members] += new[:members]
    end

    # Tries to place members into classes where they belong.
@@ -138,7 +137,7 @@ module JsDuck
    end

    def add_to_class(cls, member)
      cls[member[:meta][:static] ? :statics : :members][member[:tagname]] << member
      cls[:members] << member
    end

    def add_orphan(node)
@@ -188,8 +187,7 @@ module JsDuck
        :doc => doc,
        :mixins => [],
        :alternateClassNames => [],
        :members => Class.default_members_hash,
        :statics => Class.default_members_hash,
        :members => [],
        :aliases => {},
        :meta => {},
        :files => [{:filename => "", :linenr => 0, :href => ""}],
@@ -215,7 +213,9 @@ module JsDuck
        :doc => "The options object passed to {@link Ext.util.Observable#addListener}."
      }
      @classes.each_value do |cls|
        cls[:members][:event].each {|e| e[:params] << options }
        cls[:members].each do |m|
          m[:params] << options if m[:tagname] == :event
        end
      end
    end

+2 −3
Original line number Diff line number Diff line
@@ -224,7 +224,6 @@ module JsDuck
      cls[:mixins] = []
      cls[:aliases] = []
      cls[:members] = []
      cls[:statics] = []
      cls[:code_type] = :ext_define

      each_pair_in_object_expression(ast["arguments"][1]) do |key, value, pair|
@@ -254,9 +253,9 @@ module JsDuck
        when "eventedConfig"
          cls[:members] += make_configs(value, {:accessor => true, :evented => true})
        when "statics"
          cls[:statics] += make_statics(value)
          cls[:members] += make_statics(value)
        when "inheritableStatics"
          cls[:statics] += make_statics(value, {:inheritable => true})
          cls[:members] += make_statics(value, {:inheritable => true})
        else
          detect_method_or_property(cls, key, value, pair)
        end
+23 −26
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ module JsDuck
      # differenciating between existing and missing classes.
      @doc[:name] = ClassNameString.new(@doc[:name], class_exists)

      @doc[:members] = Class.default_members_hash if !@doc[:members]
      @doc[:statics] = Class.default_members_hash if !@doc[:statics]
      @doc[:members] = [] if !@doc[:members]

      @relations = nil
    end

@@ -121,7 +121,7 @@ module JsDuck
    #
    # See members_hash for details.
    def members(type, context=:members)
      ms = members_hash(type, context).values #.find_all {|m| !m[:private] }
      ms = members_hash(type, context).values
      ms.sort! {|a,b| a[:name] <=> b[:name] }
      type == :method ? constructor_first(ms) : ms
    end
@@ -147,11 +147,13 @@ module JsDuck
      # Singletons have no static members
      if @doc[:singleton] && context == :statics
        # Warn if singleton has static members
        @doc[context][type].each do |m|
        @doc[:members].each do |m|
          if m[:meta] && m[:meta][:static]
            ctx = m[:files][0]
            msg = "Singleton class #{@doc[:name]} can't have static members, remove the @static tag."
            Logger.instance.warn(:sing_static, msg, ctx[:filename], ctx[:linenr])
          end
        end
        return {}
      end

@@ -172,7 +174,7 @@ module JsDuck
      # instance members.  Otherwise they will be completely excluded
      # from the docs, as the static members block is not created for
      # singletons.
      if @doc[:singleton] && @doc[:statics][type].length > 0
      if @doc[:singleton]
        merge!(ms, local_members_hash(type, :statics))
      end

@@ -230,10 +232,16 @@ module JsDuck

    # Helper method to get the direct members of this class
    def local_members_hash(type, context)
      is_static = (context == :statics)
      local_members = {}
      (@doc[context][type] || []).each do |m|

      @doc[:members].find_all do |m|
        static = (m[:meta] || {})[:static] || false
        m[:tagname] == type && static == is_static
      end.each do |m|
        local_members[m[:name]] = m
      end

      local_members
    end

@@ -250,12 +258,8 @@ module JsDuck
      # 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[key] = (@members_map[key] || []) + [member]
            end
          end
        all_members.each do |m|
          @members_map[m[:name]] = (@members_map[m[:name]] || []) + [m]
        end
      end

@@ -275,23 +279,16 @@ module JsDuck
    # Returns all members of class, including the inherited and mixed in ones
    def all_members
      all = []
      [:members, :statics].each do |group|
        @doc[group].each_key do |type|
          all += members(type, group)
        end
      [:cfg, :property, :method, :event, :css_mixin, :css_var].each do |type|
        all += members(type, :members)
        all += members(type, :statics)
      end
      all
    end

    # Returns all local members of class
    def all_local_members
      all = []
      [:members, :statics].each do |group|
        @doc[group].each_value do |ms|
          all += ms
        end
      end
      all
      @doc[:members]
    end

    # A way to access full class name with similar syntax to
+0 −5
Original line number Diff line number Diff line
@@ -107,14 +107,9 @@ module JsDuck
      results = []

      if docset[:code]

        (docset[:code][:members] || []).each do |m|
          results << code_to_docset(m) unless @constructor_found && m[:name] == "constructor"
        end

        (docset[:code][:statics] || []).each do |m|
          results << code_to_docset(m)
        end
      end

      results
Loading