Look for the exports of the module with their comments.
This will be used for documentation.
@param {object} ast - AST of the module.
@returns {array} `{ id, type, comments }`
974515
function findExports( ast ) {
    try {
        const
            publics = {},
            privates = {},
            body = ast.program.body[ 0 ].expression.arguments[ 1 ].body.body;

        body.forEach( function ( item ) {
            if ( parseExports( item, publics ) ) return;
            if ( parseModuleExports( item, publics ) ) return;
            parseFunctionDeclaration( item, privates );
        } );

        const output = [];
        Object.keys( publics ).forEach( function ( exportName ) {
            const
                exportValue = publics[ exportName ],
                target = privates[ exportValue.target ];
            if ( target ) {
                exportValue.comments = exportValue.comments || target.comments;
                exportValue.type = target.type;
                exportValue.params = target.params;
            }
            output.push( {
                id: exportName,
                type: exportValue.type,
                params: exportValue.params,
                comments: exportValue.comments
            } );
        } );

        return output;
    } catch ( ex ) {
        throw new Error( `${ex}\n...in module-analyser/findExports()` );
    }
}
97697
def filter_ast(module_ast):
    
    def node_predicate(node):
        """
        Return true if given node is whitelisted
        """
        for an in ALLOWED_NODES:
            if isinstance(node, an):
                return True

        # Recurse through Assign node LHS targets when an id is not specified,
        # otherwise check that the id is uppercase
        if isinstance(node, ast.Assign):
            return all([node_predicate(t) for t in node.targets if not hasattr(t, 'id')]) \
                and all([t.id.isupper() for t in node.targets if hasattr(t, 'id')])

        return False

    module_ast.body = [n for n in module_ast.body if node_predicate(n)]
    return module_ast
83214
function _depFinder(ast) {
    const {visit} = require('ast-types');
    const imports = {};
    const exports = {};
    const globals = {};

    visit(ast, {
        /************** IMPORT/REQUIRE ***************/
        visitImportDeclaration: function(nodePath) {
            const node = nodePath.value;
            imports[node.source.value] = true;
            return false;
        },
        visitCallExpression: function(nodePath) {
            const node = nodePath.value;

            // cjs require syntax support
            if (
                node.callee.type === 'Identifier' &&
                node.callee.name === 'require' &&
                node.arguments[0].type === 'Literal'
            ) {
                imports[node.arguments[0].value] = true;
            }

            return this.traverse(nodePath);
        },
        visitMemberExpression(nodePath) {
            const node = nodePath.value;
            if (node.object.type === 'Identifier' &&
                !nodePath.scope.lookup(node.object.name) &&
                GLOBAL_WHITELIST.indexOf(node.object.name) >= 0) {
                globals[node.object.name] = true;
            }

            return this.traverse(nodePath);
        },
        visitExportNamedDeclaration(nodePath) {
            const node = nodePath.value;

            let exportName = '';

            if (!node.declaration && node.specifiers.length) {
                node.specifiers
                .filter(({type}) => type === 'ExportSpecifier')
                .forEach(({exported}) => exports[exported.name] = []);
            } else if (node.declaration) {
                if (node.declaration.type === 'FunctionDeclaration') {
                    exportName = node.declaration.id.name;
                } else if (node.declaration.type === 'VariableDeclaration') {
                    const declarator = node.declaration.declarations
                        .find(({type}) => type === 'VariableDeclarator');
                    exportName = declarator && declarator.id.name;
                }

                if (exportName) {
                    exports[exportName] = [];
                }
            }

            return this.traverse(nodePath);
        },
        visitExportDefaultDeclaration(nodePath) {
            exports.default = [];

            return this.traverse(nodePath);
        },
    });

    Object.keys(globals).forEach(use => {
        imports[use] = true;
    });

    return {
        imports: Object.keys(imports),
        exports: Object.keys(exports),
    };
}
630398
function extractInfoFromAst( ast ) {
    const output = {
        requires: [],
        exports: findExports( ast )
    };
    recursivelyExtractInfoFromAst( ast.program.body, output );
    return output;
}
661635
function (_module) {
        if (! this.name) {
            throw new exports.ValueError({message: 'name is empty'});
        }
        var _exports = _module.exports || _module;
        _exports[this.name] = this;
        return this;
    }
1224112
Comment comment() {
        if (comment == null) {
            String d = documentation();
            if (env.javaScriptScanner != null) {
                env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() {
                    @Override
                    public void report() {
                        env.error(DocImpl.this, "javadoc.JavaScript_in_comment");
                        throw new FatalError();
                    }
                });
            }
            if (env.doclint != null
                    && treePath != null
                    && env.shouldCheck(treePath.getCompilationUnit())
                    && d.equals(getCommentText(treePath))) {
                env.doclint.scan(treePath);
            }
            comment = new Comment(this, d);
        }
        return comment;
    }
1265412
function getDescriptions(comments) {
  var ret = {
    component: comments.description || null,
    props: {}
  };
  comments.tags.forEach(function (tag) {
    if (tag.name) {
      ret.props[tag.name] = tag.description || null;
    }
  });
  return ret;
}
529015
function checkASTandNodeArray(ast, nodes) {
  typeCheckObject(ast, 'ast');
  typeCheckArray(nodes, 'nodes');
  nodes.forEach((node, index) => {
    typeCheckObject(node, 'nodes (index: ' + index + ')');
  });
  runValidator(ast, 'ast');
  nodes.forEach((node, index) => {
    runValidator(node, 'nodes (index: ' + index + ')');
  });
}
451229
function(declarations) {
    var strCss = '';
    if (declarations.type === 'declaration') {
      strCss += '\n\t' + processDeclaration(declarations);
    } else if (declarations.type === 'comment') {
      strCss += ' ' + processComment(declarations);
    }
    return strCss;
  }
1316630
function identifyCommentType(tag) {
    var commentType = null;
    for (var tagName in tag) {
        if (tag.hasOwnProperty(tagName)) {
            switch (tagName) {
                case exports.TAG_NAMES.API:
                case exports.TAG_NAMES.METHOD:
                case exports.TAG_NAMES.METHOD_SIGNATURE:
                case exports.TAG_NAMES.METHOD_NAME:
                case exports.TAG_NAMES.PARAM:
                case exports.TAG_NAMES.RETURN:
                case exports.TAG_NAMES.THROWS:
                    commentType = exports.COMMENT_TYPES.METHOD;
                    break;
                case exports.TAG_NAMES.MODULE:
                case exports.TAG_NAMES.REQUIRES:
                    commentType = exports.COMMENT_TYPES.MODULE;
                    break;
                case exports.TAG_NAMES.CLASS:
                    commentType = exports.COMMENT_TYPES.TYPE;
                    break;
                case exports.TAG_NAMES.VARIABLE_NAME:
                    commentType = exports.COMMENT_TYPES.VARIABLE;
                    break;
            }
        }
    }

    return commentType;
}
295248
def check_imports(self):
        
        modules = []
        for filename in sorted(os.listdir(self.app_path)):
            if not filename.endswith('.py'):
                continue

            fq_path = os.path.join(self.app_path, filename)
            with open(fq_path, 'rb') as f:
                # TODO: fix this
                code_lines = deque([(f.read(), 1)])

                while code_lines:
                    m_status = True
                    code, lineno = code_lines.popleft()  # pylint: disable=W0612
                    try:
                        parsed_code = ast.parse(code)
                        for node in ast.walk(parsed_code):
                            if isinstance(node, ast.Import):
                                for n in node.names:
                                    m = n.name.split('.')[0]
                                    if self.check_import_stdlib(m):
                                        # stdlib module, not need to proceed
                                        continue
                                    m_status = self.check_imported(m)
                                    modules.append(
                                        {'file': filename, 'module': m, 'status': m_status}
                                    )
                            elif isinstance(node, ast.ImportFrom):
                                m = node.module.split('.')[0]
                                if self.check_import_stdlib(m):
                                    # stdlib module, not need to proceed
                                    continue
                                m_status = self.check_imported(m)
                                modules.append({'file': filename, 'module': m, 'status': m_status})
                            else:
                                continue
                    except SyntaxError:
                        pass

        for module_data in modules:
            status = True
            if not module_data.get('status'):
                status = False
                # update validation data errors
                self.validation_data['errors'].append(
                    'Module validation failed for {} (module "{}" could not be imported).'.format(
                        module_data.get('file'), module_data.get('module')
                    )
                )
            # update validation data for module
            self.validation_data['moduleImports'].append(
                {
                    'filename': module_data.get('file'),
                    'module': module_data.get('module'),
                    'status': status,
                }
            )
452194
function getCommentedFunctionNode(node) {
    if (!node.leadingComments) {
        // JSDoc comments are always before the function, so if there is
        // nothing here, we ain't interested.
        return null;
    }
    // console.log("=================");
    // console.log("type: " + node.type);
    // console.log(util.inspect(node));
    /*
     * We handle the following function representations:
     *
     *     Type               Path to Function              Example
     * ==========================================================================================
     * FunctionDeclaration           -                  function foo(bar) {}
     * VariableDeclaration   .declarations[0].init      var foo = function(bar) {}
     * ExpressionStatement   .expression.right          ObjClass.prototype.foo = function(bar) {}
     * MethodDefinition      .value                     class ObjClass { foo(bar) {} }
     * Property              .value                     var obj = { key: function(bar) {} }
     * ReturnStatement       .argument                  return function(foo, bar) {}
     * ArrowFunctionExpression       -                  (foo, bar) => {}
     * ExportNamedDeclaration .declaration              export function foo(bar) {}
     *
     */
    var nodeTypes = [
        "FunctionDeclaration", "ExpressionStatement", "VariableDeclaration",
        "MethodDefinition", "Property", "ReturnStatement", "ArrowFunctionExpression",
        "ExportNamedDeclaration"
    ];
    if (nodeTypes.indexOf(node.type) === -1) {
        return null;
    }
    var funcNode = null;
    switch (node.type) {
        case "FunctionDeclaration":
        case "ArrowFunctionExpression":
            funcNode = node;
            break;
        case "VariableDeclaration":
            funcNode = node.declarations[0].init;
            break;
        case "ExpressionStatement":
            funcNode = node.expression.right;
            break;
        case "MethodDefinition":
            funcNode = node.value;
            break;
        case "Property":
            funcNode = node.value;
            break;
        case "ReturnStatement":
            funcNode = node.argument;
            break;
        case "ExportNamedDeclaration":
            var declaration = node.declaration;
            if (declaration.type === 'VariableDeclaration') {
                funcNode = declaration.declarations[0].init;
            } else {
                funcNode = declaration
            }
            break;
    }
    var funcNodeTypes = ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"];
    if (!funcNode || funcNodeTypes.indexOf(funcNode.type) === -1) {
        // We can't find a function here which can map to leadingComments.
        return null;
    }
    var funcDocs = null;
    for (var i=0; i<node.leadingComments.length; i++) {
        // Block comments are either JSDoc or flow-jsdoc specific in-inline syntax
        if (node.leadingComments[i].type === "Block") {
            funcDocs = extractJsdoc(node.leadingComments[i].value);
            if (funcDocs) { break; }
            // may be inline form with /* */
            funcDocs = extractInlineAnnotations(funcNode, node.leadingComments[i].value);
            if (funcDocs) {
                node.leadingComments[i].update("");
                break;
            }
        }
        else if (node.leadingComments[i].type === "Line") {
            // Line comments can only be flow-jsdoc specific in-line syntax.
            funcDocs = extractInlineAnnotations(funcNode, node.leadingComments[i].value);
            if (funcDocs) {
                node.leadingComments[i].update("");
                break;
            }
        }
    }

    return {
        node: funcNode,
        jsdoc: funcDocs
    };
}
1317146
function getES5ReactComponents(ast) {
  const output = {
    name: '',
    state: {},
    props: {},
    methods: [],
    children: [],
  };
  let iter = [];
  let topJsxComponent;
  let outside;
  const checker = {};
  esrecurse.visit(ast, {
    VariableDeclarator(node) {
      topJsxComponent = node.id.name;
      this.visitChildren(node);
    },
    MemberExpression(node) {
      if (node.property && node.property.name === 'createClass') {
        output.name = topJsxComponent;
      }
      this.visitChildren(node);
    },
    ObjectExpression(node) {
      node.properties.forEach(prop => {
        if (reactMethods.indexOf(prop.key.name) < 0
          && prop.value.type === 'FunctionExpression') {
          output.methods.push(prop.key.name);
        }
      });
      this.visitChildren(node);
    },
    JSXElement(node) {
      output.children = getChildJSXElements(node, output.name);
      output.props = getReactProps(node, output.name);
      if (htmlElements.indexOf(node.openingElement.name.name) < 0) {
        outside = {
          name: node.openingElement.name.name,
          children: getChildJSXElements(node, output.name),
          props: getReactProps(node, output.name),
          state: {},
          methods: [],
        };
      }
    },
  });

  const forIn = esquery(ast, 'ForInStatement').filter(ele => {
    const searched = bfs(ele).filter(n => {
      return n.type === 'JSXElement';
    });
    return searched.length > 0;
  });
  if (forIn.length > 0) iter = iter.concat(forInFinder(forIn, output.name));

  const forLoop = esquery(ast, 'ForStatement').filter(ele => {
    const searched = bfs(ele).filter(n => {
      return n.type === 'JSXElement';
    });
    return searched.length > 0;
  });
  if (forLoop.length > 0) iter = iter.concat(forLoopFinder(forLoop, output.name));

  const higherOrderFunc = esquery(ast, 'CallExpression').filter(ele => {
    let higherOrderChecker = false;
    const searched = bfs(ele).filter(n => {
      return n.type === 'JSXElement';
    });
    if (ele.callee.property && ele.callee.property.name.match(/(map|forEach|filter|reduce)/)) {
      higherOrderChecker = ele.callee.property.name.match(/(map|forEach|filter|reduce)/);
    }
    return searched.length > 0 && higherOrderChecker;
  });
  if (higherOrderFunc.length > 0) {
    iter = iter.concat(higherOrderFunctionFinder(higherOrderFunc, output.name));
  }
  if (outside) output.children.push(outside);
  output.children.forEach((ele, i) => {
    checker[ele.name] = i;
  });

  for (let i = 0; i < iter.length; i++) {
    if (checker.hasOwnProperty(iter[i].jsx.name)) {
      output.children[checker[iter[i].jsx.name]] = iter[i].jsx;
    }
  }

  return output;
}
397778
function misc (options) {
  options.hash.scope = undefined
  options.hash['!kind'] = /module|constructor|external/
  options.hash['!isExported'] = true
  return handlebars.helpers.each(_identifiers(options), options)
}
870261
function exportDeclarations() {

    var docs = getJSONDocs();
    var sugarjs = getDeclaredNamespace('sugarjs');

    var extendedInterfaces = [], nativeNames = [];

    function getNamespaceTypesMerged(num, suffixVal, join, supplementary) {
      var types = nativeNames.concat(supplementary || []);
      var indent = ' '.repeat(num);
      return types.map(function(type) {
        var suffix = typeof suffixVal === 'function' ? suffixVal(type) : suffixVal;
        return type + suffix;
      }).join(' ' + join + '\n' + indent);
    }

    function getChainableNameExternal(type) {
      return '.Chainable' + getChainableBaseGenerics(type, CHAINABLE_RAW_TYPE, 'any');
    }

    function writeDeclarations(filename, declarations) {
      declarations = compact(declarations);
      var hasNoDeclarations = declarations.every(function(dec) {
        return /^\/\//.test(dec);
      });
      if (hasNoDeclarations) {
        return;
      }
      writeFile(path.join(basePath || '', filename), compact(declarations).join('\n\n'));
    }

    sugarjs.interfaces.push(getLocaleInterface(docs.namespaces));

    // Sort namespaces for Sugar to come before SugarNamespace
    // as it has ExtendOptions which are defined first.
    docs.namespaces.sort(collateNamespaces);

    docs.namespaces.forEach(function(namespace) {

      function addExtras(module) {
        addCallbackTypes(module);
        addOptionsInterfaces(module);
      }

      function addCallbackTypes(module) {

        // If the param has multiple types, then move callbacks into the
        // module as named types. Only do this if there are multiple
        // types, otherwise the callback signature can be inlined into
        // the method declaration.
        function getAlternateTypes(method) {
          var types = [];

          function process(arr) {
            if (arr) {
              arr.forEach(function(obj) {
                if (obj.type) {
                  var split = obj.type.split('|');
                  if (split.length > 1) {
                    types = types.concat(split);
                  }
                }
              });
            }
          }

          process(method.params);
          process(method.options);

          return types;
        }

        function addModuleCallbackType(method, callback) {
          var typeExists = module.types.some(function(t) {
            return t.name === callback.name;
          });
          if (!typeExists) {
            var signature = getCallbackSignature(callback, method, namespace);
            if (method.generics) {
              moduleCallbackGenerics[namespace.name + ':' + callback.name] = method.generics;
            }
            module.types.push({
              name: callback.name,
              generics: getGenericSource(callback.generics),
              type: signature
            });
          }
        }

        namespace.methods.forEach(function(method) {
          if (!method.callbacks || methodIsBlacklisted(namespace.name, method)) {
            return;
          }
          getAlternateTypes(method).forEach(function(type) {
            if (type.match(/Fn$/)) {
              var callback = findMethodCallbackByName(method, type);
              addModuleCallbackType(method, callback);
            }
          });
        });

      }

      function addOptionsInterfaces(module) {
        namespace.methods.forEach(function(method) {
          if (!method.options || methodIsBlacklisted(namespace.name, method)) {
            return;
          }

          var params = method.params;
          (method.signatures || []).forEach(function(signature) {
            params = params.concat(signature);
          })

          var optionsParam = params.find(function(param) {
            return param.type.match(/Options$/);
          });

          var optionsGenerics = [];

          var src = method.options.map(function(option) {
            var types = option.type.split('|');
            types = types.map(function(type) {
              if (type.match(/Fn$/)) {
                var callback = findMethodCallbackByName(method, type);
                if (types.length === 1 && type.match(/Fn$/)) {
                  // Inline a callback delcaration
                  type = getCallbackSignature(callback, method, namespace);
                } else {
                  // Refer to callback externally
                  type += getGenericSource(moduleCallbackGenerics[namespace.name + ':' + callback.name]);
                }
                optionsGenerics = optionsGenerics.concat(callback.generics);
              }
              return type;
            });
            return option.name + (option.required ? '' : '?') + ': ' + types.join('|') + ';';
          }).join('\n');

          // Store references to the namespaces that option interfaces exist in
          // so that we can reference them externally later.
          if (!namespace.name.match(/^Sugar/)) {
            optionInterfaceNamespaces[optionsParam.type] = namespace.name;
          }

          moduleOptionsGenerics[namespace.name + ':' + optionsParam.type] = optionsGenerics;
          var name = optionsParam.type + getGenericSource(optionsGenerics);
          module.interfaces.push(getInterfaceSource(name, src));
        });
      }

      function getCallbackSignature(callback, method, namespace) {
        var genericsLength = method.generic && method.generics.length || 0, gen;
        var params = getParams(callback.params, method, namespace);
        var returns = callback.returns ? getType(callback.returns, method) : 'void';
        // Slightly convoluted way of getting generics for the callback by
        // subtracting method generics from what they were previously.
        callback.generics = method.generics.slice(genericsLength);
        return '(' + params + ') => ' + returns;
      }

      function findMethodCallbackByName(method, name) {
        return method.callbacks.find(function(callback) {
          return callback.name === name;
        });
      }


      // Exclude polyfills
      namespace.methods = namespace.methods.filter(function(method) {
        return !method.module.match(/ES[5-7]/);
      });

      // Unpack sets like "[unit]FromNow"
      namespace.methods = unpackMethodSets(namespace.methods);

      if (namespace.name === 'Sugar') {
        addExtras(sugarjs);
        sugarjs.interfaces.push(getSugarInterface(namespace, docs.namespaces));
      } else if (namespace.name === 'SugarNamespace') {
        // The generic "SugarNamespace" interface is required for the
        // "createNamespace" method that needs to return an as-yet undefined
        // type. For existing namespaces, the methods here will instead be
        // mixed into each individual interface. This is required, as each
        // namespace returns a reference to itself, and so (it would appear)
        // cannot use extend.
        addExtras(sugarjs);
        sugarjs.interfaces.push(getSugarNamespaceInterface(namespace));
      } else if (namespace.name === 'Range') {
        sugarjs.interfaces.push(getRangeInterface(namespace));
      } else {
        var module = getDeclaredNamespace(namespace.name);
        addExtras(module);
        module.interfaces.push(getConstructorInterface(namespace, module));
        module.interfaces.push(getChainableBaseInterface(namespace));


        // Export extended interfaces unless opting out.
        if (args['extended-mode'] !== false) {
          extendedInterfaces.push(getExtendedConstructorInterface(namespace));

          // Note: due to Typescript quirkiness about incompatible interfaces,
          // Object.prototype mode cannot be supported here for now.
          if (namespace.name !== 'Object') {
            extendedInterfaces.push(getExtendedInstanceInterface(namespace));
          }
        }

        sugarjs.namespaces.push(getDeclaredNamespaceSource(module));
        nativeNames.push(namespace.name);
      }

    });

    var wrappedGeneric = getGenericSource(CHAINABLE_RAW_TYPE);
    sugarjs.types.push({
      name: 'SugarDefaultChainable' + wrappedGeneric,
      type: getNamespaceTypesMerged(39, getChainableNameExternal, '&'),
    });

    sugarjs.types.push({
      name: 'NativeConstructor',
      type: getNamespaceTypesMerged(25, 'Constructor', '|', ['Boolean', 'Error']),
    });


    var baseDeclarations = [];
    baseDeclarations.push(TS_LICENSE);
    baseDeclarations.push(getDeclaredNamespaceSource(sugarjs, true));
    baseDeclarations.push(getDeclaredModuleSource());
    baseDeclarations.push('declare var Sugar: sugarjs.Sugar;');

    var extendedDeclarations = [];
    extendedDeclarations.push(TS_EXTENDED_LICENSE);
    extendedDeclarations.push('/// <reference path="sugar.d.ts" />');
    extendedDeclarations.push(getInterfaceBlocks(extendedInterfaces));

    writeDeclarations('sugar.d.ts', baseDeclarations);
    writeDeclarations('sugar-extended.d.ts', extendedDeclarations);
  }
694038
def _docspec_comments(obj) -> Dict[str, str]:
    
    # Sometimes our docstring is on the class, and sometimes it's on the initializer,
    # so we've got to check both.
    class_docstring = getattr(obj, '__doc__', None)
    init_docstring = getattr(obj.__init__, '__doc__', None) if hasattr(obj, '__init__') else None

    docstring = class_docstring or init_docstring or ''

    doc = NumpyDocString(docstring)
    params = doc["Parameters"]
    comments: Dict[str, str] = {}

    for line in params:
        # It looks like when there's not a space after the parameter name,
        # numpydocstring parses it incorrectly.
        name_bad = line[0]
        name = name_bad.split(":")[0]

        # Sometimes the line has 3 fields, sometimes it has 4 fields.
        comment = "\n".join(line[-1])

        comments[name] = comment

    return comments
681332
function findJSDocComment(comments, line) {

    if (comments) {
        for (var i = comments.length - 1; i >= 0; i--) {
            if (comments[i].type === "Block" && comments[i].value.charAt(0) === "*") {

                if (line - comments[i].loc.end.line <= 1) {
                    return comments[i];
                }
                break;
            }
        }
    }

    return null;
}