Update dependencies
This commit is contained in:
parent
176039b833
commit
510e88928d
1174 changed files with 3378 additions and 2107 deletions
267
node_modules/uglify-js/lib/ast.js
generated
vendored
267
node_modules/uglify-js/lib/ast.js
generated
vendored
|
@ -109,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||
start: "[AST_Token] The first token of this node",
|
||||
end: "[AST_Token] The last token of this node"
|
||||
},
|
||||
equals: function(node) {
|
||||
return this.TYPE == node.TYPE && this._equals(node);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
visitor.visit(this);
|
||||
},
|
||||
|
@ -138,6 +141,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||
}, null);
|
||||
|
||||
DEF_BITPROPS(AST_Node, [
|
||||
// AST_Node
|
||||
"_optimized",
|
||||
"_squeezed",
|
||||
// AST_Call
|
||||
|
@ -172,6 +176,8 @@ DEF_BITPROPS(AST_Node, [
|
|||
"pure",
|
||||
// AST_Assign
|
||||
"redundant",
|
||||
// AST_Node
|
||||
"single_use",
|
||||
// AST_ClassProperty
|
||||
"static",
|
||||
// AST_Call
|
||||
|
@ -231,6 +237,24 @@ AST_Node.disable_validation = function() {
|
|||
while (restore = restore_transforms.pop()) restore();
|
||||
};
|
||||
|
||||
function all_equals(k, l) {
|
||||
return k.length == l.length && all(k, function(m, i) {
|
||||
return m.equals(l[i]);
|
||||
});
|
||||
}
|
||||
|
||||
function list_equals(s, t) {
|
||||
return s.length == t.length && all(s, function(u, i) {
|
||||
return u == t[i];
|
||||
});
|
||||
}
|
||||
|
||||
function prop_equals(u, v) {
|
||||
if (u === v) return true;
|
||||
if (u == null) return v == null;
|
||||
return u instanceof AST_Node && v instanceof AST_Node && u.equals(v);
|
||||
}
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
var AST_Statement = DEFNODE("Statement", null, {
|
||||
|
@ -242,6 +266,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
|||
|
||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
|
@ -250,6 +275,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
|||
quote: "[string?] the original quote character",
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.value == node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
|
@ -260,7 +288,8 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
|||
}, AST_Statement);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
function is_statement(node) {
|
||||
|
@ -291,6 +320,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
|||
$propdoc: {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -342,6 +374,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -376,6 +411,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||
$propdoc: {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.label.equals(node.label)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -417,6 +456,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||
must_be_expression(this, "condition");
|
||||
|
@ -431,7 +474,7 @@ var AST_Do = DEFNODE("Do", null, {
|
|||
node.body.walk(visitor);
|
||||
node.condition.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
|
@ -442,7 +485,7 @@ var AST_While = DEFNODE("While", null, {
|
|||
node.condition.walk(visitor);
|
||||
node.body.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
|
@ -452,6 +495,12 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.init, node.init)
|
||||
&& prop_equals(this.condition, node.condition)
|
||||
&& prop_equals(this.step, node.step)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -479,6 +528,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
|||
init: "[AST_Node] the assignment target during iteration",
|
||||
object: "[AST_Node] the object to iterate over"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.init.equals(node.init)
|
||||
&& this.object.equals(node.object)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -519,6 +573,10 @@ var AST_With = DEFNODE("With", "expression", {
|
|||
$propdoc: {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -621,6 +679,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_argu
|
|||
});
|
||||
if (this.rest) this.rest.walk(tw);
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.value, node.value)
|
||||
&& all_equals(this.argnames, node.argnames)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -831,6 +896,11 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
|||
extends: "[AST_Node?] the super class, or null if not specified",
|
||||
properties: "[AST_ClassProperty*] array of class properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.extends, node.extends)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
|
@ -883,6 +953,12 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
|||
static: "[boolean] whether this is a static property",
|
||||
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.private == !node.private
|
||||
&& !this.static == !node.static
|
||||
&& prop_equals(this.key, node.key)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -959,6 +1035,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||
$propdoc: {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -989,6 +1068,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||
$propdoc: {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.label, node.label);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1019,6 +1101,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||
condition: "[AST_Node] the `if` condition",
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition)
|
||||
&& prop_equals(this.alternative, node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1042,6 +1129,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||
$propdoc: {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1073,6 +1164,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
|||
$propdoc: {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1093,6 +1188,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body)
|
||||
&& prop_equals(this.bcatch, node.bcatch)
|
||||
&& prop_equals(this.bfinally, node.bfinally);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1116,6 +1216,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||
$propdoc: {
|
||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.argname, node.argname)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1141,6 +1245,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.definitions, node.definitions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1197,6 +1304,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1216,6 +1327,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
|||
$propdoc: {
|
||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1236,6 +1350,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||
$propdoc: {
|
||||
body: "[AST_Node] the default export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1249,29 +1366,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||
$documentation: "An `export ... from '...'` statement",
|
||||
$propdoc: {
|
||||
aliases: "[string*] array of aliases to export",
|
||||
keys: "[string*] array of keys to import",
|
||||
path: "[string] the path to import module",
|
||||
quote: "[string?] the original quote character",
|
||||
aliases: "[AST_String*] array of aliases to export",
|
||||
keys: "[AST_String*] array of keys to import",
|
||||
path: "[AST_String] the path to import module",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& all_equals(this.aliases, node.aliases)
|
||||
&& all_equals(this.keys, node.keys);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.aliases.length != this.keys.length) {
|
||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||
}
|
||||
this.aliases.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||
});
|
||||
this.keys.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("keys must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||
});
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
|
@ -1280,6 +1397,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||
$propdoc: {
|
||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1295,14 +1415,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||
$documentation: "An `import` statement",
|
||||
$propdoc: {
|
||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||
path: "[string] the path to import module",
|
||||
path: "[AST_String] the path to import module",
|
||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||
quote: "[string?] the original quote character",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& prop_equals(this.all, node.all)
|
||||
&& prop_equals(this.default, node.default)
|
||||
&& !this.properties == !node.properties
|
||||
&& (!this.properties || all_equals(this.properties, node.properties));
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
|
@ -1321,16 +1447,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
|||
}
|
||||
if (this.default != null) {
|
||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
||||
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||
}
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
if (this.properties != null) this.properties.forEach(function(node) {
|
||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||
});
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
|
@ -1340,6 +1462,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
|||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1367,6 +1493,11 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
|||
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& this.expression.equals(node.expression)
|
||||
&& all_equals(this.args, node.args);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1395,6 +1526,9 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1422,6 +1556,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
|||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& prop_equals(this.property, node.property)
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
get_property: function() {
|
||||
var p = this.property;
|
||||
if (p instanceof AST_Constant) return p.value;
|
||||
|
@ -1466,6 +1605,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
|||
$propdoc: {
|
||||
expression: "[AST_Node] expression to be expanded",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1483,6 +1625,10 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||
operator: "[string] the operator",
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1511,6 +1657,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
|||
operator: "[string] the operator",
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.left.equals(node.left)
|
||||
&& this.right.equals(node.right);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1532,6 +1683,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|||
consequent: "[AST_Node]",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.condition.equals(node.condition)
|
||||
&& this.consequent.equals(node.consequent)
|
||||
&& this.alternative.equals(node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1573,6 +1729,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
|||
$propdoc: {
|
||||
expression: "[AST_Node] expression with Promise to resolve on",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1590,6 +1749,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
|||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||
nested: "[boolean] whether to iterate over expression as generator",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.nested == !node.nested
|
||||
&& prop_equals(this.expression, node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1612,6 +1775,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1654,6 +1820,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
|||
$propdoc: {
|
||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1671,6 +1841,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
|||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1692,6 +1866,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
|||
$propdoc: {
|
||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1713,6 +1891,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||
$propdoc: {
|
||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1736,6 +1917,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
|
@ -1790,6 +1975,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||
if (typeof this.name != "string") throw new Error("name must be string");
|
||||
|
@ -1807,10 +1995,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
|||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||
$documentation: "Symbol defined by an `import` statement",
|
||||
$propdoc: {
|
||||
key: "[string] the original `export` name",
|
||||
key: "[AST_String] the original `export` name",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.key.equals(node.key);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.key != "string") throw new Error("key must be string");
|
||||
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||
},
|
||||
}, AST_SymbolConst);
|
||||
|
||||
|
@ -1864,10 +2056,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
|||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||
$documentation: "Reference in an `export` statement",
|
||||
$propdoc: {
|
||||
alias: "[string] the `export` alias",
|
||||
alias: "[AST_String] the `export` alias",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.alias.equals(node.alias);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||
},
|
||||
}, AST_SymbolRef);
|
||||
|
||||
|
@ -1877,6 +2073,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
|||
|
||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||
$documentation: "Base class for `super` & `this`",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||
},
|
||||
|
@ -1911,7 +2108,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||
$propdoc: {
|
||||
expressions: "[AST_Node*] the placeholder expressions",
|
||||
strings: "[string*] the raw text segments",
|
||||
tag: "[AST_Node] tag function, or null if absent",
|
||||
tag: "[AST_Node?] tag function, or null if absent",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.tag, node.tag)
|
||||
&& list_equals(this.strings, node.strings)
|
||||
&& all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
|
@ -1936,6 +2138,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||
|
||||
var AST_Constant = DEFNODE("Constant", null, {
|
||||
$documentation: "Base class for all constants",
|
||||
_equals: function(node) {
|
||||
return this.value === node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||
},
|
||||
|
@ -1984,6 +2189,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||
$propdoc: {
|
||||
value: "[RegExp] the actual regexp"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return "" + this.value == "" + node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||
},
|
||||
|
@ -1991,6 +2199,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||
|
||||
var AST_Atom = DEFNODE("Atom", null, {
|
||||
$documentation: "Base class for atoms",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||
},
|
||||
|
|
543
node_modules/uglify-js/lib/compress.js
generated
vendored
543
node_modules/uglify-js/lib/compress.js
generated
vendored
|
@ -270,10 +270,6 @@ Compressor.prototype.compress = function(node) {
|
|||
return self;
|
||||
});
|
||||
|
||||
AST_Node.DEFMETHOD("equivalent_to", function(node) {
|
||||
return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string();
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("hoist_exports", function(compressor) {
|
||||
if (!compressor.option("hoist_exports")) return;
|
||||
var body = this.body, props = [];
|
||||
|
@ -298,7 +294,7 @@ Compressor.prototype.compress = function(node) {
|
|||
function export_symbol(sym) {
|
||||
if (!(sym instanceof AST_SymbolDeclaration)) return;
|
||||
var node = make_node(AST_SymbolExport, sym, sym);
|
||||
node.alias = node.name;
|
||||
node.alias = make_node(AST_String, node, { value: node.name });
|
||||
props.push(node);
|
||||
}
|
||||
});
|
||||
|
@ -930,7 +926,7 @@ Compressor.prototype.compress = function(node) {
|
|||
var scan = ld || left instanceof AST_Destructured;
|
||||
switch (node.operator) {
|
||||
case "=":
|
||||
if (left.equivalent_to(right) && !left.has_side_effects(compressor)) {
|
||||
if (left.equals(right) && !left.has_side_effects(compressor)) {
|
||||
right.walk(tw);
|
||||
walk_prop(left);
|
||||
node.redundant = true;
|
||||
|
@ -1669,6 +1665,19 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
}
|
||||
|
||||
function find_try(compressor, level, node, scope, may_throw, sync) {
|
||||
for (var parent; parent = compressor.parent(level++); node = parent) {
|
||||
if (parent === scope) return false;
|
||||
if (sync && parent instanceof AST_Lambda) {
|
||||
if (parent.name || is_async(parent) || is_generator(parent)) return true;
|
||||
} else if (parent instanceof AST_Try) {
|
||||
if (parent.bfinally && parent.bfinally !== node) return true;
|
||||
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var identifier_atom = makePredicate("Infinity NaN undefined");
|
||||
function is_lhs_read_only(lhs, compressor) {
|
||||
if (lhs instanceof AST_ObjectIdentity) return true;
|
||||
|
@ -1909,7 +1918,7 @@ Compressor.prototype.compress = function(node) {
|
|||
var in_lambda = last_of(compressor, function(node) {
|
||||
return node instanceof AST_Lambda;
|
||||
});
|
||||
var block_scope, in_loop, in_try, scope;
|
||||
var block_scope, iife_in_try, in_iife_single, in_loop, in_try, scope;
|
||||
find_loop_scope_try();
|
||||
var changed, last_changed, max_iter = 10;
|
||||
do {
|
||||
|
@ -1950,20 +1959,18 @@ Compressor.prototype.compress = function(node) {
|
|||
return statements;
|
||||
|
||||
function last_of(compressor, predicate) {
|
||||
var block = compressor.self(), level = 0;
|
||||
var block = compressor.self(), level = 0, stat;
|
||||
do {
|
||||
if (block instanceof AST_Catch) {
|
||||
block = compressor.parent(level++);
|
||||
} else if (block instanceof AST_LabeledStatement) {
|
||||
block = block.body;
|
||||
}
|
||||
var stat = null;
|
||||
while (true) {
|
||||
if (predicate(block)) return true;
|
||||
block = compressor.parent(level++);
|
||||
if (!(block instanceof AST_If)) break;
|
||||
do {
|
||||
stat = block;
|
||||
}
|
||||
if (predicate(stat)) return stat;
|
||||
block = compressor.parent(level++);
|
||||
} while (block instanceof AST_If);
|
||||
} while (stat
|
||||
&& (block instanceof AST_BlockStatement
|
||||
|| block instanceof AST_Catch
|
||||
|
@ -2033,7 +2040,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// Cascade compound assignments
|
||||
if (compound && scan_lhs && can_replace && !stop_if_hit
|
||||
&& node instanceof AST_Assign && node.operator != "=" && node.left.equivalent_to(lhs)) {
|
||||
&& node instanceof AST_Assign && node.operator != "=" && node.left.equals(lhs)) {
|
||||
replaced++;
|
||||
changed = true;
|
||||
AST_Node.info("Cascading {node} [{file}:{line},{col}]", {
|
||||
|
@ -2073,11 +2080,11 @@ Compressor.prototype.compress = function(node) {
|
|||
return node;
|
||||
}
|
||||
// Skip transient nodes caused by single-use variable replacement
|
||||
if (node.single_use && parent instanceof AST_VarDef && parent.value === node) return node;
|
||||
if (node.single_use) return node;
|
||||
// Replace variable with assignment when found
|
||||
var hit_rhs;
|
||||
if (!(node instanceof AST_SymbolDeclaration)
|
||||
&& (scan_lhs && lhs.equivalent_to(node)
|
||||
&& (scan_lhs && lhs.equals(node)
|
||||
|| scan_rhs && (hit_rhs = scan_rhs(node, this)))) {
|
||||
if (!can_replace || stop_if_hit && (hit_rhs || !lhs_local || !replace_all)) {
|
||||
if (!hit_rhs && !value_def) abort = true;
|
||||
|
@ -2422,11 +2429,11 @@ Compressor.prototype.compress = function(node) {
|
|||
if (node !== parent.init) return true;
|
||||
}
|
||||
if (node instanceof AST_Assign) {
|
||||
return node.operator != "=" && lhs.equivalent_to(node.left);
|
||||
return node.operator != "=" && lhs.equals(node.left);
|
||||
}
|
||||
if (node instanceof AST_Call) {
|
||||
if (!(lhs instanceof AST_PropAccess)) return false;
|
||||
if (!lhs.equivalent_to(node.expression)) return false;
|
||||
if (!lhs.equals(node.expression)) return false;
|
||||
return !(rvalue instanceof AST_LambdaExpression && !rvalue.contains_this());
|
||||
}
|
||||
if (node instanceof AST_Class) return !compressor.has_directive("use strict");
|
||||
|
@ -2483,24 +2490,24 @@ Compressor.prototype.compress = function(node) {
|
|||
can_replace = false;
|
||||
var after = stop_after;
|
||||
var if_hit = stop_if_hit;
|
||||
if (!all(fn.argnames, function(argname) {
|
||||
if (argname instanceof AST_DefaultValue) {
|
||||
argname.value.transform(scanner);
|
||||
if (abort) return false;
|
||||
argname = argname.name;
|
||||
for (var i = 0; !abort && i < fn.argnames.length; i++) {
|
||||
if (arg_may_throw(reject, fn.argnames[i], node.args[i])) abort = true;
|
||||
}
|
||||
if (!abort) {
|
||||
if (fn.rest && arg_may_throw(reject, fn.rest, make_node(AST_Array, node, {
|
||||
elements: node.args.slice(i),
|
||||
}))) {
|
||||
abort = true;
|
||||
} else if (is_arrow(fn) && fn.value) {
|
||||
fn.value.transform(scanner);
|
||||
} else for (var i = 0; !abort && i < fn.body.length; i++) {
|
||||
var stat = fn.body[i];
|
||||
if (stat instanceof AST_Return) {
|
||||
if (stat.value) stat.value.transform(scanner);
|
||||
break;
|
||||
}
|
||||
stat.transform(scanner);
|
||||
}
|
||||
return !(argname instanceof AST_Destructured);
|
||||
})) {
|
||||
abort = true;
|
||||
} else if (is_arrow(fn) && fn.value) {
|
||||
fn.value.transform(scanner);
|
||||
} else for (var i = 0; !abort && i < fn.body.length; i++) {
|
||||
var stat = fn.body[i];
|
||||
if (stat instanceof AST_Return) {
|
||||
if (stat.value) stat.value.transform(scanner);
|
||||
break;
|
||||
}
|
||||
stat.transform(scanner);
|
||||
}
|
||||
stop_if_hit = if_hit;
|
||||
stop_after = after;
|
||||
|
@ -2566,115 +2573,143 @@ Compressor.prototype.compress = function(node) {
|
|||
return node instanceof AST_SymbolRef
|
||||
&& (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
|
||||
}, true);
|
||||
|
||||
function reject(node) {
|
||||
node.transform(scanner);
|
||||
return abort;
|
||||
}
|
||||
}
|
||||
|
||||
function may_throw_destructured(node, value) {
|
||||
if (!value) return !(node instanceof AST_Symbol);
|
||||
function arg_may_throw(reject, node, value) {
|
||||
if (node instanceof AST_DefaultValue) {
|
||||
return value.has_side_effects(compressor)
|
||||
|| node.value.has_side_effects(compressor)
|
||||
|| may_throw_destructured(node.name, is_undefined(value) && node.value);
|
||||
return reject(node.value)
|
||||
|| arg_may_throw(reject, node.name, node.value)
|
||||
|| !is_undefined(value) && arg_may_throw(reject, node.name, value);
|
||||
}
|
||||
if (!value) return !(node instanceof AST_Symbol);
|
||||
if (node instanceof AST_Destructured) {
|
||||
if (node.rest && may_throw_destructured(node.rest)) return true;
|
||||
if (node.rest && arg_may_throw(reject, node.rest)) return true;
|
||||
if (node instanceof AST_DestructuredArray) {
|
||||
if (!(value instanceof AST_Array || value.is_string(compressor))) return true;
|
||||
if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
|
||||
return !arg_may_throw(reject, element, value[index]);
|
||||
});
|
||||
if (!value.is_string(compressor)) return true;
|
||||
return !all(node.elements, function(element) {
|
||||
return !may_throw_destructured(element);
|
||||
return !arg_may_throw(reject, element);
|
||||
});
|
||||
}
|
||||
if (node instanceof AST_DestructuredObject) {
|
||||
if (!value.is_defined(compressor)) return true;
|
||||
if (value.may_throw_on_access(compressor)) return true;
|
||||
return !all(node.properties, function(prop) {
|
||||
if (prop instanceof AST_Node && prop.has_side_effects(compressor)) return false;
|
||||
return !may_throw_destructured(prop.value);
|
||||
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
|
||||
return !arg_may_throw(reject, prop.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extract_args() {
|
||||
var iife, fn = compressor.self();
|
||||
if (fn instanceof AST_LambdaExpression
|
||||
&& !is_generator(fn)
|
||||
&& !fn.uses_arguments
|
||||
&& !fn.pinned()
|
||||
&& (iife = compressor.parent()) instanceof AST_Call
|
||||
&& iife.expression === fn
|
||||
&& is_iife_single(iife)
|
||||
&& all(iife.args, function(arg) {
|
||||
return !(arg instanceof AST_Spread);
|
||||
})) {
|
||||
var fn_strict = fn.in_strict_mode(compressor)
|
||||
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
|
||||
var has_await = is_async(fn) ? function(node) {
|
||||
if (in_iife_single === false) return;
|
||||
var iife = compressor.parent(), fn = compressor.self();
|
||||
if (in_iife_single === undefined) {
|
||||
if (!(fn instanceof AST_LambdaExpression)
|
||||
|| is_generator(fn)
|
||||
|| fn.uses_arguments
|
||||
|| fn.pinned()
|
||||
|| !(iife instanceof AST_Call)
|
||||
|| iife.expression !== fn
|
||||
|| !all(iife.args, function(arg) {
|
||||
return !(arg instanceof AST_Spread);
|
||||
})) {
|
||||
in_iife_single = false;
|
||||
return;
|
||||
}
|
||||
if (!is_iife_single(iife)) return;
|
||||
in_iife_single = true;
|
||||
}
|
||||
var fn_strict = fn.in_strict_mode(compressor)
|
||||
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
|
||||
var has_await;
|
||||
if (is_async(fn)) {
|
||||
has_await = function(node) {
|
||||
return node instanceof AST_Symbol && node.name == "await";
|
||||
} : function(node) {
|
||||
};
|
||||
iife_in_try = true;
|
||||
} else {
|
||||
has_await = function(node) {
|
||||
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
|
||||
};
|
||||
var arg_scope = null;
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (!arg) return true;
|
||||
if (has_await(node) || node instanceof AST_Yield) {
|
||||
arg = null;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_ObjectIdentity && (fn_strict || !arg_scope)) {
|
||||
arg = null;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
|
||||
var s = node.definition().scope;
|
||||
if (s !== scope) while (s = s.parent_scope) {
|
||||
if (s === scope) return true;
|
||||
}
|
||||
if (iife_in_try === undefined) iife_in_try = find_try(compressor, 1, iife, null, true, true);
|
||||
}
|
||||
var arg_scope = null;
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (!arg) return true;
|
||||
if (has_await(node) || node instanceof AST_Yield) {
|
||||
arg = null;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_ObjectIdentity) {
|
||||
if (fn_strict || !arg_scope) arg = null;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
var def;
|
||||
if (node.in_arg && !is_safe_lexical(node.definition())
|
||||
|| (def = fn.variables.get(node.name)) && def !== node.definition()) {
|
||||
arg = null;
|
||||
}
|
||||
if (node instanceof AST_Scope && !is_arrow(node)) {
|
||||
var save_scope = arg_scope;
|
||||
arg_scope = node;
|
||||
descend();
|
||||
arg_scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
args = iife.args.slice();
|
||||
var len = args.length;
|
||||
var names = new Dictionary();
|
||||
for (var i = fn.argnames.length; --i >= 0;) {
|
||||
var sym = fn.argnames[i];
|
||||
var arg = args[i];
|
||||
var value;
|
||||
if (sym instanceof AST_DefaultValue) {
|
||||
value = sym.value;
|
||||
sym = sym.name;
|
||||
args[len + i] = value;
|
||||
}
|
||||
if (sym instanceof AST_Destructured) {
|
||||
if (!may_throw_destructured(sym, arg)) continue;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope && !is_arrow(node)) {
|
||||
var save_scope = arg_scope;
|
||||
arg_scope = node;
|
||||
descend();
|
||||
arg_scope = save_scope;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
args = iife.args.slice();
|
||||
var len = args.length;
|
||||
var names = new Dictionary();
|
||||
for (var i = fn.argnames.length; --i >= 0;) {
|
||||
var sym = fn.argnames[i];
|
||||
var arg = args[i];
|
||||
var value = null;
|
||||
if (sym instanceof AST_DefaultValue) {
|
||||
value = sym.value;
|
||||
sym = sym.name;
|
||||
args[len + i] = value;
|
||||
}
|
||||
if (sym instanceof AST_Destructured) {
|
||||
if (iife_in_try && arg_may_throw(function(node) {
|
||||
return node.has_side_effects(compressor);
|
||||
}, sym, arg)) {
|
||||
candidates.length = 0;
|
||||
break;
|
||||
}
|
||||
if (names.has(sym.name)) continue;
|
||||
names.set(sym.name, true);
|
||||
if (value) arg = is_undefined(arg) ? value : null;
|
||||
if (!arg && !value) {
|
||||
arg = make_node(AST_Undefined, sym).transform(compressor);
|
||||
} else if (arg instanceof AST_Lambda && arg.pinned()) {
|
||||
arg = null;
|
||||
} else if (arg) {
|
||||
arg.walk(tw);
|
||||
}
|
||||
if (!arg) continue;
|
||||
var candidate = make_node(AST_VarDef, sym, {
|
||||
name: sym,
|
||||
value: arg,
|
||||
});
|
||||
candidate.name_index = i;
|
||||
candidate.arg_index = value ? len + i : i;
|
||||
candidates.unshift([ candidate ]);
|
||||
args[len + i] = fn.argnames[i];
|
||||
continue;
|
||||
}
|
||||
if (names.has(sym.name)) continue;
|
||||
names.set(sym.name, true);
|
||||
if (value) arg = is_undefined(arg) ? value : null;
|
||||
if (!arg && !value) {
|
||||
arg = make_node(AST_Undefined, sym).transform(compressor);
|
||||
} else if (arg instanceof AST_Lambda && arg.pinned()) {
|
||||
arg = null;
|
||||
} else if (arg) {
|
||||
arg.walk(tw);
|
||||
}
|
||||
if (!arg) continue;
|
||||
var candidate = make_node(AST_VarDef, sym, {
|
||||
name: sym,
|
||||
value: arg,
|
||||
});
|
||||
candidate.name_index = i;
|
||||
candidate.arg_index = value ? len + i : i;
|
||||
candidates.unshift([ candidate ]);
|
||||
}
|
||||
if (fn.rest) args.push(fn.rest);
|
||||
}
|
||||
|
||||
function extract_candidates(expr, unused) {
|
||||
|
@ -3104,7 +3139,7 @@ Compressor.prototype.compress = function(node) {
|
|||
return !circular && rhs_exact_match;
|
||||
|
||||
function rhs_exact_match(node) {
|
||||
return expr.equivalent_to(node);
|
||||
return expr.equals(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3402,7 +3437,7 @@ Compressor.prototype.compress = function(node) {
|
|||
var changed = false;
|
||||
var parent = compressor.parent();
|
||||
var self = compressor.self();
|
||||
var exit, exit_defs, merge_exit;
|
||||
var exit, merge_exit;
|
||||
var in_iife = in_lambda && parent && parent.TYPE == "Call" && parent.expression === self;
|
||||
var chain_if_returns = in_lambda && compressor.option("conditionals") && compressor.option("sequences");
|
||||
var multiple_if_returns = has_multiple_if_returns(statements);
|
||||
|
@ -3411,21 +3446,22 @@ Compressor.prototype.compress = function(node) {
|
|||
var j = next_index(i);
|
||||
var next = statements[j];
|
||||
|
||||
if (in_lambda && !next && stat instanceof AST_Return) {
|
||||
if (!stat.value) {
|
||||
if (in_lambda && !next && stat instanceof AST_Return
|
||||
&& !(in_try && in_try.bfinally && in_async_generator(in_lambda))) {
|
||||
var body = stat.value;
|
||||
if (!body) {
|
||||
changed = true;
|
||||
statements.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
var tail = stat.value.tail_node();
|
||||
if (tail instanceof AST_UnaryPrefix && tail.operator == "void") {
|
||||
var tail = body.tail_node();
|
||||
if (is_undefined(tail)) {
|
||||
changed = true;
|
||||
var body;
|
||||
if (tail === stat.value) {
|
||||
body = tail.expression;
|
||||
} else {
|
||||
body = stat.value.clone();
|
||||
body.expressions[body.length - 1] = tail.expression;
|
||||
if (body instanceof AST_UnaryPrefix) {
|
||||
body = body.expression;
|
||||
} else if (tail instanceof AST_UnaryPrefix) {
|
||||
body = body.clone();
|
||||
body.expressions[body.expressions.length - 1] = tail.expression;
|
||||
}
|
||||
statements[i] = make_node(AST_SimpleStatement, stat, { body: body });
|
||||
continue;
|
||||
|
@ -3549,8 +3585,10 @@ Compressor.prototype.compress = function(node) {
|
|||
|
||||
if (stat instanceof AST_Exit) {
|
||||
exit = stat;
|
||||
exit_defs = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (exit && exit === next) eliminate_returns(stat);
|
||||
}
|
||||
return changed;
|
||||
|
||||
|
@ -3571,25 +3609,29 @@ Compressor.prototype.compress = function(node) {
|
|||
});
|
||||
}
|
||||
|
||||
function match_return(ab, exact) {
|
||||
if (!exit) return false;
|
||||
if (exit.TYPE != ab.TYPE) return false;
|
||||
var value = ab.value;
|
||||
if (!value) return false;
|
||||
var equals = exit.equals(ab);
|
||||
if (!equals && value instanceof AST_Sequence) {
|
||||
value = value.tail_node();
|
||||
if (exit.value && exit.value.equals(value)) equals = 2;
|
||||
}
|
||||
if (!equals && !exact && exit.value instanceof AST_Sequence) {
|
||||
if (exit.value.tail_node().equals(value)) equals = 3;
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
function can_drop_abort(ab) {
|
||||
if (ab instanceof AST_Exit) {
|
||||
if (exit && exit.equivalent_to(ab)) {
|
||||
if (!exit_defs) {
|
||||
exit_defs = new Dictionary();
|
||||
exit.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolRef) exit_defs.set(node.name, node.definition());
|
||||
}));
|
||||
}
|
||||
var abort = false;
|
||||
ab.walk(new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (node instanceof AST_SymbolRef && exit_defs.get(node.name) !== node.definition()) {
|
||||
return abort = true;
|
||||
}
|
||||
}));
|
||||
if (!abort) return merge_exit = true;
|
||||
}
|
||||
return in_lambda && ab instanceof AST_Return && is_undefined(ab.value);
|
||||
if (merge_exit = match_return(ab)) return true;
|
||||
if (!in_lambda) return false;
|
||||
if (!(ab instanceof AST_Return)) return false;
|
||||
if (is_undefined(ab.value)) return true;
|
||||
return ab.value instanceof AST_Sequence && is_undefined(ab.value.tail_node());
|
||||
}
|
||||
if (!(ab instanceof AST_LoopControl)) return false;
|
||||
var lct = compressor.loopcontrol_target(ab);
|
||||
|
@ -3636,10 +3678,25 @@ Compressor.prototype.compress = function(node) {
|
|||
if (is_lexical_definition(stat)) lexical = true;
|
||||
return true;
|
||||
});
|
||||
if (merge_exit === 3) {
|
||||
tail.push(make_node(AST_SimpleStatement, exit.value, {
|
||||
body: make_sequence(exit.value, exit.value.expressions.slice(0, -1)),
|
||||
}));
|
||||
exit.value = exit.value.tail_node();
|
||||
}
|
||||
[].push.apply(lexical ? tail : statements, defuns);
|
||||
return tail;
|
||||
}
|
||||
|
||||
function trim_return(value, mode) {
|
||||
if (value) switch (mode) {
|
||||
case 3:
|
||||
if (!(value instanceof AST_Sequence)) break;
|
||||
case 2:
|
||||
return make_sequence(value, value.expressions.slice(0, -1));
|
||||
}
|
||||
}
|
||||
|
||||
function as_statement_array_with_return(node, ab) {
|
||||
var body = as_statement_array(node);
|
||||
var block = body, last;
|
||||
|
@ -3647,7 +3704,9 @@ Compressor.prototype.compress = function(node) {
|
|||
block = last.body;
|
||||
}
|
||||
block.pop();
|
||||
if (!merge_exit && ab.value) block.push(make_node(AST_SimpleStatement, ab.value, { body: ab.value }));
|
||||
var value = ab.value;
|
||||
if (merge_exit) value = trim_return(value, merge_exit);
|
||||
if (value) block.push(make_node(AST_SimpleStatement, value, { body: value }));
|
||||
return body;
|
||||
}
|
||||
|
||||
|
@ -3683,6 +3742,32 @@ Compressor.prototype.compress = function(node) {
|
|||
if (var_defs.length > 0) args.push(make_node(AST_Var, stat, { definitions: var_defs }));
|
||||
return args;
|
||||
}
|
||||
|
||||
function eliminate_returns(stat, in_block) {
|
||||
if (stat instanceof AST_Exit) {
|
||||
var mode = match_return(stat, true);
|
||||
if (mode) {
|
||||
var value = trim_return(stat.value, mode);
|
||||
if (value) return make_node(AST_SimpleStatement, value, { body: value });
|
||||
return in_block ? null : make_node(AST_EmptyStatement, stat);
|
||||
}
|
||||
} else if (stat instanceof AST_If) {
|
||||
stat.body = eliminate_returns(stat.body);
|
||||
if (stat.alternative) stat.alternative = eliminate_returns(stat.alternative);
|
||||
} else if (stat instanceof AST_LabeledStatement) {
|
||||
stat.body = eliminate_returns(stat.body);
|
||||
} else if (stat instanceof AST_Try) {
|
||||
if (!stat.bfinally || !exit.value || exit.value.is_constant()) {
|
||||
if (stat.bcatch) eliminate_returns(stat.bcatch);
|
||||
var trimmed = eliminate_returns(stat.body.pop(), true);
|
||||
if (trimmed) stat.body.push(trimmed);
|
||||
}
|
||||
} else if (stat instanceof AST_Block && !(stat instanceof AST_Scope || stat instanceof AST_Switch)) {
|
||||
var trimmed = eliminate_returns(stat.body.pop(), true);
|
||||
if (trimmed) stat.body.push(trimmed);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
}
|
||||
|
||||
function eliminate_dead_code(statements, compressor) {
|
||||
|
@ -4571,7 +4656,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (keep_unary
|
||||
&& fixed instanceof AST_UnaryPrefix
|
||||
&& fixed.operator == "+"
|
||||
&& fixed.expression.equivalent_to(this)) {
|
||||
&& fixed.expression.equals(this)) {
|
||||
return false;
|
||||
}
|
||||
this.is_number = return_false;
|
||||
|
@ -4722,9 +4807,9 @@ Compressor.prototype.compress = function(node) {
|
|||
|
||||
function best_of_statement(ast1, ast2, threshold) {
|
||||
return best_of_expression(make_node(AST_SimpleStatement, ast1, {
|
||||
body: ast1
|
||||
body: ast1,
|
||||
}), make_node(AST_SimpleStatement, ast2, {
|
||||
body: ast2
|
||||
body: ast2,
|
||||
}), threshold).body;
|
||||
}
|
||||
|
||||
|
@ -4947,6 +5032,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (def.undeclared) return this;
|
||||
if (def.last_ref !== lhs) return this;
|
||||
if (def.single_use == "m") return this;
|
||||
if (this.right.has_side_effects(compressor)) return this;
|
||||
}
|
||||
}
|
||||
var op = this.operator;
|
||||
|
@ -5413,17 +5499,14 @@ Compressor.prototype.compress = function(node) {
|
|||
function basic_negation(exp) {
|
||||
return make_node(AST_UnaryPrefix, exp, {
|
||||
operator: "!",
|
||||
expression: exp
|
||||
expression: exp,
|
||||
});
|
||||
}
|
||||
function best(orig, alt, first_in_statement) {
|
||||
var negated = basic_negation(orig);
|
||||
if (first_in_statement) {
|
||||
var stat = make_node(AST_SimpleStatement, alt, {
|
||||
body: alt
|
||||
});
|
||||
return best_of_expression(negated, stat) === stat ? alt : negated;
|
||||
}
|
||||
if (first_in_statement) return best_of_expression(negated, make_node(AST_SimpleStatement, alt, {
|
||||
body: alt,
|
||||
})) === negated ? negated : alt;
|
||||
return best_of_expression(negated, alt);
|
||||
}
|
||||
def(AST_Node, function() {
|
||||
|
@ -5904,7 +5987,7 @@ Compressor.prototype.compress = function(node) {
|
|||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
if (self.inlined || node.redef) {
|
||||
if (self.inlined || node.redef || node.in_arg) {
|
||||
result = false;
|
||||
return true;
|
||||
}
|
||||
|
@ -7598,6 +7681,7 @@ Compressor.prototype.compress = function(node) {
|
|||
var def = node.left.definition();
|
||||
if (def.scope.resolve() === self) assignments.add(def.id, node);
|
||||
}
|
||||
if (node instanceof AST_SymbolRef && node.in_arg) var_defs[node.definition().id] = 0;
|
||||
if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) {
|
||||
var def = node.expression.definition();
|
||||
if (def.scope.resolve() === self) assignments.add(def.id, node);
|
||||
|
@ -8091,7 +8175,9 @@ Compressor.prototype.compress = function(node) {
|
|||
// collect only vars which don't show up in self's arguments list
|
||||
var defns = [];
|
||||
if (self instanceof AST_Lambda) self.each_argname(function(argname) {
|
||||
vars.del(argname.name);
|
||||
if (all(argname.definition().references, function(ref) {
|
||||
return !ref.in_arg;
|
||||
})) vars.del(argname.name);
|
||||
});
|
||||
vars.each(function(defn, name) {
|
||||
defn = defn.clone();
|
||||
|
@ -9392,10 +9478,10 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
|
||||
function match(cond) {
|
||||
if (node.equivalent_to(cond)) return true;
|
||||
if (node.equals(cond)) return true;
|
||||
if (!(cond instanceof AST_UnaryPrefix)) return false;
|
||||
if (cond.operator != "!") return false;
|
||||
if (!node.equivalent_to(cond.expression)) return false;
|
||||
if (!node.equals(cond.expression)) return false;
|
||||
negated = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -9569,9 +9655,43 @@ Compressor.prototype.compress = function(node) {
|
|||
self.alternative = null;
|
||||
return make_node(AST_BlockStatement, self, { body: [ self, body ] }).optimize(compressor);
|
||||
}
|
||||
if (self.alternative) {
|
||||
var body_stats = as_array(self.body);
|
||||
var body_index = last_index(body_stats);
|
||||
var alt_stats = as_array(self.alternative);
|
||||
var alt_index = last_index(alt_stats);
|
||||
for (var stats = []; body_index >= 0 && alt_index >= 0;) {
|
||||
var stat = body_stats[body_index];
|
||||
if (!stat.equals(alt_stats[alt_index])) break;
|
||||
body_stats.splice(body_index--, 1);
|
||||
alt_stats.splice(alt_index--, 1);
|
||||
stats.unshift(stat);
|
||||
}
|
||||
if (stats.length > 0) {
|
||||
self.body = body_stats.length > 0 ? make_node(AST_BlockStatement, self, {
|
||||
body: body_stats,
|
||||
}) : make_node(AST_EmptyStatement, self);
|
||||
self.alternative = alt_stats.length > 0 ? make_node(AST_BlockStatement, self, {
|
||||
body: alt_stats,
|
||||
}) : null;
|
||||
stats.unshift(self);
|
||||
return make_node(AST_BlockStatement, self, { body: stats }).optimize(compressor);
|
||||
}
|
||||
}
|
||||
if (compressor.option("typeofs")) mark_locally_defined(self.condition, self.body, self.alternative);
|
||||
return self;
|
||||
|
||||
function as_array(node) {
|
||||
return node instanceof AST_BlockStatement ? node.body : [ node ];
|
||||
}
|
||||
|
||||
function last_index(stats) {
|
||||
for (var index = stats.length; --index >= 0;) {
|
||||
if (!is_declaration(stats[index], true)) break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
function sequencesize(stat, defuns, var_defs, refs) {
|
||||
if (stat == null) return [];
|
||||
if (stat instanceof AST_BlockStatement) {
|
||||
|
@ -9689,7 +9809,7 @@ Compressor.prototype.compress = function(node) {
|
|||
case 0:
|
||||
var prev_block = make_node(AST_BlockStatement, prev, prev);
|
||||
var next_block = make_node(AST_BlockStatement, branch, { body: statements });
|
||||
if (prev_block.equivalent_to(next_block)) prev.body = [];
|
||||
if (prev_block.equals(next_block)) prev.body = [];
|
||||
}
|
||||
}
|
||||
if (side_effects.length) {
|
||||
|
@ -10867,7 +10987,10 @@ Compressor.prototype.compress = function(node) {
|
|||
append_var(decls, expressions, symbol);
|
||||
if (value) expressions.push(value);
|
||||
} else {
|
||||
if (!value && in_loop && argname === name) value = make_node(AST_Undefined, self);
|
||||
if (!value && argname === name && (in_loop
|
||||
|| name.name == "arguments" && !is_arrow(fn) && is_arrow(scope))) {
|
||||
value = make_node(AST_Undefined, self);
|
||||
}
|
||||
append_var(decls, expressions, symbol, value);
|
||||
}
|
||||
}
|
||||
|
@ -11148,7 +11271,8 @@ Compressor.prototype.compress = function(node) {
|
|||
// !!foo ---> foo, if we're in boolean context
|
||||
if (exp instanceof AST_UnaryPrefix && exp.operator == "!") return exp.expression;
|
||||
if (exp instanceof AST_Binary) {
|
||||
self = best_of(compressor, self, exp.negate(compressor, first_in_statement(compressor)));
|
||||
var first = first_in_statement(compressor);
|
||||
self = (first ? best_of_statement : best_of_expression)(self, exp.negate(compressor, first));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -11390,7 +11514,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (self.left instanceof AST_SymbolRef
|
||||
&& assign instanceof AST_Assign
|
||||
&& assign.operator == "="
|
||||
&& self.left.equivalent_to(assign.left)) {
|
||||
&& self.left.equals(assign.left)) {
|
||||
return make_node(AST_Assign, self, {
|
||||
operator: "=",
|
||||
left: assign.left,
|
||||
|
@ -11416,7 +11540,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
|
||||
(self.left.is_number(compressor) && self.right.is_number(compressor)) ||
|
||||
(self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) ||
|
||||
repeatable(compressor, self.left) && self.left.equivalent_to(self.right)) {
|
||||
repeatable(compressor, self.left) && self.left.equals(self.right)) {
|
||||
self.operator = self.operator.slice(0, 2);
|
||||
}
|
||||
// XXX: intentionally falling down to the next case
|
||||
|
@ -11463,7 +11587,7 @@ Compressor.prototype.compress = function(node) {
|
|||
&& (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null
|
||||
|| lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor))
|
||||
&& !expr.has_side_effects(compressor)
|
||||
&& expr.equivalent_to(self.right.right)) {
|
||||
&& expr.equals(self.right.right)) {
|
||||
lhs.operator = lhs.operator.slice(0, -1);
|
||||
lhs.left = make_node(AST_Null, self);
|
||||
return self.left;
|
||||
|
@ -11475,7 +11599,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (compressor.option("booleans")) {
|
||||
var lhs = self.left;
|
||||
if (lazy_op[self.operator] && !lhs.has_side_effects(compressor)) {
|
||||
if (lhs.equivalent_to(self.right)) {
|
||||
if (lhs.equals(self.right)) {
|
||||
return maintain_this_binding(compressor, parent, compressor.self(), lhs).optimize(compressor);
|
||||
}
|
||||
mark_duplicate_condition(compressor, lhs);
|
||||
|
@ -11512,12 +11636,12 @@ Compressor.prototype.compress = function(node) {
|
|||
break;
|
||||
}
|
||||
if (compressor.option("comparisons") && self.is_boolean(compressor)) {
|
||||
if (!(parent instanceof AST_Binary) || parent instanceof AST_Assign) {
|
||||
var negated = best_of(compressor, self, make_node(AST_UnaryPrefix, self, {
|
||||
if (parent.TYPE != "Binary") {
|
||||
var negated = make_node(AST_UnaryPrefix, self, {
|
||||
operator: "!",
|
||||
expression: self.negate(compressor, first_in_statement(compressor))
|
||||
}));
|
||||
if (negated !== self) return negated;
|
||||
expression: self.negate(compressor),
|
||||
});
|
||||
if (best_of(compressor, self, negated) === negated) return negated;
|
||||
}
|
||||
switch (self.operator) {
|
||||
case ">": reverse("<"); break;
|
||||
|
@ -11761,17 +11885,11 @@ Compressor.prototype.compress = function(node) {
|
|||
&& !(self.left instanceof AST_Binary
|
||||
&& self.left.operator != self.operator
|
||||
&& PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
|
||||
var reversed = make_node(AST_Binary, self, {
|
||||
self = best_of(compressor, self, make_node(AST_Binary, self, {
|
||||
operator: self.operator,
|
||||
left: self.right,
|
||||
right: self.left
|
||||
});
|
||||
if (self.right instanceof AST_Constant
|
||||
&& !(self.left instanceof AST_Constant)) {
|
||||
self = best_of(compressor, reversed, self);
|
||||
} else {
|
||||
self = best_of(compressor, self, reversed);
|
||||
}
|
||||
right: self.left,
|
||||
}), self.right instanceof AST_Constant && !(self.left instanceof AST_Constant));
|
||||
}
|
||||
if (!associative || !self.is_number(compressor)) break;
|
||||
// a + (b + c) ---> (a + b) + c
|
||||
|
@ -12296,7 +12414,6 @@ Compressor.prototype.compress = function(node) {
|
|||
left: make_node(AST_Template, self, {
|
||||
expressions: exprs.slice(0, -1),
|
||||
strings: strs.slice(0, -1),
|
||||
tag: tag,
|
||||
}).transform(compressor),
|
||||
right: exprs[exprs.length - 1],
|
||||
}).optimize(compressor);
|
||||
|
@ -12319,7 +12436,6 @@ Compressor.prototype.compress = function(node) {
|
|||
right: make_node(AST_Template, self, {
|
||||
expressions: exprs.slice(i),
|
||||
strings: strs.slice(i),
|
||||
tag: tag,
|
||||
}).transform(compressor),
|
||||
}).optimize(compressor));
|
||||
}
|
||||
|
@ -12427,7 +12543,7 @@ Compressor.prototype.compress = function(node) {
|
|||
exprs.push(self.right);
|
||||
return make_sequence(self, exprs).optimize(compressor);
|
||||
}
|
||||
if (self.left.equivalent_to(self.right) && !self.left.has_side_effects(compressor)) {
|
||||
if (self.left.equals(self.right) && !self.left.has_side_effects(compressor)) {
|
||||
return self.right;
|
||||
}
|
||||
var exp = self.left.expression;
|
||||
|
@ -12443,7 +12559,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
} else if (self.left instanceof AST_SymbolRef && can_drop_symbol(self.left, compressor)) {
|
||||
var parent;
|
||||
if (self.operator == "=" && self.left.equivalent_to(self.right)
|
||||
if (self.operator == "=" && self.left.equals(self.right)
|
||||
&& !((parent = compressor.parent()) instanceof AST_UnaryPrefix && parent.operator == "delete")) {
|
||||
return self.right;
|
||||
}
|
||||
|
@ -12575,15 +12691,7 @@ Compressor.prototype.compress = function(node) {
|
|||
self.right = make_node(AST_Null, right);
|
||||
var may_throw = node.may_throw(compressor);
|
||||
self.right = right;
|
||||
for (var parent; parent = compressor.parent(level++); node = parent) {
|
||||
if (parent === scope) return false;
|
||||
if (sync && parent instanceof AST_Lambda) {
|
||||
if (parent.name || is_async(parent) || is_generator(parent)) return true;
|
||||
} else if (parent instanceof AST_Try) {
|
||||
if (parent.bfinally && parent.bfinally !== node) return true;
|
||||
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
|
||||
}
|
||||
}
|
||||
return find_try(compressor, level, node, scope, may_throw, sync);
|
||||
}
|
||||
|
||||
function strip_assignment(def) {
|
||||
|
@ -12616,12 +12724,13 @@ Compressor.prototype.compress = function(node) {
|
|||
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor);
|
||||
}
|
||||
var negated = condition.negate(compressor, first_in_statement(compressor));
|
||||
if (best_of(compressor, condition, negated) === negated) {
|
||||
var first = first_in_statement(compressor);
|
||||
var negated = condition.negate(compressor, first);
|
||||
if ((first ? best_of_statement : best_of_expression)(condition, negated) === negated) {
|
||||
self = make_node(AST_Conditional, self, {
|
||||
condition: negated,
|
||||
consequent: self.alternative,
|
||||
alternative: self.consequent
|
||||
alternative: self.consequent,
|
||||
});
|
||||
negated = condition;
|
||||
condition = self.condition;
|
||||
|
@ -12630,13 +12739,13 @@ Compressor.prototype.compress = function(node) {
|
|||
var alternative = self.alternative;
|
||||
if (repeatable(compressor, condition)) {
|
||||
// x ? x : y ---> x || y
|
||||
if (condition.equivalent_to(consequent)) return make_node(AST_Binary, self, {
|
||||
if (condition.equals(consequent)) return make_node(AST_Binary, self, {
|
||||
operator: "||",
|
||||
left: condition,
|
||||
right: alternative,
|
||||
}).optimize(compressor);
|
||||
// x ? y : x ---> x && y
|
||||
if (condition.equivalent_to(alternative)) return make_node(AST_Binary, self, {
|
||||
if (condition.equals(alternative)) return make_node(AST_Binary, self, {
|
||||
operator: "&&",
|
||||
left: condition,
|
||||
right: consequent,
|
||||
|
@ -12653,7 +12762,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if ((is_eq || consequent === seq_tail)
|
||||
&& alt_tail instanceof AST_Assign
|
||||
&& seq_tail.operator == alt_tail.operator
|
||||
&& seq_tail.left.equivalent_to(alt_tail.left)
|
||||
&& seq_tail.left.equals(alt_tail.left)
|
||||
&& (is_eq && seq_tail.left instanceof AST_SymbolRef
|
||||
|| !condition.has_side_effects(compressor)
|
||||
&& can_shift_lhs_of_tail(consequent)
|
||||
|
@ -12670,7 +12779,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
}
|
||||
// x ? y : y ---> x, y
|
||||
if (consequent.equivalent_to(alternative)) return make_sequence(self, [
|
||||
if (consequent.equals(alternative)) return make_sequence(self, [
|
||||
condition,
|
||||
consequent
|
||||
]).optimize(compressor);
|
||||
|
@ -12684,7 +12793,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (consequent instanceof AST_Call
|
||||
&& alternative.TYPE == consequent.TYPE
|
||||
&& (arg_index = arg_diff(consequent, alternative)) >= 0
|
||||
&& consequent.expression.equivalent_to(alternative.expression)
|
||||
&& consequent.expression.equals(alternative.expression)
|
||||
&& !condition.has_side_effects(compressor)
|
||||
&& !consequent.expression.has_side_effects(compressor)) {
|
||||
var node = consequent.clone();
|
||||
|
@ -12704,7 +12813,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// x ? (y ? a : b) : b ---> x && y ? a : b
|
||||
if (consequent instanceof AST_Conditional
|
||||
&& consequent.alternative.equivalent_to(alternative)) {
|
||||
&& consequent.alternative.equals(alternative)) {
|
||||
return make_node(AST_Conditional, self, {
|
||||
condition: make_node(AST_Binary, self, {
|
||||
left: condition,
|
||||
|
@ -12717,7 +12826,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// x ? (y ? a : b) : a ---> !x || y ? a : b
|
||||
if (consequent instanceof AST_Conditional
|
||||
&& consequent.consequent.equivalent_to(alternative)) {
|
||||
&& consequent.consequent.equals(alternative)) {
|
||||
return make_node(AST_Conditional, self, {
|
||||
condition: make_node(AST_Binary, self, {
|
||||
left: negated,
|
||||
|
@ -12730,7 +12839,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// x ? a : (y ? a : b) ---> x || y ? a : b
|
||||
if (alternative instanceof AST_Conditional
|
||||
&& consequent.equivalent_to(alternative.consequent)) {
|
||||
&& consequent.equals(alternative.consequent)) {
|
||||
return make_node(AST_Conditional, self, {
|
||||
condition: make_node(AST_Binary, self, {
|
||||
left: condition,
|
||||
|
@ -12743,7 +12852,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// x ? b : (y ? a : b) ---> !x && y ? a : b
|
||||
if (alternative instanceof AST_Conditional
|
||||
&& consequent.equivalent_to(alternative.alternative)) {
|
||||
&& consequent.equals(alternative.alternative)) {
|
||||
return make_node(AST_Conditional, self, {
|
||||
condition: make_node(AST_Binary, self, {
|
||||
left: negated,
|
||||
|
@ -12756,7 +12865,7 @@ Compressor.prototype.compress = function(node) {
|
|||
}
|
||||
// x ? (a, c) : (b, c) ---> x ? a : b, c
|
||||
if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence)
|
||||
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
||||
&& consequent.tail_node().equals(alternative.tail_node())) {
|
||||
return make_sequence(self, [
|
||||
make_node(AST_Conditional, self, {
|
||||
condition: condition,
|
||||
|
@ -12769,7 +12878,7 @@ Compressor.prototype.compress = function(node) {
|
|||
// x ? y && a : a ---> (!x || y) && a
|
||||
if (consequent instanceof AST_Binary
|
||||
&& consequent.operator == "&&"
|
||||
&& consequent.right.equivalent_to(alternative)) {
|
||||
&& consequent.right.equals(alternative)) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator: "&&",
|
||||
left: make_node(AST_Binary, self, {
|
||||
|
@ -12783,7 +12892,7 @@ Compressor.prototype.compress = function(node) {
|
|||
// x ? y || a : a ---> x && y || a
|
||||
if (consequent instanceof AST_Binary
|
||||
&& consequent.operator == "||"
|
||||
&& consequent.right.equivalent_to(alternative)) {
|
||||
&& consequent.right.equals(alternative)) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator: "||",
|
||||
left: make_node(AST_Binary, self, {
|
||||
|
@ -12797,7 +12906,7 @@ Compressor.prototype.compress = function(node) {
|
|||
// x ? a : y && a ---> (x || y) && a
|
||||
if (alternative instanceof AST_Binary
|
||||
&& alternative.operator == "&&"
|
||||
&& alternative.right.equivalent_to(consequent)) {
|
||||
&& alternative.right.equals(consequent)) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator: "&&",
|
||||
left: make_node(AST_Binary, self, {
|
||||
|
@ -12811,7 +12920,7 @@ Compressor.prototype.compress = function(node) {
|
|||
// x ? a : y || a ---> !x && y || a
|
||||
if (alternative instanceof AST_Binary
|
||||
&& alternative.operator == "||"
|
||||
&& alternative.right.equivalent_to(consequent)) {
|
||||
&& alternative.right.equals(consequent)) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator: "||",
|
||||
left: make_node(AST_Binary, self, {
|
||||
|
@ -12907,10 +13016,10 @@ Compressor.prototype.compress = function(node) {
|
|||
var len = a.length;
|
||||
if (len != b.length) return -2;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (!a[i].equivalent_to(b[i])) {
|
||||
if (!a[i].equals(b[i])) {
|
||||
if (a[i] instanceof AST_Spread !== b[i] instanceof AST_Spread) return -3;
|
||||
for (var j = i + 1; j < len; j++) {
|
||||
if (!a[j].equivalent_to(b[j])) return -2;
|
||||
if (!a[j].equals(b[j])) return -2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -12931,7 +13040,7 @@ Compressor.prototype.compress = function(node) {
|
|||
if (!(consequent instanceof AST_PropAccess)) return;
|
||||
var p = consequent.property;
|
||||
var q = alternative.property;
|
||||
return (p instanceof AST_Node ? p.equivalent_to(q) : p == q)
|
||||
return (p instanceof AST_Node ? p.equals(q) : p == q)
|
||||
&& !(consequent.expression instanceof AST_Super || alternative.expression instanceof AST_Super);
|
||||
}
|
||||
|
||||
|
|
154
node_modules/uglify-js/lib/mozilla-ast.js
generated
vendored
154
node_modules/uglify-js/lib/mozilla-ast.js
generated
vendored
|
@ -192,6 +192,19 @@
|
|||
value: from_moz(M.value),
|
||||
});
|
||||
},
|
||||
StaticBlock: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ClassInit({
|
||||
start: start,
|
||||
end: end,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
end: end,
|
||||
body: normalize_directives(M.body.map(from_moz)),
|
||||
}),
|
||||
});
|
||||
},
|
||||
ForOfStatement: function(M) {
|
||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||
start: my_start_token(M),
|
||||
|
@ -303,13 +316,22 @@
|
|||
});
|
||||
},
|
||||
ExportAllDeclaration: function(M) {
|
||||
var alias = M.exported ? read_name(M.exported) : "*";
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: M.source.value,
|
||||
start: start,
|
||||
end: end,
|
||||
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
keys: [ new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ExportDefaultDeclaration: function(M) {
|
||||
|
@ -346,15 +368,15 @@
|
|||
if (M.source) {
|
||||
var aliases = [], keys = [];
|
||||
M.specifiers.forEach(function(prop) {
|
||||
aliases.push(read_name(prop.exported));
|
||||
keys.push(read_name(prop.local));
|
||||
aliases.push(from_moz_alias(prop.exported));
|
||||
keys.push(from_moz_alias(prop.local));
|
||||
});
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: aliases,
|
||||
keys: keys,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
}
|
||||
return new AST_ExportReferences({
|
||||
|
@ -362,38 +384,48 @@
|
|||
end: my_end_token(M),
|
||||
properties: M.specifiers.map(function(prop) {
|
||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||
sym.alias = read_name(prop.exported);
|
||||
sym.alias = from_moz_alias(prop.exported);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
},
|
||||
ImportDeclaration: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
var all = null, def = null, props = null;
|
||||
M.specifiers.forEach(function(prop) {
|
||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||
switch (prop.type) {
|
||||
case "ImportDefaultSpecifier":
|
||||
def = sym;
|
||||
def.key = "";
|
||||
def.key = new AST_String({
|
||||
start: start,
|
||||
value: "",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
case "ImportNamespaceSpecifier":
|
||||
all = sym;
|
||||
all.key = "*";
|
||||
all.key = new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
sym.key = prop.imported.name || syn.name;
|
||||
sym.key = from_moz_alias(prop.imported);
|
||||
if (!props) props = [];
|
||||
props.push(sym);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return new AST_Import({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
start: start,
|
||||
end: end,
|
||||
all: all,
|
||||
default: def,
|
||||
properties: props,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ImportExpression: function(M) {
|
||||
|
@ -714,6 +746,10 @@
|
|||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) {
|
||||
return to_moz_scope("StaticBlock", M.value);
|
||||
});
|
||||
|
||||
function To_Moz_ForOfStatement(is_await) {
|
||||
return function(M) {
|
||||
return {
|
||||
|
@ -780,38 +816,26 @@
|
|||
});
|
||||
|
||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||
if (M.keys[0] == "*") return {
|
||||
if (M.keys[0].value == "*") return {
|
||||
type: "ExportAllDeclaration",
|
||||
exported: M.aliases[0] == "*" ? null : {
|
||||
type: "Identifier",
|
||||
name: M.aliases[0],
|
||||
},
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
var specifiers = [];
|
||||
for (var i = 0; i < M.aliases.length; i++) {
|
||||
specifiers.push({
|
||||
specifiers.push(set_moz_loc({
|
||||
start: M.keys[i].start,
|
||||
end: M.aliases[i].end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: M.aliases[i],
|
||||
},
|
||||
local: {
|
||||
type: "Identifier",
|
||||
name: M.keys[i],
|
||||
},
|
||||
});
|
||||
local: to_moz_alias(M.keys[i]),
|
||||
exported: to_moz_alias(M.aliases[i]),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -819,44 +843,41 @@
|
|||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.start,
|
||||
end: prop.alias.end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
local: to_moz(prop),
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: prop.alias,
|
||||
},
|
||||
};
|
||||
exported: to_moz_alias(prop.alias),
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.key.start,
|
||||
end: prop.end,
|
||||
}, {
|
||||
type: "ImportSpecifier",
|
||||
local: to_moz(prop),
|
||||
imported: {
|
||||
type: "Identifier",
|
||||
name: prop.key,
|
||||
},
|
||||
};
|
||||
imported: to_moz_alias(prop.key),
|
||||
});
|
||||
}) : [];
|
||||
if (M.all) specifiers.unshift({
|
||||
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||
type: "ImportNamespaceSpecifier",
|
||||
local: to_moz(M.all),
|
||||
});
|
||||
if (M.default) specifiers.unshift({
|
||||
}));
|
||||
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||
type: "ImportDefaultSpecifier",
|
||||
local: to_moz(M.default),
|
||||
});
|
||||
}));
|
||||
return {
|
||||
type: "ImportDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -1203,6 +1224,14 @@
|
|||
return node;
|
||||
}
|
||||
|
||||
function from_moz_alias(moz) {
|
||||
return new AST_String({
|
||||
start: my_start_token(moz),
|
||||
value: read_name(moz),
|
||||
end: my_end_token(moz),
|
||||
});
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
|
@ -1254,6 +1283,13 @@
|
|||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
|
||||
function to_moz_alias(alias) {
|
||||
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||
type: "Identifier",
|
||||
name: alias.value,
|
||||
}) : to_moz(alias);
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
|
|
28
node_modules/uglify-js/lib/output.js
generated
vendored
28
node_modules/uglify-js/lib/output.js
generated
vendored
|
@ -1061,6 +1061,14 @@ function OutputStream(options) {
|
|||
}
|
||||
output.semicolon();
|
||||
});
|
||||
function print_alias(alias, output) {
|
||||
var value = alias.value;
|
||||
if (value == "*" || is_identifier_string(value)) {
|
||||
output.print_name(value);
|
||||
} else {
|
||||
output.print_string(value, alias.quote);
|
||||
}
|
||||
}
|
||||
DEFPRINT(AST_ExportForeign, function(output) {
|
||||
var self = this;
|
||||
output.print("export");
|
||||
|
@ -1068,7 +1076,7 @@ function OutputStream(options) {
|
|||
var len = self.keys.length;
|
||||
if (len == 0) {
|
||||
print_braced_empty(self, output);
|
||||
} else if (self.keys[0] == "*") {
|
||||
} else if (self.keys[0].value == "*") {
|
||||
print_entry(0);
|
||||
} else output.with_block(function() {
|
||||
output.indent();
|
||||
|
@ -1084,18 +1092,18 @@ function OutputStream(options) {
|
|||
output.space();
|
||||
output.print("from");
|
||||
output.space();
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
|
||||
function print_entry(index) {
|
||||
var alias = self.aliases[index];
|
||||
var key = self.keys[index];
|
||||
output.print_name(key);
|
||||
if (alias != key) {
|
||||
print_alias(key, output);
|
||||
if (alias.value != key.value) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1124,7 +1132,7 @@ function OutputStream(options) {
|
|||
output.print("from");
|
||||
output.space();
|
||||
}
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
|
@ -1734,19 +1742,19 @@ function OutputStream(options) {
|
|||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
if (alias.value != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
if (key.value && key.value != name) {
|
||||
print_alias(key, output);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
|
|
111
node_modules/uglify-js/lib/parse.js
generated
vendored
111
node_modules/uglify-js/lib/parse.js
generated
vendored
|
@ -552,16 +552,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||
|
||||
function handle_dot() {
|
||||
next();
|
||||
var ch = peek();
|
||||
if (ch == ".") {
|
||||
var op = ".";
|
||||
do {
|
||||
op += ".";
|
||||
next();
|
||||
} while (peek() == ".");
|
||||
return token("operator", op);
|
||||
}
|
||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
}
|
||||
|
||||
function read_word() {
|
||||
|
@ -815,7 +807,7 @@ function parse($TEXT, options) {
|
|||
}
|
||||
}
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(toplevel) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
|
@ -854,15 +846,15 @@ function parse($TEXT, options) {
|
|||
if (S.in_async) return simple_statement();
|
||||
break;
|
||||
case "export":
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return export_();
|
||||
case "import":
|
||||
var token = peek();
|
||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
||||
next();
|
||||
return import_();
|
||||
}
|
||||
break;
|
||||
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return import_();
|
||||
case "let":
|
||||
if (is_vardefs()) {
|
||||
next();
|
||||
|
@ -1442,28 +1434,41 @@ function parse($TEXT, options) {
|
|||
}
|
||||
|
||||
function is_alias() {
|
||||
return is("name") || is_identifier_string(S.token.value);
|
||||
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||
}
|
||||
|
||||
function make_string(token) {
|
||||
return new AST_String({
|
||||
start: token,
|
||||
quote: token.quote,
|
||||
value: token.value,
|
||||
end: token,
|
||||
});
|
||||
}
|
||||
|
||||
function as_path() {
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return make_string(path);
|
||||
}
|
||||
|
||||
function export_() {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
var alias = key;
|
||||
next();
|
||||
var alias = "*";
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
alias = S.token.value;
|
||||
alias = S.token;
|
||||
next();
|
||||
}
|
||||
expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: [ make_string(alias) ],
|
||||
keys: [ make_string(key) ],
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
if (is("punc", "{")) {
|
||||
|
@ -1477,26 +1482,20 @@ function parse($TEXT, options) {
|
|||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
aliases.push(S.token.value);
|
||||
aliases.push(S.token);
|
||||
next();
|
||||
} else {
|
||||
aliases.push(key.value);
|
||||
aliases.push(key);
|
||||
}
|
||||
if (!is("punc", "}")) expect(",");
|
||||
}
|
||||
expect("}");
|
||||
if (is("name", "from")) {
|
||||
next();
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: aliases,
|
||||
keys: keys.map(function(token) {
|
||||
return token.value;
|
||||
}),
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: aliases.map(make_string),
|
||||
keys: keys.map(make_string),
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
semicolon();
|
||||
|
@ -1504,7 +1503,7 @@ function parse($TEXT, options) {
|
|||
properties: keys.map(function(token, index) {
|
||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||
var sym = _make_symbol(AST_SymbolExport, token);
|
||||
sym.alias = aliases[index];
|
||||
sym.alias = make_string(aliases[index]);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
|
@ -1594,26 +1593,42 @@ function parse($TEXT, options) {
|
|||
var all = null;
|
||||
var def = as_symbol(AST_SymbolImport, true);
|
||||
var props = null;
|
||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
||||
var cont;
|
||||
if (def) {
|
||||
def.key = new AST_String({
|
||||
start: def.start,
|
||||
value: "",
|
||||
end: def.end,
|
||||
});
|
||||
if (cont = is("punc", ",")) next();
|
||||
} else {
|
||||
cont = !is("string");
|
||||
}
|
||||
if (cont) {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
next();
|
||||
expect_token("name", "as");
|
||||
all = as_symbol(AST_SymbolImport);
|
||||
all.key = "*";
|
||||
all.key = make_string(key);
|
||||
} else {
|
||||
expect("{");
|
||||
props = [];
|
||||
while (is_alias()) {
|
||||
var alias;
|
||||
if (is_token(peek(), "name", "as")) {
|
||||
var key = S.token.value;
|
||||
var key = S.token;
|
||||
next();
|
||||
next();
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = key;
|
||||
alias.key = make_string(key);
|
||||
} else {
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = alias.name;
|
||||
alias.key = new AST_String({
|
||||
start: alias.start,
|
||||
value: alias.name,
|
||||
end: alias.end,
|
||||
});
|
||||
}
|
||||
props.push(alias);
|
||||
if (!is("punc", "}")) expect(",");
|
||||
|
@ -1622,15 +1637,11 @@ function parse($TEXT, options) {
|
|||
}
|
||||
}
|
||||
if (all || def || props) expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_Import({
|
||||
all: all,
|
||||
default: def,
|
||||
path: path.value,
|
||||
path: as_path(),
|
||||
properties: props,
|
||||
quote: path.quote,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1808,7 +1819,7 @@ function parse($TEXT, options) {
|
|||
ret = new AST_BigInt({ value: value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({ value : value, quote : tok.quote });
|
||||
ret = new AST_String({ value: value, quote: tok.quote });
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ value: value });
|
||||
|
@ -2563,7 +2574,7 @@ function parse($TEXT, options) {
|
|||
}
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev() || start;
|
||||
var toplevel = options.toplevel;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue