src/js/instrument/esnstrument.js
function hoistFunctionDeclaration(ast, hoisteredFunctions) {
        var key, child, startIndex = 0;
        if (ast.body) {
            var newBody = [];
            if (ast.body.length > 0) { // do not hoister function declaration before J$.Fe or J$.Se
                if (ast.body[0].type === 'ExpressionStatement') {
                    if (ast.body[0].expression.type === 'CallExpression') {
                        if (ast.body[0].expression.callee.object &&
                            ast.body[0].expression.callee.object.name === 'J$'
                            && ast.body[0].expression.callee.property
                            &&
                            (ast.body[0].expression.callee.property.name === 'Se' || ast.body[0].
                                expression.callee.property.name === 'Fe')) {

                            newBody.push(ast.body[0]);
                            startIndex = 1;
                        }
                    }
                }
            }
            for (var i = startIndex; i < ast.body.length; i++) {

                if (ast.body[i].type === 'FunctionDeclaration') {
                    newBody.push(ast.body[i]);
                    if (newBody.length !== i + 1) {
                        hoisteredFunctions.push(ast.body[i].id.name);
                    }
                }
            }
            for (var i = startIndex; i < ast.body.length; i++) {
                if (ast.body[i].type !== 'FunctionDeclaration') {
                    newBody.push(ast.body[i]);
                }
            }
            while (ast.body.length > 0) {
                ast.body.pop();
            }
            for (var i = 0; i < newBody.length; i++) {
                ast.body.push(newBody[i]);
            }
        } else {
            //console.log(typeof ast.body);
        }
        for (key in ast) {
            if (ast.hasOwnProperty(key)) {
                child = ast[key];
                if (typeof child === 'object' && child !== null && key !==
                    "scope") {
                    hoistFunctionDeclaration(child, hoisteredFunctions);
                }

            }
        }

        return ast;
    }
function hoistFunctionDeclaration(ast, hoisteredFunctions) {
        var key, child, startIndex = 0;
        if (ast.body) {
            var newBody = [];
            if (ast.body.length > 0) { // do not hoister function declaration before J$.Fe or J$.Se
                if (ast.body[0].type === 'ExpressionStatement') {
                    if (ast.body[0].expression.type === 'CallExpression') {
                        if (ast.body[0].expression.callee.object &&
                            ast.body[0].expression.callee.object.name === 'J$'
                            && ast.body[0].expression.callee.property
                            &&
                            (ast.body[0].expression.callee.property.name === 'Se' || ast.body[0].
                                expression.callee.property.name === 'Fe')) {

                            newBody.push(ast.body[0]);
                            startIndex = 1;
                        }
                    }
                }
            }
            for (var i = startIndex; i < ast.body.length; i++) {

                if (ast.body[i].type === 'FunctionDeclaration') {
                    newBody.push(ast.body[i]);
                    if (newBody.length !== i + 1) {
                        hoisteredFunctions.push(ast.body[i].id.name);
                    }
                }
            }
            for (var i = startIndex; i < ast.body.length; i++) {
                if (ast.body[i].type !== 'FunctionDeclaration') {
                    newBody.push(ast.body[i]);
                }
            }
            while (ast.body.length > 0) {
                ast.body.pop();
            }
            for (var i = 0; i < newBody.length; i++) {
                ast.body.push(newBody[i]);
            }
        } else {
            //console.log(typeof ast.body);
        }
        for (key in ast) {
            if (ast.hasOwnProperty(key)) {
                child = ast[key];
                if (typeof child === 'object' && child !== null && key !==
                    "scope") {
                    hoistFunctionDeclaration(child, hoisteredFunctions);
                }

            }
        }

        return ast;
    }
function hoistFunctionDeclaration ( ast , hoisteredFunctions ) { var key , child , startIndex = 0 ; if ( ast . body ) { var newBody = [ ] ; if ( ast . body . length > 0 ) { // do not hoister function declaration before J$.Fe or J$.Se if ( ast . body [ 0 ] . type === 'ExpressionStatement' ) { if ( ast . body [ 0 ] . expression . type === 'CallExpression' ) { if ( ast . body [ 0 ] . expression . callee . object && ast . body [ 0 ] . expression . callee . object . name === 'J$' && ast . body [ 0 ] . expression . callee . property && ( ast . body [ 0 ] . expression . callee . property . name === 'Se' || ast . body [ 0 ] . expression . callee . property . name === 'Fe' ) ) { newBody . push ( ast . body [ 0 ] ) ; startIndex = 1 ; } } } } for ( var i = startIndex ; i < ast . body . length ; i ++ ) { if ( ast . body [ i ] . type === 'FunctionDeclaration' ) { newBody . push ( ast . body [ i ] ) ; if ( newBody . length !== i + 1 ) { hoisteredFunctions . push ( ast . body [ i ] . id . name ) ; } } } for ( var i = startIndex ; i < ast . body . length ; i ++ ) { if ( ast . body [ i ] . type !== 'FunctionDeclaration' ) { newBody . push ( ast . body [ i ] ) ; } } while ( ast . body . length > 0 ) { ast . body . pop ( ) ; } for ( var i = 0 ; i < newBody . length ; i ++ ) { ast . body . push ( newBody [ i ] ) ; } } else { //console.log(typeof ast.body); } for ( key in ast ) { if ( ast . hasOwnProperty ( key ) ) { child = ast [ key ] ; if ( typeof child === 'object' && child !== null && key !== "scope" ) { hoistFunctionDeclaration ( child , hoisteredFunctions ) ; } } } return ast ; }
START of Liang Gong's AST post-processor
START of Liang Gong s AST post - processor