Commit 8b585f85 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Changing auto-detected properties to configs.

When parent class has config "foo" then the auto-detected property
"foo" in child class should also be a config.

Incorporated this logic in InheritDoc class.
Added separate test file.
parent b465662f
Loading
Loading
Loading
Loading
+42 −3
Original line number Diff line number Diff line
@@ -13,29 +13,46 @@ module JsDuck
    def resolve_all
      @relations.each do |cls|
        resolve_class(cls) if cls[:inheritdoc]

        new_cfgs = []
        cls.all_local_members.each do |member|
          if member[:inheritdoc] || member[:autodetected]
            resolve(member)
            resolve(member, new_cfgs)
          end
        end
        move_cfgs(cls, new_cfgs)
      end
    end

    private

    # Copy over doc/params/return from parent member.
    def resolve(m)
    def resolve(m, new_cfgs)
      parent = find_parent(m)

      if m[:inheritdoc] && parent
        m[:doc] = (m[:doc] + "\n\n" + parent[:doc]).strip
        m[:params] = parent[:params] if parent[:params]
        m[:return] = parent[:return] if parent[:return]

        # remember properties that have changed to configs
        if m[:tagname] != parent[:tagname]
          new_cfgs << m
        end
      end

      resolve_visibility(m, parent)
    end

    # Changes given properties into configs within class
    def move_cfgs(cls, members)
      members.each do |m|
        m[:tagname] = :cfg
        cls[:members][:property].delete(m)
        cls[:members][:cfg] << m
      end
    end

    # 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)
@@ -101,7 +118,29 @@ module JsDuck

    def lookup_member(cls, m)
      inherit = m[:inheritdoc] || {}
      cls.get_members(inherit[:member] || m[:name], inherit[:type] || m[:tagname], inherit[:static] || m[:meta][:static])[0]
      name = inherit[:member] || m[:name]
      tagname = inherit[:type] || m[:tagname]
      static = inherit[:static] || m[:meta][:static]

      # Auto-detected properties can override either a property or a
      # config. So look for both types.
      if m[:autodetected] && tagname == :property
        cfg = cls.get_members(name, :cfg, static)[0]
        prop = cls.get_members(name, :property, static)[0]

        if cfg && prop
          prop
        elsif cfg
          cfg
        elsif prop
          prop
        else
          nil
        end

      else
        cls.get_members(name, tagname, static)[0]
      end
    end

    # Copy over doc from parent class.
+77 −0
Original line number Diff line number Diff line
require "jsduck/aggregator"
require "jsduck/source_file"
require "jsduck/class"
require "jsduck/relations"
require "jsduck/inherit_doc"

describe JsDuck::Aggregator do
  def parse(string)
    agr = JsDuck::Aggregator.new
    agr.aggregate(JsDuck::SourceFile.new(string))
    relations = JsDuck::Relations.new(agr.result.map {|cls| JsDuck::Class.new(cls) })
    JsDuck::InheritDoc.new(relations).resolve_all
    relations
  end

  describe "auto-detected property overriding property in parent" do
    let(:classes) do
      parse(<<-EOS)
        /** */
        Ext.define("Parent", {
            /** @property */
            blah: 7
        });

        /** */
        Ext.define("Child", {
            extend: "Parent",
            blah: 8
        });
      EOS
    end

    it "detects one property in parent" do
      classes["Parent"][:members][:property].length.should == 1
    end

    it "detects one property in child" do
      classes["Child"][:members][:property].length.should == 1
    end

    it "detects property in child as public" do
      classes["Child"][:members][:property][0][:private].should_not == true
    end
  end

  describe "auto-detected property overriding config in parent" do
    let(:classes) do
      parse(<<-EOS)
        /** */
        Ext.define("Parent", {
            /** @cfg */
            blah: 7
        });

        /** */
        Ext.define("Child", {
            extend: "Parent",
            blah: 8
        });
      EOS
    end

    it "detects one config in parent" do
      classes["Parent"][:members][:cfg].length.should == 1
    end

    it "detects one config in child" do
      classes["Child"][:members][:cfg].length.should == 1
    end

    it "detects no properties in child" do
      classes["Child"][:members][:property].length.should == 0
    end
  end

end