tree transformer api (WIP)
This commit is contained in:
@@ -1014,6 +1014,7 @@ function Compressor(options, false_by_default) {
|
|||||||
self = self.clone();
|
self = self.clone();
|
||||||
self.expression = self.expression.squeeze(compressor);
|
self.expression = self.expression.squeeze(compressor);
|
||||||
self.body = self.body.squeeze(compressor);
|
self.body = self.body.squeeze(compressor);
|
||||||
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
SQUEEZE(AST_Exit, function(self, compressor){
|
SQUEEZE(AST_Exit, function(self, compressor){
|
||||||
@@ -1569,13 +1570,6 @@ function Compressor(options, false_by_default) {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
SQUEEZE(AST_Assign, function(self, compressor){
|
|
||||||
self = self.clone();
|
|
||||||
self.left = self.left.squeeze(compressor);
|
|
||||||
self.right = self.right.squeeze(compressor);
|
|
||||||
return self.optimize(compressor);
|
|
||||||
});
|
|
||||||
|
|
||||||
SQUEEZE(AST_SymbolRef, function(self, compressor){
|
SQUEEZE(AST_SymbolRef, function(self, compressor){
|
||||||
return self.optimize(compressor);
|
return self.optimize(compressor);
|
||||||
});
|
});
|
||||||
|
|||||||
226
lib/transform.js
Normal file
226
lib/transform.js
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
// Tree transformer helpers.
|
||||||
|
// XXX: eventually I should refactor the compressor to use this infrastructure.
|
||||||
|
|
||||||
|
function TreeTransformer(before, after) {
|
||||||
|
this.before = before;
|
||||||
|
this.after = after;
|
||||||
|
this.stack = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeTransformer.prototype = {
|
||||||
|
push: function (node) {
|
||||||
|
this.stack.push(node);
|
||||||
|
},
|
||||||
|
pop: function() {
|
||||||
|
return this.stack.pop();
|
||||||
|
},
|
||||||
|
parent: function (n) {
|
||||||
|
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(undefined){
|
||||||
|
|
||||||
|
function _(node, descend) {
|
||||||
|
node.DEFMETHOD("transform", function(tw, in_list){
|
||||||
|
var x, y;
|
||||||
|
tw.push(this);
|
||||||
|
x = tw.before(this, function(){
|
||||||
|
descend(x, tw);
|
||||||
|
}, in_list);
|
||||||
|
if (x === undefined) {
|
||||||
|
x = this.clone();
|
||||||
|
descend(x, tw);
|
||||||
|
y = tw.after(this, in_list);
|
||||||
|
if (y !== undefined) x = y;
|
||||||
|
}
|
||||||
|
tw.pop();
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function do_list(list, tw) {
|
||||||
|
return MAP(list, function(node){
|
||||||
|
return node.transform(tw, true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_(AST_Node, noop);
|
||||||
|
|
||||||
|
_(AST_LabeledStatement, function(self, tw){
|
||||||
|
self.label = self.label.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_SimpleStatement, function(self, tw){
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_BlockStatement, function(self, tw){
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Block, function(self, tw){
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_DWLoop, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_For, function(self, tw){
|
||||||
|
if (self.init) self.init = self.init.transform(tw);
|
||||||
|
if (self.condition) self.condition = self.condition.transform(tw);
|
||||||
|
if (self.step) self.step = self.step.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_ForIn, function(self, tw){
|
||||||
|
self.init = self.init.transform(tw);
|
||||||
|
self.object = self.object.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_With, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Exit, function(self, tw){
|
||||||
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_LoopControl, function(self, tw){
|
||||||
|
if (self.label) self.label = self.label.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_If, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Switch, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Case, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Try, function(self, tw){
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Catch, function(self, tw){
|
||||||
|
self.argname = self.argname.transform(tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Definitions, function(self, tw){
|
||||||
|
self.definitions = do_list(self.definitions, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_VarDef, function(self, tw){
|
||||||
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Lambda, function(self, tw){
|
||||||
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
|
self.argnames = do_list(self.argnames, tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Call, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.args = do_list(self.args, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Seq, function(self, tw){
|
||||||
|
self.car = self.car.transform(tw);
|
||||||
|
self.cdr = self.cdr.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Dot, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Sub, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.property = self.property.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Unary, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Binary, function(self, tw){
|
||||||
|
self.left = self.left.transform(tw);
|
||||||
|
self.right = self.right.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Conditional, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.consequent = self.consequent.transform(tw);
|
||||||
|
self.alternative = self.alternative.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Array, function(self, tw){
|
||||||
|
self.elements = do_list(self.elements, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Object, function(self, tw){
|
||||||
|
self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_ObjectProperty, function(self, tw){
|
||||||
|
self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -9,15 +9,31 @@ var filename = process.argv[2];
|
|||||||
var code = fs.readFileSync(filename, "utf8");
|
var code = fs.readFileSync(filename, "utf8");
|
||||||
|
|
||||||
var ast = UglifyJS.parse(code);
|
var ast = UglifyJS.parse(code);
|
||||||
ast.figure_out_scope();
|
|
||||||
ast = ast.squeeze(UglifyJS.Compressor());
|
|
||||||
|
|
||||||
ast.compute_char_frequency();
|
var tt = new UglifyJS.TreeTransformer(
|
||||||
UglifyJS.base54.sort();
|
function before(node, descend) {
|
||||||
|
if (node instanceof UglifyJS.AST_Var) {
|
||||||
|
//return new UglifyJS.AST_EmptyStatement(node);
|
||||||
|
return UglifyJS.MAP.skip;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function after(node) {
|
||||||
|
console.log("After ", node.TYPE);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ast.figure_out_scope();
|
var x = ast.transform(tt);
|
||||||
ast.scope_warnings();
|
sys.print(x.print_to_string({ beautify: true }));
|
||||||
ast.mangle_names();
|
|
||||||
|
|
||||||
sys.error(UglifyJS.base54.get());
|
// ast.figure_out_scope();
|
||||||
sys.print(ast.print_to_string({ beautify: true }));
|
// ast = ast.squeeze(UglifyJS.Compressor());
|
||||||
|
|
||||||
|
// ast.compute_char_frequency();
|
||||||
|
// UglifyJS.base54.sort();
|
||||||
|
|
||||||
|
// ast.figure_out_scope();
|
||||||
|
// ast.scope_warnings();
|
||||||
|
// ast.mangle_names();
|
||||||
|
|
||||||
|
// sys.error(UglifyJS.base54.get());
|
||||||
|
// sys.print(ast.print_to_string({ beautify: true }));
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ function load_global(file) {
|
|||||||
load_global("../lib/utils.js");
|
load_global("../lib/utils.js");
|
||||||
load_global("../lib/ast.js");
|
load_global("../lib/ast.js");
|
||||||
load_global("../lib/parse.js");
|
load_global("../lib/parse.js");
|
||||||
|
load_global("../lib/transform.js");
|
||||||
load_global("../lib/scope.js");
|
load_global("../lib/scope.js");
|
||||||
load_global("../lib/output.js");
|
load_global("../lib/output.js");
|
||||||
load_global("../lib/compress.js");
|
load_global("../lib/compress.js");
|
||||||
|
|||||||
Reference in New Issue
Block a user