12

I 'd like to parse some JavasScript code to list all methods for a given "class" using uglify js 2. In my case the TreeWalker returns a node with name : null and there is no information that allow conclusions to parent.

Does anyone know a different approach? I expected something like name : "Test.method_name"
So far I tryied the 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 node:

{ 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 }
Stephan Ahlf
  • 2,839
  • 3
  • 31
  • 65
  • 1
    Do you exclusively want to use uglify-js2 or are you open to other solutions? – Tristan Foureur Apr 11 '15 at 22:37
  • This won't be as easy as you think as you'd need to track dynamic allocation through other methods, unless you know they were done a certain way. I think [Tern](http://ternjs.net) does a bit of analysis like this but I'm not sure whether that's suitable for your needs. – Qantas 94 Heavy Apr 13 '15 at 11:51

2 Answers2

5

I wrote a script able to parse and identify those syntax. I open sourced it at https://github.com/s-a/deep-js.

Currently it covers a bunch of use cases described at https://github.com/s-a/deep-js/blob/3c1e52b75be197ff19a5530d011e999416e21afd/use-case-main.js And tested with https://github.com/s-a/deep-js/tree/3c1e52b75be197ff19a5530d011e999416e21afd/test. You can see the results at https://travis-ci.org/s-a/deep-js/builds/58511486. Current code state is limited. For example this could currently not resolved if used over another var like self. Deep nested assignments and namespaces are another problem. However so far it is stable if code complexity is not too high.

Stephan Ahlf
  • 2,839
  • 3
  • 31
  • 65
0

In your case the function does not have a name, it is assigned to a property which has a name. You must name your function as follows:

Test.prototype.method_name = function method_name(first_argument) {
    // body...
    return "a";
};
Matthew Herbst
  • 21,357
  • 19
  • 68
  • 107
Georgi-it
  • 3,458
  • 1
  • 17
  • 23
  • 1
    I don't think you quite understand what the question is asking for. The OP is looking to statically determine the methods that a constructor has, not find the name of a function during debugging. – Qantas 94 Heavy Apr 15 '15 at 01:58