function getParameterListAndReturnType()

in lib/index.ts [314:364]


function getParameterListAndReturnType(obj: Function, fn: ts.FunctionExpression): [dom.Parameter[], dom.Type] {
    let usedArguments = false;
    let hasReturn = false;
    const funcStack: boolean[] = [];

    if (isNativeFunction(obj)) {
        const args: dom.Parameter[] = [];
        for (let i = 0; i < obj.length; i++) {
            args.push(create.parameter(`p${i}`, dom.type.any));
        }
        return [args, dom.type.any];
    } else {
        ts.forEachChild(fn, visit);

        let params = [create.parameter('args', dom.type.array(dom.type.any), dom.ParameterFlags.Rest)];
        if (fn.parameters) {
            params = fn.parameters.map(p => create.parameter(`${p.name.getText()}`, inferParameterType(fn, p)));
            if (usedArguments) {
                params.push(create.parameter('args', dom.type.array(dom.type.any), dom.ParameterFlags.Rest));
            }
        }
        return [params, hasReturn ? dom.type.any : dom.type.void];
    }

    function visit(node: ts.Node) {
        switch (node.kind) {
            case ts.SyntaxKind.Identifier:
                if ((node as ts.Identifier).getText() === 'arguments') {
                    usedArguments = true;
                }
                break;
            case ts.SyntaxKind.ReturnStatement:
                const ret = node as ts.ReturnStatement;
                if (funcStack.length === 0 && ret.expression && ret.expression.kind !== ts.SyntaxKind.VoidExpression) {
                    hasReturn = true;
                }
        }
        switch (node.kind) {
            case ts.SyntaxKind.FunctionExpression:
            case ts.SyntaxKind.FunctionDeclaration:
                funcStack.push(true);
                ts.forEachChild(node, visit);
                funcStack.pop();

            default:
                ts.forEachChild(node, visit);
                break;
        }
    }

}