简体   繁体   English

Esprima get 函数和变量声明

[英]Esprima get function and variable declarations

I want to get all function and variable declarations made in a Javascript code.我想获得在 Javascript 代码中进行的所有函数和变量声明。 I use esprima and I wonder if there is script that I can use for my goal?我使用 esprima,我想知道是否有可以用于我的目标的脚本?

For example we have this code:例如我们有这样的代码:

var myVar1;
var myVar2;
function myTestFunction(funcVar1, funcVar2) {
  var myVar3; 
}

What I except:我除了:

Array with variables带变量的数组

["myVar1", "myVar2"]

And an array with functions:还有一个带有函数的数组:

[{"name": "myTestFuncttion", "params":["funcVar1", "funcVar2"], "variables": ["myVar3"]}]

Any ideas how to achieve this?任何想法如何实现这一目标?

Complete solution with fiddle:使用小提琴的完整解决方案:

Here is some JavaScript code for a test-run:下面是一些用于测试运行的 JavaScript 代码:

var hello = 41;
function aaaaa(p1, p2, p3){
    var a1 = 7, a2 = 8;
    var a3 = 9;
    function bbbbb(q1, q2){
        var b1 = 10, b2 = 11;
        return 12;
    }
    var a4 = 99;
    function ccccc(r1, r2, r3){
        var c1 = 13;
        var c2 = 14;
        var c3 = 15, c4 = 16;
        return 17;
    }
    var a5 = 88, a6 = 77;
    function ddddd(s1){
        return s1 === 18
            ? function (x){ return x+1; }
            : function (y){ return 22; }
    }
    return p1 + a3 <= 42 ? 55 : ccc(p1, 0, 0);
}
var world = 42;
function xxxxx(x){
    var z=0;
    return 0;
}

I'm assuming that this is the desired output:我假设这是所需的输出:

{
    "vars": ["hello", "world" ],
    "funcs": [
        {
            "name": "aaaaa",
            "params": ["p1", "p2", "p3"],
            "variables": ["a1","a2","a3","a4","a5","a6"]
        },
        {
            "name": "bbbbb",
            "params": ["q1","q2"],
            "variables": ["b1","b2"]
        },
        {
            "name": "ccccc",
            "params": ["r1","r2","r3"],
            "variables": ["c1","c2","c3","c4"]
        },
        {
            "name": "ddddd",
            "params": ["s1"],
            "variables": []
        },
        {
            "name": "xxxxx",
            "params": ["x"],
            "variables": ["z"]
        }
    ]
}

The lists are flat and the anonymous functions within ddddd are being ignored (they are FunctionExpressions not FunctionDeclarations).列表是扁平的,ddddd 中的匿名函数被忽略(它们是 FunctionExpressions 而不是 FunctionDeclarations)。 Guessing that this is how you want it.猜测这就是你想要的。

Here is the code - probably / hopefully easy to understand without further explanation:这是代码 - 可能/希望很容易理解,无需进一步解释:

function findDeclarations(code){
    var ast = esprima.parse(code);
    var funcDecls = [];
    var globalVarDecls = [];
    var funcStack = [];
    function visitEachAstNode(root, enter, leave){
        function visit(node){
            function isSubNode(key){
                var child = node[key];
                if (child===null) return false;
                var ty = typeof child;
                if (ty!=='object') return false;
                if (child.constructor===Array) return ( key!=='range' );
                if (key==='loc') return false;
                if ('type' in child){
                    if (child.type in esprima.Syntax) return true;
                    debugger; throw new Error('unexpected');
                } else { return false; }
            }
            enter(node);
            var keys = Object.keys(node);
            var subNodeKeys = keys.filter(isSubNode);
            for (var i=0; i<subNodeKeys.length; i++){
                var key = subNodeKeys[i];
                visit(node[key]);
            }
            leave(node);
        }
        visit(root);
    }
    function myEnter(node){
        if (node.type==='FunctionDeclaration') {
            var current = {
                name      : node.id.name,
                params    : node.params.map(function(p){return p.name;}),
                variables : []
            }
            funcDecls.push(current);
            funcStack.push(current);
        }
        if (node.type==='VariableDeclaration'){
            var foundVarNames = node.declarations.map(function(d){ return d.id.name; });
            if (funcStack.length===0){
                globalVarDecls = globalVarDecls.concat(foundVarNames);
            } else {
                var onTopOfStack = funcStack[funcStack.length-1];
                onTopOfStack.variables = onTopOfStack.variables.concat(foundVarNames);
            }
        }
    }
    function myLeave(node){
        if (node.type==='FunctionDeclaration') {
            funcStack.pop();
        }
    }
    visitEachAstNode(ast, myEnter, myLeave);
    return {
        vars  : globalVarDecls,
        funcs : funcDecls
    };
}

for testing, you can type为了测试,你可以输入

JSON.stringify(
    findDeclarations(
        'var hello=41;\n' +
        aaaaa.toString() +
        'var world=42;\n' +
        xxxxx.toString()
    ),
    null, 4
)

You can also use the estraverse package, it's available on github.你也可以使用 estraverse 包,它在 github 上可用。 Then, essentially, the function visitEachAstNode should be replaced by estraverse.traverse, and otherwise you can leave the code unchanged.然后,本质上,函数visitEachAstNode 应该替换为estraverse.traverse,否则您可以保持代码不变。

fiddle小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 函数声明在变量声明之前是否真的被提升了? - Are function declarations really hoisted before variable declarations? 将所有变量声明包装在一个函数中 - Wrap all variable declarations in a function 函数头部的Javascript变量声明 - Javascript variable declarations at the head of a function 为什么变量声明总是可以覆盖函数声明? - Why can variable declarations always overwrite function declarations? 函数声明优先/覆盖变量声明? 起重? 为什么? - Function declarations precedence/overwriting variable declarations? Hoisting? Why? 无法使用Esprima / Acorn解析函数:意外令牌&#39;(&#39; - Unable to parse function with Esprima/Acorn: unexpected token '(' 在 function 参数中声明变量有什么意义? - What is the point of having variable declarations in function parameters? Javascript最佳实践,为什么要使用逗号来链接函数/变量声明? - Javascript best practices, why to use comma to chain function/variable declarations? 如何避免JavaScript中函数输出的多个变量重新声明 - How to avoid multiple variable re-declarations on function outputs in JavaScript 为什么函数声明会被提升而函数表达式不会? - Why do function declarations get hoisted and function expressions don't?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM