Created
October 16, 2012 16:48
-
-
Save alex-seville/3900493 to your computer and use it in GitHub Desktop.
test uglify parse
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// sample on how to use the parser and walker API to instrument some code | |
var jsp = require("uglify-js").parser; | |
var pro = require("uglify-js").uglify; | |
function instrument(code) { | |
var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want | |
// to have start/end tokens embedded in the | |
// statements | |
var w = pro.ast_walker(); | |
// we're gonna need this to push elements that we're currently looking at, to avoid | |
// endless recursion. | |
var analyzing = []; | |
function do_stat() { | |
var ret; | |
if (this[0].start && analyzing.indexOf(this) < 0) { | |
// without the `analyzing' hack, w.walk(this) would re-enter here leading | |
// to infinite recursion | |
analyzing.push(this); | |
ret = [ "splice", // XXX: "block" is safer | |
[ [ "stat", | |
[ "call", [ "name", "trace" ], | |
[ [ "string", this[0].toString() ], | |
[ "num", this[0].start.line ], | |
[ "num", this[0].start.col ], | |
[ "num", this[0].end.line ], | |
[ "num", this[0].end.col ]]]], | |
w.walk(this) ]]; | |
analyzing.pop(this); | |
} | |
return ret; | |
}; | |
function do_stat_bracketCheck() { | |
var ret; | |
if (this[0].start && analyzing.indexOf(this) < 0) { | |
// without the `analyzing' hack, w.walk(this) would re-enter here leading | |
// to infinite recursion | |
analyzing.push(this); | |
ret = [ "block", // XXX: "block" is safer | |
[ [ "stat", | |
[ "call", [ "name", "trace" ], | |
[ [ "string", this[0].toString() ], | |
[ "num", this[0].start.line ], | |
[ "num", this[0].start.col ], | |
[ "num", this[0].end.line ], | |
[ "num", this[0].end.col ]]]], | |
w.walk(this) ]]; | |
analyzing.pop(this); | |
} | |
return ret; | |
}; | |
function checkBracket(){ | |
var line = this.join(","); | |
console.log("l:"+line); | |
console.log("end:"+JSON.stringify(this[0].end)); | |
if (line.indexOf("stat") < line.indexOf("block") || line.indexOf("block") < 0){ | |
//add block | |
//I don't know how to do it, but I know that the 'stat' leaf needs to be wrapped by a block token | |
//basically we artifically insert brackets | |
return do_stat_bracketCheck.apply(this,arguments); | |
}else{ | |
return do_stat.apply(this,arguments); | |
} | |
} | |
var new_ast = w.with_walkers({ | |
"stat" : do_stat, | |
"label" : do_stat, | |
"break" : do_stat, | |
"continue" : do_stat, | |
"debugger" : do_stat, | |
"var" : do_stat, | |
"const" : do_stat, | |
"return" : do_stat, | |
"throw" : do_stat, | |
"try" : checkBracket, | |
"defun" : do_stat, | |
"if" : checkBracket, | |
"while" : checkBracket, | |
"do" : checkBracket, | |
"for" : checkBracket, | |
"for-in" : checkBracket, | |
"switch" : do_stat, | |
"with" : checkBracket | |
}, function(){ | |
return w.walk(ast); | |
}); | |
return pro.gen_code(new_ast, { beautify: true }); | |
} | |
////// test code follows. | |
var code = instrument(test.toString()); | |
console.log(code); | |
function test() { | |
// simple stats | |
a = 5; | |
c += a + b; | |
"foo"; | |
// var | |
var foo = 5; | |
const bar = 6, baz = 7; | |
// switch block. note we can't track case lines the same way. | |
switch ("foo") { | |
case "foo": | |
return 1; | |
case "bar": | |
return 2; | |
} | |
// for/for in | |
for (var i = 0; i < 5; ++i) { | |
console.log("Hello " + i); | |
} | |
for (var i in [ 1, 2, 3]) { | |
console.log(i); | |
} | |
// EDGE CASE 1, no bracket for BREAKS | |
for (var i = 0; i < 5; ++i) | |
console.log("foo2"); | |
// EDGE case 2, no bracket if BREAKS | |
if (a == 5) | |
console.log("foo3") | |
//EDGE case 3, mis matching the brackets WORKS | |
if (a == -1){ | |
console.log("dujh"); | |
} | |
else | |
{ | |
console.log("foo3"); | |
} | |
//EDGE case 4, multi line logical statement WORKS | |
var out = a == 7 || | |
a == 5; | |
console.log(out); | |
//EDGE case 5, multi line arithmetic WORKS | |
var lastcase = 12+ | |
12+ | |
6; | |
console.log(lastcase); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment