lib/jsduck/ast.rb in jsduck-4.0.beta vs lib/jsduck/ast.rb in jsduck-4.0.beta2

- old
+ new

@@ -71,19 +71,19 @@ elsif exp && assignment?(exp) && ext_extend?(exp["right"]) make_class(to_s(exp["left"]), exp["right"]) # Foo = ... elsif exp && assignment?(exp) && class_name?(to_s(exp["left"])) - make_class(to_s(exp["left"])) + make_class(to_s(exp["left"]), exp["right"]) # var foo = Ext.extend("Parent", {}) elsif var && var["init"] && ext_extend?(var["init"]) make_class(to_s(var["id"]), var["init"]) # var Foo = ... elsif var && class_name?(to_s(var["id"])) - make_class(to_s(var["id"])) + make_class(to_s(var["id"]), var["right"]) # function Foo() {} elsif function?(ast) && class_name?(to_s(ast["id"])) make_class(to_s(ast["id"])) @@ -191,16 +191,24 @@ cls = { :tagname => :class, :name => name, } - # apply information from Ext.extend or Ext.define + # apply information from Ext.extend, Ext.define, or {} if ast if ext_extend?(ast) - cls[:extends] = to_s(ast["arguments"][0]) + args = ast["arguments"] + cls[:extends] = to_s(args[0]) + if args.length == 2 && args[1]["type"] == "ObjectExpression" + detect_class_members_from_object(cls, args[1]) + end elsif ext_define?(ast) detect_ext_define(cls, ast) + elsif ast["type"] == "ObjectExpression" + detect_class_members_from_object(cls, ast) + elsif ast["type"] == "ArrayExpression" + detect_class_members_from_array(cls, ast) end end return cls end @@ -215,10 +223,11 @@ cls[:alternateClassNames] = [] 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| case key when "extend" cls[:extends] = make_extends(value) @@ -245,21 +254,42 @@ when "statics" cls[:statics] += make_statics(value) when "inheritableStatics" cls[:statics] += make_statics(value, {:inheritable => true}) else - if function?(value) - m = make_method(key, value) - cls[:members] << m if apply_autodetected(m, pair) - else - p = make_property(key, value) - cls[:members] << p if apply_autodetected(p, pair) - end + detect_method_or_property(cls, key, value, pair) end end end + # Detects class members from object literal + def detect_class_members_from_object(cls, ast) + cls[:members] = [] + each_pair_in_object_expression(ast) do |key, value, pair| + detect_method_or_property(cls, key, value, pair) + end + end + + # Detects class members from array literal + def detect_class_members_from_array(cls, ast) + cls[:members] = [] + ast["elements"].each do |el| + detect_method_or_property(cls, key_value(el), el, el) + end + end + + # Detects item in object literal either as method or property + def detect_method_or_property(cls, key, value, pair) + if function?(value) + m = make_method(key, value) + cls[:members] << m if apply_autodetected(m, pair) + else + p = make_property(key, value) + cls[:members] << p if apply_autodetected(p, pair) + end + end + def make_extends(cfg_value) return nil unless cfg_value parent = to_value(cfg_value) @@ -323,12 +353,12 @@ # # When member has a comment, adds code to the related docset and # returns false. # # Otherwise detects the line number of member and returns true. - def apply_autodetected(m, pair, inheritable=true) - docset = find_docset(pair) + def apply_autodetected(m, ast, inheritable=true) + docset = find_docset(ast) if !docset || docset[:type] != :doc_comment if inheritable m[:inheritdoc] = {} else @@ -342,10 +372,10 @@ return false else # Get line number from third place at range array. # This third item exists in forked EsprimaJS at # https://github.com/nene/esprima/tree/linenr-in-range - m[:linenr] = pair["range"][2] + m[:linenr] = ast["range"][2] return true end end # Looks up docset associated with given AST node.