[英]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個腳本。
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.