Update dependencies

This commit is contained in:
grandeljay 2022-08-05 09:44:52 +02:00
parent 176039b833
commit 510e88928d
1174 changed files with 3378 additions and 2107 deletions

267
node_modules/uglify-js/lib/ast.js generated vendored
View file

@ -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");
},

View file

@ -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);
}

View file

@ -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
View file

@ -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
View file

@ -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;