2015-04-07 11 views
12

Ich würde gerne einige JavasScript-Code analysieren, um alle Methoden für eine gegebene "Klasse" mit uglify js2 aufzulisten. In meinem Fall gibt der TreeWalker einen Knoten mit name : null zurück und es gibt keine Informationen, die Rückschlüsse auf Eltern erlauben.Wie parsen und iterieren Sie Prototyp-Methoden mit Uglify.js?

Kennt jemand einen anderen Ansatz? Ich erwartete etwas wie name : "Test.method_name"
Bisher tryied ich die Folowing ...

parsetests.js

var UglifyJS = require("uglify-js2"); 
var util = require("util"); 
var code = require("fs").readFileSync("test.js").toString(); 
var toplevel = UglifyJS.parse(code); 
var log = function(obj, depth) { 
    console.log(util.inspect(obj, showHidden=false, depth, colorize=true)); 
}; 
var toplevel = UglifyJS.parse(code); 
var walker = new UglifyJS.TreeWalker(function(node){ 
    if (node instanceof UglifyJS.AST_Function) { 
     log(node, 2);   
    } 
}); 
toplevel.walk(walker); 

test.js

function Test(argument1) { 
    var m = argument1 + "test"; 
    return this; 
} 


Test.prototype.method_name = function(first_argument) { 
    // body... 
    return "a"; 
}; 

UglifyJS.TreeWalker Knoten:

{ end: 
    { file: null, 
    comments_before: [], 
    nlb: true, 
    endpos: 156, 
    pos: 155, 
    col: 0, 
    line: 10, 
    value: '}', 
    type: 'punc' }, 
    start: 
    { file: null, 
    comments_before: [], 
    nlb: false, 
    endpos: 111, 
    pos: 103, 
    col: 29, 
    line: 7, 
    value: 'function', 
    type: 'keyword' }, 
    body: 
    [ { end: [Object], 
     start: [Object], 
     value: [Object] } ], 
    cname: undefined, 
    enclosed: undefined, 
    parent_scope: undefined, 
    uses_eval: undefined, 
    uses_with: undefined, 
    functions: undefined, 
    variables: undefined, 
    directives: undefined, 
    uses_arguments: undefined, 
    argnames: 
    [ { end: [Object], 
     start: [Object], 
     thedef: undefined, 
     name: 'first_argument', 
     scope: undefined, 
     init: undefined } ], 
    name: null } 
+1

Möchten Sie ausschließlich mit uglify-js2 arbeiten oder sind Sie offen für andere Lösungen? –

+0

Dies wird nicht so einfach sein, wie Sie denken, da Sie die dynamische Zuweisung über andere Methoden verfolgen müssen, es sei denn, Sie wissen, dass sie auf eine bestimmte Weise ausgeführt wurden. Ich denke, [Tern] (http://ternjs.net) macht ein bisschen Analyse, aber ich bin mir nicht sicher, ob das für Ihre Bedürfnisse geeignet ist. –

Antwort

5

Ich schrieb ein Skript in der Lage, diese Syntax zu analysieren und zu identifizieren. Ich habe es unter geöffnet.

Derzeit umfasst es eine Reihe von Anwendungsfällen beschrieben unter https://github.com/s-a/deep-js/blob/3c1e52b75be197ff19a5530d011e999416e21afd/use-case-main.js Und getestet mit https://github.com/s-a/deep-js/tree/3c1e52b75be197ff19a5530d011e999416e21afd/test. Sie können die Ergebnisse unter https://travis-ci.org/s-a/deep-js/builds/58511486 sehen. Der aktuelle Code-Status ist begrenzt. Zum Beispiel könnte this momentan nicht aufgelöst werden, wenn es über eine andere Variable wie self verwendet wird. Tief verschachtelte Zuweisungen und Namespaces sind ein anderes Problem. Bisher ist es jedoch stabil, wenn die Komplexität des Codes nicht zu hoch ist.

0

In Ihrem Fall e Die Funktion hat keinen Namen, sie ist einer Eigenschaft zugeordnet, die einen Namen hat. Sie müssen Ihre Funktion wie folgt benennen:

Test.prototype.method_name = function method_name(first_argument) { 
    // body... 
    return "a"; 
}; 
+1

Ich glaube nicht, dass Sie verstehen, was die Frage verlangt. Das OP versucht, die Methoden, die ein Konstruktor hat, statisch zu bestimmen, den Namen einer Funktion während des Debuggens nicht zu finden. –

+0

@ Qantas94Heavy das ist genau der Punkt. –