Commit 260ec07d authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Implicit function parameter names.

parent 897b8ef6
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -108,6 +108,23 @@ module JsDuck
      end
    end

    # sets default names and possibly other properties of params
    def set_default_params(params)
      if @tags[:param] then
        0.upto(params.length-1) do |i|
          if @tags[:param][i] then
            params[i].each do |key, val|
              @tags[:param][i][key] = val unless @tags[:param][i][key]
            end
          else
            @tags[:param] << params[i]
          end
        end
      else
        @tags[:param] = params
      end
    end

    def [](tagname)
      @tags[tagname]
    end
@@ -228,15 +245,24 @@ module JsDuck
          lex.next
          # function name(){
          doc.set_default(:function, {:name => lex.next})
          doc.set_default_params(parse_params(lex))
        elsif lex.look("var", :ident, "=", "function") then
          lex.next
          # var name = function(){
          doc.set_default(:function, {:name => lex.next})
          lex.next # =
          lex.next # function
          lex.next if lex.look(:ident) # optional anonymous function name
          doc.set_default_params(parse_params(lex))
        elsif lex.look(:ident, "=", "function") ||
            lex.look(:ident, ":", "function") ||
            lex.look(:string, ":", "function") then
          # name: function(){
          doc.set_default(:function, {:name => lex.next})
          lex.next # : or =
          lex.next # function
          lex.next if lex.look(:ident) # optional anonymous function name
          doc.set_default_params(parse_params(lex))
        elsif lex.look(:ident, ".") then
          # some.long.prototype.chain = function() {
          lex.next
@@ -245,6 +271,10 @@ module JsDuck
            name = lex.next
            if lex.look("=", "function") then
              doc.set_default(:function, {:name => name})
              lex.next # =
              lex.next # function
              lex.next if lex.look(:ident) # optional anonymous function name
              doc.set_default_params(parse_params(lex))
            end
          end
        end
@@ -256,6 +286,22 @@ module JsDuck
    return docs
  end

  def JsDuck.parse_params(lex)
    params = []
    if lex.look("(") then
      lex.next
      while lex.look(:ident) do
        params << {:name => lex.next}
        if lex.look(",") then
          lex.next
        else
          break
        end
      end
    end
    params
  end

end


+66 −6
Original line number Diff line number Diff line
@@ -52,61 +52,67 @@ class TestJsDuck < Test::Unit::TestCase
/**
 * Some function
 */
function foo() {
function foo(x) {
}
")
    assert_equal("Some function", docs[0][:function][:doc])
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_with_var
    docs = JsDuck.parse("
/**
 */
var foo = function() {
var foo = function(x) {
}
")
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_without_var
    docs = JsDuck.parse("
/**
 */
foo = function() {
foo = function(x) {
}
")
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_in_object_literal
    docs = JsDuck.parse("
/**
 */
foo: function() {
foo: function(x) {
}
")
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_in_object_literal_string
    docs = JsDuck.parse("
/**
 */
'foo': function() {
'foo': function(x) {
}
")
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_in_prototype
    docs = JsDuck.parse("
/**
 */
Some.Long.prototype.foo = function() {
Some.Long.prototype.foo = function(x) {
}
")
    assert_equal("foo", docs[0][:function][:name])
    assert_equal("x", docs[0][:param][0][:name])
  end

  def test_function_private
@@ -142,5 +148,59 @@ function goodby(){}
    assert_equal("Just some function", docs[0][:function][:doc])
  end

  def test_implicit_function_parameters
    docs = JsDuck.parse("
/**
 */
function f(foo, bar, baz){}
")
    params = docs[0][:param]
    assert_equal("foo", params[0][:name])
    assert_equal("bar", params[1][:name])
    assert_equal("baz", params[2][:name])
  end

  def test_explicit_function_parameters_override_implicit_ones
    docs = JsDuck.parse("
/**
 * @param {String} x
 * @param {String} y
 * @param {String} z
 */
function f(foo, bar, baz){}
")
    params = docs[0][:param]
    assert_equal("x", params[0][:name])
    assert_equal("y", params[1][:name])
    assert_equal("z", params[2][:name])
  end

  def test_some_explicit_and_some_implicit_parameters
    docs = JsDuck.parse("
/**
 * @param {String} x
 */
function f(foo, bar){}
")
    params = docs[0][:param]
    assert_equal("x", params[0][:name])
    assert_equal("bar", params[1][:name])
  end

  def test_explicit_parameter_types_and_implicit_names
    docs = JsDuck.parse("
/**
 * @param {String}
 * @param {Number}
 */
function f(foo, bar){}
")
    params = docs[0][:param]
    assert_equal("foo", params[0][:name])
    assert_equal("String", params[0][:type])
    assert_equal("bar", params[1][:name])
    assert_equal("Number", params[1][:type])
  end

end