Commit 05f9cb0a authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Implement auto-detection of static members.

parent f5a0ab0c
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ module JsDuck
          members += make_configs(cfg["cachedConfig"], {:accessor => true})
          members += make_configs(cfg["eventedConfig"], {:accessor => true, :evented => true})
          cls[:members] = members.length > 0 ? members : nil

          statics = []
          statics += make_statics(cfg["statics"])
          cls[:statics] = statics.length > 0 ? statics : nil
        end
      end

@@ -263,6 +267,36 @@ module JsDuck
      configs
    end

    def make_statics(ast, defaults={})
      return [] unless ast && ast["type"] == "ObjectExpression"

      statics = []

      ast["properties"].each do |p|
        name = key_value(p["key"])

        if p["value"]["type"] == "FunctionExpression"
          s = make_method(name, p["value"])
        else
          s = make_property(name, p["value"])
        end

        s[:meta] = {:static => true}

        docset = find_docset(p)
        if docset
          docset[:code] = s
        else
          s[:private] = true
          s[:autodetected] = true
          s[:linenr] = p["range"][2]
          statics << s
        end
      end

      statics
    end

    # Looks up docset associated with given AST node.
    # A dead-stupid and -slow implementation, but works.
    def find_docset(ast)
+20 −9
Original line number Diff line number Diff line
@@ -99,9 +99,23 @@ module JsDuck
    # right.
    def expand_code(docset)
      results = []
      if docset[:code] && docset[:code][:members]
        docset[:code][:members].each do |m|
          results << {

      if docset[:code]

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

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

      results
    end

    def code_to_docset(m)
      return {
        :tagname => m[:tagname],
        :type => :no_comment,
        :comment => [],
@@ -109,9 +123,6 @@ module JsDuck
        :linenr => m[:linenr],
      }
    end
      end
      results
    end

  end

+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ module JsDuck
      # Copy private to meta
      h[:meta][:private] = h[:private] if h[:private]

      # Copy :static flag from code if present
      if code[:meta] && code[:meta][:static]
        h[:meta][:static] = true
      end

      # Remember auto-detection info
      h[:autodetected] = code[:autodetected] if code[:autodetected]

+87 −0
Original line number Diff line number Diff line
@@ -77,4 +77,91 @@ describe JsDuck::Aggregator do
    end
  end

  describe "Ext.define() with undocumented property in statics:" do
    let(:statics) do
      parse(<<-EOS)[0][:statics]
        /**
         * Some documentation.
         */
        Ext.define("MyClass", {
            statics: {
                foo: 42
            }
        });
      EOS
    end

    it "auto-detects one static property" do
      statics[:property].length.should == 1
    end

    describe "auto-detects static property" do
      let(:property) { statics[:property][0] }

      it "with :static flag" do
        property[:meta][:static].should == true
      end

      it "with :autodetected flag" do
        property[:autodetected].should == true
      end

      it "with owner" do
        property[:owner].should == "MyClass"
      end

      it "as private" do
        property[:private].should == true
      end

      it "with :linenr field" do
        property[:linenr].should == 6
      end
    end
  end

  describe "Ext.define() with documented method in statics:" do
    let(:statics) do
      parse(<<-EOS)[0][:statics]
        /**
         * Some documentation.
         */
        Ext.define("MyClass", {
            statics: {
                /** Docs for bar */
                bar: function() {}
            }
        });
      EOS
    end

    it "detects one static method" do
      statics[:method].length.should == 1
    end

    describe "detects static method" do
      let(:method) { statics[:method][0] }

      it "with :static flag" do
        method[:meta][:static].should == true
      end

      it "with docs" do
        method[:doc].should == "Docs for bar"
      end

      it "with owner" do
        method[:owner].should == "MyClass"
      end

      it "as public" do
        method[:private].should_not == true
      end

      it "with :linenr field" do
        method[:linenr].should == 6
      end
    end
  end

end
+53 −0
Original line number Diff line number Diff line
require "jsduck/ast"
require "jsduck/js_parser"

describe "JsDuck::Ast detecting" do
  def detect(string)
    node = JsDuck::JsParser.new(string).parse[0]
    return JsDuck::Ast.new.detect(node[:code])
  end

  describe "Ext.define()" do
    let (:statics) do
      detect(<<-EOS)[:statics]
        /** */
        Ext.define('MyClass', {
            statics: {
                foo: true,
                bar: function(){}
            }
        });
      EOS
    end

    it "adds :statics as array" do
      statics.should be_kind_of(Array)
    end

    describe "finds static property" do
      it "with :property tagname" do
        statics[0][:tagname].should == :property
      end
      it "with name" do
        statics[0][:name].should == "foo"
      end
      it "with :static flag" do
        statics[0][:meta][:static].should == true
      end
    end

    describe "finds static method" do
      it "with :property tagname" do
        statics[1][:tagname].should == :method
      end
      it "with name" do
        statics[1][:name].should == "bar"
      end
      it "with :static flag" do
        statics[1][:meta][:static].should == true
      end
    end

  end

end