Commit 790fc1e9 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Class.methods now returns all class methods.

Including the ones belonging to parent classes.
All methods are augmented with :member field that
says the class they belong to.

In top-level filter_classes each Class instance
also receives a hash of all classes - so that the
Class.parent() method can return instance of parent class.

Finally added some rudimentary tests for all this.
parent a29eebd1
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -50,15 +50,15 @@ module JsDuck
  # Filters out class-documentations, converting them to Class objects.
  # For each other type, prints a warning message and discards it
  def self.filter_classes(docs)
    classes = []
    classes = {}
    docs.each do |d|
      if d[:tagname] == :class
        classes << Class.new(d)
        classes[d[:name]] = Class.new(d, classes)
      else
        puts "Warning: Ignoring " + d[:tagname].to_s + ": " + (d[:name] || "")
      end
    end
    classes
    classes.values
  end

  def self.print_debug(docs)
+28 −1
Original line number Diff line number Diff line
@@ -4,14 +4,41 @@ module JsDuck
  # methods on it.  Otherwise it acts like Hash, providing the []
  # method.
  class Class
    def initialize(doc)
    def initialize(doc, classes={})
      @doc = doc
      @classes = classes
    end

    def [](key)
      @doc[key]
    end

    # Returns instance of parent class, or nil if there is none
    def parent
      @doc[:extends] ? @classes[@doc[:extends]] : nil
    end

    # Returns array of all methods in a class, sorted by name.
    # See methods_hash for details.
    def methods
      methods_hash.values.sort {|a,b| a[:name] <=> b[:name] }
    end

    # Returns hash of methods in class (and parent classes).
    # When parent and child have methods with same name,
    # method from child overrides tha parent method.
    #
    # We also set :member property to each method to the full class
    # name where it belongs, so one can tell them apart afterwards.
    def methods_hash
      parent_methods = parent ? parent.methods_hash : {}
      @doc[:method].each do |m|
        m[:member] = full_name
        parent_methods[m[:name]] = m
      end
      parent_methods
    end

    # A way to access full class name with similar syntax to
    # package_name and short_name
    def full_name
+6 −5
Original line number Diff line number Diff line
@@ -69,15 +69,16 @@ module JsDuck
    end

    def methods
      table("methods", "Public Methods", "Method", @cls[:method].collect {|m| method_row(m) })
      table("methods", "Public Methods", "Method", @cls.methods.collect {|m| method_row(m) })
    end

    def method_row(method)
      table_row("method-row " + expandable_class(method),
        "<a id='#{@cls.full_name}-#{method[:name]}'></a>" +
        "<b><a href='source/sample.html#prop-#{@cls.full_name}-#{method[:name]}'>#{method[:name]}</a></b>()" +
        " : " + (method[:return] ? method[:return][:type] : "void") +
        mdesc(method)
        " : " + (method[:return] ? (method[:return][:type] || "void") : "void") +
        mdesc(method),
        Class.short_name(method[:member])
      )
    end

@@ -123,12 +124,12 @@ module JsDuck
      ].join("\n")
    end

    def table_row(className, contents)
    def table_row(className, contents, defined_by=nil)
      [
       "<tr class='#{className}'>",
         "<td class='micon'><a href='#expand' class='exi'>&nbsp;</a></td>",
         "<td class='sig'>#{contents}</td>",
         "<td class='msource'>#{@cls.short_name}</td>",
         "<td class='msource'>#{defined_by ? defined_by : @cls.short_name}</td>",
       "</tr>",
      ].join("")
    end

test/tc_class.rb

0 → 100644
+49 −0
Original line number Diff line number Diff line
require "jsduck/class"
require "test/unit"

class TestClass < Test::Unit::TestCase

  def test_local_methods
    cls = JsDuck::Class.new({
      :name => "MyClass",
      :method => [
        {:name => "foo"},
        {:name => "bar"},
      ]
    });

    ms = cls.methods_hash
    assert_equal(2, ms.values.length)
    assert_equal("MyClass", ms["foo"][:member])
    assert_equal("MyClass", ms["bar"][:member])
  end

  def test_parent_methods
    classes = {}
    parent = JsDuck::Class.new({
      :name => "ParentClass",
      :method => [
        {:name => "baz"},
        {:name => "foo"},
      ]
    }, classes);
    classes["ParentClass"] = parent
    child = JsDuck::Class.new({
      :name => "MyClass",
      :extends => "ParentClass",
      :method => [
        {:name => "foo"},
        {:name => "bar"},
      ]
    }, classes);
    classes["MyClass"] = child

    ms = child.methods_hash
    assert_equal(3, ms.values.length)
    assert_equal("MyClass", ms["foo"][:member], "foo should be overridden in child class")
    assert_equal("MyClass", ms["bar"][:member], "bar is only in child class")
    assert_equal("ParentClass", ms["baz"][:member], "baz is only in parent class")
  end

end