Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88c8f4e363 | ||
|
|
ab36b9b10a | ||
|
|
28330913d8 | ||
|
|
766a4147d4 | ||
|
|
915c7e234d | ||
|
|
e54ddcbb8a | ||
|
|
9e19e63551 |
77
lib/ast.js
77
lib/ast.js
@@ -44,21 +44,21 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function DEFNODE(type, props, methods, base) {
|
function DEFNODE(type, props, methods, base) {
|
||||||
if (arguments.length < 4) base = AST_Node;
|
if (typeof base === "undefined") base = AST_Node;
|
||||||
if (!props) props = [];
|
props = props ? props.split(/\s+/) : [];
|
||||||
else props = props.split(/\s+/);
|
|
||||||
var self_props = props;
|
var self_props = props;
|
||||||
if (base && base.PROPS)
|
if (base && base.PROPS) props = props.concat(base.PROPS);
|
||||||
props = props.concat(base.PROPS);
|
var code = [
|
||||||
var code = "return function AST_" + type + "(props){ if (props) { ";
|
"return function AST_", type, "(props){",
|
||||||
for (var i = props.length; --i >= 0;) {
|
"if(props){",
|
||||||
code += "this." + props[i] + " = props." + props[i] + ";";
|
];
|
||||||
}
|
props.forEach(function(prop) {
|
||||||
|
code.push("this.", prop, "=props.", prop, ";");
|
||||||
|
});
|
||||||
var proto = base && new base;
|
var proto = base && new base;
|
||||||
if (proto && proto.initialize || (methods && methods.initialize))
|
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
||||||
code += "this.initialize();";
|
code.push("}}");
|
||||||
code += "}}";
|
var ctor = new Function(code.join(""))();
|
||||||
var ctor = new Function(code)();
|
|
||||||
if (proto) {
|
if (proto) {
|
||||||
ctor.prototype = proto;
|
ctor.prototype = proto;
|
||||||
ctor.BASE = base;
|
ctor.BASE = base;
|
||||||
@@ -71,11 +71,11 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
if (type) {
|
if (type) {
|
||||||
ctor.prototype.TYPE = ctor.TYPE = type;
|
ctor.prototype.TYPE = ctor.TYPE = type;
|
||||||
}
|
}
|
||||||
if (methods) for (i in methods) if (HOP(methods, i)) {
|
if (methods) for (var name in methods) if (HOP(methods, name)) {
|
||||||
if (/^\$/.test(i)) {
|
if (/^\$/.test(name)) {
|
||||||
ctor[i.substr(1)] = methods[i];
|
ctor[name.substr(1)] = methods[name];
|
||||||
} else {
|
} else {
|
||||||
ctor.prototype[i] = methods[i];
|
ctor.prototype[name] = methods[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctor.DEFMETHOD = function(name, method) {
|
ctor.DEFMETHOD = function(name, method) {
|
||||||
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
exports["AST_" + type] = ctor;
|
exports["AST_" + type] = ctor;
|
||||||
}
|
}
|
||||||
return ctor;
|
return ctor;
|
||||||
};
|
}
|
||||||
|
|
||||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
|
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
|
||||||
}, null);
|
}, null);
|
||||||
@@ -158,11 +158,10 @@ function walk_body(node, visitor) {
|
|||||||
var body = node.body;
|
var body = node.body;
|
||||||
if (body instanceof AST_Statement) {
|
if (body instanceof AST_Statement) {
|
||||||
body._walk(visitor);
|
body._walk(visitor);
|
||||||
|
} else body.forEach(function(node) {
|
||||||
|
node._walk(visitor);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else for (var i = 0, len = body.length; i < len; i++) {
|
|
||||||
body[i]._walk(visitor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var AST_Block = DEFNODE("Block", "body", {
|
var AST_Block = DEFNODE("Block", "body", {
|
||||||
$documentation: "A body of statements (usually braced)",
|
$documentation: "A body of statements (usually braced)",
|
||||||
@@ -365,10 +364,9 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
|||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
if (this.name) this.name._walk(visitor);
|
if (this.name) this.name._walk(visitor);
|
||||||
var argnames = this.argnames;
|
this.argnames.forEach(function(argname) {
|
||||||
for (var i = 0, len = argnames.length; i < len; i++) {
|
argname._walk(visitor);
|
||||||
argnames[i]._walk(visitor);
|
});
|
||||||
}
|
|
||||||
walk_body(this, visitor);
|
walk_body(this, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -528,10 +526,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
var definitions = this.definitions;
|
this.definitions.forEach(function(defn) {
|
||||||
for (var i = 0, len = definitions.length; i < len; i++) {
|
defn._walk(visitor);
|
||||||
definitions[i]._walk(visitor);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -682,10 +679,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
var elements = this.elements;
|
this.elements.forEach(function(element) {
|
||||||
for (var i = 0, len = elements.length; i < len; i++) {
|
element._walk(visitor);
|
||||||
elements[i]._walk(visitor);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -697,10 +693,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
var properties = this.properties;
|
this.properties.forEach(function(prop) {
|
||||||
for (var i = 0, len = properties.length; i < len; i++) {
|
prop._walk(visitor);
|
||||||
properties[i]._walk(visitor);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -839,12 +834,12 @@ var AST_NaN = DEFNODE("NaN", null, {
|
|||||||
|
|
||||||
var AST_Undefined = DEFNODE("Undefined", null, {
|
var AST_Undefined = DEFNODE("Undefined", null, {
|
||||||
$documentation: "The `undefined` value",
|
$documentation: "The `undefined` value",
|
||||||
value: (function(){}())
|
value: function(){}()
|
||||||
}, AST_Atom);
|
}, AST_Atom);
|
||||||
|
|
||||||
var AST_Hole = DEFNODE("Hole", null, {
|
var AST_Hole = DEFNODE("Hole", null, {
|
||||||
$documentation: "A hole in an array",
|
$documentation: "A hole in an array",
|
||||||
value: (function(){}())
|
value: function(){}()
|
||||||
}, AST_Atom);
|
}, AST_Atom);
|
||||||
|
|
||||||
var AST_Infinity = DEFNODE("Infinity", null, {
|
var AST_Infinity = DEFNODE("Infinity", null, {
|
||||||
@@ -872,7 +867,7 @@ function TreeWalker(callback) {
|
|||||||
this.visit = callback;
|
this.visit = callback;
|
||||||
this.stack = [];
|
this.stack = [];
|
||||||
this.directives = Object.create(null);
|
this.directives = Object.create(null);
|
||||||
};
|
}
|
||||||
TreeWalker.prototype = {
|
TreeWalker.prototype = {
|
||||||
_visit: function(node, descend) {
|
_visit: function(node, descend) {
|
||||||
this.push(node);
|
this.push(node);
|
||||||
|
|||||||
221
lib/compress.js
221
lib/compress.js
@@ -136,7 +136,7 @@ function Compressor(options, false_by_default) {
|
|||||||
var sequences = this.options["sequences"];
|
var sequences = this.options["sequences"];
|
||||||
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
||||||
this.warnings_produced = {};
|
this.warnings_produced = {};
|
||||||
};
|
}
|
||||||
|
|
||||||
Compressor.prototype = new TreeTransformer;
|
Compressor.prototype = new TreeTransformer;
|
||||||
merge(Compressor.prototype, {
|
merge(Compressor.prototype, {
|
||||||
@@ -201,11 +201,10 @@ merge(Compressor.prototype, {
|
|||||||
},
|
},
|
||||||
before: function(node, descend, in_list) {
|
before: function(node, descend, in_list) {
|
||||||
if (node._squeezed) return node;
|
if (node._squeezed) return node;
|
||||||
var was_scope = false;
|
var is_scope = node instanceof AST_Scope;
|
||||||
if (node instanceof AST_Scope) {
|
if (is_scope) {
|
||||||
node = node.hoist_properties(this);
|
node.hoist_properties(this);
|
||||||
node = node.hoist_declarations(this);
|
node.hoist_declarations(this);
|
||||||
was_scope = true;
|
|
||||||
}
|
}
|
||||||
// Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize()
|
// Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize()
|
||||||
// would call AST_Node.transform() if a different instance of AST_Node is
|
// would call AST_Node.transform() if a different instance of AST_Node is
|
||||||
@@ -220,7 +219,7 @@ merge(Compressor.prototype, {
|
|||||||
// output and performance.
|
// output and performance.
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
var opt = node.optimize(this);
|
var opt = node.optimize(this);
|
||||||
if (was_scope && opt instanceof AST_Scope) {
|
if (is_scope) {
|
||||||
opt.drop_unused(this);
|
opt.drop_unused(this);
|
||||||
descend(opt, this);
|
descend(opt, this);
|
||||||
}
|
}
|
||||||
@@ -229,19 +228,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
(function(){
|
(function(OPT) {
|
||||||
|
|
||||||
function OPT(node, optimizer) {
|
|
||||||
node.DEFMETHOD("optimize", function(compressor){
|
|
||||||
var self = this;
|
|
||||||
if (self._optimized) return self;
|
|
||||||
if (compressor.has_directive("use asm")) return self;
|
|
||||||
var opt = optimizer(self, compressor);
|
|
||||||
opt._optimized = true;
|
|
||||||
return opt;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
OPT(AST_Node, function(self, compressor) {
|
OPT(AST_Node, function(self, compressor) {
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
@@ -531,14 +518,15 @@ merge(Compressor.prototype, {
|
|||||||
var sym = node.left;
|
var sym = node.left;
|
||||||
if (!(sym instanceof AST_SymbolRef)) return;
|
if (!(sym instanceof AST_SymbolRef)) return;
|
||||||
var d = sym.definition();
|
var d = sym.definition();
|
||||||
|
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
||||||
|
d.assignments++;
|
||||||
|
if (!safe) return;
|
||||||
var fixed = d.fixed;
|
var fixed = d.fixed;
|
||||||
if (!fixed && node.operator != "=") return;
|
if (!fixed && node.operator != "=") return;
|
||||||
if (!safe_to_assign(tw, d, sym.scope, node.right)) return;
|
|
||||||
var eq = node.operator == "=";
|
var eq = node.operator == "=";
|
||||||
var value = eq ? node.right : node;
|
var value = eq ? node.right : node;
|
||||||
if (is_modified(compressor, tw, node, value, 0)) return;
|
if (is_modified(compressor, tw, node, value, 0)) return;
|
||||||
d.references.push(sym);
|
d.references.push(sym);
|
||||||
d.assignments++;
|
|
||||||
if (!eq) d.chained = true;
|
if (!eq) d.chained = true;
|
||||||
d.fixed = eq ? function() {
|
d.fixed = eq ? function() {
|
||||||
return node.right;
|
return node.right;
|
||||||
@@ -670,7 +658,7 @@ merge(Compressor.prototype, {
|
|||||||
// So existing transformation rules can work on them.
|
// So existing transformation rules can work on them.
|
||||||
node.argnames.forEach(function(arg, i) {
|
node.argnames.forEach(function(arg, i) {
|
||||||
var d = arg.definition();
|
var d = arg.definition();
|
||||||
if (!node.uses_arguments && d.fixed === undefined) {
|
if (d.fixed === undefined && (!node.uses_arguments || tw.has_directive("use strict"))) {
|
||||||
d.fixed = function() {
|
d.fixed = function() {
|
||||||
return iife.args[i] || make_node(AST_Undefined, iife);
|
return iife.args[i] || make_node(AST_Undefined, iife);
|
||||||
};
|
};
|
||||||
@@ -773,11 +761,12 @@ merge(Compressor.prototype, {
|
|||||||
var exp = node.expression;
|
var exp = node.expression;
|
||||||
if (!(exp instanceof AST_SymbolRef)) return;
|
if (!(exp instanceof AST_SymbolRef)) return;
|
||||||
var d = exp.definition();
|
var d = exp.definition();
|
||||||
|
var safe = safe_to_assign(tw, d, exp.scope, true);
|
||||||
|
d.assignments++;
|
||||||
|
if (!safe) return;
|
||||||
var fixed = d.fixed;
|
var fixed = d.fixed;
|
||||||
if (!fixed) return;
|
if (!fixed) return;
|
||||||
if (!safe_to_assign(tw, d, exp.scope, true)) return;
|
|
||||||
d.references.push(exp);
|
d.references.push(exp);
|
||||||
d.assignments++;
|
|
||||||
d.chained = true;
|
d.chained = true;
|
||||||
d.fixed = function() {
|
d.fixed = function() {
|
||||||
return make_node(AST_Binary, node, {
|
return make_node(AST_Binary, node, {
|
||||||
@@ -894,7 +883,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!props.end) props.end = orig.end;
|
if (!props.end) props.end = orig.end;
|
||||||
}
|
}
|
||||||
return new ctor(props);
|
return new ctor(props);
|
||||||
};
|
}
|
||||||
|
|
||||||
function make_sequence(orig, expressions) {
|
function make_sequence(orig, expressions) {
|
||||||
if (expressions.length == 1) return expressions[0];
|
if (expressions.length == 1) return expressions[0];
|
||||||
@@ -971,21 +960,21 @@ merge(Compressor.prototype, {
|
|||||||
if (thing instanceof AST_EmptyStatement) return [];
|
if (thing instanceof AST_EmptyStatement) return [];
|
||||||
if (thing instanceof AST_Statement) return [ thing ];
|
if (thing instanceof AST_Statement) return [ thing ];
|
||||||
throw new Error("Can't convert thing to statement array");
|
throw new Error("Can't convert thing to statement array");
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_empty(thing) {
|
function is_empty(thing) {
|
||||||
if (thing === null) return true;
|
if (thing === null) return true;
|
||||||
if (thing instanceof AST_EmptyStatement) return true;
|
if (thing instanceof AST_EmptyStatement) return true;
|
||||||
if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
|
if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
|
|
||||||
function loop_body(x) {
|
function loop_body(x) {
|
||||||
if (x instanceof AST_IterationStatement) {
|
if (x instanceof AST_IterationStatement) {
|
||||||
return x.body instanceof AST_BlockStatement ? x.body : x;
|
return x.body instanceof AST_BlockStatement ? x.body : x;
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
|
||||||
function root_expr(prop) {
|
function root_expr(prop) {
|
||||||
while (prop instanceof AST_PropAccess) prop = prop.expression;
|
while (prop instanceof AST_PropAccess) prop = prop.expression;
|
||||||
@@ -1406,7 +1395,10 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
} else if (expr instanceof AST_VarDef) {
|
} else if (expr instanceof AST_VarDef) {
|
||||||
if (expr.value) {
|
if (expr.value) {
|
||||||
|
var def = expr.name.definition();
|
||||||
|
if (def.references.length > def.replaced) {
|
||||||
candidates.push(hit_stack.slice());
|
candidates.push(hit_stack.slice());
|
||||||
|
}
|
||||||
extract_candidates(expr.value);
|
extract_candidates(expr.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1476,7 +1468,6 @@ merge(Compressor.prototype, {
|
|||||||
var def = expr.name.definition();
|
var def = expr.name.definition();
|
||||||
if (!member(expr.name, def.orig)) return;
|
if (!member(expr.name, def.orig)) return;
|
||||||
var referenced = def.references.length - def.replaced;
|
var referenced = def.references.length - def.replaced;
|
||||||
if (!referenced) return;
|
|
||||||
var declared = def.orig.length - def.eliminated;
|
var declared = def.orig.length - def.eliminated;
|
||||||
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
||||||
|| (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
|
|| (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
|
||||||
@@ -1947,7 +1938,7 @@ merge(Compressor.prototype, {
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
var left = prev.body;
|
var left = prev.body;
|
||||||
return make_sequence(left, [ left, right ]).transform(compressor);
|
return make_sequence(left, [ left, right ]).transform(compressor);
|
||||||
};
|
}
|
||||||
var n = 0, prev;
|
var n = 0, prev;
|
||||||
for (var i = 0; i < statements.length; i++) {
|
for (var i = 0; i < statements.length; i++) {
|
||||||
var stat = statements[i];
|
var stat = statements[i];
|
||||||
@@ -2164,7 +2155,7 @@ merge(Compressor.prototype, {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
};
|
}
|
||||||
|
|
||||||
function get_value(key) {
|
function get_value(key) {
|
||||||
if (key instanceof AST_Constant) {
|
if (key instanceof AST_Constant) {
|
||||||
@@ -3195,14 +3186,14 @@ merge(Compressor.prototype, {
|
|||||||
// tell me if a statement aborts
|
// tell me if a statement aborts
|
||||||
function aborts(thing) {
|
function aborts(thing) {
|
||||||
return thing && thing.aborts();
|
return thing && thing.aborts();
|
||||||
};
|
}
|
||||||
(function(def) {
|
(function(def) {
|
||||||
def(AST_Statement, return_null);
|
def(AST_Statement, return_null);
|
||||||
def(AST_Jump, return_this);
|
def(AST_Jump, return_this);
|
||||||
function block_aborts() {
|
function block_aborts() {
|
||||||
var n = this.body.length;
|
var n = this.body.length;
|
||||||
return n > 0 && aborts(this.body[n - 1]);
|
return n > 0 && aborts(this.body[n - 1]);
|
||||||
};
|
}
|
||||||
def(AST_BlockStatement, block_aborts);
|
def(AST_BlockStatement, block_aborts);
|
||||||
def(AST_SwitchBranch, block_aborts);
|
def(AST_SwitchBranch, block_aborts);
|
||||||
def(AST_If, function() {
|
def(AST_If, function() {
|
||||||
@@ -3300,6 +3291,15 @@ merge(Compressor.prototype, {
|
|||||||
// this scope (not in nested scopes).
|
// this scope (not in nested scopes).
|
||||||
var scope = this;
|
var scope = this;
|
||||||
var tw = new TreeWalker(function(node, descend) {
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
|
||||||
|
node.argnames.forEach(function(argname) {
|
||||||
|
var def = argname.definition();
|
||||||
|
if (!(def.id in in_use_ids)) {
|
||||||
|
in_use_ids[def.id] = true;
|
||||||
|
in_use.push(def);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if (node === self) return;
|
if (node === self) return;
|
||||||
if (node instanceof AST_Defun) {
|
if (node instanceof AST_Defun) {
|
||||||
var node_def = node.name.definition();
|
var node_def = node.name.definition();
|
||||||
@@ -3387,8 +3387,7 @@ merge(Compressor.prototype, {
|
|||||||
// any declarations with same name will overshadow
|
// any declarations with same name will overshadow
|
||||||
// name of this anonymous function and can therefore
|
// name of this anonymous function and can therefore
|
||||||
// never be used anywhere
|
// never be used anywhere
|
||||||
if (!(def.id in in_use_ids) || def.orig.length > 1)
|
if (!(def.id in in_use_ids) || def.orig.length > 1) node.name = null;
|
||||||
node.name = null;
|
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
||||||
var trim = !compressor.option("keep_fargs");
|
var trim = !compressor.option("keep_fargs");
|
||||||
@@ -3400,8 +3399,7 @@ merge(Compressor.prototype, {
|
|||||||
a.pop();
|
a.pop();
|
||||||
compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
|
compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
trim = false;
|
trim = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3608,28 +3606,30 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
||||||
var self = this;
|
if (compressor.has_directive("use asm")) return;
|
||||||
if (compressor.has_directive("use asm")) return self;
|
|
||||||
var hoist_funs = compressor.option("hoist_funs");
|
var hoist_funs = compressor.option("hoist_funs");
|
||||||
var hoist_vars = compressor.option("hoist_vars");
|
var hoist_vars = compressor.option("hoist_vars");
|
||||||
if (hoist_funs || hoist_vars) {
|
var self = this;
|
||||||
var dirs = [];
|
if (hoist_vars) {
|
||||||
var hoisted = [];
|
|
||||||
var vars = new Dictionary(), vars_found = 0, var_decl = 0;
|
|
||||||
// let's count var_decl first, we seem to waste a lot of
|
// let's count var_decl first, we seem to waste a lot of
|
||||||
// space if we hoist `var` when there's only one.
|
// space if we hoist `var` when there's only one.
|
||||||
|
var var_decl = 0;
|
||||||
self.walk(new TreeWalker(function(node) {
|
self.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope && node !== self)
|
if (var_decl > 1) return true;
|
||||||
return true;
|
if (node instanceof AST_Scope && node !== self) return true;
|
||||||
if (node instanceof AST_Var) {
|
if (node instanceof AST_Var) {
|
||||||
++var_decl;
|
var_decl++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
hoist_vars = hoist_vars && var_decl > 1;
|
if (var_decl <= 1) hoist_vars = false;
|
||||||
var tt = new TreeTransformer(
|
}
|
||||||
function before(node) {
|
if (!hoist_funs && !hoist_vars) return;
|
||||||
if (node !== self) {
|
var dirs = [];
|
||||||
|
var hoisted = [];
|
||||||
|
var vars = new Dictionary(), vars_found = 0;
|
||||||
|
var tt = new TreeTransformer(function(node) {
|
||||||
|
if (node === self) return;
|
||||||
if (node instanceof AST_Directive) {
|
if (node instanceof AST_Directive) {
|
||||||
dirs.push(node);
|
dirs.push(node);
|
||||||
return make_node(AST_EmptyStatement, node);
|
return make_node(AST_EmptyStatement, node);
|
||||||
@@ -3647,26 +3647,19 @@ merge(Compressor.prototype, {
|
|||||||
var seq = node.to_assignments(compressor);
|
var seq = node.to_assignments(compressor);
|
||||||
var p = tt.parent();
|
var p = tt.parent();
|
||||||
if (p instanceof AST_ForIn && p.init === node) {
|
if (p instanceof AST_ForIn && p.init === node) {
|
||||||
if (seq == null) {
|
if (seq) return seq;
|
||||||
var def = node.definitions[0].name;
|
var def = node.definitions[0].name;
|
||||||
return make_node(AST_SymbolRef, def, def);
|
return make_node(AST_SymbolRef, def, def);
|
||||||
}
|
}
|
||||||
return seq;
|
if (p instanceof AST_For && p.init === node) return seq;
|
||||||
}
|
|
||||||
if (p instanceof AST_For && p.init === node) {
|
|
||||||
return seq;
|
|
||||||
}
|
|
||||||
if (!seq) return make_node(AST_EmptyStatement, node);
|
if (!seq) return make_node(AST_EmptyStatement, node);
|
||||||
return make_node(AST_SimpleStatement, node, {
|
return make_node(AST_SimpleStatement, node, {
|
||||||
body: seq
|
body: seq
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Scope)
|
if (node instanceof AST_Scope) return node;
|
||||||
return node; // to avoid descending in nested scopes
|
});
|
||||||
}
|
self.transform(tt);
|
||||||
}
|
|
||||||
);
|
|
||||||
self = self.transform(tt);
|
|
||||||
if (vars_found > 0) {
|
if (vars_found > 0) {
|
||||||
// collect only vars which don't show up in self's arguments list
|
// collect only vars which don't show up in self's arguments list
|
||||||
var defs = [];
|
var defs = [];
|
||||||
@@ -3731,11 +3724,9 @@ merge(Compressor.prototype, {
|
|||||||
definitions: defs
|
definitions: defs
|
||||||
});
|
});
|
||||||
hoisted.push(defs);
|
hoisted.push(defs);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
self.body = dirs.concat(hoisted, self.body);
|
self.body = dirs.concat(hoisted, self.body);
|
||||||
}
|
|
||||||
return self;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("var_names", function() {
|
AST_Scope.DEFMETHOD("var_names", function() {
|
||||||
@@ -3762,11 +3753,11 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
||||||
|
if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return;
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
|
|
||||||
var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
|
var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
|
||||||
var defs_by_id = Object.create(null);
|
var defs_by_id = Object.create(null);
|
||||||
return self.transform(new TreeTransformer(function(node, descend) {
|
self.transform(new TreeTransformer(function(node, descend) {
|
||||||
if (node instanceof AST_Assign
|
if (node instanceof AST_Assign
|
||||||
&& node.operator == "="
|
&& node.operator == "="
|
||||||
&& node.write_only
|
&& node.write_only
|
||||||
@@ -3832,6 +3823,7 @@ merge(Compressor.prototype, {
|
|||||||
if (def.assignments != count) return;
|
if (def.assignments != count) return;
|
||||||
if (def.direct_access) return;
|
if (def.direct_access) return;
|
||||||
if (def.escaped == 1) return;
|
if (def.escaped == 1) return;
|
||||||
|
if (def.references.length == count) return;
|
||||||
if (def.single_use) return;
|
if (def.single_use) return;
|
||||||
if (top_retain(def)) return;
|
if (top_retain(def)) return;
|
||||||
if (sym.fixed_value() !== right) return;
|
if (sym.fixed_value() !== right) return;
|
||||||
@@ -4469,7 +4461,9 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Definitions.DEFMETHOD("remove_initializers", function() {
|
AST_Definitions.DEFMETHOD("remove_initializers", function() {
|
||||||
this.definitions.forEach(function(def){ def.value = null });
|
this.definitions.forEach(function(def) {
|
||||||
|
def.value = null;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
||||||
@@ -6186,6 +6180,16 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function safe_to_flatten(value, compressor) {
|
||||||
|
if (value instanceof AST_SymbolRef) {
|
||||||
|
value = value.fixed_value();
|
||||||
|
}
|
||||||
|
if (!value) return false;
|
||||||
|
return !(value instanceof AST_Lambda)
|
||||||
|
|| compressor.parent() instanceof AST_New
|
||||||
|
|| !value.contains_this();
|
||||||
|
}
|
||||||
|
|
||||||
OPT(AST_Sub, function(self, compressor) {
|
OPT(AST_Sub, function(self, compressor) {
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
var prop = self.property;
|
var prop = self.property;
|
||||||
@@ -6213,6 +6217,39 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var fn;
|
||||||
|
if (compressor.option("arguments")
|
||||||
|
&& expr instanceof AST_SymbolRef
|
||||||
|
&& expr.name == "arguments"
|
||||||
|
&& expr.definition().orig.length == 1
|
||||||
|
&& (fn = expr.scope) instanceof AST_Lambda
|
||||||
|
&& prop instanceof AST_Number) {
|
||||||
|
var index = prop.getValue();
|
||||||
|
var argname = fn.argnames[index];
|
||||||
|
if (argname && compressor.has_directive("use strict")) {
|
||||||
|
var def = argname.definition();
|
||||||
|
if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
|
||||||
|
argname = null;
|
||||||
|
}
|
||||||
|
} else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
|
||||||
|
while (index >= fn.argnames.length) {
|
||||||
|
argname = make_node(AST_SymbolFunarg, fn, {
|
||||||
|
name: fn.make_var_name("argument_" + fn.argnames.length),
|
||||||
|
scope: fn
|
||||||
|
});
|
||||||
|
fn.argnames.push(argname);
|
||||||
|
fn.enclosed.push(fn.def_variable(argname));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argname && find_if(function(node) {
|
||||||
|
return node.name === argname.name;
|
||||||
|
}, fn.argnames) === argname) {
|
||||||
|
var sym = make_node(AST_SymbolRef, self, argname);
|
||||||
|
sym.reference({});
|
||||||
|
delete argname.__unused;
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (is_lhs(self, compressor.parent())) return self;
|
if (is_lhs(self, compressor.parent())) return self;
|
||||||
if (key !== prop) {
|
if (key !== prop) {
|
||||||
var sub = self.flatten_object(property, compressor);
|
var sub = self.flatten_object(property, compressor);
|
||||||
@@ -6225,7 +6262,8 @@ merge(Compressor.prototype, {
|
|||||||
&& prop instanceof AST_Number && expr instanceof AST_Array) {
|
&& prop instanceof AST_Number && expr instanceof AST_Array) {
|
||||||
var index = prop.getValue();
|
var index = prop.getValue();
|
||||||
var elements = expr.elements;
|
var elements = expr.elements;
|
||||||
if (index in elements) {
|
var retValue = elements[index];
|
||||||
|
if (safe_to_flatten(retValue, compressor)) {
|
||||||
var flatten = true;
|
var flatten = true;
|
||||||
var values = [];
|
var values = [];
|
||||||
for (var i = elements.length; --i > index;) {
|
for (var i = elements.length; --i > index;) {
|
||||||
@@ -6235,7 +6273,6 @@ merge(Compressor.prototype, {
|
|||||||
if (flatten && value.has_side_effects(compressor)) flatten = false;
|
if (flatten && value.has_side_effects(compressor)) flatten = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var retValue = elements[index];
|
|
||||||
retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
|
retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
|
||||||
if (!flatten) values.unshift(retValue);
|
if (!flatten) values.unshift(retValue);
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
@@ -6256,31 +6293,6 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var fn;
|
|
||||||
if (compressor.option("arguments")
|
|
||||||
&& expr instanceof AST_SymbolRef
|
|
||||||
&& expr.name == "arguments"
|
|
||||||
&& expr.definition().orig.length == 1
|
|
||||||
&& (fn = expr.scope) instanceof AST_Lambda
|
|
||||||
&& prop instanceof AST_Number) {
|
|
||||||
var index = prop.getValue();
|
|
||||||
var argname = fn.argnames[index];
|
|
||||||
if (!argname && !compressor.option("keep_fargs")) {
|
|
||||||
while (index >= fn.argnames.length) {
|
|
||||||
argname = make_node(AST_SymbolFunarg, fn, {
|
|
||||||
name: fn.make_var_name("argument_" + fn.argnames.length),
|
|
||||||
scope: fn
|
|
||||||
});
|
|
||||||
fn.argnames.push(argname);
|
|
||||||
fn.enclosed.push(fn.def_variable(argname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (argname) {
|
|
||||||
var sym = make_node(AST_SymbolRef, self, argname);
|
|
||||||
sym.reference({});
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var ev = self.evaluate(compressor);
|
var ev = self.evaluate(compressor);
|
||||||
if (ev !== self) {
|
if (ev !== self) {
|
||||||
ev = make_node_from_constant(ev, self).optimize(compressor);
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
||||||
@@ -6311,10 +6323,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!all(props, function(prop) {
|
if (!all(props, function(prop) {
|
||||||
return prop instanceof AST_ObjectKeyVal;
|
return prop instanceof AST_ObjectKeyVal;
|
||||||
})) break;
|
})) break;
|
||||||
var value = prop.value;
|
if (!safe_to_flatten(prop.value, compressor)) break;
|
||||||
if (value instanceof AST_Function
|
|
||||||
&& !(compressor.parent() instanceof AST_New)
|
|
||||||
&& value.contains_this()) break;
|
|
||||||
return make_node(AST_Sub, this, {
|
return make_node(AST_Sub, this, {
|
||||||
expression: make_node(AST_Array, expr, {
|
expression: make_node(AST_Array, expr, {
|
||||||
elements: props.map(function(prop) {
|
elements: props.map(function(prop) {
|
||||||
@@ -6406,5 +6415,13 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
})(function(node, optimizer) {
|
||||||
})();
|
node.DEFMETHOD("optimize", function(compressor) {
|
||||||
|
var self = this;
|
||||||
|
if (self._optimized) return self;
|
||||||
|
if (compressor.has_directive("use asm")) return self;
|
||||||
|
var opt = optimizer(self, compressor);
|
||||||
|
opt._optimized = true;
|
||||||
|
return opt;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -44,10 +44,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
function normalize_directives(body) {
|
||||||
var normalize_directives = function(body) {
|
|
||||||
var in_directive = true;
|
var in_directive = true;
|
||||||
|
|
||||||
for (var i = 0; i < body.length; i++) {
|
for (var i = 0; i < body.length; i++) {
|
||||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||||
body[i] = new AST_Directive({
|
body[i] = new AST_Directive({
|
||||||
@@ -59,9 +57,8 @@
|
|||||||
in_directive = false;
|
in_directive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
};
|
}
|
||||||
|
|
||||||
var MOZ_TO_ME = {
|
var MOZ_TO_ME = {
|
||||||
Program: function(M) {
|
Program: function(M) {
|
||||||
@@ -480,7 +477,7 @@
|
|||||||
endpos : range ? range[0] : moznode.start,
|
endpos : range ? range[0] : moznode.start,
|
||||||
raw : raw_token(moznode),
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function my_end_token(moznode) {
|
function my_end_token(moznode) {
|
||||||
var loc = moznode.loc, end = loc && loc.end;
|
var loc = moznode.loc, end = loc && loc.end;
|
||||||
@@ -495,7 +492,7 @@
|
|||||||
endpos : range ? range[1] : moznode.end,
|
endpos : range ? range[1] : moznode.end,
|
||||||
raw : raw_token(moznode),
|
raw : raw_token(moznode),
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function map(moztype, mytype, propmap) {
|
function map(moztype, mytype, propmap) {
|
||||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||||
@@ -550,7 +547,7 @@
|
|||||||
);
|
);
|
||||||
MOZ_TO_ME[moztype] = moz_to_me;
|
MOZ_TO_ME[moztype] = moz_to_me;
|
||||||
def_to_moz(mytype, me_to_moz);
|
def_to_moz(mytype, me_to_moz);
|
||||||
};
|
}
|
||||||
|
|
||||||
var FROM_MOZ_STACK = null;
|
var FROM_MOZ_STACK = null;
|
||||||
|
|
||||||
@@ -559,7 +556,7 @@
|
|||||||
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||||
FROM_MOZ_STACK.pop();
|
FROM_MOZ_STACK.pop();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
AST_Node.from_mozilla_ast = function(node) {
|
AST_Node.from_mozilla_ast = function(node) {
|
||||||
var save_stack = FROM_MOZ_STACK;
|
var save_stack = FROM_MOZ_STACK;
|
||||||
@@ -600,24 +597,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return moznode;
|
return moznode;
|
||||||
};
|
}
|
||||||
|
|
||||||
function def_to_moz(mytype, handler) {
|
function def_to_moz(mytype, handler) {
|
||||||
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
||||||
return set_moz_loc(this, handler(this));
|
return set_moz_loc(this, handler(this));
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz(node) {
|
function to_moz(node) {
|
||||||
return node != null ? node.to_mozilla_ast() : null;
|
return node != null ? node.to_mozilla_ast() : null;
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz_block(node) {
|
function to_moz_block(node) {
|
||||||
return {
|
return {
|
||||||
type: "BlockStatement",
|
type: "BlockStatement",
|
||||||
body: node.body.map(to_moz)
|
body: node.body.map(to_moz)
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function to_moz_scope(type, node) {
|
function to_moz_scope(type, node) {
|
||||||
var body = node.body.map(to_moz);
|
var body = node.body.map(to_moz);
|
||||||
@@ -628,5 +625,5 @@
|
|||||||
type: type,
|
type: type,
|
||||||
body: body
|
body: body
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1011,36 +1011,27 @@ function OutputStream(options) {
|
|||||||
self._do_print(output);
|
self._do_print(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ exits ]----- */
|
/* -----[ jumps ]----- */
|
||||||
AST_Exit.DEFMETHOD("_do_print", function(output, kind){
|
function print_jump(output, kind, target) {
|
||||||
output.print(kind);
|
output.print(kind);
|
||||||
if (this.value) {
|
if (target) {
|
||||||
output.space();
|
output.space();
|
||||||
this.value.print(output);
|
target.print(output);
|
||||||
}
|
}
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
}
|
||||||
|
|
||||||
DEFPRINT(AST_Return, function(self, output) {
|
DEFPRINT(AST_Return, function(self, output) {
|
||||||
self._do_print(output, "return");
|
print_jump(output, "return", self.value);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Throw, function(self, output) {
|
DEFPRINT(AST_Throw, function(self, output) {
|
||||||
self._do_print(output, "throw");
|
print_jump(output, "throw", self.value);
|
||||||
});
|
|
||||||
|
|
||||||
/* -----[ loop control ]----- */
|
|
||||||
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
|
|
||||||
output.print(kind);
|
|
||||||
if (this.label) {
|
|
||||||
output.space();
|
|
||||||
this.label.print(output);
|
|
||||||
}
|
|
||||||
output.semicolon();
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Break, function(self, output) {
|
DEFPRINT(AST_Break, function(self, output) {
|
||||||
self._do_print(output, "break");
|
print_jump(output, "break", self.label);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Continue, function(self, output) {
|
DEFPRINT(AST_Continue, function(self, output) {
|
||||||
self._do_print(output, "continue");
|
print_jump(output, "continue", self.label);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ if ]----- */
|
/* -----[ if ]----- */
|
||||||
@@ -1161,22 +1152,15 @@ function OutputStream(options) {
|
|||||||
print_braced(self, output);
|
print_braced(self, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ var/const ]----- */
|
DEFPRINT(AST_Var, function(self, output) {
|
||||||
AST_Definitions.DEFMETHOD("_do_print", function(output, kind){
|
output.print("var");
|
||||||
output.print(kind);
|
|
||||||
output.space();
|
output.space();
|
||||||
this.definitions.forEach(function(def, i){
|
self.definitions.forEach(function(def, i) {
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
def.print(output);
|
def.print(output);
|
||||||
});
|
});
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
var in_for = p instanceof AST_For || p instanceof AST_ForIn;
|
if (p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon();
|
||||||
var avoid_semicolon = in_for && p.init === this;
|
|
||||||
if (!avoid_semicolon)
|
|
||||||
output.semicolon();
|
|
||||||
});
|
|
||||||
DEFPRINT(AST_Var, function(self, output){
|
|
||||||
self._do_print(output, "var");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function parenthesize_for_noin(node, output, noin) {
|
function parenthesize_for_noin(node, output, noin) {
|
||||||
@@ -1225,9 +1209,8 @@ function OutputStream(options) {
|
|||||||
output.space();
|
output.space();
|
||||||
AST_Call.prototype._codegen(self, output);
|
AST_Call.prototype._codegen(self, output);
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Sequence, function(self, output) {
|
||||||
AST_Sequence.DEFMETHOD("_do_print", function(output){
|
self.expressions.forEach(function(node, index) {
|
||||||
this.expressions.forEach(function(node, index) {
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
output.comma();
|
output.comma();
|
||||||
if (output.should_break()) {
|
if (output.should_break()) {
|
||||||
@@ -1238,17 +1221,6 @@ function OutputStream(options) {
|
|||||||
node.print(output);
|
node.print(output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Sequence, function(self, output){
|
|
||||||
self._do_print(output);
|
|
||||||
// var p = output.parent();
|
|
||||||
// if (p instanceof AST_Statement) {
|
|
||||||
// output.with_indent(output.next_indent(), function(){
|
|
||||||
// self._do_print(output);
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// self._do_print(output);
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
DEFPRINT(AST_Dot, function(self, output) {
|
DEFPRINT(AST_Dot, function(self, output) {
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
|
|||||||
179
lib/parse.js
179
lib/parse.js
@@ -130,7 +130,7 @@ function is_letter(code) {
|
|||||||
return (code >= 97 && code <= 122)
|
return (code >= 97 && code <= 122)
|
||||||
|| (code >= 65 && code <= 90)
|
|| (code >= 65 && code <= 90)
|
||||||
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_surrogate_pair_head(code) {
|
function is_surrogate_pair_head(code) {
|
||||||
if (typeof code == "string")
|
if (typeof code == "string")
|
||||||
@@ -146,11 +146,11 @@ function is_surrogate_pair_tail(code) {
|
|||||||
|
|
||||||
function is_digit(code) {
|
function is_digit(code) {
|
||||||
return code >= 48 && code <= 57;
|
return code >= 48 && code <= 57;
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_alphanumeric_char(code) {
|
function is_alphanumeric_char(code) {
|
||||||
return is_digit(code) || is_letter(code);
|
return is_digit(code) || is_letter(code);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_unicode_digit(code) {
|
function is_unicode_digit(code) {
|
||||||
return UNICODE.digit.test(String.fromCharCode(code));
|
return UNICODE.digit.test(String.fromCharCode(code));
|
||||||
@@ -158,19 +158,19 @@ function is_unicode_digit(code) {
|
|||||||
|
|
||||||
function is_unicode_combining_mark(ch) {
|
function is_unicode_combining_mark(ch) {
|
||||||
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
|
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_unicode_connector_punctuation(ch) {
|
function is_unicode_connector_punctuation(ch) {
|
||||||
return UNICODE.connector_punctuation.test(ch);
|
return UNICODE.connector_punctuation.test(ch);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_identifier(name) {
|
function is_identifier(name) {
|
||||||
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_identifier_start(code) {
|
function is_identifier_start(code) {
|
||||||
return code == 36 || code == 95 || is_letter(code);
|
return code == 36 || code == 95 || is_letter(code);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_identifier_char(ch) {
|
function is_identifier_char(ch) {
|
||||||
var code = ch.charCodeAt(0);
|
var code = ch.charCodeAt(0);
|
||||||
@@ -182,11 +182,11 @@ function is_identifier_char(ch) {
|
|||||||
|| is_unicode_connector_punctuation(ch)
|
|| is_unicode_connector_punctuation(ch)
|
||||||
|| is_unicode_digit(code)
|
|| is_unicode_digit(code)
|
||||||
;
|
;
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_identifier_string(str) {
|
function is_identifier_string(str) {
|
||||||
return /^[a-z_$][a-z0-9_$]*$/i.test(str);
|
return /^[a-z_$][a-z0-9_$]*$/i.test(str);
|
||||||
};
|
}
|
||||||
|
|
||||||
function parse_js_number(num) {
|
function parse_js_number(num) {
|
||||||
if (RE_HEX_NUMBER.test(num)) {
|
if (RE_HEX_NUMBER.test(num)) {
|
||||||
@@ -197,7 +197,7 @@ function parse_js_number(num) {
|
|||||||
var val = parseFloat(num);
|
var val = parseFloat(num);
|
||||||
if (val == num) return val;
|
if (val == num) return val;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function JS_Parse_Error(message, filename, line, col, pos) {
|
function JS_Parse_Error(message, filename, line, col, pos) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
@@ -205,7 +205,7 @@ function JS_Parse_Error(message, filename, line, col, pos) {
|
|||||||
this.line = line;
|
this.line = line;
|
||||||
this.col = col;
|
this.col = col;
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
};
|
}
|
||||||
JS_Parse_Error.prototype = Object.create(Error.prototype);
|
JS_Parse_Error.prototype = Object.create(Error.prototype);
|
||||||
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
|
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
|
||||||
JS_Parse_Error.prototype.name = "SyntaxError";
|
JS_Parse_Error.prototype.name = "SyntaxError";
|
||||||
@@ -213,11 +213,11 @@ configure_error_stack(JS_Parse_Error);
|
|||||||
|
|
||||||
function js_error(message, filename, line, col, pos) {
|
function js_error(message, filename, line, col, pos) {
|
||||||
throw new JS_Parse_Error(message, filename, line, col, pos);
|
throw new JS_Parse_Error(message, filename, line, col, pos);
|
||||||
};
|
}
|
||||||
|
|
||||||
function is_token(token, type, val) {
|
function is_token(token, type, val) {
|
||||||
return token.type == type && (val == null || token.value == val);
|
return token.type == type && (val == null || token.value == val);
|
||||||
};
|
}
|
||||||
|
|
||||||
var EX_EOF = {};
|
var EX_EOF = {};
|
||||||
|
|
||||||
@@ -239,7 +239,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
directive_stack : []
|
directive_stack : []
|
||||||
};
|
};
|
||||||
|
|
||||||
function peek() { return S.text.charAt(S.pos); };
|
function peek() {
|
||||||
|
return S.text.charAt(S.pos);
|
||||||
|
}
|
||||||
|
|
||||||
function next(signal_eof, in_string) {
|
function next(signal_eof, in_string) {
|
||||||
var ch = S.text.charAt(S.pos++);
|
var ch = S.text.charAt(S.pos++);
|
||||||
@@ -258,15 +260,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
++S.col;
|
++S.col;
|
||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
};
|
}
|
||||||
|
|
||||||
function forward(i) {
|
function forward(i) {
|
||||||
while (i-- > 0) next();
|
while (i-- > 0) next();
|
||||||
};
|
}
|
||||||
|
|
||||||
function looking_at(str) {
|
function looking_at(str) {
|
||||||
return S.text.substr(S.pos, str.length) == str;
|
return S.text.substr(S.pos, str.length) == str;
|
||||||
};
|
}
|
||||||
|
|
||||||
function find_eol() {
|
function find_eol() {
|
||||||
var text = S.text;
|
var text = S.text;
|
||||||
@@ -276,19 +278,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
}
|
||||||
|
|
||||||
function find(what, signal_eof) {
|
function find(what, signal_eof) {
|
||||||
var pos = S.text.indexOf(what, S.pos);
|
var pos = S.text.indexOf(what, S.pos);
|
||||||
if (signal_eof && pos == -1) throw EX_EOF;
|
if (signal_eof && pos == -1) throw EX_EOF;
|
||||||
return pos;
|
return pos;
|
||||||
};
|
}
|
||||||
|
|
||||||
function start_token() {
|
function start_token() {
|
||||||
S.tokline = S.line;
|
S.tokline = S.line;
|
||||||
S.tokcol = S.col;
|
S.tokcol = S.col;
|
||||||
S.tokpos = S.pos;
|
S.tokpos = S.pos;
|
||||||
};
|
}
|
||||||
|
|
||||||
var prev_was_dot = false;
|
var prev_was_dot = false;
|
||||||
function token(type, value, is_comment) {
|
function token(type, value, is_comment) {
|
||||||
@@ -321,23 +323,23 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
S.newline_before = false;
|
S.newline_before = false;
|
||||||
return new AST_Token(ret);
|
return new AST_Token(ret);
|
||||||
};
|
}
|
||||||
|
|
||||||
function skip_whitespace() {
|
function skip_whitespace() {
|
||||||
while (WHITESPACE_CHARS[peek()])
|
while (WHITESPACE_CHARS[peek()])
|
||||||
next();
|
next();
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_while(pred) {
|
function read_while(pred) {
|
||||||
var ret = "", ch, i = 0;
|
var ret = "", ch, i = 0;
|
||||||
while ((ch = peek()) && pred(ch, i++))
|
while ((ch = peek()) && pred(ch, i++))
|
||||||
ret += next();
|
ret += next();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function parse_error(err) {
|
function parse_error(err) {
|
||||||
js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
|
js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_num(prefix) {
|
function read_num(prefix) {
|
||||||
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
||||||
@@ -367,7 +369,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
} else {
|
} else {
|
||||||
parse_error("Invalid syntax: " + num);
|
parse_error("Invalid syntax: " + num);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_escaped_char(in_string) {
|
function read_escaped_char(in_string) {
|
||||||
var ch = next(true, in_string);
|
var ch = next(true, in_string);
|
||||||
@@ -390,7 +392,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
if (ch >= "0" && ch <= "7")
|
if (ch >= "0" && ch <= "7")
|
||||||
return read_octal_escape_sequence(ch);
|
return read_octal_escape_sequence(ch);
|
||||||
return ch;
|
return ch;
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_octal_escape_sequence(ch) {
|
function read_octal_escape_sequence(ch) {
|
||||||
// Read
|
// Read
|
||||||
@@ -417,7 +419,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
num = (num << 4) | digit;
|
num = (num << 4) | digit;
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
};
|
}
|
||||||
|
|
||||||
var read_string = with_eof_error("Unterminated string constant", function(quote_char) {
|
var read_string = with_eof_error("Unterminated string constant", function(quote_char) {
|
||||||
var quote = next(), ret = "";
|
var quote = next(), ret = "";
|
||||||
@@ -447,7 +449,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
S.comments_before.push(token(type, ret, true));
|
S.comments_before.push(token(type, ret, true));
|
||||||
S.regex_allowed = regex_allowed;
|
S.regex_allowed = regex_allowed;
|
||||||
return next_token;
|
return next_token;
|
||||||
};
|
}
|
||||||
|
|
||||||
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
|
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
|
||||||
var regex_allowed = S.regex_allowed;
|
var regex_allowed = S.regex_allowed;
|
||||||
@@ -481,7 +483,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
};
|
}
|
||||||
|
|
||||||
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||||
var prev_backslash = false, ch, in_class = false;
|
var prev_backslash = false, ch, in_class = false;
|
||||||
@@ -523,9 +525,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
} else {
|
} else {
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
return token("operator", grow(prefix || next()));
|
return token("operator", grow(prefix || next()));
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_slash() {
|
function handle_slash() {
|
||||||
next();
|
next();
|
||||||
@@ -538,14 +540,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
return skip_multiline_comment();
|
return skip_multiline_comment();
|
||||||
}
|
}
|
||||||
return S.regex_allowed ? read_regexp("") : read_operator("/");
|
return S.regex_allowed ? read_regexp("") : read_operator("/");
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_dot() {
|
function handle_dot() {
|
||||||
next();
|
next();
|
||||||
return is_digit(peek().charCodeAt(0))
|
return is_digit(peek().charCodeAt(0))
|
||||||
? read_num(".")
|
? read_num(".")
|
||||||
: token("punc", ".");
|
: token("punc", ".");
|
||||||
};
|
}
|
||||||
|
|
||||||
function read_word() {
|
function read_word() {
|
||||||
var word = read_name();
|
var word = read_name();
|
||||||
@@ -554,7 +556,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
: !KEYWORDS[word] ? token("name", word)
|
: !KEYWORDS[word] ? token("name", word)
|
||||||
: OPERATORS[word] ? token("operator", word)
|
: OPERATORS[word] ? token("operator", word)
|
||||||
: token("keyword", word);
|
: token("keyword", word);
|
||||||
};
|
}
|
||||||
|
|
||||||
function with_eof_error(eof_error, cont) {
|
function with_eof_error(eof_error, cont) {
|
||||||
return function(x) {
|
return function(x) {
|
||||||
@@ -565,7 +567,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
else throw ex;
|
else throw ex;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function next_token(force_regexp) {
|
function next_token(force_regexp) {
|
||||||
if (force_regexp != null)
|
if (force_regexp != null)
|
||||||
@@ -609,7 +611,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parse_error("Unexpected character '" + ch + "'");
|
parse_error("Unexpected character '" + ch + "'");
|
||||||
};
|
}
|
||||||
|
|
||||||
next_token.context = function(nc) {
|
next_token.context = function(nc) {
|
||||||
if (nc) S = nc;
|
if (nc) S = nc;
|
||||||
@@ -645,8 +647,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return next_token;
|
return next_token;
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/* -----[ Parser (constants) ]----- */
|
/* -----[ Parser (constants) ]----- */
|
||||||
|
|
||||||
@@ -666,7 +667,7 @@ var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
|
|||||||
|
|
||||||
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
|
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
|
||||||
|
|
||||||
var PRECEDENCE = (function(a, ret){
|
var PRECEDENCE = function(a, ret) {
|
||||||
for (var i = 0; i < a.length; ++i) {
|
for (var i = 0; i < a.length; ++i) {
|
||||||
var b = a[i];
|
var b = a[i];
|
||||||
for (var j = 0; j < b.length; ++j) {
|
for (var j = 0; j < b.length; ++j) {
|
||||||
@@ -674,8 +675,7 @@ var PRECEDENCE = (function(a, ret){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
})(
|
}([
|
||||||
[
|
|
||||||
["||"],
|
["||"],
|
||||||
["&&"],
|
["&&"],
|
||||||
["|"],
|
["|"],
|
||||||
@@ -686,16 +686,13 @@ var PRECEDENCE = (function(a, ret){
|
|||||||
[">>", "<<", ">>>"],
|
[">>", "<<", ">>>"],
|
||||||
["+", "-"],
|
["+", "-"],
|
||||||
["*", "/", "%"]
|
["*", "/", "%"]
|
||||||
],
|
], {});
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||||
|
|
||||||
/* -----[ Parser ]----- */
|
/* -----[ Parser ]----- */
|
||||||
|
|
||||||
function parse($TEXT, options) {
|
function parse($TEXT, options) {
|
||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
bare_returns : false,
|
bare_returns : false,
|
||||||
expression : false,
|
expression : false,
|
||||||
@@ -724,9 +721,11 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function is(type, value) {
|
function is(type, value) {
|
||||||
return is_token(S.token, type, value);
|
return is_token(S.token, type, value);
|
||||||
};
|
}
|
||||||
|
|
||||||
function peek() { return S.peeked || (S.peeked = S.input()); };
|
function peek() {
|
||||||
|
return S.peeked || (S.peeked = S.input());
|
||||||
|
}
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
S.prev = S.token;
|
S.prev = S.token;
|
||||||
@@ -740,11 +739,11 @@ function parse($TEXT, options) {
|
|||||||
S.token.type == "string" || is("punc", ";")
|
S.token.type == "string" || is("punc", ";")
|
||||||
);
|
);
|
||||||
return S.token;
|
return S.token;
|
||||||
};
|
}
|
||||||
|
|
||||||
function prev() {
|
function prev() {
|
||||||
return S.prev;
|
return S.prev;
|
||||||
};
|
}
|
||||||
|
|
||||||
function croak(msg, line, col, pos) {
|
function croak(msg, line, col, pos) {
|
||||||
var ctx = S.input.context();
|
var ctx = S.input.context();
|
||||||
@@ -753,26 +752,28 @@ function parse($TEXT, options) {
|
|||||||
line != null ? line : ctx.tokline,
|
line != null ? line : ctx.tokline,
|
||||||
col != null ? col : ctx.tokcol,
|
col != null ? col : ctx.tokcol,
|
||||||
pos != null ? pos : ctx.tokpos);
|
pos != null ? pos : ctx.tokpos);
|
||||||
};
|
}
|
||||||
|
|
||||||
function token_error(token, msg) {
|
function token_error(token, msg) {
|
||||||
croak(msg, token.line, token.col);
|
croak(msg, token.line, token.col);
|
||||||
};
|
}
|
||||||
|
|
||||||
function unexpected(token) {
|
function unexpected(token) {
|
||||||
if (token == null)
|
if (token == null)
|
||||||
token = S.token;
|
token = S.token;
|
||||||
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
|
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
|
||||||
};
|
}
|
||||||
|
|
||||||
function expect_token(type, val) {
|
function expect_token(type, val) {
|
||||||
if (is(type, val)) {
|
if (is(type, val)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
|
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
|
||||||
};
|
}
|
||||||
|
|
||||||
function expect(punc) { return expect_token("punc", punc); };
|
function expect(punc) {
|
||||||
|
return expect_token("punc", punc);
|
||||||
|
}
|
||||||
|
|
||||||
function has_newline_before(token) {
|
function has_newline_before(token) {
|
||||||
return token.nlb || !all(token.comments_before, function(comment) {
|
return token.nlb || !all(token.comments_before, function(comment) {
|
||||||
@@ -783,19 +784,19 @@ function parse($TEXT, options) {
|
|||||||
function can_insert_semicolon() {
|
function can_insert_semicolon() {
|
||||||
return !options.strict
|
return !options.strict
|
||||||
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||||
};
|
}
|
||||||
|
|
||||||
function semicolon(optional) {
|
function semicolon(optional) {
|
||||||
if (is("punc", ";")) next();
|
if (is("punc", ";")) next();
|
||||||
else if (!optional && !can_insert_semicolon()) unexpected();
|
else if (!optional && !can_insert_semicolon()) unexpected();
|
||||||
};
|
}
|
||||||
|
|
||||||
function parenthesised() {
|
function parenthesised() {
|
||||||
expect("(");
|
expect("(");
|
||||||
var exp = expression(true);
|
var exp = expression(true);
|
||||||
expect(")");
|
expect(")");
|
||||||
return exp;
|
return exp;
|
||||||
};
|
}
|
||||||
|
|
||||||
function embed_tokens(parser) {
|
function embed_tokens(parser) {
|
||||||
return function() {
|
return function() {
|
||||||
@@ -806,14 +807,14 @@ function parse($TEXT, options) {
|
|||||||
expr.end = end;
|
expr.end = end;
|
||||||
return expr;
|
return expr;
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
function handle_regexp() {
|
function handle_regexp() {
|
||||||
if (is("operator", "/") || is("operator", "/=")) {
|
if (is("operator", "/") || is("operator", "/=")) {
|
||||||
S.peeked = null;
|
S.peeked = null;
|
||||||
S.token = S.input(S.token.value.substr(1)); // force regexp
|
S.token = S.input(S.token.value.substr(1)); // force regexp
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var statement = embed_tokens(function(strict_defun) {
|
var statement = embed_tokens(function(strict_defun) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
@@ -995,11 +996,11 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new AST_LabeledStatement({ body: stat, label: label });
|
return new AST_LabeledStatement({ body: stat, label: label });
|
||||||
};
|
}
|
||||||
|
|
||||||
function simple_statement(tmp) {
|
function simple_statement(tmp) {
|
||||||
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
|
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
|
||||||
};
|
}
|
||||||
|
|
||||||
function break_cont(type) {
|
function break_cont(type) {
|
||||||
var label = null, ldef;
|
var label = null, ldef;
|
||||||
@@ -1007,18 +1008,17 @@ function parse($TEXT, options) {
|
|||||||
label = as_symbol(AST_LabelRef, true);
|
label = as_symbol(AST_LabelRef, true);
|
||||||
}
|
}
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
ldef = find_if(function(l){ return l.name == label.name }, S.labels);
|
ldef = find_if(function(l) {
|
||||||
if (!ldef)
|
return l.name == label.name;
|
||||||
croak("Undefined label " + label.name);
|
}, S.labels);
|
||||||
|
if (!ldef) croak("Undefined label " + label.name);
|
||||||
label.thedef = ldef;
|
label.thedef = ldef;
|
||||||
}
|
} else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
|
||||||
else if (S.in_loop == 0)
|
|
||||||
croak(type.TYPE + " not inside a loop or switch");
|
|
||||||
semicolon();
|
semicolon();
|
||||||
var stat = new type({ label: label });
|
var stat = new type({ label: label });
|
||||||
if (ldef) ldef.references.push(stat);
|
if (ldef) ldef.references.push(stat);
|
||||||
return stat;
|
return stat;
|
||||||
};
|
}
|
||||||
|
|
||||||
function for_() {
|
function for_() {
|
||||||
expect("(");
|
expect("(");
|
||||||
@@ -1039,7 +1039,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return regular_for(init);
|
return regular_for(init);
|
||||||
};
|
}
|
||||||
|
|
||||||
function regular_for(init) {
|
function regular_for(init) {
|
||||||
expect(";");
|
expect(";");
|
||||||
@@ -1053,7 +1053,7 @@ function parse($TEXT, options) {
|
|||||||
step : step,
|
step : step,
|
||||||
body : in_loop(statement)
|
body : in_loop(statement)
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function for_in(init) {
|
function for_in(init) {
|
||||||
var obj = expression(true);
|
var obj = expression(true);
|
||||||
@@ -1063,7 +1063,7 @@ function parse($TEXT, options) {
|
|||||||
object : obj,
|
object : obj,
|
||||||
body : in_loop(statement)
|
body : in_loop(statement)
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
var function_ = function(ctor) {
|
var function_ = function(ctor) {
|
||||||
var in_statement = ctor === AST_Defun;
|
var in_statement = ctor === AST_Defun;
|
||||||
@@ -1113,7 +1113,7 @@ function parse($TEXT, options) {
|
|||||||
body : body,
|
body : body,
|
||||||
alternative : belse
|
alternative : belse
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function block_(strict_defun) {
|
function block_(strict_defun) {
|
||||||
expect("{");
|
expect("{");
|
||||||
@@ -1124,7 +1124,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return a;
|
return a;
|
||||||
};
|
}
|
||||||
|
|
||||||
function switch_body_() {
|
function switch_body_() {
|
||||||
expect("{");
|
expect("{");
|
||||||
@@ -1159,7 +1159,7 @@ function parse($TEXT, options) {
|
|||||||
if (branch) branch.end = prev();
|
if (branch) branch.end = prev();
|
||||||
next();
|
next();
|
||||||
return a;
|
return a;
|
||||||
};
|
}
|
||||||
|
|
||||||
function try_() {
|
function try_() {
|
||||||
var body = block_(), bcatch = null, bfinally = null;
|
var body = block_(), bcatch = null, bfinally = null;
|
||||||
@@ -1192,7 +1192,7 @@ function parse($TEXT, options) {
|
|||||||
bcatch : bcatch,
|
bcatch : bcatch,
|
||||||
bfinally : bfinally
|
bfinally : bfinally
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function vardefs(no_in) {
|
function vardefs(no_in) {
|
||||||
var a = [];
|
var a = [];
|
||||||
@@ -1208,7 +1208,7 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
};
|
}
|
||||||
|
|
||||||
var var_ = function(no_in) {
|
var var_ = function(no_in) {
|
||||||
return new AST_Var({
|
return new AST_Var({
|
||||||
@@ -1274,7 +1274,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
var expr_atom = function(allow_calls) {
|
var expr_atom = function(allow_calls) {
|
||||||
if (is("operator", "new")) {
|
if (is("operator", "new")) {
|
||||||
@@ -1340,7 +1340,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return a;
|
return a;
|
||||||
};
|
}
|
||||||
|
|
||||||
var array_ = embed_tokens(function() {
|
var array_ = embed_tokens(function() {
|
||||||
expect("[");
|
expect("[");
|
||||||
@@ -1417,14 +1417,14 @@ function parse($TEXT, options) {
|
|||||||
default:
|
default:
|
||||||
unexpected();
|
unexpected();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function as_name() {
|
function as_name() {
|
||||||
var tmp = S.token;
|
var tmp = S.token;
|
||||||
if (tmp.type != "name") unexpected();
|
if (tmp.type != "name") unexpected();
|
||||||
next();
|
next();
|
||||||
return tmp.value;
|
return tmp.value;
|
||||||
};
|
}
|
||||||
|
|
||||||
function _make_symbol(type) {
|
function _make_symbol(type) {
|
||||||
var name = S.token.value;
|
var name = S.token.value;
|
||||||
@@ -1433,7 +1433,7 @@ function parse($TEXT, options) {
|
|||||||
start : S.token,
|
start : S.token,
|
||||||
end : S.token
|
end : S.token
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function strict_verify_symbol(sym) {
|
function strict_verify_symbol(sym) {
|
||||||
if (sym.name == "arguments" || sym.name == "eval")
|
if (sym.name == "arguments" || sym.name == "eval")
|
||||||
@@ -1451,7 +1451,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return sym;
|
return sym;
|
||||||
};
|
}
|
||||||
|
|
||||||
function mark_pure(call) {
|
function mark_pure(call) {
|
||||||
var start = call.start;
|
var start = call.start;
|
||||||
@@ -1536,7 +1536,7 @@ function parse($TEXT, options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return new ctor({ operator: op, expression: expr });
|
return new ctor({ operator: op, expression: expr });
|
||||||
};
|
}
|
||||||
|
|
||||||
var expr_op = function(left, min_prec, no_in) {
|
var expr_op = function(left, min_prec, no_in) {
|
||||||
var op = is("operator") ? S.token.value : null;
|
var op = is("operator") ? S.token.value : null;
|
||||||
@@ -1558,7 +1558,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function expr_ops(no_in) {
|
function expr_ops(no_in) {
|
||||||
return expr_op(maybe_unary(true), 0, no_in);
|
return expr_op(maybe_unary(true), 0, no_in);
|
||||||
};
|
}
|
||||||
|
|
||||||
var maybe_conditional = function(no_in) {
|
var maybe_conditional = function(no_in) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
@@ -1580,7 +1580,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function is_assignable(expr) {
|
function is_assignable(expr) {
|
||||||
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
|
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
|
||||||
};
|
}
|
||||||
|
|
||||||
var maybe_assign = function(no_in) {
|
var maybe_assign = function(no_in) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
@@ -1622,13 +1622,13 @@ function parse($TEXT, options) {
|
|||||||
var ret = cont();
|
var ret = cont();
|
||||||
--S.in_loop;
|
--S.in_loop;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (options.expression) {
|
if (options.expression) {
|
||||||
return expression(true);
|
return expression(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (function(){
|
return function() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var body = [];
|
var body = [];
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
@@ -1644,6 +1644,5 @@ function parse($TEXT, options) {
|
|||||||
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
|
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
|
||||||
}
|
}
|
||||||
return toplevel;
|
return toplevel;
|
||||||
})();
|
}();
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|||||||
11
lib/scope.js
11
lib/scope.js
@@ -132,10 +132,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.thedef = node;
|
node.thedef = node;
|
||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolDefun || options.ie8 && node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
|
||||||
// Careful here, the scope where this should be defined is
|
// Careful here, the scope where this should be defined is
|
||||||
// the parent scope. The reason is that we enter a new
|
// the parent scope. The reason is that we enter a new
|
||||||
// scope when we encounter the AST_Defun node (which is
|
// scope when we encounter the AST_Defun node (which is
|
||||||
@@ -143,6 +140,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// later.
|
// later.
|
||||||
(node.scope = defun.parent_scope).def_function(node, defun);
|
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_SymbolLambda) {
|
||||||
|
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
|
}
|
||||||
else if (node instanceof AST_SymbolVar) {
|
else if (node instanceof AST_SymbolVar) {
|
||||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||||
if (defun !== scope) {
|
if (defun !== scope) {
|
||||||
@@ -349,9 +349,6 @@ function next_mangled_name(scope, options, def) {
|
|||||||
holes.push(scope.cname);
|
holes.push(scope.cname);
|
||||||
}
|
}
|
||||||
scope.names_in_use[name] = true;
|
scope.names_in_use[name] = true;
|
||||||
if (options.ie8 && def.orig[0] instanceof AST_SymbolLambda) {
|
|
||||||
names_in_use(scope.parent_scope, options)[name] = true;
|
|
||||||
}
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,9 @@ function SourceMap(options) {
|
|||||||
file: null,
|
file: null,
|
||||||
root: null,
|
root: null,
|
||||||
orig: null,
|
orig: null,
|
||||||
|
|
||||||
orig_line_diff: 0,
|
orig_line_diff: 0,
|
||||||
dest_line_diff: 0,
|
dest_line_diff: 0,
|
||||||
});
|
}, true);
|
||||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||||
file: options.file,
|
file: options.file,
|
||||||
sourceRoot: options.root
|
sourceRoot: options.root
|
||||||
@@ -68,8 +67,8 @@ function SourceMap(options) {
|
|||||||
}
|
}
|
||||||
maps[source] = map;
|
maps[source] = map;
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
add: function(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||||
var map = maps && maps[source];
|
var map = maps && maps[source];
|
||||||
if (map) {
|
if (map) {
|
||||||
var info = map.originalPositionFor({
|
var info = map.originalPositionFor({
|
||||||
@@ -83,15 +82,23 @@ function SourceMap(options) {
|
|||||||
name = info.name || name;
|
name = info.name || name;
|
||||||
}
|
}
|
||||||
generator.addMapping({
|
generator.addMapping({
|
||||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
name: name,
|
||||||
original : { line: orig_line + options.orig_line_diff, column: orig_col },
|
|
||||||
source: source,
|
source: source,
|
||||||
name : name
|
generated: {
|
||||||
|
line: gen_line + options.dest_line_diff,
|
||||||
|
column: gen_col
|
||||||
|
},
|
||||||
|
original: {
|
||||||
|
line: orig_line + options.orig_line_diff,
|
||||||
|
column: orig_col
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
get: function() {
|
||||||
|
return generator;
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
return JSON.stringify(generator.toJSON());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return {
|
}
|
||||||
add : add,
|
|
||||||
get : function() { return generator },
|
|
||||||
toString : function() { return JSON.stringify(generator.toJSON()); }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|||||||
130
lib/transform.js
130
lib/transform.js
@@ -43,8 +43,6 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Tree transformer helpers.
|
|
||||||
|
|
||||||
function TreeTransformer(before, after) {
|
function TreeTransformer(before, after) {
|
||||||
TreeWalker.call(this);
|
TreeWalker.call(this);
|
||||||
this.before = before;
|
this.before = before;
|
||||||
@@ -52,168 +50,136 @@ function TreeTransformer(before, after) {
|
|||||||
}
|
}
|
||||||
TreeTransformer.prototype = new TreeWalker;
|
TreeTransformer.prototype = new TreeWalker;
|
||||||
|
|
||||||
(function(undefined){
|
(function(DEF) {
|
||||||
|
|
||||||
function _(node, descend) {
|
|
||||||
node.DEFMETHOD("transform", function(tw, in_list){
|
|
||||||
var x, y;
|
|
||||||
tw.push(this);
|
|
||||||
if (tw.before) x = tw.before(this, descend, in_list);
|
|
||||||
if (x === undefined) {
|
|
||||||
x = this;
|
|
||||||
descend(x, tw);
|
|
||||||
if (tw.after) {
|
|
||||||
y = tw.after(x, in_list);
|
|
||||||
if (y !== undefined) x = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tw.pop();
|
|
||||||
return x;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function do_list(list, tw) {
|
function do_list(list, tw) {
|
||||||
return MAP(list, function(node) {
|
return MAP(list, function(node) {
|
||||||
return node.transform(tw, true);
|
return node.transform(tw, true);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
_(AST_Node, noop);
|
DEF(AST_Node, noop);
|
||||||
|
DEF(AST_LabeledStatement, function(self, tw) {
|
||||||
_(AST_LabeledStatement, function(self, tw){
|
|
||||||
self.label = self.label.transform(tw);
|
self.label = self.label.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_SimpleStatement, function(self, tw) {
|
||||||
_(AST_SimpleStatement, function(self, tw){
|
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Block, function(self, tw) {
|
||||||
_(AST_Block, function(self, tw){
|
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Do, function(self, tw) {
|
||||||
_(AST_Do, function(self, tw){
|
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_While, function(self, tw) {
|
||||||
_(AST_While, function(self, tw){
|
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_For, function(self, tw) {
|
||||||
_(AST_For, function(self, tw){
|
|
||||||
if (self.init) self.init = self.init.transform(tw);
|
if (self.init) self.init = self.init.transform(tw);
|
||||||
if (self.condition) self.condition = self.condition.transform(tw);
|
if (self.condition) self.condition = self.condition.transform(tw);
|
||||||
if (self.step) self.step = self.step.transform(tw);
|
if (self.step) self.step = self.step.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_ForIn, function(self, tw) {
|
||||||
_(AST_ForIn, function(self, tw){
|
|
||||||
self.init = self.init.transform(tw);
|
self.init = self.init.transform(tw);
|
||||||
self.object = self.object.transform(tw);
|
self.object = self.object.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_With, function(self, tw) {
|
||||||
_(AST_With, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Exit, function(self, tw) {
|
||||||
_(AST_Exit, function(self, tw){
|
|
||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_LoopControl, function(self, tw) {
|
||||||
_(AST_LoopControl, function(self, tw){
|
|
||||||
if (self.label) self.label = self.label.transform(tw);
|
if (self.label) self.label = self.label.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_If, function(self, tw) {
|
||||||
_(AST_If, function(self, tw){
|
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Switch, function(self, tw) {
|
||||||
_(AST_Switch, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Case, function(self, tw) {
|
||||||
_(AST_Case, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Try, function(self, tw) {
|
||||||
_(AST_Try, function(self, tw){
|
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Catch, function(self, tw) {
|
||||||
_(AST_Catch, function(self, tw){
|
|
||||||
self.argname = self.argname.transform(tw);
|
self.argname = self.argname.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Definitions, function(self, tw) {
|
||||||
_(AST_Definitions, function(self, tw){
|
|
||||||
self.definitions = do_list(self.definitions, tw);
|
self.definitions = do_list(self.definitions, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_VarDef, function(self, tw) {
|
||||||
_(AST_VarDef, function(self, tw){
|
|
||||||
self.name = self.name.transform(tw);
|
self.name = self.name.transform(tw);
|
||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Lambda, function(self, tw) {
|
||||||
_(AST_Lambda, function(self, tw){
|
|
||||||
if (self.name) self.name = self.name.transform(tw);
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
self.argnames = do_list(self.argnames, tw);
|
self.argnames = do_list(self.argnames, tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Call, function(self, tw) {
|
||||||
_(AST_Call, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.args = do_list(self.args, tw);
|
self.args = do_list(self.args, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Sequence, function(self, tw) {
|
||||||
_(AST_Sequence, function(self, tw){
|
|
||||||
self.expressions = do_list(self.expressions, tw);
|
self.expressions = do_list(self.expressions, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Dot, function(self, tw) {
|
||||||
_(AST_Dot, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Sub, function(self, tw) {
|
||||||
_(AST_Sub, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.property = self.property.transform(tw);
|
self.property = self.property.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Unary, function(self, tw) {
|
||||||
_(AST_Unary, function(self, tw){
|
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Binary, function(self, tw) {
|
||||||
_(AST_Binary, function(self, tw){
|
|
||||||
self.left = self.left.transform(tw);
|
self.left = self.left.transform(tw);
|
||||||
self.right = self.right.transform(tw);
|
self.right = self.right.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Conditional, function(self, tw) {
|
||||||
_(AST_Conditional, function(self, tw){
|
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.consequent = self.consequent.transform(tw);
|
self.consequent = self.consequent.transform(tw);
|
||||||
self.alternative = self.alternative.transform(tw);
|
self.alternative = self.alternative.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Array, function(self, tw) {
|
||||||
_(AST_Array, function(self, tw){
|
|
||||||
self.elements = do_list(self.elements, tw);
|
self.elements = do_list(self.elements, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Object, function(self, tw) {
|
||||||
_(AST_Object, function(self, tw){
|
|
||||||
self.properties = do_list(self.properties, tw);
|
self.properties = do_list(self.properties, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_ObjectProperty, function(self, tw) {
|
||||||
_(AST_ObjectProperty, function(self, tw){
|
|
||||||
self.value = self.value.transform(tw);
|
self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
})(function(node, descend) {
|
||||||
})();
|
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||||
|
var x, y;
|
||||||
|
tw.push(this);
|
||||||
|
if (tw.before) x = tw.before(this, descend, in_list);
|
||||||
|
if (typeof x === "undefined") {
|
||||||
|
x = this;
|
||||||
|
descend(x, tw);
|
||||||
|
if (tw.after) {
|
||||||
|
y = tw.after(x, in_list);
|
||||||
|
if (typeof y !== "undefined") x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tw.pop();
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
14
lib/utils.js
14
lib/utils.js
@@ -52,9 +52,7 @@ function member(name, array) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function find_if(func, array) {
|
function find_if(func, array) {
|
||||||
for (var i = 0, n = array.length; i < n; ++i) {
|
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||||
if (func(array[i])) return array[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function repeat_string(str, i) {
|
function repeat_string(str, i) {
|
||||||
@@ -138,7 +136,7 @@ var MAP = (function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return is_last;
|
return is_last;
|
||||||
};
|
}
|
||||||
if (Array.isArray(a)) {
|
if (Array.isArray(a)) {
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||||
@@ -152,14 +150,14 @@ var MAP = (function(){
|
|||||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
for (i in a) if (HOP(a, i)) if (doit()) break;
|
||||||
}
|
}
|
||||||
return top.concat(ret);
|
return top.concat(ret);
|
||||||
};
|
}
|
||||||
MAP.at_top = function(val) { return new AtTop(val) };
|
MAP.at_top = function(val) { return new AtTop(val) };
|
||||||
MAP.splice = function(val) { return new Splice(val) };
|
MAP.splice = function(val) { return new Splice(val) };
|
||||||
MAP.last = function(val) { return new Last(val) };
|
MAP.last = function(val) { return new Last(val) };
|
||||||
var skip = MAP.skip = {};
|
var skip = MAP.skip = {};
|
||||||
function AtTop(val) { this.v = val };
|
function AtTop(val) { this.v = val }
|
||||||
function Splice(val) { this.v = val };
|
function Splice(val) { this.v = val }
|
||||||
function Last(val) { this.v = val };
|
function Last(val) { this.v = val }
|
||||||
return MAP;
|
return MAP;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.4.0",
|
"version": "3.4.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ replace_index: {
|
|||||||
properties: true,
|
properties: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(arguments && arguments[0]);
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
(function() {
|
(function() {
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
@@ -21,7 +22,8 @@ replace_index: {
|
|||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(arguments && arguments[0]);
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
(function() {
|
(function() {
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
@@ -45,6 +47,37 @@ replace_index: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replace_index_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
replace_index_keep_fargs: {
|
replace_index_keep_fargs: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
@@ -53,7 +86,8 @@ replace_index_keep_fargs: {
|
|||||||
properties: true,
|
properties: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(arguments && arguments[0]);
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
(function() {
|
(function() {
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
@@ -69,7 +103,8 @@ replace_index_keep_fargs: {
|
|||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(arguments && arguments[0]);
|
var arguments = [];
|
||||||
|
console.log(arguments[0]);
|
||||||
(function(argument_0, argument_1) {
|
(function(argument_0, argument_1) {
|
||||||
console.log(argument_1, argument_1, arguments.foo);
|
console.log(argument_1, argument_1, arguments.foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
@@ -93,6 +128,38 @@ replace_index_keep_fargs: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replace_index_keep_fargs_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(argument_0, argument_1) {
|
||||||
|
console.log(argument_1, argument_1, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function(a, b) {
|
||||||
|
console.log(b, b, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42 42 undefined",
|
||||||
|
"42 42 undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
modified: {
|
modified: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
@@ -101,8 +168,10 @@ modified: {
|
|||||||
(function(a, b) {
|
(function(a, b) {
|
||||||
var c = arguments[0];
|
var c = arguments[0];
|
||||||
var d = arguments[1];
|
var d = arguments[1];
|
||||||
a = "foo";
|
var a = "foo";
|
||||||
b++;
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
@@ -110,10 +179,61 @@ modified: {
|
|||||||
(function(a, b) {
|
(function(a, b) {
|
||||||
var c = a;
|
var c = a;
|
||||||
var d = b;
|
var d = b;
|
||||||
a = "foo";
|
var a = "foo";
|
||||||
b++;
|
b++;
|
||||||
|
a = "moo";
|
||||||
|
b *= 2;
|
||||||
console.log(a, b, c, d, a, b);
|
console.log(a, b, c, d, a, b);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
expect_stdout: "foo 43 bar 42 foo 43"
|
expect_stdout: "moo 86 bar 42 moo 86"
|
||||||
|
}
|
||||||
|
|
||||||
|
modified_strict: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function(a, b) {
|
||||||
|
var c = arguments[0];
|
||||||
|
var d = arguments[1];
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(a, b) {
|
||||||
|
var c = arguments[0];
|
||||||
|
var d = arguments[1];
|
||||||
|
var a = "foo";
|
||||||
|
b++;
|
||||||
|
arguments[0] = "moo";
|
||||||
|
arguments[1] *= 2;
|
||||||
|
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||||
|
})("bar", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo 43 bar 42 moo 84"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argname: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b, a) {
|
||||||
|
console.log(a, b, arguments[0], arguments[1], arguments[2]);
|
||||||
|
})("foo", 42, "bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b, a) {
|
||||||
|
console.log(a, b, arguments[0], b, a);
|
||||||
|
})("foo", 42, "bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "bar 42 foo 42 bar"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1926,3 +1926,31 @@ issue_3146_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3192: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a = "foo", arguments[0]);
|
||||||
|
})("bar");
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log(a = "foo", arguments[0]);
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a = "foo", arguments[0]);
|
||||||
|
})("bar");
|
||||||
|
(function(a) {
|
||||||
|
"use strict";
|
||||||
|
console.log("foo", arguments[0]);
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo foo",
|
||||||
|
"foo bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -420,8 +420,8 @@ issue_24_2: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(n) {
|
(function(o) {
|
||||||
console.log(typeof function o(){} === typeof n ? "FAIL" : "PASS");
|
console.log(typeof function n(){} === typeof o ? "FAIL" : "PASS");
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -457,9 +457,29 @@ issue_2976_2: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function n() {
|
console.log(function f() {
|
||||||
var o;
|
var n;
|
||||||
return o === n ? "FAIL" : "PASS";
|
return n === f ? "FAIL" : "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2976_3: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f() {
|
||||||
|
var a;
|
||||||
|
return a === f ? "FAIL" : "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function o() {
|
||||||
|
var n;
|
||||||
|
return n === o ? "FAIL" : "PASS";
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -538,3 +558,111 @@ issue_3035_ie8: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3197_1: {
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var window = {};
|
||||||
|
!function() {
|
||||||
|
function Foo() {
|
||||||
|
console.log(this instanceof Foo);
|
||||||
|
}
|
||||||
|
window.Foo = Foo;
|
||||||
|
}();
|
||||||
|
new window.Foo();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var window = {};
|
||||||
|
window.Foo = function o() {
|
||||||
|
console.log(this instanceof o);
|
||||||
|
};
|
||||||
|
new window.Foo();
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3197_1_ie8: {
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var window = {};
|
||||||
|
!function() {
|
||||||
|
function Foo() {
|
||||||
|
console.log(this instanceof Foo);
|
||||||
|
}
|
||||||
|
window.Foo = Foo;
|
||||||
|
}();
|
||||||
|
new window.Foo();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var window = {};
|
||||||
|
window.Foo = function Foo() {
|
||||||
|
console.log(this instanceof Foo);
|
||||||
|
};
|
||||||
|
new window.Foo();
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3197_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
var f = function f() {
|
||||||
|
console.log(this instanceof f);
|
||||||
|
};
|
||||||
|
new f(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(n) {
|
||||||
|
var o = function n() {
|
||||||
|
console.log(this instanceof n);
|
||||||
|
};
|
||||||
|
new o(n);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3197_2_ie8: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
var f = function f() {
|
||||||
|
console.log(this instanceof f);
|
||||||
|
};
|
||||||
|
new f(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(n) {
|
||||||
|
var o = function o() {
|
||||||
|
console.log(this instanceof o);
|
||||||
|
};
|
||||||
|
new o(n);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1729,3 +1729,106 @@ issue_869_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3188_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(this.p);
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
f: f
|
||||||
|
};
|
||||||
|
o.f();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(this.p);
|
||||||
|
}
|
||||||
|
({
|
||||||
|
p: "PASS",
|
||||||
|
f: f
|
||||||
|
}).f();
|
||||||
|
var o;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3188_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var f = function() {
|
||||||
|
console.log(this.p);
|
||||||
|
};
|
||||||
|
function g() {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
f: f
|
||||||
|
};
|
||||||
|
o.f();
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
p: "PASS",
|
||||||
|
f: function() {
|
||||||
|
console.log(this.p);
|
||||||
|
}
|
||||||
|
}).f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3188_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(this[0]);
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
var o = ["PASS", f];
|
||||||
|
o[1]();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(this[0]);
|
||||||
|
}
|
||||||
|
["PASS", f][1]();
|
||||||
|
var o;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("arguments", function() {
|
describe("arguments", function() {
|
||||||
it("Should known that arguments in functions are local scoped", function() {
|
it("Should known that arguments in functions are local scoped", function() {
|
||||||
var ast = UglifyJS.parse("var arguments; var f = function() {arguments.length}");
|
var ast = UglifyJS.parse("var arguments; var f = function() {arguments.length}");
|
||||||
ast.figure_out_scope();
|
ast.figure_out_scope();
|
||||||
|
|
||||||
// Test scope of `var arguments`
|
// Test scope of `var arguments`
|
||||||
assert.strictEqual(ast.find_variable("arguments").global, true);
|
assert.strictEqual(ast.find_variable("arguments").global, true);
|
||||||
|
|
||||||
// Select arguments symbol in function
|
// Select arguments symbol in function
|
||||||
var symbol = ast.body[1].definitions[0].value.find_variable("arguments");
|
var symbol = ast.body[1].definitions[0].value.find_variable("arguments");
|
||||||
|
|
||||||
assert.strictEqual(symbol.global, false);
|
assert.strictEqual(symbol.global, false);
|
||||||
assert.strictEqual(symbol.scope, ast. // From ast
|
assert.strictEqual(symbol.scope, ast. // From ast
|
||||||
body[1]. // Select 2nd statement (equals to `var f ...`)
|
body[1]. // Select 2nd statement (equals to `var f ...`)
|
||||||
|
|||||||
@@ -10,55 +10,43 @@ describe("bin/uglifyjs", function() {
|
|||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
it("should produce a functional build when using --self", function(done) {
|
it("should produce a functional build when using --self", function(done) {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
|
||||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
eval(stdout);
|
eval(stdout);
|
||||||
|
assert.strictEqual(typeof WrappedUglifyJS, "object");
|
||||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
|
||||||
var result = WrappedUglifyJS.minify("foo([true,,2+3]);");
|
var result = WrappedUglifyJS.minify("foo([true,,2+3]);");
|
||||||
assert.strictEqual(result.error, undefined);
|
assert.strictEqual(result.error, undefined);
|
||||||
assert.strictEqual(result.code, "foo([!0,,5]);");
|
assert.strictEqual(result.code, "foo([!0,,5]);");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should be able to filter comments correctly with `--comments all`", function(done) {
|
it("Should be able to filter comments correctly with `--comments all`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
|
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should be able to filter comments correctly with `--comment <RegExp>`", function(done) {
|
it("Should be able to filter comments correctly with `--comment <RegExp>`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
|
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should be able to filter comments correctly with just `--comment`", function(done) {
|
it("Should be able to filter comments correctly with just `--comment`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "/*@preserve*/\n\n");
|
assert.strictEqual(stdout, "/*@preserve*/\n\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should give sensible error against invalid input source map", function(done) {
|
it("Should give sensible error against invalid input source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline";
|
var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline";
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.deepEqual(stderr.split(/\n/).slice(0, 2), [
|
assert.deepEqual(stderr.split(/\n/).slice(0, 2), [
|
||||||
@@ -70,21 +58,20 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should append source map to output when using --source-map url=inline", function(done) {
|
it("Should append source map to output when using --source-map url=inline", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==\n");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not append source map to output when not using --source-map url=inline", function(done) {
|
it("should not append source map to output when not using --source-map url=inline", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
|
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -96,10 +83,8 @@ describe("bin/uglifyjs", function() {
|
|||||||
"--source-map", "content=test/input/issue-2082/sample.js.map",
|
"--source-map", "content=test/input/issue-2082/sample.js.map",
|
||||||
"--source-map", "url=inline",
|
"--source-map", "url=inline",
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
var stderrLines = stderr.split("\n");
|
var stderrLines = stderr.split("\n");
|
||||||
assert.strictEqual(stderrLines[0], "INFO: Using input source map: test/input/issue-2082/sample.js.map");
|
assert.strictEqual(stderrLines[0], "INFO: Using input source map: test/input/issue-2082/sample.js.map");
|
||||||
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
|
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
|
||||||
@@ -138,80 +123,64 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should work with --keep-fnames (mangle only)", function(done) {
|
it("Should work with --keep-fnames (mangle only)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --keep-fnames (mangle & compress)", function(done) {
|
it("Should work with --keep-fnames (mangle & compress)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with keep_fnames under mangler options", function(done) {
|
it("Should work with keep_fnames under mangler options", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (simple)", function(done) {
|
it("Should work with --define (simple)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(5);\n");
|
assert.strictEqual(stdout, "console.log(5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (nested)", function(done) {
|
it("Should work with --define (nested)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
|
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(3,5);\n");
|
assert.strictEqual(stdout, "console.log(3,5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (AST_Node)", function(done) {
|
it("Should work with --define (AST_Node)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
|
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "stdout.println(D);\n");
|
assert.strictEqual(stdout, "stdout.println(D);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with `--beautify`", function(done) {
|
it("Should work with `--beautify`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with `--beautify braces`", function(done) {
|
it("Should work with `--beautify braces`", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b braces';
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b braces';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, read("test/input/issue-1482/braces.js"));
|
assert.strictEqual(stdout, read("test/input/issue-1482/braces.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -225,20 +194,16 @@ describe("bin/uglifyjs", function() {
|
|||||||
"--source-map", "includeSources=true",
|
"--source-map", "includeSources=true",
|
||||||
"--source-map", "url=inline",
|
"--source-map", "url=inline",
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, read("test/input/issue-520/output.js"));
|
assert.strictEqual(stdout, read("test/input/issue-520/output.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should warn for missing inline source map", function(done) {
|
it("Should warn for missing inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
@@ -256,10 +221,8 @@ describe("bin/uglifyjs", function() {
|
|||||||
"test/input/issue-1323/sample.js",
|
"test/input/issue-1323/sample.js",
|
||||||
"--source-map", "content=inline,url=inline",
|
"--source-map", "content=inline,url=inline",
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUFBLE1BQWdCQyxRQUFRQyxJQUFJLEVBQUUsSUFBTyxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUFBLE1BQWdCQyxRQUFRQyxJQUFJLEVBQUUsSUFBTyxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
@@ -272,7 +235,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with acorn and inline source map", function(done) {
|
it("Should fail with acorn and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
@@ -281,7 +243,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
@@ -290,7 +251,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with invalid syntax", function(done) {
|
it("Should fail with invalid syntax", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/simple.js';
|
var command = uglifyjscmd + ' test/input/invalid/simple.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
var lines = stderr.split(/\n/);
|
||||||
@@ -303,7 +263,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with correct marking of tabs", function(done) {
|
it("Should fail with correct marking of tabs", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/tab.js';
|
var command = uglifyjscmd + ' test/input/invalid/tab.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
var lines = stderr.split(/\n/);
|
||||||
@@ -316,7 +275,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with correct marking at start of line", function(done) {
|
it("Should fail with correct marking at start of line", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/eof.js';
|
var command = uglifyjscmd + ' test/input/invalid/eof.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
var lines = stderr.split(/\n/);
|
||||||
@@ -329,7 +287,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should fail with a missing loop body", function(done) {
|
it("Should fail with a missing loop body", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/loop-no-body.js';
|
var command = uglifyjscmd + ' test/input/invalid/loop-no-body.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
var lines = stderr.split(/\n/);
|
||||||
@@ -342,7 +299,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (5--)", function(done) {
|
it("Should throw syntax error (5--)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -357,7 +313,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (Math.random() /= 2)", function(done) {
|
it("Should throw syntax error (Math.random() /= 2)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -372,7 +327,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (++this)", function(done) {
|
it("Should throw syntax error (++this)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -387,7 +341,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (++null)", function(done) {
|
it("Should throw syntax error (++null)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -402,7 +355,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (a.=)", function(done) {
|
it("Should throw syntax error (a.=)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -417,7 +369,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (%.a)", function(done) {
|
it("Should throw syntax error (%.a)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -432,7 +383,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (a./();)", function(done) {
|
it("Should throw syntax error (a./();)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -447,7 +397,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error ({%: 1})", function(done) {
|
it("Should throw syntax error ({%: 1})", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/object.js';
|
var command = uglifyjscmd + ' test/input/invalid/object.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -462,7 +411,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (delete x)", function(done) {
|
it("Should throw syntax error (delete x)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/delete.js';
|
var command = uglifyjscmd + ' test/input/invalid/delete.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -477,7 +425,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (function g(arguments))", function(done) {
|
it("Should throw syntax error (function g(arguments))", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -492,7 +439,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (function eval())", function(done) {
|
it("Should throw syntax error (function eval())", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -507,7 +453,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (iife arguments())", function(done) {
|
it("Should throw syntax error (iife arguments())", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -522,7 +467,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (catch(eval))", function(done) {
|
it("Should throw syntax error (catch(eval))", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/try.js';
|
var command = uglifyjscmd + ' test/input/invalid/try.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -537,7 +481,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (var eval)", function(done) {
|
it("Should throw syntax error (var eval)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/var.js';
|
var command = uglifyjscmd + ' test/input/invalid/var.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -552,7 +495,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (else)", function(done) {
|
it("Should throw syntax error (else)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/else.js';
|
var command = uglifyjscmd + ' test/input/invalid/else.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -567,7 +509,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (return)", function(done) {
|
it("Should throw syntax error (return)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/return.js';
|
var command = uglifyjscmd + ' test/input/invalid/return.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -582,7 +523,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (for-in init)", function(done) {
|
it("Should throw syntax error (for-in init)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -597,7 +537,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should throw syntax error (for-in var)", function(done) {
|
it("Should throw syntax error (for-in var)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
@@ -617,10 +556,8 @@ describe("bin/uglifyjs", function() {
|
|||||||
"--source-map",
|
"--source-map",
|
||||||
'content="' + read_map() + '",url=inline'
|
'content="' + read_map() + '",url=inline'
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||||
@@ -642,10 +579,8 @@ describe("bin/uglifyjs", function() {
|
|||||||
"-c",
|
"-c",
|
||||||
"--source-map", "url=inline",
|
"--source-map", "url=inline",
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
'function foo(){return function(){console.log("PASS")}}foo()();',
|
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||||
@@ -658,7 +593,6 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
var ast = JSON.parse(stdout);
|
var ast = JSON.parse(stdout);
|
||||||
assert.strictEqual(ast._class, "AST_Toplevel");
|
assert.strictEqual(ast._class, "AST_Toplevel");
|
||||||
assert.ok(Array.isArray(ast.body));
|
assert.ok(Array.isArray(ast.body));
|
||||||
@@ -676,20 +610,16 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
it("Should work with --mangle reserved=[]", function(done) {
|
it("Should work with --mangle reserved=[]", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=[callback]";
|
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=[callback]";
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
|
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --mangle reserved=false", function(done) {
|
it("Should work with --mangle reserved=false", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=false";
|
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=false";
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
|
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
|
||||||
|
|
||||||
describe("comment filters", function() {
|
|
||||||
it("Should be able to filter comments by passing regexp", function() {
|
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to filter comments with the 'all' option", function() {
|
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to filter commments with the 'some' option", function() {
|
|
||||||
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to filter comments by passing a function", function() {
|
|
||||||
var ast = UglifyJS.parse("/*TEST 123*/\n//An other comment\n//8 chars.");
|
|
||||||
var f = function(node, comment) {
|
|
||||||
return comment.value.length === 8;
|
|
||||||
};
|
|
||||||
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to filter comments by passing regex in string format", function() {
|
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to get the comment and comment type when using a function", function() {
|
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
|
||||||
var f = function(node, comment) {
|
|
||||||
return comment.type == "comment1" || comment.type == "comment3";
|
|
||||||
};
|
|
||||||
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should be able to filter comments by passing a boolean", function() {
|
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
|
||||||
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: false}), "");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should never be able to filter comment5 (shebangs)", function() {
|
|
||||||
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
|
|
||||||
var f = function(node, comment) {
|
|
||||||
assert.strictEqual(comment.type === "comment5", false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should never be able to filter comment5 when using 'some' as filter", function() {
|
|
||||||
var ast = UglifyJS.parse("#!foo\n//foo\n/*@preserve*/\n/* please hide me */");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: "some"}), "#!foo\n/*@preserve*/");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should have no problem on multiple calls", function() {
|
|
||||||
const options = {
|
|
||||||
comments: /ok/
|
|
||||||
};
|
|
||||||
|
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should handle shebang and preamble correctly", function() {
|
|
||||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
|
||||||
output: { preamble: "/* Build */" }
|
|
||||||
}).code;
|
|
||||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should handle preamble without shebang correctly", function() {
|
|
||||||
var code = UglifyJS.minify("var x = 10;", {
|
|
||||||
output: { preamble: "/* Build */" }
|
|
||||||
}).code;
|
|
||||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var uglify = require("../node");
|
|
||||||
|
|
||||||
describe("Comment", function() {
|
|
||||||
it("Should recognize eol of single line comments", function() {
|
|
||||||
var tests = [
|
|
||||||
"//Some comment 1\n>",
|
|
||||||
"//Some comment 2\r>",
|
|
||||||
"//Some comment 3\r\n>",
|
|
||||||
"//Some comment 4\u2028>",
|
|
||||||
"//Some comment 5\u2029>"
|
|
||||||
];
|
|
||||||
|
|
||||||
var fail = function(e) {
|
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
|
||||||
e.message === "Unexpected token: operator (>)" &&
|
|
||||||
e.line === 2 &&
|
|
||||||
e.col === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
assert.throws(function() {
|
|
||||||
uglify.parse(tests[i]);
|
|
||||||
}, fail, tests[i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should update the position of a multiline comment correctly", function() {
|
|
||||||
var tests = [
|
|
||||||
"/*Some comment 1\n\n\n*/\n>\n\n\n\n\n\n",
|
|
||||||
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
|
|
||||||
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
|
|
||||||
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
|
|
||||||
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
|
|
||||||
];
|
|
||||||
|
|
||||||
var fail = function(e) {
|
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
|
||||||
e.message === "Unexpected token: operator (>)" &&
|
|
||||||
e.line === 5 &&
|
|
||||||
e.col === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
assert.throws(function() {
|
|
||||||
uglify.parse(tests[i]);
|
|
||||||
}, fail, tests[i]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should handle comment within return correctly", function() {
|
|
||||||
var result = uglify.minify([
|
|
||||||
"function unequal(x, y) {",
|
|
||||||
" return (",
|
|
||||||
" // Either one",
|
|
||||||
" x < y",
|
|
||||||
" ||",
|
|
||||||
" y < x",
|
|
||||||
" );",
|
|
||||||
"}",
|
|
||||||
].join("\n"), {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, [
|
|
||||||
"function unequal(x, y) {",
|
|
||||||
" // Either one",
|
|
||||||
" return x < y || y < x;",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should handle comment folded into return correctly", function() {
|
|
||||||
var result = uglify.minify([
|
|
||||||
"function f() {",
|
|
||||||
" /* boo */ x();",
|
|
||||||
" return y();",
|
|
||||||
"}",
|
|
||||||
].join("\n"), {
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, [
|
|
||||||
"function f() {",
|
|
||||||
" /* boo */",
|
|
||||||
" return x(), y();",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should not drop comments after first OutputStream", function() {
|
|
||||||
var code = "/* boo */\nx();";
|
|
||||||
var ast = uglify.parse(code);
|
|
||||||
var out1 = uglify.OutputStream({
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
});
|
|
||||||
ast.print(out1);
|
|
||||||
var out2 = uglify.OutputStream({
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
});
|
|
||||||
ast.print(out2);
|
|
||||||
assert.strictEqual(out1.get(), code);
|
|
||||||
assert.strictEqual(out2.get(), out1.get());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should retain trailing comments", function() {
|
|
||||||
var code = [
|
|
||||||
"if (foo /* lost comment */ && bar /* lost comment */) {",
|
|
||||||
" // this one is kept",
|
|
||||||
" {/* lost comment */}",
|
|
||||||
" !function() {",
|
|
||||||
" // lost comment",
|
|
||||||
" }();",
|
|
||||||
" function baz() {/* lost comment */}",
|
|
||||||
" // lost comment",
|
|
||||||
"}",
|
|
||||||
"// comments right before EOF are lost as well",
|
|
||||||
].join("\n");
|
|
||||||
var result = uglify.minify(code, {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, code);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should retain comments within braces", function() {
|
|
||||||
var code = [
|
|
||||||
"{/* foo */}",
|
|
||||||
"a({/* foo */});",
|
|
||||||
"while (a) {/* foo */}",
|
|
||||||
"switch (a) {/* foo */}",
|
|
||||||
"if (a) {/* foo */} else {/* bar */}",
|
|
||||||
].join("\n\n");
|
|
||||||
var result = uglify.minify(code, {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, code);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should correctly preserve new lines around comments", function() {
|
|
||||||
var tests = [
|
|
||||||
[
|
|
||||||
"// foo",
|
|
||||||
"// bar",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"// foo",
|
|
||||||
"/* bar */",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"// foo",
|
|
||||||
"/* bar */ x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"/* foo */",
|
|
||||||
"// bar",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"/* foo */ // bar",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"/* foo */",
|
|
||||||
"/* bar */",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"/* foo */",
|
|
||||||
"/* bar */ x();",
|
|
||||||
].join("\n"),
|
|
||||||
[
|
|
||||||
"/* foo */ /* bar */",
|
|
||||||
"x();",
|
|
||||||
].join("\n"),
|
|
||||||
"/* foo */ /* bar */ x();",
|
|
||||||
].forEach(function(code) {
|
|
||||||
var result = uglify.minify(code, {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
beautify: true,
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, code);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should preserve new line before comment without beautify", function() {
|
|
||||||
var code = [
|
|
||||||
"function f(){",
|
|
||||||
"/* foo */bar()}",
|
|
||||||
].join("\n");
|
|
||||||
var result = uglify.minify(code, {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, code);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should preserve comments around IIFE", function() {
|
|
||||||
var result = uglify.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should output line comments after statements", function() {
|
|
||||||
var result = uglify.minify([
|
|
||||||
"x()//foo",
|
|
||||||
"{y()//bar",
|
|
||||||
"}",
|
|
||||||
].join("\n"), {
|
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
comments: "all",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
assert.strictEqual(result.code, [
|
|
||||||
"x();//foo",
|
|
||||||
"{y();//bar",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
|
||||||
|
|
||||||
describe("comment before constant", function() {
|
|
||||||
var js = 'function f() { /*c1*/ var /*c2*/ foo = /*c3*/ false; return foo; }';
|
|
||||||
|
|
||||||
it("Should test comment before constant is retained and output after mangle.", function() {
|
|
||||||
var result = Uglify.minify(js, {
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
|
||||||
output: { comments: true },
|
|
||||||
});
|
|
||||||
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should test code works when comments disabled.", function() {
|
|
||||||
var result = Uglify.minify(js, {
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
|
||||||
output: { comments: false },
|
|
||||||
});
|
|
||||||
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
380
test/mocha/comments.js
Normal file
380
test/mocha/comments.js
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
|
describe("comments", function() {
|
||||||
|
it("Should recognize eol of single line comments", function() {
|
||||||
|
var tests = [
|
||||||
|
"//Some comment 1\n>",
|
||||||
|
"//Some comment 2\r>",
|
||||||
|
"//Some comment 3\r\n>",
|
||||||
|
"//Some comment 4\u2028>",
|
||||||
|
"//Some comment 5\u2029>"
|
||||||
|
];
|
||||||
|
|
||||||
|
var fail = function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
|
&& e.message === "Unexpected token: operator (>)"
|
||||||
|
&& e.line === 2
|
||||||
|
&& e.col === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(tests[i]);
|
||||||
|
}, fail, tests[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should update the position of a multiline comment correctly", function() {
|
||||||
|
var tests = [
|
||||||
|
"/*Some comment 1\n\n\n*/\n>\n\n\n\n\n\n",
|
||||||
|
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
|
||||||
|
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
|
||||||
|
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
|
||||||
|
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
|
||||||
|
];
|
||||||
|
|
||||||
|
var fail = function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
|
&& e.message === "Unexpected token: operator (>)"
|
||||||
|
&& e.line === 5
|
||||||
|
&& e.col === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(tests[i]);
|
||||||
|
}, fail, tests[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should handle comment within return correctly", function() {
|
||||||
|
var result = UglifyJS.minify([
|
||||||
|
"function unequal(x, y) {",
|
||||||
|
" return (",
|
||||||
|
" // Either one",
|
||||||
|
" x < y",
|
||||||
|
" ||",
|
||||||
|
" y < x",
|
||||||
|
" );",
|
||||||
|
"}",
|
||||||
|
].join("\n"), {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"function unequal(x, y) {",
|
||||||
|
" // Either one",
|
||||||
|
" return x < y || y < x;",
|
||||||
|
"}",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should handle comment folded into return correctly", function() {
|
||||||
|
var result = UglifyJS.minify([
|
||||||
|
"function f() {",
|
||||||
|
" /* boo */ x();",
|
||||||
|
" return y();",
|
||||||
|
"}",
|
||||||
|
].join("\n"), {
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"function f() {",
|
||||||
|
" /* boo */",
|
||||||
|
" return x(), y();",
|
||||||
|
"}",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not drop comments after first OutputStream", function() {
|
||||||
|
var code = "/* boo */\nx();";
|
||||||
|
var ast = UglifyJS.parse(code);
|
||||||
|
var out1 = UglifyJS.OutputStream({
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
});
|
||||||
|
ast.print(out1);
|
||||||
|
var out2 = UglifyJS.OutputStream({
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
});
|
||||||
|
ast.print(out2);
|
||||||
|
assert.strictEqual(out1.get(), code);
|
||||||
|
assert.strictEqual(out2.get(), out1.get());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should retain trailing comments", function() {
|
||||||
|
var code = [
|
||||||
|
"if (foo /* lost comment */ && bar /* lost comment */) {",
|
||||||
|
" // this one is kept",
|
||||||
|
" {/* lost comment */}",
|
||||||
|
" !function() {",
|
||||||
|
" // lost comment",
|
||||||
|
" }();",
|
||||||
|
" function baz() {/* lost comment */}",
|
||||||
|
" // lost comment",
|
||||||
|
"}",
|
||||||
|
"// comments right before EOF are lost as well",
|
||||||
|
].join("\n");
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should retain comments within braces", function() {
|
||||||
|
var code = [
|
||||||
|
"{/* foo */}",
|
||||||
|
"a({/* foo */});",
|
||||||
|
"while (a) {/* foo */}",
|
||||||
|
"switch (a) {/* foo */}",
|
||||||
|
"if (a) {/* foo */} else {/* bar */}",
|
||||||
|
].join("\n\n");
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should correctly preserve new lines around comments", function() {
|
||||||
|
var tests = [
|
||||||
|
[
|
||||||
|
"// foo",
|
||||||
|
"// bar",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"// foo",
|
||||||
|
"/* bar */",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"// foo",
|
||||||
|
"/* bar */ x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"/* foo */",
|
||||||
|
"// bar",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"/* foo */ // bar",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"/* foo */",
|
||||||
|
"/* bar */",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"/* foo */",
|
||||||
|
"/* bar */ x();",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"/* foo */ /* bar */",
|
||||||
|
"x();",
|
||||||
|
].join("\n"),
|
||||||
|
"/* foo */ /* bar */ x();",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should preserve new line before comment without beautify", function() {
|
||||||
|
var code = [
|
||||||
|
"function f(){",
|
||||||
|
"/* foo */bar()}",
|
||||||
|
].join("\n");
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should preserve comments around IIFE", function() {
|
||||||
|
var result = UglifyJS.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should output line comments after statements", function() {
|
||||||
|
var result = UglifyJS.minify([
|
||||||
|
"x()//foo",
|
||||||
|
"{y()//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"), {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"x();//foo",
|
||||||
|
"{y();//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("comment before constant", function() {
|
||||||
|
var js = 'function f() { /*c1*/ var /*c2*/ foo = /*c3*/ false; return foo; }';
|
||||||
|
|
||||||
|
it("Should test comment before constant is retained and output after mangle.", function() {
|
||||||
|
var result = UglifyJS.minify(js, {
|
||||||
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
|
output: { comments: true },
|
||||||
|
});
|
||||||
|
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should test code works when comments disabled.", function() {
|
||||||
|
var result = UglifyJS.minify(js, {
|
||||||
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
|
output: { comments: false },
|
||||||
|
});
|
||||||
|
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("comment filters", function() {
|
||||||
|
it("Should be able to filter comments by passing regexp", function() {
|
||||||
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to filter comments with the 'all' option", function() {
|
||||||
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to filter commments with the 'some' option", function() {
|
||||||
|
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to filter comments by passing a function", function() {
|
||||||
|
var ast = UglifyJS.parse("/*TEST 123*/\n//An other comment\n//8 chars.");
|
||||||
|
var f = function(node, comment) {
|
||||||
|
return comment.value.length === 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to filter comments by passing regex in string format", function() {
|
||||||
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to get the comment and comment type when using a function", function() {
|
||||||
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
var f = function(node, comment) {
|
||||||
|
return comment.type == "comment1" || comment.type == "comment3";
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to filter comments by passing a boolean", function() {
|
||||||
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: false}), "");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should never be able to filter comment5 (shebangs)", function() {
|
||||||
|
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
|
||||||
|
var f = function(node, comment) {
|
||||||
|
assert.strictEqual(comment.type === "comment5", false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should never be able to filter comment5 when using 'some' as filter", function() {
|
||||||
|
var ast = UglifyJS.parse("#!foo\n//foo\n/*@preserve*/\n/* please hide me */");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: "some"}), "#!foo\n/*@preserve*/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should have no problem on multiple calls", function() {
|
||||||
|
const options = {
|
||||||
|
comments: /ok/
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should handle shebang and preamble correctly", function() {
|
||||||
|
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||||
|
output: { preamble: "/* Build */" }
|
||||||
|
}).code;
|
||||||
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should handle preamble without shebang correctly", function() {
|
||||||
|
var code = UglifyJS.minify("var x = 10;", {
|
||||||
|
output: { preamble: "/* Build */" }
|
||||||
|
}).code;
|
||||||
|
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Huge number of comments.", function() {
|
||||||
|
it("Should parse and compress code with thousands of consecutive comments", function() {
|
||||||
|
var js = "function lots_of_comments(x) { return 7 -";
|
||||||
|
for (var i = 1; i <= 5000; ++i) js += "// " + i + "\n";
|
||||||
|
for (; i <= 10000; ++i) js += "/* " + i + " */ /**/";
|
||||||
|
js += "x; }";
|
||||||
|
var result = UglifyJS.minify(js, { mangle: false });
|
||||||
|
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("Directives", function() {
|
describe("Directives", function() {
|
||||||
it ("Should allow tokenizer to store directives state", function() {
|
it ("Should allow tokenizer to store directives state", function() {
|
||||||
var tokenizer = uglify.tokenizer("", "foo.js");
|
var tokenizer = UglifyJS.tokenizer("", "foo.js");
|
||||||
|
|
||||||
// Stack level 0
|
// Stack level 0
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
||||||
@@ -161,13 +161,13 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
// Fail parser deliberately to get state at failure
|
// Fail parser deliberately to get state at failure
|
||||||
var tokenizer = uglify.tokenizer(tests[i].input + "]", "foo.js");
|
var tokenizer = UglifyJS.tokenizer(tests[i].input + "]", "foo.js");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var parser = uglify.parse(tokenizer);
|
var parser = UglifyJS.parse(tokenizer);
|
||||||
throw new Error("Expected parser to fail");
|
throw new Error("Expected parser to fail");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
assert.strictEqual(e instanceof uglify.JS_Parse_Error, true);
|
assert.strictEqual(e instanceof UglifyJS.JS_Parse_Error, true);
|
||||||
assert.strictEqual(e.message, "Unexpected token: punc (])");
|
assert.strictEqual(e.message, "Unexpected token: punc (])");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ describe("Directives", function() {
|
|||||||
["'tests';\n\n", true],
|
["'tests';\n\n", true],
|
||||||
["\n\n\"use strict\";\n\n", true]
|
["\n\n\"use strict\";\n\n", true]
|
||||||
].forEach(function(test) {
|
].forEach(function(test) {
|
||||||
var out = uglify.OutputStream();
|
var out = UglifyJS.OutputStream();
|
||||||
out.print(test[0]);
|
out.print(test[0]);
|
||||||
out.print_string("", null, true);
|
out.print_string("", null, true);
|
||||||
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
|
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
|
||||||
@@ -195,7 +195,7 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(
|
UglifyJS.minify(
|
||||||
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
||||||
{output: {beautify: true, quote_style: 3}, compress: false}
|
{output: {beautify: true, quote_style: 3}, compress: false}
|
||||||
).code,
|
).code,
|
||||||
@@ -225,7 +225,7 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {compress: false, mangle: false}).code,
|
UglifyJS.minify(tests[i][0], {compress: false, mangle: false}).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
@@ -233,7 +233,7 @@ describe("Directives", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||||
var code = uglify.minify('"use strict";"use\\x20strict";',
|
var code = UglifyJS.minify('"use strict";"use\\x20strict";',
|
||||||
{output: {semicolons: false}, compress: false}
|
{output: {semicolons: false}, compress: false}
|
||||||
).code;
|
).code;
|
||||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
||||||
@@ -340,7 +340,7 @@ describe("Directives", function() {
|
|||||||
];
|
];
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
UglifyJS.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
||||||
tests[i][2],
|
tests[i][2],
|
||||||
tests[i][0] + " using mode " + tests[i][1]
|
tests[i][0] + " using mode " + tests[i][1]
|
||||||
);
|
);
|
||||||
@@ -372,7 +372,7 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0]).code,
|
UglifyJS.minify(tests[i][0]).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("Getters and setters", function() {
|
describe("Getters and setters", function() {
|
||||||
it("Should not accept operator symbols as getter/setter name", function() {
|
it("Should not accept operator symbols as getter/setter name", function() {
|
||||||
@@ -61,29 +61,24 @@ describe("Getters and setters", function() {
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
var testCase = function(data) {
|
var testCase = function(data) {
|
||||||
return function() {
|
return function() {
|
||||||
UglifyJS.parse(data.code);
|
UglifyJS.parse(data.code);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var fail = function(data) {
|
var fail = function(data) {
|
||||||
return function(e) {
|
return function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Unexpected token: operator (" + data.operator + ")";
|
&& e.message === "Unexpected token: operator (" + data.operator + ")";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var errorMessage = function(data) {
|
var errorMessage = function(data) {
|
||||||
return "Expected but didn't get a syntax error while parsing following line:\n" + data.code;
|
return "Expected but didn't get a syntax error while parsing following line:\n" + data.code;
|
||||||
};
|
};
|
||||||
|
|
||||||
var tests = generator();
|
var tests = generator();
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
var test = tests[i];
|
var test = tests[i];
|
||||||
assert.throws(testCase(test), fail(test), errorMessage(test));
|
assert.throws(testCase(test), fail(test), errorMessage(test));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
|
||||||
|
|
||||||
describe("Huge number of comments.", function() {
|
|
||||||
it("Should parse and compress code with thousands of consecutive comments", function() {
|
|
||||||
var js = 'function lots_of_comments(x) { return 7 -';
|
|
||||||
var i;
|
|
||||||
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
|
|
||||||
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
|
|
||||||
js += "x; }";
|
|
||||||
var result = Uglify.minify(js, { mangle: false });
|
|
||||||
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
21
test/mocha/ie8.js
Normal file
21
test/mocha/ie8.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
|
describe("ie8", function() {
|
||||||
|
it("Should be able to minify() with undefined as catch parameter in a try...catch statement", function() {
|
||||||
|
assert.strictEqual(
|
||||||
|
UglifyJS.minify([
|
||||||
|
"function a(b){",
|
||||||
|
" try {",
|
||||||
|
" throw 'Stuff';",
|
||||||
|
" } catch (undefined) {",
|
||||||
|
" console.log('caught: ' + undefined);",
|
||||||
|
" }",
|
||||||
|
" console.log('undefined is ' + undefined);",
|
||||||
|
" return b === undefined;",
|
||||||
|
"};",
|
||||||
|
].join("\n")).code,
|
||||||
|
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var Uglify = require("../../");
|
|
||||||
var SourceMapConsumer = require("source-map").SourceMapConsumer;
|
|
||||||
|
|
||||||
function getMap() {
|
|
||||||
return {
|
|
||||||
"version": 3,
|
|
||||||
"sources": ["index.js"],
|
|
||||||
"names": [],
|
|
||||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
|
||||||
"file": "bundle.js",
|
|
||||||
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareMap(sourceMap) {
|
|
||||||
var code = [
|
|
||||||
'"use strict";',
|
|
||||||
"",
|
|
||||||
"var foo = function foo(x) {",
|
|
||||||
' return "foo " + x;',
|
|
||||||
"};",
|
|
||||||
'console.log(foo("bar"));',
|
|
||||||
"",
|
|
||||||
"//# sourceMappingURL=bundle.js.map",
|
|
||||||
].join("\n");
|
|
||||||
var result = Uglify.minify(code, {
|
|
||||||
sourceMap: {
|
|
||||||
content: sourceMap,
|
|
||||||
includeSources: true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
return new SourceMapConsumer(result.map);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("input sourcemaps", function() {
|
|
||||||
it("Should copy over original sourcesContent", function() {
|
|
||||||
var orig = getMap();
|
|
||||||
var map = prepareMap(orig);
|
|
||||||
assert.equal(map.sourceContentFor("index.js"), orig.sourcesContent[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should copy sourcesContent if sources are relative", function() {
|
|
||||||
var relativeMap = getMap();
|
|
||||||
relativeMap.sources = ['./index.js'];
|
|
||||||
var map = prepareMap(relativeMap);
|
|
||||||
assert.notEqual(map.sourcesContent, null);
|
|
||||||
assert.equal(map.sourcesContent.length, 1);
|
|
||||||
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should not have invalid mappings from inputSourceMap (issue #882)", function() {
|
|
||||||
var map = prepareMap(getMap());
|
|
||||||
// The original source has only 2 lines, check that mappings don't have more lines
|
|
||||||
var msg = "Mapping should not have higher line number than the original file had";
|
|
||||||
map.eachMapping(function(mapping) {
|
|
||||||
assert.ok(mapping.originalLine <= 2, msg);
|
|
||||||
});
|
|
||||||
map.allGeneratedPositionsFor({
|
|
||||||
source: "index.js",
|
|
||||||
line: 1,
|
|
||||||
column: 1
|
|
||||||
}).forEach(function(pos) {
|
|
||||||
assert.ok(pos.line <= 2, msg);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("let", function() {
|
describe("let", function() {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
@@ -10,7 +10,7 @@ describe("let", function() {
|
|||||||
s += "var v" + i + "=0;";
|
s += "var v" + i + "=0;";
|
||||||
}
|
}
|
||||||
s += '}';
|
s += '}';
|
||||||
var result = Uglify.minify(s, {
|
var result = UglifyJS.minify(s, {
|
||||||
compress: false
|
compress: false
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ describe("let", function() {
|
|||||||
for (var i = 0; i < 18000; i++) {
|
for (var i = 0; i < 18000; i++) {
|
||||||
s += "v.b" + i + ";";
|
s += "v.b" + i + ";";
|
||||||
}
|
}
|
||||||
var result = Uglify.minify(s, {
|
var result = UglifyJS.minify(s, {
|
||||||
compress: false,
|
compress: false,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
mangle: {
|
mangle: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var Uglify = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("line-endings", function() {
|
describe("line-endings", function() {
|
||||||
var options = {
|
var options = {
|
||||||
@@ -14,19 +14,19 @@ describe("line-endings", function() {
|
|||||||
|
|
||||||
it("Should parse LF line endings", function() {
|
it("Should parse LF line endings", function() {
|
||||||
var js = '/*!one\n2\n3*///comment\nfunction f(x) {\n if (x)\n//comment\n return 3;\n}\n';
|
var js = '/*!one\n2\n3*///comment\nfunction f(x) {\n if (x)\n//comment\n return 3;\n}\n';
|
||||||
var result = Uglify.minify(js, options);
|
var result = UglifyJS.minify(js, options);
|
||||||
assert.strictEqual(result.code, expected_code);
|
assert.strictEqual(result.code, expected_code);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should parse CR/LF line endings", function() {
|
it("Should parse CR/LF line endings", function() {
|
||||||
var js = '/*!one\r\n2\r\n3*///comment\r\nfunction f(x) {\r\n if (x)\r\n//comment\r\n return 3;\r\n}\r\n';
|
var js = '/*!one\r\n2\r\n3*///comment\r\nfunction f(x) {\r\n if (x)\r\n//comment\r\n return 3;\r\n}\r\n';
|
||||||
var result = Uglify.minify(js, options);
|
var result = UglifyJS.minify(js, options);
|
||||||
assert.strictEqual(result.code, expected_code);
|
assert.strictEqual(result.code, expected_code);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should parse CR line endings", function() {
|
it("Should parse CR line endings", function() {
|
||||||
var js = '/*!one\r2\r3*///comment\rfunction f(x) {\r if (x)\r//comment\r return 3;\r}\r';
|
var js = '/*!one\r2\r3*///comment\rfunction f(x) {\r if (x)\r//comment\r return 3;\r}\r';
|
||||||
var result = Uglify.minify(js, options);
|
var result = UglifyJS.minify(js, options);
|
||||||
assert.strictEqual(result.code, expected_code);
|
assert.strictEqual(result.code, expected_code);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,16 +44,15 @@ describe("line-endings", function() {
|
|||||||
]
|
]
|
||||||
var test = function(input) {
|
var test = function(input) {
|
||||||
return function() {
|
return function() {
|
||||||
Uglify.parse(input);
|
UglifyJS.parse(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var fail = function(e) {
|
var fail = function(e) {
|
||||||
return e instanceof Uglify.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Unexpected line terminator";
|
&& e.message === "Unexpected line terminator";
|
||||||
}
|
}
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
for (var i = 0; i < inputs.length; i++) {
|
||||||
assert.throws(test(inputs[i]), fail);
|
assert.throws(test(inputs[i]), fail);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("Input file as map", function() {
|
describe("Input file as map", function() {
|
||||||
it("Should accept object", function() {
|
it("Should accept object", function() {
|
||||||
var jsMap = {
|
var jsMap = {
|
||||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||||
};
|
};
|
||||||
var result = Uglify.minify(jsMap, {sourceMap: true});
|
var result = UglifyJS.minify(jsMap, {sourceMap: true});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||||
assert.strictEqual(map.file, undefined);
|
assert.strictEqual(map.file, undefined);
|
||||||
|
|
||||||
result = Uglify.minify(jsMap);
|
result = UglifyJS.minify(jsMap);
|
||||||
assert.strictEqual(result.map, undefined);
|
assert.strictEqual(result.map, undefined);
|
||||||
|
|
||||||
result = Uglify.minify(jsMap, {sourceMap: {filename: 'out.js'}});
|
result = UglifyJS.minify(jsMap, {sourceMap: {filename: 'out.js'}});
|
||||||
map = JSON.parse(result.map);
|
map = JSON.parse(result.map);
|
||||||
assert.strictEqual(map.file, 'out.js');
|
assert.strictEqual(map.file, 'out.js');
|
||||||
});
|
});
|
||||||
@@ -26,7 +26,7 @@ describe("Input file as map", function() {
|
|||||||
'var foo = {"x": 1, y: 2, \'z\': 3};',
|
'var foo = {"x": 1, y: 2, \'z\': 3};',
|
||||||
'var bar = 15;'
|
'var bar = 15;'
|
||||||
];
|
];
|
||||||
var result = Uglify.minify(jsSeq, {sourceMap: true});
|
var result = UglifyJS.minify(jsSeq, {sourceMap: true});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||||
@@ -37,7 +37,7 @@ describe("Input file as map", function() {
|
|||||||
var jsMap = {
|
var jsMap = {
|
||||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||||
};
|
};
|
||||||
var result = Uglify.minify(jsMap, {sourceMap: {includeSources: true}});
|
var result = UglifyJS.minify(jsMap, {sourceMap: {includeSources: true}});
|
||||||
|
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
var run_code = require("../sandbox").run_code;
|
var run_code = require("../sandbox").run_code;
|
||||||
|
var UglifyJS = require("../../");
|
||||||
|
|
||||||
function read(path) {
|
function read(path) {
|
||||||
return readFileSync(path, "utf8");
|
return readFileSync(path, "utf8");
|
||||||
@@ -10,14 +10,14 @@ function read(path) {
|
|||||||
describe("minify", function() {
|
describe("minify", function() {
|
||||||
it("Should test basic sanity of minify with default options", function() {
|
it("Should test basic sanity of minify with default options", function() {
|
||||||
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
|
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
|
||||||
var result = Uglify.minify(js);
|
var result = UglifyJS.minify(js);
|
||||||
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
|
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should skip inherited keys from `files`", function() {
|
it("Should skip inherited keys from `files`", function() {
|
||||||
var files = Object.create({ skip: this });
|
var files = Object.create({ skip: this });
|
||||||
files[0] = "alert(1 + 1)";
|
files[0] = "alert(1 + 1)";
|
||||||
var result = Uglify.minify(files);
|
var result = UglifyJS.minify(files);
|
||||||
assert.strictEqual(result.code, "alert(2);");
|
assert.strictEqual(result.code, "alert(2);");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ describe("minify", function() {
|
|||||||
"qux.js",
|
"qux.js",
|
||||||
].forEach(function(file) {
|
].forEach(function(file) {
|
||||||
var code = read("test/input/issue-1242/" + file);
|
var code = read("test/input/issue-1242/" + file);
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
mangle: {
|
mangle: {
|
||||||
cache: cache,
|
cache: cache,
|
||||||
toplevel: true
|
toplevel: true
|
||||||
@@ -65,7 +65,7 @@ describe("minify", function() {
|
|||||||
"qux.js",
|
"qux.js",
|
||||||
].forEach(function(file) {
|
].forEach(function(file) {
|
||||||
var code = read("test/input/issue-1242/" + file);
|
var code = read("test/input/issue-1242/" + file);
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
mangle: {
|
mangle: {
|
||||||
toplevel: true
|
toplevel: true
|
||||||
},
|
},
|
||||||
@@ -96,7 +96,7 @@ describe("minify", function() {
|
|||||||
'"xxyyy";var j={t:2,u:3},k=4;',
|
'"xxyyy";var j={t:2,u:3},k=4;',
|
||||||
'console.log(i.s,j.t,j.u,k);',
|
'console.log(i.s,j.t,j.u,k);',
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: {
|
mangle: {
|
||||||
properties: true,
|
properties: true,
|
||||||
@@ -117,15 +117,15 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should not parse invalid use of reserved words", function() {
|
it("Should not parse invalid use of reserved words", function() {
|
||||||
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("keep_quoted_props", function() {
|
describe("keep_quoted_props", function() {
|
||||||
it("Should preserve quotes in object literals", function() {
|
it("Should preserve quotes in object literals", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = UglifyJS.minify(js, {
|
||||||
output: {
|
output: {
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
}});
|
}});
|
||||||
@@ -134,7 +134,7 @@ describe("minify", function() {
|
|||||||
|
|
||||||
it("Should preserve quote styles when quote_style is 3", function() {
|
it("Should preserve quote styles when quote_style is 3", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = UglifyJS.minify(js, {
|
||||||
output: {
|
output: {
|
||||||
keep_quoted_props: true,
|
keep_quoted_props: true,
|
||||||
quote_style: 3
|
quote_style: 3
|
||||||
@@ -144,7 +144,7 @@ describe("minify", function() {
|
|||||||
|
|
||||||
it("Should not preserve quotes in object literals when disabled", function() {
|
it("Should not preserve quotes in object literals when disabled", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
var result = Uglify.minify(js, {
|
var result = UglifyJS.minify(js, {
|
||||||
output: {
|
output: {
|
||||||
keep_quoted_props: false,
|
keep_quoted_props: false,
|
||||||
quote_style: 3
|
quote_style: 3
|
||||||
@@ -156,7 +156,7 @@ describe("minify", function() {
|
|||||||
describe("mangleProperties", function() {
|
describe("mangleProperties", function() {
|
||||||
it("Shouldn't mangle quoted properties", function() {
|
it("Shouldn't mangle quoted properties", function() {
|
||||||
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
||||||
var result = Uglify.minify(js, {
|
var result = UglifyJS.minify(js, {
|
||||||
compress: {
|
compress: {
|
||||||
properties: false
|
properties: false
|
||||||
},
|
},
|
||||||
@@ -174,7 +174,7 @@ describe("minify", function() {
|
|||||||
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||||
});
|
});
|
||||||
it("Should not mangle quoted property within dead code", function() {
|
it("Should not mangle quoted property within dead code", function() {
|
||||||
var result = Uglify.minify('({ "keep": 1 }); g.keep = g.change;', {
|
var result = UglifyJS.minify('({ "keep": 1 }); g.keep = g.change;', {
|
||||||
mangle: {
|
mangle: {
|
||||||
properties: {
|
properties: {
|
||||||
keep_quoted: true
|
keep_quoted: true
|
||||||
@@ -188,7 +188,7 @@ describe("minify", function() {
|
|||||||
|
|
||||||
describe("#__PURE__", function() {
|
describe("#__PURE__", function() {
|
||||||
it("should drop #__PURE__ hint after use", function() {
|
it("should drop #__PURE__ hint after use", function() {
|
||||||
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
var result = UglifyJS.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -198,7 +198,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
||||||
});
|
});
|
||||||
it("should drop #__PURE__ hint if function is retained", function() {
|
it("should drop #__PURE__ hint if function is retained", function() {
|
||||||
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
var result = UglifyJS.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -211,7 +211,7 @@ describe("minify", function() {
|
|||||||
|
|
||||||
describe("JS_Parse_Error", function() {
|
describe("JS_Parse_Error", function() {
|
||||||
it("should return syntax error", function() {
|
it("should return syntax error", function() {
|
||||||
var result = Uglify.minify("function f(a{}");
|
var result = UglifyJS.minify("function f(a{}");
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
||||||
@@ -220,7 +220,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
});
|
});
|
||||||
it("should reject duplicated label name", function() {
|
it("should reject duplicated label name", function() {
|
||||||
var result = Uglify.minify("L:{L:{}}");
|
var result = UglifyJS.minify("L:{L:{}}");
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Label L defined twice");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Label L defined twice");
|
||||||
@@ -232,7 +232,7 @@ describe("minify", function() {
|
|||||||
|
|
||||||
describe("global_defs", function() {
|
describe("global_defs", function() {
|
||||||
it("should throw for non-trivial expressions", function() {
|
it("should throw for non-trivial expressions", function() {
|
||||||
var result = Uglify.minify("alert(42);", {
|
var result = UglifyJS.minify("alert(42);", {
|
||||||
compress: {
|
compress: {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
"@alert": "debugger"
|
"@alert": "debugger"
|
||||||
@@ -246,7 +246,7 @@ describe("minify", function() {
|
|||||||
it("should skip inherited properties", function() {
|
it("should skip inherited properties", function() {
|
||||||
var foo = Object.create({ skip: this });
|
var foo = Object.create({ skip: this });
|
||||||
foo.bar = 42;
|
foo.bar = 42;
|
||||||
var result = Uglify.minify("alert(FOO);", {
|
var result = UglifyJS.minify("alert(FOO);", {
|
||||||
compress: {
|
compress: {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
FOO: foo
|
FOO: foo
|
||||||
@@ -266,7 +266,7 @@ describe("minify", function() {
|
|||||||
"}",
|
"}",
|
||||||
"f();",
|
"f();",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
var ast = Uglify.minify(code, {
|
var ast = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
@@ -279,7 +279,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(ast.body[0].body.length, 2);
|
assert.strictEqual(ast.body[0].body.length, 2);
|
||||||
assert.strictEqual(ast.body[0].body[0].TYPE, "SimpleStatement");
|
assert.strictEqual(ast.body[0].body[0].TYPE, "SimpleStatement");
|
||||||
var stat = ast.body[0].body[0];
|
var stat = ast.body[0].body[0];
|
||||||
Uglify.minify(ast, {
|
UglifyJS.minify(ast, {
|
||||||
compress: {
|
compress: {
|
||||||
sequences: false
|
sequences: false
|
||||||
},
|
},
|
||||||
@@ -294,7 +294,7 @@ describe("minify", function() {
|
|||||||
it("Should be repeatable", function() {
|
it("Should be repeatable", function() {
|
||||||
var code = "!function(x){return x(x)}(y);";
|
var code = "!function(x){return x(x)}(y);";
|
||||||
for (var i = 0; i < 2; i++) {
|
for (var i = 0; i < 2; i++) {
|
||||||
assert.strictEqual(Uglify.minify(code, {
|
assert.strictEqual(UglifyJS.minify(code, {
|
||||||
compress: {
|
compress: {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
},
|
},
|
||||||
@@ -307,7 +307,7 @@ describe("minify", function() {
|
|||||||
describe("enclose", function() {
|
describe("enclose", function() {
|
||||||
var code = read("test/input/enclose/input.js");
|
var code = read("test/input/enclose/input.js");
|
||||||
it("Should work with true", function() {
|
it("Should work with true", function() {
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
enclose: true,
|
enclose: true,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
@@ -316,7 +316,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code, '(function(){function enclose(){console.log("test enclose")}enclose()})();');
|
assert.strictEqual(result.code, '(function(){function enclose(){console.log("test enclose")}enclose()})();');
|
||||||
});
|
});
|
||||||
it("Should work with arg", function() {
|
it("Should work with arg", function() {
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
enclose: 'undefined',
|
enclose: 'undefined',
|
||||||
mangle: false,
|
mangle: false,
|
||||||
@@ -325,7 +325,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code, '(function(undefined){function enclose(){console.log("test enclose")}enclose()})();');
|
assert.strictEqual(result.code, '(function(undefined){function enclose(){console.log("test enclose")}enclose()})();');
|
||||||
});
|
});
|
||||||
it("Should work with arg:value", function() {
|
it("Should work with arg:value", function() {
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
enclose: 'window,undefined:window',
|
enclose: 'window,undefined:window',
|
||||||
mangle: false,
|
mangle: false,
|
||||||
@@ -334,7 +334,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code, '(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window);');
|
assert.strictEqual(result.code, '(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window);');
|
||||||
});
|
});
|
||||||
it("Should work alongside wrap", function() {
|
it("Should work alongside wrap", function() {
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
enclose: 'window,undefined:window',
|
enclose: 'window,undefined:window',
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("Number literals", function() {
|
describe("Number literals", function() {
|
||||||
it("Should not allow legacy octal literals in strict mode", function() {
|
it("Should not allow legacy octal literals in strict mode", function() {
|
||||||
@@ -7,16 +7,15 @@ describe("Number literals", function () {
|
|||||||
'"use strict";00;',
|
'"use strict";00;',
|
||||||
'"use strict"; var foo = 00;'
|
'"use strict"; var foo = 00;'
|
||||||
];
|
];
|
||||||
|
|
||||||
var test = function(input) {
|
var test = function(input) {
|
||||||
return function() {
|
return function() {
|
||||||
uglify.parse(input);
|
UglifyJS.parse(input);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Legacy octal literals are not allowed in strict mode";
|
&& e.message === "Legacy octal literals are not allowed in strict mode";
|
||||||
}
|
};
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
for (var i = 0; i < inputs.length; i++) {
|
||||||
assert.throws(test(inputs[i]), error, inputs[i]);
|
assert.throws(test(inputs[i]), error, inputs[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("operator", function() {
|
describe("operator", function() {
|
||||||
it("Should handle mixing of ++/+/--/- correctly", function() {
|
it("Should handle mixing of ++/+/--/- correctly", function() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("parentheses", function() {
|
describe("parentheses", function() {
|
||||||
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
|
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
|
||||||
@@ -33,7 +33,7 @@ describe("parentheses", function() {
|
|||||||
];
|
];
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i], {
|
UglifyJS.minify(tests[i], {
|
||||||
output: {beautify: true},
|
output: {beautify: true},
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
@@ -74,7 +74,7 @@ describe("parentheses", function() {
|
|||||||
];
|
];
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i], {
|
UglifyJS.minify(tests[i], {
|
||||||
output: {beautify: false},
|
output: {beautify: false},
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
@@ -94,7 +94,7 @@ describe("parentheses", function() {
|
|||||||
code = code.concat(code);
|
code = code.concat(code);
|
||||||
}
|
}
|
||||||
code = code.join("");
|
code = code.join("");
|
||||||
var result = uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var uglify = require("../../");
|
|
||||||
|
|
||||||
describe("screw-ie8", function () {
|
|
||||||
it("Should be able to minify() with undefined as catch parameter in a try...catch statement", function () {
|
|
||||||
assert.strictEqual(
|
|
||||||
uglify.minify(
|
|
||||||
"function a(b){\
|
|
||||||
try {\
|
|
||||||
throw 'Stuff';\
|
|
||||||
} catch (undefined) {\
|
|
||||||
console.log('caught: ' + undefined);\
|
|
||||||
}\
|
|
||||||
console.log('undefined is ' + undefined);\
|
|
||||||
return b === undefined;\
|
|
||||||
};"
|
|
||||||
).code,
|
|
||||||
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,19 +1,52 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
var Uglify = require("../../");
|
var SourceMapConsumer = require("source-map").SourceMapConsumer;
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
function read(path) {
|
function read(path) {
|
||||||
return readFileSync(path, "utf8");
|
return readFileSync(path, "utf8");
|
||||||
}
|
}
|
||||||
|
|
||||||
function source_map(code) {
|
function source_map(code) {
|
||||||
return JSON.parse(Uglify.minify(code, {
|
return JSON.parse(UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
}).map);
|
}).map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_map() {
|
||||||
|
return {
|
||||||
|
"version": 3,
|
||||||
|
"sources": ["index.js"],
|
||||||
|
"names": [],
|
||||||
|
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||||
|
"file": "bundle.js",
|
||||||
|
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_map(sourceMap) {
|
||||||
|
var code = [
|
||||||
|
'"use strict";',
|
||||||
|
"",
|
||||||
|
"var foo = function foo(x) {",
|
||||||
|
' return "foo " + x;',
|
||||||
|
"};",
|
||||||
|
'console.log(foo("bar"));',
|
||||||
|
"",
|
||||||
|
"//# sourceMappingURL=bundle.js.map",
|
||||||
|
].join("\n");
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
sourceMap: {
|
||||||
|
content: sourceMap,
|
||||||
|
includeSources: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
return new SourceMapConsumer(result.map);
|
||||||
|
}
|
||||||
|
|
||||||
describe("sourcemaps", function() {
|
describe("sourcemaps", function() {
|
||||||
it("Should give correct version", function() {
|
it("Should give correct version", function() {
|
||||||
var map = source_map("var x = 1 + 1;");
|
var map = source_map("var x = 1 + 1;");
|
||||||
@@ -36,7 +69,7 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should mark array/object literals", function() {
|
it("Should mark array/object literals", function() {
|
||||||
var result = Uglify.minify([
|
var result = UglifyJS.minify([
|
||||||
"var obj = {};",
|
"var obj = {};",
|
||||||
"obj.wat([]);",
|
"obj.wat([]);",
|
||||||
].join("\n"), {
|
].join("\n"), {
|
||||||
@@ -48,9 +81,21 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should give correct sourceRoot", function() {
|
||||||
|
var code = "console.log(42);";
|
||||||
|
var result = UglifyJS.minify(code, {
|
||||||
|
sourceMap: {
|
||||||
|
root: "//foo.bar/",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["console","log"],"mappings":"AAAAA,QAAQC,IAAI","sourceRoot":"//foo.bar/"}');
|
||||||
|
});
|
||||||
|
|
||||||
describe("inSourceMap", function() {
|
describe("inSourceMap", function() {
|
||||||
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() {
|
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled", function() {
|
||||||
var result = Uglify.minify(read("./test/input/issue-1236/simple.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-1236/simple.js"), {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: read("./test/input/issue-1236/simple.js.map"),
|
content: read("./test/input/issue-1236/simple.js.map"),
|
||||||
filename: "simple.min.js",
|
filename: "simple.min.js",
|
||||||
@@ -64,7 +109,7 @@ describe("sourcemaps", function() {
|
|||||||
assert.equal(map.sourcesContent[0], 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
assert.equal(map.sourcesContent[0], 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function() {
|
it("Should process inline source map", function() {
|
||||||
var result = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-520/input.js"), {
|
||||||
compress: { toplevel: true },
|
compress: { toplevel: true },
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
@@ -76,13 +121,13 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-520/output.js", "utf8"));
|
assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||||
});
|
});
|
||||||
it("Should warn for missing inline source map", function() {
|
it("Should warn for missing inline source map", function() {
|
||||||
var warn_function = Uglify.AST_Node.warn_function;
|
var warn_function = UglifyJS.AST_Node.warn_function;
|
||||||
var warnings = [];
|
var warnings = [];
|
||||||
Uglify.AST_Node.warn_function = function(txt) {
|
UglifyJS.AST_Node.warn_function = function(txt) {
|
||||||
warnings.push(txt);
|
warnings.push(txt);
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
var result = Uglify.minify(read("./test/input/issue-1323/sample.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-1323/sample.js"), {
|
||||||
mangle: false,
|
mangle: false,
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline"
|
content: "inline"
|
||||||
@@ -92,17 +137,17 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(warnings.length, 1);
|
assert.strictEqual(warnings.length, 1);
|
||||||
assert.strictEqual(warnings[0], "inline source map not found: 0");
|
assert.strictEqual(warnings[0], "inline source map not found: 0");
|
||||||
} finally {
|
} finally {
|
||||||
Uglify.AST_Node.warn_function = warn_function;
|
UglifyJS.AST_Node.warn_function = warn_function;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should handle multiple input and inline source map", function() {
|
it("Should handle multiple input and inline source map", function() {
|
||||||
var warn_function = Uglify.AST_Node.warn_function;
|
var warn_function = UglifyJS.AST_Node.warn_function;
|
||||||
var warnings = [];
|
var warnings = [];
|
||||||
Uglify.AST_Node.warn_function = function(txt) {
|
UglifyJS.AST_Node.warn_function = function(txt) {
|
||||||
warnings.push(txt);
|
warnings.push(txt);
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
var result = Uglify.minify([
|
var result = UglifyJS.minify([
|
||||||
read("./test/input/issue-520/input.js"),
|
read("./test/input/issue-520/input.js"),
|
||||||
read("./test/input/issue-1323/sample.js"),
|
read("./test/input/issue-1323/sample.js"),
|
||||||
], {
|
], {
|
||||||
@@ -119,11 +164,11 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(warnings.length, 1);
|
assert.strictEqual(warnings.length, 1);
|
||||||
assert.strictEqual(warnings[0], "inline source map not found: 1");
|
assert.strictEqual(warnings[0], "inline source map not found: 1");
|
||||||
} finally {
|
} finally {
|
||||||
Uglify.AST_Node.warn_function = warn_function;
|
UglifyJS.AST_Node.warn_function = warn_function;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should drop source contents for includeSources=false", function() {
|
it("Should drop source contents for includeSources=false", function() {
|
||||||
var result = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-520/input.js"), {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
@@ -134,7 +179,7 @@ describe("sourcemaps", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
assert.strictEqual(map.sourcesContent.length, 1);
|
assert.strictEqual(map.sourcesContent.length, 1);
|
||||||
result = Uglify.minify(result.code, {
|
result = UglifyJS.minify(result.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
@@ -149,7 +194,7 @@ describe("sourcemaps", function() {
|
|||||||
|
|
||||||
describe("sourceMapInline", function() {
|
describe("sourceMapInline", function() {
|
||||||
it("Should append source map to output js when sourceMapInline is enabled", function() {
|
it("Should append source map to output js when sourceMapInline is enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
var result = UglifyJS.minify('var a = function(foo) { return foo; };', {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
url: "inline"
|
url: "inline"
|
||||||
}
|
}
|
||||||
@@ -160,13 +205,13 @@ describe("sourcemaps", function() {
|
|||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
||||||
});
|
});
|
||||||
it("Should not append source map to output js when sourceMapInline is not enabled", function() {
|
it("Should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
var result = UglifyJS.minify('var a = function(foo) { return foo; };');
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};");
|
assert.strictEqual(code, "var a=function(n){return n};");
|
||||||
});
|
});
|
||||||
it("Should work with max_line_len", function() {
|
it("Should work with max_line_len", function() {
|
||||||
var result = Uglify.minify(read("./test/input/issue-505/input.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-505/input.js"), {
|
||||||
output: {
|
output: {
|
||||||
max_line_len: 20
|
max_line_len: 20
|
||||||
},
|
},
|
||||||
@@ -182,7 +227,7 @@ describe("sourcemaps", function() {
|
|||||||
"var tëst = '→unicøde←';",
|
"var tëst = '→unicøde←';",
|
||||||
"alert(tëst);",
|
"alert(tëst);",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
var result = Uglify.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
includeSources: true,
|
includeSources: true,
|
||||||
url: "inline",
|
url: "inline",
|
||||||
@@ -196,7 +241,7 @@ describe("sourcemaps", function() {
|
|||||||
map = JSON.parse(new Buffer(encoded, "base64").toString());
|
map = JSON.parse(new Buffer(encoded, "base64").toString());
|
||||||
assert.strictEqual(map.sourcesContent.length, 1);
|
assert.strictEqual(map.sourcesContent.length, 1);
|
||||||
assert.strictEqual(map.sourcesContent[0], code);
|
assert.strictEqual(map.sourcesContent[0], code);
|
||||||
result = Uglify.minify(result.code, {
|
result = UglifyJS.minify(result.code, {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
includeSources: true,
|
includeSources: true,
|
||||||
@@ -209,4 +254,37 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(map.names[1], "alert");
|
assert.strictEqual(map.names[1], "alert");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("input sourcemaps", function() {
|
||||||
|
it("Should copy over original sourcesContent", function() {
|
||||||
|
var orig = get_map();
|
||||||
|
var map = prepare_map(orig);
|
||||||
|
assert.equal(map.sourceContentFor("index.js"), orig.sourcesContent[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should copy sourcesContent if sources are relative", function() {
|
||||||
|
var relativeMap = get_map();
|
||||||
|
relativeMap.sources = ['./index.js'];
|
||||||
|
var map = prepare_map(relativeMap);
|
||||||
|
assert.notEqual(map.sourcesContent, null);
|
||||||
|
assert.equal(map.sourcesContent.length, 1);
|
||||||
|
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not have invalid mappings from inputSourceMap", function() {
|
||||||
|
var map = prepare_map(get_map());
|
||||||
|
// The original source has only 2 lines, check that mappings don't have more lines
|
||||||
|
var msg = "Mapping should not have higher line number than the original file had";
|
||||||
|
map.eachMapping(function(mapping) {
|
||||||
|
assert.ok(mapping.originalLine <= 2, msg);
|
||||||
|
});
|
||||||
|
map.allGeneratedPositionsFor({
|
||||||
|
source: "index.js",
|
||||||
|
line: 1,
|
||||||
|
column: 1
|
||||||
|
}).forEach(function(pos) {
|
||||||
|
assert.ok(pos.line <= 2, msg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var uglify = require("../node");
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("spidermonkey export/import sanity test", function() {
|
describe("spidermonkey export/import sanity test", function() {
|
||||||
it("should produce a functional build when using --self with spidermonkey", function(done) {
|
it("should produce a functional build when using --self with spidermonkey", function(done) {
|
||||||
@@ -25,9 +25,9 @@ describe("spidermonkey export/import sanity test", function() {
|
|||||||
|
|
||||||
it("should not add unnecessary escape slashes to regexps", function() {
|
it("should not add unnecessary escape slashes to regexps", function() {
|
||||||
var input = "/[\\\\/]/;";
|
var input = "/[\\\\/]/;";
|
||||||
var ast = uglify.parse(input).to_mozilla_ast();
|
var ast = UglifyJS.parse(input).to_mozilla_ast();
|
||||||
assert.equal(
|
assert.equal(
|
||||||
uglify.AST_Node.from_mozilla_ast(ast).print_to_string(),
|
UglifyJS.AST_Node.from_mozilla_ast(ast).print_to_string(),
|
||||||
input
|
input
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -99,10 +99,10 @@ describe("spidermonkey export/import sanity test", function() {
|
|||||||
var counter_directives;
|
var counter_directives;
|
||||||
var counter_strings;
|
var counter_strings;
|
||||||
|
|
||||||
var checkWalker = new uglify.TreeWalker(function(node, descend) {
|
var checkWalker = new UglifyJS.TreeWalker(function(node, descend) {
|
||||||
if (node instanceof uglify.AST_String) {
|
if (node instanceof UglifyJS.AST_String) {
|
||||||
counter_strings++;
|
counter_strings++;
|
||||||
} else if (node instanceof uglify.AST_Directive) {
|
} else if (node instanceof UglifyJS.AST_Directive) {
|
||||||
counter_directives++;
|
counter_directives++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -111,9 +111,9 @@ describe("spidermonkey export/import sanity test", function() {
|
|||||||
counter_directives = 0;
|
counter_directives = 0;
|
||||||
counter_strings = 0;
|
counter_strings = 0;
|
||||||
|
|
||||||
var ast = uglify.parse(tests[i].input);
|
var ast = UglifyJS.parse(tests[i].input);
|
||||||
var moz_ast = ast.to_mozilla_ast();
|
var moz_ast = ast.to_mozilla_ast();
|
||||||
var from_moz_ast = uglify.AST_Node.from_mozilla_ast(moz_ast);
|
var from_moz_ast = UglifyJS.AST_Node.from_mozilla_ast(moz_ast);
|
||||||
|
|
||||||
from_moz_ast.walk(checkWalker);
|
from_moz_ast.walk(checkWalker);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("String literals", function() {
|
describe("String literals", function() {
|
||||||
it("Should throw syntax error if a string literal contains a newline", function() {
|
it("Should throw syntax error if a string literal contains a newline", function() {
|
||||||
@@ -18,8 +18,8 @@ describe("String literals", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Unterminated string constant";
|
&& e.message === "Unterminated string constant";
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var input in inputs) {
|
for (var input in inputs) {
|
||||||
@@ -48,8 +48,8 @@ describe("String literals", function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Legacy octal escape sequences are not allowed in strict mode";
|
&& e.message === "Legacy octal escape sequences are not allowed in strict mode";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var input in inputs) {
|
for (var input in inputs) {
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
var UglifyJS = require("../node");
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("Accessor tokens", function() {
|
describe("tokens", function() {
|
||||||
it("Should fill the token information for accessors (issue #1492)", function() {
|
it("Should give correct positions for accessors", function() {
|
||||||
// location 0 1 2 3 4
|
// location 0 1 2 3 4
|
||||||
// 01234567890123456789012345678901234567890123456789
|
// 01234567890123456789012345678901234567890123456789
|
||||||
var ast = UglifyJS.parse("var obj = { get latest() { return undefined; } }");
|
var ast = UglifyJS.parse("var obj = { get latest() { return undefined; } }");
|
||||||
|
|
||||||
// test all AST_ObjectProperty tokens are set as expected
|
// test all AST_ObjectProperty tokens are set as expected
|
||||||
var checkedAST_ObjectProperty = false;
|
var found = false;
|
||||||
var checkWalker = new UglifyJS.TreeWalker(function(node, descend) {
|
ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
if (node instanceof UglifyJS.AST_ObjectProperty) {
|
if (node instanceof UglifyJS.AST_ObjectProperty) {
|
||||||
checkedAST_ObjectProperty = true;
|
found = true;
|
||||||
|
|
||||||
assert.equal(node.start.pos, 12);
|
assert.equal(node.start.pos, 12);
|
||||||
assert.equal(node.end.endpos, 46);
|
assert.equal(node.end.endpos, 46);
|
||||||
|
|
||||||
assert(node.key instanceof UglifyJS.AST_SymbolAccessor);
|
assert(node.key instanceof UglifyJS.AST_SymbolAccessor);
|
||||||
assert.equal(node.key.start.pos, 16);
|
assert.equal(node.key.start.pos, 16);
|
||||||
assert.equal(node.key.end.endpos, 22);
|
assert.equal(node.key.end.endpos, 22);
|
||||||
|
|
||||||
assert(node.value instanceof UglifyJS.AST_Accessor);
|
assert(node.value instanceof UglifyJS.AST_Accessor);
|
||||||
assert.equal(node.value.start.pos, 22);
|
assert.equal(node.value.start.pos, 22);
|
||||||
assert.equal(node.value.end.endpos, 46);
|
assert.equal(node.value.end.endpos, 46);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
ast.walk(checkWalker);
|
assert(found, "AST_ObjectProperty not found");
|
||||||
assert(checkedAST_ObjectProperty, "AST_ObjectProperty not found");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("With", function() {
|
describe("With", function() {
|
||||||
it("Should throw syntaxError when using with statement in strict mode", function() {
|
it("Should throw syntaxError when using with statement in strict mode", function() {
|
||||||
var code = '"use strict";\nthrow NotEarlyError;\nwith ({}) { }';
|
var code = '"use strict";\nthrow NotEarlyError;\nwith ({}) { }';
|
||||||
var test = function() {
|
var test = function() {
|
||||||
uglify.parse(code);
|
UglifyJS.parse(code);
|
||||||
}
|
}
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
e.message === "Strict mode may not include a with statement";
|
&& e.message === "Strict mode may not include a with statement";
|
||||||
}
|
}
|
||||||
assert.throws(test, error);
|
assert.throws(test, error);
|
||||||
});
|
});
|
||||||
it("Should set uses_with for scopes involving With statements", function() {
|
it("Should set uses_with for scopes involving With statements", function() {
|
||||||
var ast = uglify.parse("with(e) {f(1, 2)}");
|
var ast = UglifyJS.parse("with(e) {f(1, 2)}");
|
||||||
ast.figure_out_scope();
|
ast.figure_out_scope();
|
||||||
assert.equal(ast.uses_with, true);
|
assert.equal(ast.uses_with, true);
|
||||||
assert.equal(ast.body[0].expression.scope.uses_with, true);
|
assert.equal(ast.body[0].expression.scope.uses_with, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user