簡體   English   中英

如何從Javascript獲取所有函數和頂級名稱

[英]How to get all functions and top-level names from Javascript

我正在嘗試編寫一個程序,它將在Javascript和另一種語言(Elm)之間自動生成FFI文件。

我想知道,有沒有任何工具可以采取Javascript模塊並列出所有可用的功能,可能與他們的參數數量? 如果它只能做頂級函數,那沒關系,我意識到這會因閉包和thunk等而變得復雜。

是否有可能在Javascript中做一些類似內省的內容,或者我是否必須使用某種解析器/分析器? 如果是這樣,是否存在任何此類工具並且相當成熟/易於使用?

編輯:我意識到JavaScript是動態的。 我的主要目標是為庫和API生成FFI接口,所以那里的東西應該很容易靜態推理,因為它們不會動態地改變。 我沒關系,如果它不完美,我正在尋找一種工具來減輕我對樣板的寫作,而不是保證防彈的東西。

對你來說很棘手的是,創建Javascript模塊有許多不同的約定:將變量放在全局范圍內,從文件返回表格等等。模塊創建也非常動態,因此可能更容易做到來自Javascript內部的東西。

假設您可以使用與模塊對應的javascript對象,可以使用for in循環檢查它:

var myModule = ...
for(var key in myModule){
  if( Object.hasOwnProperty.call(myModule, key) ){
    var func = myModule[key];
    ...
  }
}

要檢查object屬性是否為函數,可以使用typeof運算符:

if(typeod func == "function")

並查看參數的數量,您可以檢查函數的length屬性:

func.length

請注意,如果函數是可變參數或以其他方式從arguments數組獲取參數,則arguments的數量可能是錯誤的。 但檢查源文本的事情也會出錯......

可以在node.js中執行此操作。 運行腳本時出於安全原因: node script.js無法查看nodejs提供的global對象中的函數或變量,但在運行帶有node -e "some script"的腳本時,可以訪問global object函數和變量。

所以我寫了3個腳本。

  1. 讀取需要解析的文件(scriptThatNeedsToBeParsed.js)和解釋文件(interpretFile.js)。 合並它們並使用node -e combinedFileContents創建一個進程
  2. 需要解析的腳本
  3. 用於解釋已解析文件的腳本

scriptThatNeedsToBeParsed.js:

function A(a,b,c){}
var abc;
function T(){}

readFile.js:

我讀的是需要被解析的文件,我定義了兩個變量: START_FROM_THIS_OBJECT文件和內容之前END_TO_THIS_OBJECT文件的內容后。 所以稍后我會知道在哪里搜索函數和變量。

if(process.argv.length !=4 )
{
    console.log("Usage %s <input-file> <interpret-file>",process.argv[0]);
    process.exit(0);
}
var input_file = process.argv[2];
var interpret_file = process.argv[3];
var fs = require('fs');
var fileToParse = ";var START_FROM_THIS_OBJECT;";
fileToParse += fs.readFileSync(input_file, "utf8");
var interpretFile = fs.readFileSync(interpret_file, "utf8");
fileToParse += ";var END_TO_THIS_OBJECT;";
var script = fileToParse + interpretFile;
var child = require('child_process').execFile('node', 
[ 
    '-e', script, 
], function(err, stdout, stderr) { 
    console.log(stdout); 
});

interpretFile.js:我在上面定義的2個控制變量“之間”搜索函數和變量

var printObjects = false;
for(var item in global)
{
    if(item == "END_TO_THIS_OBJECT")
    {
        printObjects = false;
    }
    if(printObjects)
    {

        if(typeof(global[item]) == "function")
        {
            console.log("Function :%s with nr args: %d",item,global[item].length); 
        }
        else
        {
            console.log("Variable :%s with value: %d",item,global[item]); 
        }
    }
    if(item == "START_FROM_THIS_OBJECT")
    {
        printObjects = true;
    }
}

來自nodejs的global對象的最后一部分: console.log(global);

     module:
      { id: '[eval]',
        exports: {},
        parent: undefined,
        filename: 'E:\\LOCAL\\xampp\\htdocs\\nodejs\\[eval]',
        loaded: false,
        children: [],
        paths:
         [ 'E:\\LOCAL\\xampp\\htdocs\\nodejs\\node_modules',
           'E:\\LOCAL\\xampp\\htdocs\\node_modules',
           'E:\\LOCAL\\xampp\\node_modules',
           'E:\\LOCAL\\node_modules',
           'E:\\node_modules' ] },
     __dirname: '.',
     require:
      { [Function: require]
        resolve: [Function],
        main: undefined,
        extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
        registerExtension: [Function],
        cache: {} },
     START_FROM_THIS_OBJECT: undefined,<<<<<<<<<<<<<<
     A: [Function: A],
     abc: undefined,
     T: [Function: T],
     END_TO_THIS_OBJECT: undefined,<<<<<<<<<<<<<<<<

我運行腳本: node readFile.js scriptThatNeedsToBeParsed.js interpretFile.js 這是輸出:
功能:A與nr args:3
變量:abc值:NaN
功能:T與nr args:0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM