docs: function detect(ast) {
    ast = ast || {};
  
    exp = isExpression(ast) ? ast["expression"] : null;
    var variable = isVariable(ast) ? ast["declarations"][0] : null;
  
    // Ext.define("Class", {})
    if (exp && isExtDefine(exp))
      return make_class(to_value(exp["arguments"][0]), exp);
  
    // foo = Ext.extend("Parent", {})
    else if (exp && isAssignment(exp) && isExtExtend(exp["right"]))
      return make_class(to_s(exp["left"]), exp["right"]);
  
    // Foo = ...
    else if (exp && isAssignment(exp) && class_name(to_s(exp["left"])))
      return make_class(to_s(exp["left"]), exp["right"]);
   
    // var foo = Ext.extend("Parent", {})
    else if (variable && variable["init"] && isExtExtend(variable["init"]))
      return make_class(to_s(variable["id"]), variable["init"]);
  
    // var Foo = ...
    else if (variable && class_name(to_s(variable["id"])))
      return make_class(to_s(variable["id"]), variable["right"]);
  
    // function Foo() {}
    else if (isFn(ast) && class_name(to_s(ast["id"])))
      return make_class(to_s(ast["id"]));
  
    // function foo() {}
    else if (isFn(ast))
      return make_method(to_s(ast["id"]), ast);
  
    // foo = function() {}
    else if (exp && isAssignment(exp) && isFn(exp["right"]))
      return make_method(to_s(exp["left"]), exp["right"]);
  
    // var foo = function() {}
    else if (variable && variable["init"] && isFn(variable["init"]))
      return make_method(to_s(variable["id"]), variable["init"]);
  
    // (function() {})
    else if (exp && isFn(exp))
      return make_method(exp["id"] ? to_s(exp["id"]) : "", exp);
  
    // foo: function() {}
    else if (isProperty(ast) && isFn(ast["value"]))
      return make_method(key_value(ast["key"]), ast["value"]);
  
    // foo = ...
    else if (exp && isAssignment(exp))
      return make_property(to_s(exp["left"]), exp["right"]);
  
    // var foo = ...
    else if (variable)
      return make_property(to_s(variable["id"]), variable["init"]);
  
    // foo: ...
    else if (isProperty(ast))
      return make_property(key_value(ast["key"]), ast["value"]);
  
    // foo;
    else if (exp && isIdent(exp))
      return make_property(to_s(exp));
  
    // "foo"  (inside some expression)
    else if (isString(ast))
      return make_property(to_value(ast));
  
    // "foo";  (as a statement of it's own)
    else if (exp && isString(exp))
      return make_property(to_value(exp));
  
    else
      return make_property();
  }