Use AST.Node instead of AST_Node

This commit is contained in:
Flamefire 2018-06-13 12:50:22 +02:00
parent 1ce651ee14
commit 13196026eb
14 changed files with 1611 additions and 1841 deletions

View File

@ -10,6 +10,7 @@ var info = require("../package.json");
var path = require("path");
var program = require("commander");
var UglifyJS = require("../tools/node");
var AST = UglifyJS.AST;
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
var files = {};
@ -182,11 +183,11 @@ if (program.self) {
}
function convert_ast(fn) {
return UglifyJS.ast.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
return AST.Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
}
function run() {
UglifyJS.ast.AST_Node.warn_function = function(msg) {
AST.Node.warn_function = function(msg) {
print_error("WARN: " + msg);
};
var content = program.sourceMap && program.sourceMap.content;
@ -260,11 +261,11 @@ function run() {
return value.size() ? value.map(symdef) : undefined;
}
if (skip_key(key)) return;
if (value instanceof UglifyJS.ast.AST_Token) return;
if (value instanceof AST.Token) return;
if (value instanceof UglifyJS.Dictionary) return;
if (value instanceof UglifyJS.ast.AST_Node) {
if (value instanceof AST.Node) {
var result = {
_class: "AST_" + value.TYPE
_class: "AST." + value.TYPE
};
value.CTOR.PROPS.forEach(function(prop) {
result[prop] = value[prop];
@ -359,27 +360,27 @@ function parse_js(flag) {
code: false
}
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
if (node instanceof UglifyJS.ast.AST_Assign) {
if (node instanceof AST.Assign) {
var name = node.left.print_to_string();
var value = node.right;
if (flag) {
options[name] = value;
} else if (value instanceof UglifyJS.ast.AST_Array) {
} else if (value instanceof AST.Array) {
options[name] = value.elements.map(to_string);
} else {
options[name] = to_string(value);
}
return true;
}
if (node instanceof UglifyJS.ast.AST_Symbol || node instanceof UglifyJS.ast.AST_PropAccess) {
if (node instanceof AST.Symbol || node instanceof AST.PropAccess) {
var name = node.print_to_string();
options[name] = true;
return true;
}
if (!(node instanceof UglifyJS.ast.AST_Sequence)) throw node;
if (!(node instanceof AST.Sequence)) throw node;
function to_string(value) {
return value instanceof UglifyJS.ast.AST_Constant ? value.getValue() : value.print_to_string({
return value instanceof AST.Constant ? value.getValue() : value.print_to_string({
quote_keys: true
});
}

View File

@ -1193,4 +1193,89 @@ merge(exports, {
TreeWalker : TreeWalker,
TreeTransformer : TreeTransformer,
first_in_statement : first_in_statement,
Token : AST_Token,
Node : AST_Node,
Statement : AST_Statement,
Debugger : AST_Debugger,
Directive : AST_Directive,
SimpleStatement : AST_SimpleStatement,
Block : AST_Block,
BlockStatement : AST_BlockStatement,
EmptyStatement : AST_EmptyStatement,
StatementWithBody : AST_StatementWithBody,
LabeledStatement : AST_LabeledStatement,
IterationStatement : AST_IterationStatement,
DWLoop : AST_DWLoop,
Do : AST_Do,
While : AST_While,
For : AST_For,
ForIn : AST_ForIn,
With : AST_With,
Scope : AST_Scope,
Toplevel : AST_Toplevel,
Lambda : AST_Lambda,
Accessor : AST_Accessor,
Function : AST_Function,
Defun : AST_Defun,
Jump : AST_Jump,
Exit : AST_Exit,
Return : AST_Return,
Throw : AST_Throw,
LoopControl : AST_LoopControl,
Break : AST_Break,
Continue : AST_Continue,
If : AST_If,
Switch : AST_Switch,
SwitchBranch : AST_SwitchBranch,
Default : AST_Default,
Case : AST_Case,
Try : AST_Try,
Catch : AST_Catch,
Finally : AST_Finally,
Definitions : AST_Definitions,
Var : AST_Var,
VarDef : AST_VarDef,
Call : AST_Call,
New : AST_New,
Sequence : AST_Sequence,
PropAccess : AST_PropAccess,
Dot : AST_Dot,
Sub : AST_Sub,
Unary : AST_Unary,
UnaryPrefix : AST_UnaryPrefix,
UnaryPostfix : AST_UnaryPostfix,
Binary : AST_Binary,
Conditional : AST_Conditional,
Assign : AST_Assign,
Array : AST_Array,
Object : AST_Object,
ObjectProperty : AST_ObjectProperty,
ObjectKeyVal : AST_ObjectKeyVal,
ObjectSetter : AST_ObjectSetter,
ObjectGetter : AST_ObjectGetter,
Symbol : AST_Symbol,
SymbolAccessor : AST_SymbolAccessor,
SymbolDeclaration : AST_SymbolDeclaration,
SymbolVar : AST_SymbolVar,
SymbolFunarg : AST_SymbolFunarg,
SymbolDefun : AST_SymbolDefun,
SymbolLambda : AST_SymbolLambda,
SymbolCatch : AST_SymbolCatch,
Label : AST_Label,
SymbolRef : AST_SymbolRef,
LabelRef : AST_LabelRef,
This : AST_This,
Constant : AST_Constant,
String : AST_String,
Number : AST_Number,
RegExp : AST_RegExp,
Atom : AST_Atom,
Null : AST_Null,
NaN : AST_NaN,
Undefined : AST_Undefined,
Hole : AST_Hole,
Infinity : AST_Infinity,
Boolean : AST_Boolean,
False : AST_False,
True : AST_True,
});

File diff suppressed because it is too large Load Diff

View File

@ -7,11 +7,8 @@ var HOP = utils.HOP;
var MAP = utils.MAP;
var merge = utils.merge;
var ast = require("./ast");
var AST_Node = ast.AST_Node;
var AST_Toplevel = ast.AST_Toplevel;
var AST_Directive = ast.AST_Directive;
var TreeTransformer = ast.TreeTransformer;
var AST = require("./ast");
var TreeTransformer = AST.TreeTransformer;
var parse = require("./parse");
var parse = parse.parse;
@ -35,7 +32,7 @@ var to_base64 = typeof btoa == "undefined" ? function(str) {
function read_source_map(name, code) {
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
if (!match) {
AST_Node.warn("inline source map not found: " + name);
AST.Node.warn("inline source map not found: " + name);
return null;
}
return to_ascii(match[2]);
@ -81,7 +78,7 @@ function minify(files, options) {
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
wrapped_tl = parse(wrapped_tl);
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node) {
if (node instanceof AST_Directive && node.value == "$ORIG") {
if (node instanceof AST.Directive && node.value == "$ORIG") {
return MAP.splice(body);
}
}));
@ -99,13 +96,13 @@ function minify(files, options) {
args_values.slice(index + 1),
")"
].join("")).transform(new TreeTransformer(function(node) {
if (node instanceof AST_Directive && node.value == "$ORIG") {
if (node instanceof AST.Directive && node.value == "$ORIG") {
return MAP.splice(body);
}
}));
}
var warn_function = AST_Node.warn_function;
var warn_function = AST.Node.warn_function;
try {
options = defaults(options, {
compress: {},
@ -170,14 +167,14 @@ function minify(files, options) {
}, true);
}
var warnings = [];
if (options.warnings && !AST_Node.warn_function) {
AST_Node.warn_function = function(warning) {
if (options.warnings && !AST.Node.warn_function) {
AST.Node.warn_function = function(warning) {
warnings.push(warning);
};
}
if (timings) timings.parse = Date.now();
var source_maps, toplevel;
if (files instanceof AST_Toplevel) {
if (files instanceof AST.Toplevel) {
toplevel = files;
} else {
if (typeof files == "string") {
@ -246,7 +243,7 @@ function minify(files, options) {
root: options.sourceMap.root
});
if (options.sourceMap.includeSources) {
if (files instanceof AST_Toplevel) {
if (files instanceof AST.Toplevel) {
throw new Error("original source content unavailable");
} else for (var name in files) if (HOP(files, name)) {
options.output.source_map.get().setSourceContent(name, files[name]);
@ -295,7 +292,7 @@ function minify(files, options) {
} catch (ex) {
return { error: ex };
} finally {
AST_Node.warn_function = warn_function;
AST.Node.warn_function = warn_function;
}
}

View File

@ -43,95 +43,20 @@
"use strict";
var ast = require("./ast");
var TreeWalker = ast.TreeWalker;
var AST_Token = ast.AST_Token;
var AST_Node = ast.AST_Node;
var AST_Statement = ast.AST_Statement;
var AST_Debugger = ast.AST_Debugger;
var AST_Directive = ast.AST_Directive;
var AST_SimpleStatement = ast.AST_SimpleStatement;
var AST_Block = ast.AST_Block;
var AST_BlockStatement = ast.AST_BlockStatement;
var AST_EmptyStatement = ast.AST_EmptyStatement;
var AST_LabeledStatement = ast.AST_LabeledStatement;
var AST_Do = ast.AST_Do;
var AST_While = ast.AST_While;
var AST_For = ast.AST_For;
var AST_ForIn = ast.AST_ForIn;
var AST_With = ast.AST_With;
var AST_Scope = ast.AST_Scope;
var AST_Toplevel = ast.AST_Toplevel;
var AST_Lambda = ast.AST_Lambda;
var AST_Accessor = ast.AST_Accessor;
var AST_Function = ast.AST_Function;
var AST_Defun = ast.AST_Defun;
var AST_Return = ast.AST_Return;
var AST_Throw = ast.AST_Throw;
var AST_Break = ast.AST_Break;
var AST_Continue = ast.AST_Continue;
var AST_If = ast.AST_If;
var AST_Switch = ast.AST_Switch;
var AST_SwitchBranch = ast.AST_SwitchBranch;
var AST_Default = ast.AST_Default;
var AST_Case = ast.AST_Case;
var AST_Try = ast.AST_Try;
var AST_Catch = ast.AST_Catch;
var AST_Finally = ast.AST_Finally;
var AST_Definitions = ast.AST_Definitions;
var AST_Var = ast.AST_Var;
var AST_VarDef = ast.AST_VarDef;
var AST_Call = ast.AST_Call;
var AST_New = ast.AST_New;
var AST_Sequence = ast.AST_Sequence;
var AST_PropAccess = ast.AST_PropAccess;
var AST_Dot = ast.AST_Dot;
var AST_Sub = ast.AST_Sub;
var AST_Unary = ast.AST_Unary;
var AST_UnaryPrefix = ast.AST_UnaryPrefix;
var AST_UnaryPostfix = ast.AST_UnaryPostfix;
var AST_Binary = ast.AST_Binary;
var AST_Conditional = ast.AST_Conditional;
var AST_Assign = ast.AST_Assign;
var AST_Array = ast.AST_Array;
var AST_Object = ast.AST_Object;
var AST_ObjectProperty = ast.AST_ObjectProperty;
var AST_ObjectKeyVal = ast.AST_ObjectKeyVal;
var AST_ObjectSetter = ast.AST_ObjectSetter;
var AST_ObjectGetter = ast.AST_ObjectGetter;
var AST_Symbol = ast.AST_Symbol;
var AST_SymbolAccessor = ast.AST_SymbolAccessor;
var AST_SymbolVar = ast.AST_SymbolVar;
var AST_SymbolFunarg = ast.AST_SymbolFunarg;
var AST_SymbolDefun = ast.AST_SymbolDefun;
var AST_SymbolLambda = ast.AST_SymbolLambda;
var AST_SymbolCatch = ast.AST_SymbolCatch;
var AST_Label = ast.AST_Label;
var AST_SymbolRef = ast.AST_SymbolRef;
var AST_LabelRef = ast.AST_LabelRef;
var AST_This = ast.AST_This;
var AST_Constant = ast.AST_Constant;
var AST_String = ast.AST_String;
var AST_Number = ast.AST_Number;
var AST_RegExp = ast.AST_RegExp;
var AST_Atom = ast.AST_Atom;
var AST_Null = ast.AST_Null;
var AST_Hole = ast.AST_Hole;
var AST_Boolean = ast.AST_Boolean;
var AST_False = ast.AST_False;
var AST_True = ast.AST_True;
var AST = require("./ast");
var TreeWalker = AST.TreeWalker;
(function() {
function normalize_directives(body) {
var in_directive = true;
for (var i = 0; i < body.length; i++) {
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
body[i] = new AST_Directive({
if (in_directive && body[i] instanceof AST.Statement && body[i].body instanceof AST.String) {
body[i] = new AST.Directive({
start: body[i].start,
end: body[i].end,
value: body[i].body.value
});
} else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
} else if (in_directive && !(body[i] instanceof AST.Statement && body[i].body instanceof AST.String)) {
in_directive = false;
}
}
@ -140,14 +65,14 @@ var AST_True = ast.AST_True;
var MOZ_TO_ME = {
Program: function(M) {
return new AST_Toplevel({
return new AST.Toplevel({
start: my_start_token(M),
end: my_end_token(M),
body: normalize_directives(M.body.map(from_moz))
});
},
FunctionDeclaration: function(M) {
return new AST_Defun({
return new AST.Defun({
start: my_start_token(M),
end: my_end_token(M),
name: from_moz(M.id),
@ -156,7 +81,7 @@ var AST_True = ast.AST_True;
});
},
FunctionExpression: function(M) {
return new AST_Function({
return new AST.Function({
start: my_start_token(M),
end: my_end_token(M),
name: from_moz(M.id),
@ -165,7 +90,7 @@ var AST_True = ast.AST_True;
});
},
ExpressionStatement: function(M) {
return new AST_SimpleStatement({
return new AST.SimpleStatement({
start: my_start_token(M),
end: my_end_token(M),
body: from_moz(M.expression)
@ -176,12 +101,12 @@ var AST_True = ast.AST_True;
if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
throw new Error("Multiple catch clauses are not supported.");
}
return new AST_Try({
return new AST.Try({
start : my_start_token(M),
end : my_end_token(M),
body : from_moz(M.block).body,
bcatch : from_moz(handlers[0]),
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
bfinally : M.finalizer ? new AST.Finally(from_moz(M.finalizer)) : null
});
},
Property: function(M) {
@ -192,25 +117,25 @@ var AST_True = ast.AST_True;
key : key.type == "Identifier" ? key.name : key.value,
value : from_moz(M.value)
};
if (M.kind == "init") return new AST_ObjectKeyVal(args);
args.key = new AST_SymbolAccessor({
if (M.kind == "init") return new AST.ObjectKeyVal(args);
args.key = new AST.SymbolAccessor({
name: args.key
});
args.value = new AST_Accessor(args.value);
if (M.kind == "get") return new AST_ObjectGetter(args);
if (M.kind == "set") return new AST_ObjectSetter(args);
args.value = new AST.Accessor(args.value);
if (M.kind == "get") return new AST.ObjectGetter(args);
if (M.kind == "set") return new AST.ObjectSetter(args);
},
ArrayExpression: function(M) {
return new AST_Array({
return new AST.Array({
start : my_start_token(M),
end : my_end_token(M),
elements : M.elements.map(function(elem) {
return elem === null ? new AST_Hole() : from_moz(elem);
return elem === null ? new AST.Hole() : from_moz(elem);
})
});
},
ObjectExpression: function(M) {
return new AST_Object({
return new AST.Object({
start : my_start_token(M),
end : my_end_token(M),
properties : M.properties.map(function(prop) {
@ -220,14 +145,14 @@ var AST_True = ast.AST_True;
});
},
SequenceExpression: function(M) {
return new AST_Sequence({
return new AST.Sequence({
start : my_start_token(M),
end : my_end_token(M),
expressions: M.expressions.map(from_moz)
});
},
MemberExpression: function(M) {
return new (M.computed ? AST_Sub : AST_Dot)({
return new (M.computed ? AST.Sub : AST.Dot)({
start : my_start_token(M),
end : my_end_token(M),
property : M.computed ? from_moz(M.property) : M.property.name,
@ -235,7 +160,7 @@ var AST_True = ast.AST_True;
});
},
SwitchCase: function(M) {
return new (M.test ? AST_Case : AST_Default)({
return new (M.test ? AST.Case : AST.Default)({
start : my_start_token(M),
end : my_end_token(M),
expression : from_moz(M.test),
@ -243,7 +168,7 @@ var AST_True = ast.AST_True;
});
},
VariableDeclaration: function(M) {
return new AST_Var({
return new AST.Var({
start : my_start_token(M),
end : my_end_token(M),
definitions : M.declarations.map(from_moz)
@ -254,38 +179,38 @@ var AST_True = ast.AST_True;
start : my_start_token(M),
end : my_end_token(M)
};
if (val === null) return new AST_Null(args);
if (val === null) return new AST.Null(args);
var rx = M.regex;
if (rx && rx.pattern) {
// RegExpLiteral as per ESTree AST spec
args.value = new RegExp(rx.pattern, rx.flags);
args.value.raw_source = rx.pattern;
return new AST_RegExp(args);
return new AST.RegExp(args);
} else if (rx) {
// support legacy RegExp
args.value = M.regex && M.raw ? M.raw : val;
return new AST_RegExp(args);
return new AST.RegExp(args);
}
switch (typeof val) {
case "string":
args.value = val;
return new AST_String(args);
return new AST.String(args);
case "number":
args.value = val;
return new AST_Number(args);
return new AST.Number(args);
case "boolean":
return new (val ? AST_True : AST_False)(args);
return new (val ? AST.True : AST.False)(args);
}
},
Identifier: function(M) {
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
return new ( p.type == "LabeledStatement" ? AST_Label
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
: p.type == "CatchClause" ? AST_SymbolCatch
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
: AST_SymbolRef)({
return new ( p.type == "LabeledStatement" ? AST.Label
: p.type == "VariableDeclarator" && p.id === M ? AST.SymbolVar
: p.type == "FunctionExpression" ? (p.id === M ? AST.SymbolLambda : AST.SymbolFunarg)
: p.type == "FunctionDeclaration" ? (p.id === M ? AST.SymbolDefun : AST.SymbolFunarg)
: p.type == "CatchClause" ? AST.SymbolCatch
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST.LabelRef
: AST.SymbolRef)({
start : my_start_token(M),
end : my_end_token(M),
name : M.name
@ -297,7 +222,7 @@ var AST_True = ast.AST_True;
MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
var prefix = "prefix" in M ? M.prefix
: M.type == "UnaryExpression" ? true : false;
return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
return new (prefix ? AST.UnaryPrefix : AST.UnaryPostfix)({
start : my_start_token(M),
end : my_end_token(M),
operator : M.operator,
@ -305,37 +230,37 @@ var AST_True = ast.AST_True;
});
};
map("EmptyStatement", AST_EmptyStatement);
map("BlockStatement", AST_BlockStatement, "body@body");
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
map("BreakStatement", AST_Break, "label>label");
map("ContinueStatement", AST_Continue, "label>label");
map("WithStatement", AST_With, "object>expression, body>body");
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
map("ReturnStatement", AST_Return, "argument>value");
map("ThrowStatement", AST_Throw, "argument>value");
map("WhileStatement", AST_While, "test>condition, body>body");
map("DoWhileStatement", AST_Do, "test>condition, body>body");
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
map("DebuggerStatement", AST_Debugger);
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
map("CatchClause", AST_Catch, "param>argname, body%body");
map("EmptyStatement", AST.EmptyStatement);
map("BlockStatement", AST.BlockStatement, "body@body");
map("IfStatement", AST.If, "test>condition, consequent>body, alternate>alternative");
map("LabeledStatement", AST.LabeledStatement, "label>label, body>body");
map("BreakStatement", AST.Break, "label>label");
map("ContinueStatement", AST.Continue, "label>label");
map("WithStatement", AST.With, "object>expression, body>body");
map("SwitchStatement", AST.Switch, "discriminant>expression, cases@body");
map("ReturnStatement", AST.Return, "argument>value");
map("ThrowStatement", AST.Throw, "argument>value");
map("WhileStatement", AST.While, "test>condition, body>body");
map("DoWhileStatement", AST.Do, "test>condition, body>body");
map("ForStatement", AST.For, "init>init, test>condition, update>step, body>body");
map("ForInStatement", AST.ForIn, "left>init, right>object, body>body");
map("DebuggerStatement", AST.Debugger);
map("VariableDeclarator", AST.VarDef, "id>name, init>value");
map("CatchClause", AST.Catch, "param>argname, body%body");
map("ThisExpression", AST_This);
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
map("NewExpression", AST_New, "callee>expression, arguments@args");
map("CallExpression", AST_Call, "callee>expression, arguments@args");
map("ThisExpression", AST.This);
map("BinaryExpression", AST.Binary, "operator=operator, left>left, right>right");
map("LogicalExpression", AST.Binary, "operator=operator, left>left, right>right");
map("AssignmentExpression", AST.Assign, "operator=operator, left>left, right>right");
map("ConditionalExpression", AST.Conditional, "test>condition, consequent>consequent, alternate>alternative");
map("NewExpression", AST.New, "callee>expression, arguments@args");
map("CallExpression", AST.Call, "callee>expression, arguments@args");
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
def_to_moz(AST.Toplevel, function To_Moz_Program(M) {
return to_moz_scope("Program", M);
});
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
def_to_moz(AST.Defun, function To_Moz_FunctionDeclaration(M) {
return {
type: "FunctionDeclaration",
id: to_moz(M.name),
@ -344,7 +269,7 @@ var AST_True = ast.AST_True;
}
});
def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) {
def_to_moz(AST.Function, function To_Moz_FunctionExpression(M) {
return {
type: "FunctionExpression",
id: to_moz(M.name),
@ -353,7 +278,7 @@ var AST_True = ast.AST_True;
}
});
def_to_moz(AST_Directive, function To_Moz_Directive(M) {
def_to_moz(AST.Directive, function To_Moz_Directive(M) {
return {
type: "ExpressionStatement",
expression: {
@ -363,14 +288,14 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
def_to_moz(AST.SimpleStatement, function To_Moz_ExpressionStatement(M) {
return {
type: "ExpressionStatement",
expression: to_moz(M.body)
};
});
def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
def_to_moz(AST.SwitchBranch, function To_Moz_SwitchCase(M) {
return {
type: "SwitchCase",
test: to_moz(M.expression),
@ -378,7 +303,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
def_to_moz(AST.Try, function To_Moz_TryStatement(M) {
return {
type: "TryStatement",
block: to_moz_block(M),
@ -388,7 +313,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
def_to_moz(AST.Catch, function To_Moz_CatchClause(M) {
return {
type: "CatchClause",
param: to_moz(M.argname),
@ -397,7 +322,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
def_to_moz(AST.Definitions, function To_Moz_VariableDeclaration(M) {
return {
type: "VariableDeclaration",
kind: "var",
@ -405,15 +330,15 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
def_to_moz(AST.Sequence, function To_Moz_SequenceExpression(M) {
return {
type: "SequenceExpression",
expressions: M.expressions.map(to_moz)
};
});
def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
var isComputed = M instanceof AST_Sub;
def_to_moz(AST.PropAccess, function To_Moz_MemberExpression(M) {
var isComputed = M instanceof AST.Sub;
return {
type: "MemberExpression",
object: to_moz(M.expression),
@ -422,16 +347,16 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Unary, function To_Moz_Unary(M) {
def_to_moz(AST.Unary, function To_Moz_Unary(M) {
return {
type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
operator: M.operator,
prefix: M instanceof AST_UnaryPrefix,
prefix: M instanceof AST.UnaryPrefix,
argument: to_moz(M.expression)
};
});
def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
def_to_moz(AST.Binary, function To_Moz_BinaryExpression(M) {
return {
type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression",
left: to_moz(M.left),
@ -440,33 +365,33 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
def_to_moz(AST.Array, function To_Moz_ArrayExpression(M) {
return {
type: "ArrayExpression",
elements: M.elements.map(to_moz)
};
});
def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
def_to_moz(AST.Object, function To_Moz_ObjectExpression(M) {
return {
type: "ObjectExpression",
properties: M.properties.map(to_moz)
};
});
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
def_to_moz(AST.ObjectProperty, function To_Moz_Property(M) {
var key = {
type: "Literal",
value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
value: M.key instanceof AST.SymbolAccessor ? M.key.name : M.key
};
var kind;
if (M instanceof AST_ObjectKeyVal) {
if (M instanceof AST.ObjectKeyVal) {
kind = "init";
} else
if (M instanceof AST_ObjectGetter) {
if (M instanceof AST.ObjectGetter) {
kind = "get";
} else
if (M instanceof AST_ObjectSetter) {
if (M instanceof AST.ObjectSetter) {
kind = "set";
}
return {
@ -477,7 +402,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Symbol, function To_Moz_Identifier(M) {
def_to_moz(AST.Symbol, function To_Moz_Identifier(M) {
var def = M.definition();
return {
type: "Identifier",
@ -485,7 +410,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
def_to_moz(AST.RegExp, function To_Moz_RegExpLiteral(M) {
var flags = M.value.toString().match(/[gimuy]*$/)[0];
var value = "/" + M.value.raw_source + "/" + flags;
return {
@ -499,7 +424,7 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Constant, function To_Moz_Literal(M) {
def_to_moz(AST.Constant, function To_Moz_Literal(M) {
var value = M.value;
if (typeof value === 'number' && (value < 0 || (value === 0 && 1 / value < 0))) {
return {
@ -520,19 +445,19 @@ var AST_True = ast.AST_True;
};
});
def_to_moz(AST_Atom, function To_Moz_Atom(M) {
def_to_moz(AST.Atom, function To_Moz_Atom(M) {
return {
type: "Identifier",
name: String(M.value)
};
});
AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null });
AST.Boolean.DEFMETHOD("to_mozilla_ast", AST.Constant.prototype.to_mozilla_ast);
AST.Null.DEFMETHOD("to_mozilla_ast", AST.Constant.prototype.to_mozilla_ast);
AST.Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null });
AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast);
AST.Block.DEFMETHOD("to_mozilla_ast", AST.BlockStatement.prototype.to_mozilla_ast);
AST.Lambda.DEFMETHOD("to_mozilla_ast", AST.Function.prototype.to_mozilla_ast);
/* -----[ tools ]----- */
@ -545,7 +470,7 @@ var AST_True = ast.AST_True;
function my_start_token(moznode) {
var loc = moznode.loc, start = loc && loc.start;
var range = moznode.range;
return new AST_Token({
return new AST.Token({
file : loc && loc.source,
line : start && start.line,
col : start && start.column,
@ -560,7 +485,7 @@ var AST_True = ast.AST_True;
function my_end_token(moznode) {
var loc = moznode.loc, end = loc && loc.end;
var range = moznode.range;
return new AST_Token({
return new AST.Token({
file : loc && loc.source,
line : end && end.line,
col : end && end.column,
@ -618,7 +543,7 @@ var AST_True = ast.AST_True;
//console.log(moz_to_me);
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
ast, my_start_token, my_end_token, from_moz
AST, my_start_token, my_end_token, from_moz
);
me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
to_moz, to_moz_block, to_moz_scope
@ -636,16 +561,16 @@ var AST_True = ast.AST_True;
return ret;
}
AST_Node.from_mozilla_ast = function(node) {
AST.Node.from_mozilla_ast = function(node) {
var save_stack = FROM_MOZ_STACK;
FROM_MOZ_STACK = [];
var ast = from_moz(node);
FROM_MOZ_STACK = save_stack;
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_LabelRef) {
if (node instanceof AST.LabelRef) {
for (var level = 0, parent; parent = this.parent(level); level++) {
if (parent instanceof AST_Scope) break;
if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
if (parent instanceof AST.Scope) break;
if (parent instanceof AST.LabeledStatement && parent.label.name == node.name) {
node.thedef = parent.label;
break;
}
@ -696,8 +621,8 @@ var AST_True = ast.AST_True;
function to_moz_scope(type, node) {
var body = node.body.map(to_moz);
if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
if (node.body[0] instanceof AST.SimpleStatement && node.body[0].body instanceof AST.String) {
body.unshift(to_moz(new AST.EmptyStatement(node.body[0])));
}
return {
type: type,

View File

@ -53,69 +53,9 @@ var makePredicate = utils.makePredicate;
var all = utils.all;
var merge = utils.merge;
var ast = require("./ast");
var first_in_statement = ast.first_in_statement;
var TreeWalker = ast.TreeWalker;
var AST_Node = ast.AST_Node;
var AST_Statement = ast.AST_Statement;
var AST_Debugger = ast.AST_Debugger;
var AST_Directive = ast.AST_Directive;
var AST_SimpleStatement = ast.AST_SimpleStatement;
var AST_BlockStatement = ast.AST_BlockStatement;
var AST_EmptyStatement = ast.AST_EmptyStatement;
var AST_StatementWithBody = ast.AST_StatementWithBody;
var AST_LabeledStatement = ast.AST_LabeledStatement;
var AST_Do = ast.AST_Do;
var AST_While = ast.AST_While;
var AST_For = ast.AST_For;
var AST_ForIn = ast.AST_ForIn;
var AST_With = ast.AST_With;
var AST_Scope = ast.AST_Scope;
var AST_Toplevel = ast.AST_Toplevel;
var AST_Lambda = ast.AST_Lambda;
var AST_Function = ast.AST_Function;
var AST_Jump = ast.AST_Jump;
var AST_Exit = ast.AST_Exit;
var AST_Return = ast.AST_Return;
var AST_Throw = ast.AST_Throw;
var AST_Break = ast.AST_Break;
var AST_Continue = ast.AST_Continue;
var AST_If = ast.AST_If;
var AST_Switch = ast.AST_Switch;
var AST_SwitchBranch = ast.AST_SwitchBranch;
var AST_Default = ast.AST_Default;
var AST_Case = ast.AST_Case;
var AST_Try = ast.AST_Try;
var AST_Catch = ast.AST_Catch;
var AST_Finally = ast.AST_Finally;
var AST_Definitions = ast.AST_Definitions;
var AST_Var = ast.AST_Var;
var AST_VarDef = ast.AST_VarDef;
var AST_Call = ast.AST_Call;
var AST_New = ast.AST_New;
var AST_Sequence = ast.AST_Sequence;
var AST_PropAccess = ast.AST_PropAccess;
var AST_Dot = ast.AST_Dot;
var AST_Sub = ast.AST_Sub;
var AST_Unary = ast.AST_Unary;
var AST_UnaryPrefix = ast.AST_UnaryPrefix;
var AST_UnaryPostfix = ast.AST_UnaryPostfix;
var AST_Binary = ast.AST_Binary;
var AST_Conditional = ast.AST_Conditional;
var AST_Assign = ast.AST_Assign;
var AST_Array = ast.AST_Array;
var AST_Object = ast.AST_Object;
var AST_ObjectProperty = ast.AST_ObjectProperty;
var AST_ObjectKeyVal = ast.AST_ObjectKeyVal;
var AST_ObjectSetter = ast.AST_ObjectSetter;
var AST_ObjectGetter = ast.AST_ObjectGetter;
var AST_Symbol = ast.AST_Symbol;
var AST_This = ast.AST_This;
var AST_Constant = ast.AST_Constant;
var AST_String = ast.AST_String;
var AST_Number = ast.AST_Number;
var AST_RegExp = ast.AST_RegExp;
var AST_Hole = ast.AST_Hole;
var AST = require("./ast");
var first_in_statement = AST.first_in_statement;
var TreeWalker = AST.TreeWalker;
var parse = require("./parse");
var is_surrogate_pair_head = parse.is_surrogate_pair_head;
@ -299,7 +239,7 @@ function OutputStream(options) {
!mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
);
} catch(ex) {
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
AST.Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
file: mapping.token.file,
line: mapping.token.line,
col: mapping.token.col,
@ -330,7 +270,7 @@ function OutputStream(options) {
current_col = right.length;
}
if (current_col > options.max_line_len) {
AST_Node.warn("Output exceeds {max_line_len} characters", options);
AST.Node.warn("Output exceeds {max_line_len} characters", options);
}
}
if (might_add_newline) {
@ -559,17 +499,17 @@ function OutputStream(options) {
}
comments._dumped = self;
if (node instanceof AST_Exit && node.value) {
if (node instanceof AST.Exit && node.value) {
var tw = new TreeWalker(function(node) {
var parent = tw.parent();
if (parent instanceof AST_Exit
|| parent instanceof AST_Binary && parent.left === node
if (parent instanceof AST.Exit
|| parent instanceof AST.Binary && parent.left === node
|| parent.TYPE == "Call" && parent.expression === node
|| parent instanceof AST_Conditional && parent.condition === node
|| parent instanceof AST_Dot && parent.expression === node
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|| parent instanceof AST_Sub && parent.expression === node
|| parent instanceof AST_UnaryPostfix) {
|| parent instanceof AST.Conditional && parent.condition === node
|| parent instanceof AST.Dot && parent.expression === node
|| parent instanceof AST.Sequence && parent.expressions[0] === node
|| parent instanceof AST.Sub && parent.expression === node
|| parent instanceof AST.UnaryPostfix) {
var text = node.start.comments_before;
if (text && text._dumped !== self) {
text._dumped = self;
@ -632,7 +572,7 @@ function OutputStream(options) {
if (!token) return;
var comments = token[tail ? "comments_before" : "comments_after"];
if (!comments || comments._dumped === self) return;
if (!(node instanceof AST_Statement || all(comments, function(c) {
if (!(node instanceof AST.Statement || all(comments, function(c) {
return !/comment[134]/.test(c.type);
}))) return;
comments._dumped = self;
@ -725,12 +665,12 @@ function OutputStream(options) {
var active_scope = null;
var use_asm = null;
AST_Node.DEFMETHOD("print", function(stream, force_parens) {
AST.Node.DEFMETHOD("print", function(stream, force_parens) {
var self = this, generator = self._codegen;
if (self instanceof AST_Scope) {
if (self instanceof AST.Scope) {
active_scope = self;
}
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
else if (!use_asm && self instanceof AST.Directive && self.value == "use asm") {
use_asm = active_scope;
}
function doit() {
@ -750,9 +690,9 @@ function OutputStream(options) {
use_asm = null;
}
});
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
AST.Node.DEFMETHOD("_print", AST.Node.prototype.print);
AST_Node.DEFMETHOD("print_to_string", function(options) {
AST.Node.DEFMETHOD("print_to_string", function(options) {
var s = OutputStream(options);
this.print(s);
return s.get();
@ -770,25 +710,25 @@ function OutputStream(options) {
}
}
PARENS(AST_Node, return_false);
PARENS(AST.Node, return_false);
// a function expression needs parens around it when it's provably
// the first token to appear in a statement.
PARENS(AST_Function, function(output) {
PARENS(AST.Function, function(output) {
if (!output.has_parens() && first_in_statement(output)) {
return true;
}
if (output.option('webkit')) {
var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === this) {
if (p instanceof AST.PropAccess && p.expression === this) {
return true;
}
}
if (output.option('wrap_iife')) {
var p = output.parent();
return p instanceof AST_Call && p.expression === this;
return p instanceof AST.Call && p.expression === this;
}
return false;
@ -796,43 +736,43 @@ function OutputStream(options) {
// same goes for an object literal, because otherwise it would be
// interpreted as a block of code.
PARENS(AST_Object, function(output) {
PARENS(AST.Object, function(output) {
return !output.has_parens() && first_in_statement(output);
});
PARENS(AST_Unary, function(output) {
PARENS(AST.Unary, function(output) {
var p = output.parent();
return p instanceof AST_PropAccess && p.expression === this
|| p instanceof AST_Call && p.expression === this;
return p instanceof AST.PropAccess && p.expression === this
|| p instanceof AST.Call && p.expression === this;
});
PARENS(AST_Sequence, function(output) {
PARENS(AST.Sequence, function(output) {
var p = output.parent();
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST_Unary // !(foo, bar, baz)
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
return p instanceof AST.Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST.Unary // !(foo, bar, baz)
|| p instanceof AST.Binary // 1 + (2, 3) + 4 ==> 8
|| p instanceof AST.VarDef // var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST.PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST.Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST.ObjectProperty // { foo: (1, 2) }.foo ==> 2
|| p instanceof AST.Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
* ==> 20 (side effect, set a := 10 and b := 20) */
;
});
PARENS(AST_Binary, function(output) {
PARENS(AST.Binary, function(output) {
var p = output.parent();
// (foo && bar)()
if (p instanceof AST_Call && p.expression === this)
if (p instanceof AST.Call && p.expression === this)
return true;
// typeof (foo && bar)
if (p instanceof AST_Unary)
if (p instanceof AST.Unary)
return true;
// (foo && bar)["prop"], (foo && bar).prop
if (p instanceof AST_PropAccess && p.expression === this)
if (p instanceof AST.PropAccess && p.expression === this)
return true;
// this deals with precedence: 3 * (2 + 1)
if (p instanceof AST_Binary) {
if (p instanceof AST.Binary) {
var po = p.operator, pp = PRECEDENCE[po];
var so = this.operator, sp = PRECEDENCE[so];
if (pp > sp
@ -843,9 +783,9 @@ function OutputStream(options) {
}
});
PARENS(AST_PropAccess, function(output) {
PARENS(AST.PropAccess, function(output) {
var p = output.parent();
if (p instanceof AST_New && p.expression === this) {
if (p instanceof AST.New && p.expression === this) {
// i.e. new (foo.bar().baz)
//
// if there's one call into this subtree, then we need
@ -854,8 +794,8 @@ function OutputStream(options) {
// expression.
var parens = false;
this.walk(new TreeWalker(function(node) {
if (parens || node instanceof AST_Scope) return true;
if (node instanceof AST_Call) {
if (parens || node instanceof AST.Scope) return true;
if (node instanceof AST.Call) {
parens = true;
return true;
}
@ -864,31 +804,31 @@ function OutputStream(options) {
}
});
PARENS(AST_Call, function(output) {
PARENS(AST.Call, function(output) {
var p = output.parent(), p1;
if (p instanceof AST_New && p.expression === this)
if (p instanceof AST.New && p.expression === this)
return true;
// workaround for Safari bug.
// https://bugs.webkit.org/show_bug.cgi?id=123506
return this.expression instanceof AST_Function
&& p instanceof AST_PropAccess
return this.expression instanceof AST.Function
&& p instanceof AST.PropAccess
&& p.expression === this
&& (p1 = output.parent(1)) instanceof AST_Assign
&& (p1 = output.parent(1)) instanceof AST.Assign
&& p1.left === p;
});
PARENS(AST_New, function(output) {
PARENS(AST.New, function(output) {
var p = output.parent();
if (!need_constructor_parens(this, output)
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|| p instanceof AST_Call && p.expression === this)) // (new foo)(bar)
&& (p instanceof AST.PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|| p instanceof AST.Call && p.expression === this)) // (new foo)(bar)
return true;
});
PARENS(AST_Number, function(output) {
PARENS(AST.Number, function(output) {
var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === this) {
if (p instanceof AST.PropAccess && p.expression === this) {
var value = this.getValue();
if (value < 0 || /^0/.test(make_num(value))) {
return true;
@ -896,32 +836,32 @@ function OutputStream(options) {
}
});
PARENS([ AST_Assign, AST_Conditional ], function(output) {
PARENS([ AST.Assign, AST.Conditional ], function(output) {
var p = output.parent();
// !(a = false) → true
if (p instanceof AST_Unary)
if (p instanceof AST.Unary)
return true;
// 1 + (a = 2) + 3 → 6, side effect setting a = 2
if (p instanceof AST_Binary && !(p instanceof AST_Assign))
if (p instanceof AST.Binary && !(p instanceof AST.Assign))
return true;
// (a = func)() —or— new (a = Object)()
if (p instanceof AST_Call && p.expression === this)
if (p instanceof AST.Call && p.expression === this)
return true;
// (a = foo) ? bar : baz
if (p instanceof AST_Conditional && p.condition === this)
if (p instanceof AST.Conditional && p.condition === this)
return true;
// (a = foo)["prop"] —or— (a = foo).prop
if (p instanceof AST_PropAccess && p.expression === this)
if (p instanceof AST.PropAccess && p.expression === this)
return true;
});
/* -----[ PRINTERS ]----- */
DEFPRINT(AST_Directive, function(self, output) {
DEFPRINT(AST.Directive, function(self, output) {
output.print_string(self.value, self.quote);
output.semicolon();
});
DEFPRINT(AST_Debugger, function(self, output) {
DEFPRINT(AST.Debugger, function(self, output) {
output.print("debugger");
output.semicolon();
});
@ -932,13 +872,13 @@ function OutputStream(options) {
var last = body.length - 1;
in_directive = allow_directives;
body.forEach(function(stmt, i) {
if (in_directive === true && !(stmt instanceof AST_Directive ||
stmt instanceof AST_EmptyStatement ||
(stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String)
if (in_directive === true && !(stmt instanceof AST.Directive ||
stmt instanceof AST.EmptyStatement ||
(stmt instanceof AST.SimpleStatement && stmt.body instanceof AST.String)
)) {
in_directive = false;
}
if (!(stmt instanceof AST_EmptyStatement)) {
if (!(stmt instanceof AST.EmptyStatement)) {
output.indent();
stmt.print(output);
if (!(i == last && is_toplevel)) {
@ -947,8 +887,8 @@ function OutputStream(options) {
}
}
if (in_directive === true &&
stmt instanceof AST_SimpleStatement &&
stmt.body instanceof AST_String
stmt instanceof AST.SimpleStatement &&
stmt.body instanceof AST.String
) {
in_directive = false;
}
@ -956,24 +896,24 @@ function OutputStream(options) {
in_directive = false;
}
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
AST.StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
force_statement(this.body, output);
});
DEFPRINT(AST_Statement, function(self, output) {
DEFPRINT(AST.Statement, function(self, output) {
self.body.print(output);
output.semicolon();
});
DEFPRINT(AST_Toplevel, function(self, output) {
DEFPRINT(AST.Toplevel, function(self, output) {
display_body(self.body, true, output, true);
output.print("");
});
DEFPRINT(AST_LabeledStatement, function(self, output) {
DEFPRINT(AST.LabeledStatement, function(self, output) {
self.label.print(output);
output.colon();
self.body.print(output);
});
DEFPRINT(AST_SimpleStatement, function(self, output) {
DEFPRINT(AST.SimpleStatement, function(self, output) {
self.body.print(output);
output.semicolon();
});
@ -991,13 +931,13 @@ function OutputStream(options) {
});
} else print_braced_empty(self, output);
}
DEFPRINT(AST_BlockStatement, function(self, output) {
DEFPRINT(AST.BlockStatement, function(self, output) {
print_braced(self, output);
});
DEFPRINT(AST_EmptyStatement, function(self, output) {
DEFPRINT(AST.EmptyStatement, function(self, output) {
output.semicolon();
});
DEFPRINT(AST_Do, function(self, output) {
DEFPRINT(AST.Do, function(self, output) {
output.print("do");
output.space();
make_block(self.body, output);
@ -1009,7 +949,7 @@ function OutputStream(options) {
});
output.semicolon();
});
DEFPRINT(AST_While, function(self, output) {
DEFPRINT(AST.While, function(self, output) {
output.print("while");
output.space();
output.with_parens(function() {
@ -1018,12 +958,12 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_For, function(self, output) {
DEFPRINT(AST.For, function(self, output) {
output.print("for");
output.space();
output.with_parens(function() {
if (self.init) {
if (self.init instanceof AST_Definitions) {
if (self.init instanceof AST.Definitions) {
self.init.print(output);
} else {
parenthesize_for_noin(self.init, output, true);
@ -1047,7 +987,7 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_ForIn, function(self, output) {
DEFPRINT(AST.ForIn, function(self, output) {
output.print("for");
output.space();
output.with_parens(function() {
@ -1060,7 +1000,7 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_With, function(self, output) {
DEFPRINT(AST.With, function(self, output) {
output.print("with");
output.space();
output.with_parens(function() {
@ -1071,7 +1011,7 @@ function OutputStream(options) {
});
/* -----[ functions ]----- */
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
AST.Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
var self = this;
if (!nokeyword) {
output.print("function");
@ -1089,7 +1029,7 @@ function OutputStream(options) {
output.space();
print_braced(self, output, true);
});
DEFPRINT(AST_Lambda, function(self, output) {
DEFPRINT(AST.Lambda, function(self, output) {
self._do_print(output);
});
@ -1103,16 +1043,16 @@ function OutputStream(options) {
output.semicolon();
}
DEFPRINT(AST_Return, function(self, output) {
DEFPRINT(AST.Return, function(self, output) {
print_jump(output, "return", self.value);
});
DEFPRINT(AST_Throw, function(self, output) {
DEFPRINT(AST.Throw, function(self, output) {
print_jump(output, "throw", self.value);
});
DEFPRINT(AST_Break, function(self, output) {
DEFPRINT(AST.Break, function(self, output) {
print_jump(output, "break", self.label);
});
DEFPRINT(AST_Continue, function(self, output) {
DEFPRINT(AST.Continue, function(self, output) {
print_jump(output, "continue", self.label);
});
@ -1120,7 +1060,7 @@ function OutputStream(options) {
function make_then(self, output) {
var b = self.body;
if (output.option("braces")
|| output.option("ie8") && b instanceof AST_Do)
|| output.option("ie8") && b instanceof AST.Do)
return make_block(b, output);
// The squeezer replaces "block"-s that contain only a single
// statement with the statement itself; technically, the AST
@ -1131,21 +1071,21 @@ function OutputStream(options) {
// adds the block braces if needed.
if (!b) return output.force_semicolon();
while (true) {
if (b instanceof AST_If) {
if (b instanceof AST.If) {
if (!b.alternative) {
make_block(self.body, output);
return;
}
b = b.alternative;
}
else if (b instanceof AST_StatementWithBody) {
else if (b instanceof AST.StatementWithBody) {
b = b.body;
}
else break;
}
force_statement(self.body, output);
}
DEFPRINT(AST_If, function(self, output) {
DEFPRINT(AST.If, function(self, output) {
output.print("if");
output.space();
output.with_parens(function() {
@ -1157,7 +1097,7 @@ function OutputStream(options) {
output.space();
output.print("else");
output.space();
if (self.alternative instanceof AST_If)
if (self.alternative instanceof AST.If)
self.alternative.print(output);
else
force_statement(self.alternative, output);
@ -1167,7 +1107,7 @@ function OutputStream(options) {
});
/* -----[ switch ]----- */
DEFPRINT(AST_Switch, function(self, output) {
DEFPRINT(AST.Switch, function(self, output) {
output.print("switch");
output.space();
output.with_parens(function() {
@ -1185,7 +1125,7 @@ function OutputStream(options) {
});
});
});
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
AST.SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
output.newline();
this.body.forEach(function(stmt) {
output.indent();
@ -1193,11 +1133,11 @@ function OutputStream(options) {
output.newline();
});
});
DEFPRINT(AST_Default, function(self, output) {
DEFPRINT(AST.Default, function(self, output) {
output.print("default:");
self._do_print_body(output);
});
DEFPRINT(AST_Case, function(self, output) {
DEFPRINT(AST.Case, function(self, output) {
output.print("case");
output.space();
self.expression.print(output);
@ -1206,7 +1146,7 @@ function OutputStream(options) {
});
/* -----[ exceptions ]----- */
DEFPRINT(AST_Try, function(self, output) {
DEFPRINT(AST.Try, function(self, output) {
output.print("try");
output.space();
print_braced(self, output);
@ -1219,7 +1159,7 @@ function OutputStream(options) {
self.bfinally.print(output);
}
});
DEFPRINT(AST_Catch, function(self, output) {
DEFPRINT(AST.Catch, function(self, output) {
output.print("catch");
output.space();
output.with_parens(function() {
@ -1228,13 +1168,13 @@ function OutputStream(options) {
output.space();
print_braced(self, output);
});
DEFPRINT(AST_Finally, function(self, output) {
DEFPRINT(AST.Finally, function(self, output) {
output.print("finally");
output.space();
print_braced(self, output);
});
DEFPRINT(AST_Var, function(self, output) {
DEFPRINT(AST.Var, function(self, output) {
output.print("var");
output.space();
self.definitions.forEach(function(def, i) {
@ -1242,7 +1182,7 @@ function OutputStream(options) {
def.print(output);
});
var p = output.parent();
if (p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon();
if (p.init !== self || !(p instanceof AST.For || p instanceof AST.ForIn)) output.semicolon();
});
function parenthesize_for_noin(node, output, noin) {
@ -1250,8 +1190,8 @@ function OutputStream(options) {
// need to take some precautions here:
// https://github.com/mishoo/UglifyJS2/issues/60
if (noin) node.walk(new TreeWalker(function(node) {
if (parens || node instanceof AST_Scope) return true;
if (node instanceof AST_Binary && node.operator == "in") {
if (parens || node instanceof AST.Scope) return true;
if (node instanceof AST.Binary && node.operator == "in") {
parens = true;
return true;
}
@ -1259,24 +1199,24 @@ function OutputStream(options) {
node.print(output, parens);
}
DEFPRINT(AST_VarDef, function(self, output) {
DEFPRINT(AST.VarDef, function(self, output) {
self.name.print(output);
if (self.value) {
output.space();
output.print("=");
output.space();
var p = output.parent(1);
var noin = p instanceof AST_For || p instanceof AST_ForIn;
var noin = p instanceof AST.For || p instanceof AST.ForIn;
parenthesize_for_noin(self.value, output, noin);
}
});
/* -----[ other expressions ]----- */
DEFPRINT(AST_Call, function(self, output) {
DEFPRINT(AST.Call, function(self, output) {
self.expression.print(output);
if (self instanceof AST_New && !need_constructor_parens(self, output))
if (self instanceof AST.New && !need_constructor_parens(self, output))
return;
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
if (self.expression instanceof AST.Call || self.expression instanceof AST.Lambda) {
output.add_mapping(self.start);
}
output.with_parens(function() {
@ -1286,12 +1226,12 @@ function OutputStream(options) {
});
});
});
DEFPRINT(AST_New, function(self, output) {
DEFPRINT(AST.New, function(self, output) {
output.print("new");
output.space();
AST_Call.prototype._codegen(self, output);
AST.Call.prototype._codegen(self, output);
});
DEFPRINT(AST_Sequence, function(self, output) {
DEFPRINT(AST.Sequence, function(self, output) {
self.expressions.forEach(function(node, index) {
if (index > 0) {
output.comma();
@ -1303,7 +1243,7 @@ function OutputStream(options) {
node.print(output);
});
});
DEFPRINT(AST_Dot, function(self, output) {
DEFPRINT(AST.Dot, function(self, output) {
var expr = self.expression;
expr.print(output);
var prop = self.property;
@ -1313,7 +1253,7 @@ function OutputStream(options) {
output.print_string(prop);
output.print("]");
} else {
if (expr instanceof AST_Number && expr.getValue() >= 0) {
if (expr instanceof AST.Number && expr.getValue() >= 0) {
if (!/[xa-f.)]/i.test(output.last())) {
output.print(".");
}
@ -1324,32 +1264,32 @@ function OutputStream(options) {
output.print_name(prop);
}
});
DEFPRINT(AST_Sub, function(self, output) {
DEFPRINT(AST.Sub, function(self, output) {
self.expression.print(output);
output.print("[");
self.property.print(output);
output.print("]");
});
DEFPRINT(AST_UnaryPrefix, function(self, output) {
DEFPRINT(AST.UnaryPrefix, function(self, output) {
var op = self.operator;
output.print(op);
if (/^[a-z]/i.test(op)
|| (/[+-]$/.test(op)
&& self.expression instanceof AST_UnaryPrefix
&& self.expression instanceof AST.UnaryPrefix
&& /^[+-]/.test(self.expression.operator))) {
output.space();
}
self.expression.print(output);
});
DEFPRINT(AST_UnaryPostfix, function(self, output) {
DEFPRINT(AST.UnaryPostfix, function(self, output) {
self.expression.print(output);
output.print(self.operator);
});
DEFPRINT(AST_Binary, function(self, output) {
DEFPRINT(AST.Binary, function(self, output) {
var op = self.operator;
self.left.print(output);
if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
&& self.left instanceof AST_UnaryPostfix
&& self.left instanceof AST.UnaryPostfix
&& self.left.operator == "--") {
// space is mandatory to avoid outputting -->
output.print(" ");
@ -1359,9 +1299,9 @@ function OutputStream(options) {
}
output.print(op);
if ((op == "<" || op == "<<")
&& self.right instanceof AST_UnaryPrefix
&& self.right instanceof AST.UnaryPrefix
&& self.right.operator == "!"
&& self.right.expression instanceof AST_UnaryPrefix
&& self.right.expression instanceof AST.UnaryPrefix
&& self.right.expression.operator == "--") {
// space is mandatory to avoid outputting <!--
output.print(" ");
@ -1371,7 +1311,7 @@ function OutputStream(options) {
}
self.right.print(output);
});
DEFPRINT(AST_Conditional, function(self, output) {
DEFPRINT(AST.Conditional, function(self, output) {
self.condition.print(output);
output.space();
output.print("?");
@ -1383,7 +1323,7 @@ function OutputStream(options) {
});
/* -----[ literals ]----- */
DEFPRINT(AST_Array, function(self, output) {
DEFPRINT(AST.Array, function(self, output) {
output.with_square(function() {
var a = self.elements, len = a.length;
if (len > 0) output.space();
@ -1393,13 +1333,13 @@ function OutputStream(options) {
// If the final element is a hole, we need to make sure it
// doesn't look like a trailing comma, by inserting an actual
// trailing comma.
if (i === len - 1 && exp instanceof AST_Hole)
if (i === len - 1 && exp instanceof AST.Hole)
output.comma();
});
if (len > 0) output.space();
});
});
DEFPRINT(AST_Object, function(self, output) {
DEFPRINT(AST.Object, function(self, output) {
if (self.properties.length > 0) output.with_block(function() {
self.properties.forEach(function(prop, i) {
if (i) {
@ -1430,38 +1370,38 @@ function OutputStream(options) {
}
}
DEFPRINT(AST_ObjectKeyVal, function(self, output) {
DEFPRINT(AST.ObjectKeyVal, function(self, output) {
print_property_name(self.key, self.quote, output);
output.colon();
self.value.print(output);
});
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
AST.ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
output.print(type);
output.space();
print_property_name(this.key.name, this.quote, output);
this.value._do_print(output, true);
});
DEFPRINT(AST_ObjectSetter, function(self, output) {
DEFPRINT(AST.ObjectSetter, function(self, output) {
self._print_getter_setter("set", output);
});
DEFPRINT(AST_ObjectGetter, function(self, output) {
DEFPRINT(AST.ObjectGetter, function(self, output) {
self._print_getter_setter("get", output);
});
DEFPRINT(AST_Symbol, function(self, output) {
DEFPRINT(AST.Symbol, function(self, output) {
var def = self.definition();
output.print_name(def ? def.mangled_name || def.name : self.name);
});
DEFPRINT(AST_Hole, noop);
DEFPRINT(AST_This, function(self, output) {
DEFPRINT(AST.Hole, noop);
DEFPRINT(AST.This, function(self, output) {
output.print("this");
});
DEFPRINT(AST_Constant, function(self, output) {
DEFPRINT(AST.Constant, function(self, output) {
output.print(self.getValue());
});
DEFPRINT(AST_String, function(self, output) {
DEFPRINT(AST.String, function(self, output) {
output.print_string(self.getValue(), self.quote, in_directive);
});
DEFPRINT(AST_Number, function(self, output) {
DEFPRINT(AST.Number, function(self, output) {
if (use_asm && self.start && self.start.raw != null) {
output.print(self.start.raw);
} else {
@ -1469,7 +1409,7 @@ function OutputStream(options) {
}
});
DEFPRINT(AST_RegExp, function(self, output) {
DEFPRINT(AST.RegExp, function(self, output) {
var regexp = self.getValue();
var str = regexp.toString();
if (regexp.raw_source) {
@ -1478,7 +1418,7 @@ function OutputStream(options) {
str = output.to_utf8(str);
output.print(str);
var p = output.parent();
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
if (p instanceof AST.Binary && /^in/.test(p.operator) && p.left === self)
output.print(" ");
});
@ -1486,14 +1426,14 @@ function OutputStream(options) {
if (output.option("braces")) {
make_block(stat, output);
} else {
if (!stat || stat instanceof AST_EmptyStatement)
if (!stat || stat instanceof AST.EmptyStatement)
output.force_semicolon();
else
stat.print(output);
}
}
// self should be AST_New. decide if we want to show parens or not.
// self should be AST.New. decide if we want to show parens or not.
function need_constructor_parens(self, output) {
// Always print parentheses with arguments
if (self.args.length > 0) return true;
@ -1537,9 +1477,9 @@ function OutputStream(options) {
}
function make_block(stmt, output) {
if (!stmt || stmt instanceof AST_EmptyStatement)
if (!stmt || stmt instanceof AST.EmptyStatement)
output.print("{}");
else if (stmt instanceof AST_BlockStatement)
else if (stmt instanceof AST.BlockStatement)
stmt.print(output);
else output.with_block(function() {
output.indent();
@ -1559,44 +1499,44 @@ function OutputStream(options) {
DEFMAP([
// We could easily add info for ALL nodes, but it seems to me that
// would be quite wasteful, hence this noop in the base class.
AST_Node,
AST.Node,
// since the label symbol will mark it
AST_LabeledStatement,
AST_Toplevel,
AST.LabeledStatement,
AST.Toplevel,
], noop);
// XXX: I'm not exactly sure if we need it for all of these nodes,
// or if we should add even more.
DEFMAP([
AST_Array,
AST_BlockStatement,
AST_Catch,
AST_Constant,
AST_Debugger,
AST_Definitions,
AST_Directive,
AST_Finally,
AST_Jump,
AST_Lambda,
AST_New,
AST_Object,
AST_StatementWithBody,
AST_Symbol,
AST_Switch,
AST_SwitchBranch,
AST_Try,
AST.Array,
AST.BlockStatement,
AST.Catch,
AST.Constant,
AST.Debugger,
AST.Definitions,
AST.Directive,
AST.Finally,
AST.Jump,
AST.Lambda,
AST.New,
AST.Object,
AST.StatementWithBody,
AST.Symbol,
AST.Switch,
AST.SwitchBranch,
AST.Try,
], function(output) {
output.add_mapping(this.start);
});
DEFMAP([
AST_ObjectGetter,
AST_ObjectSetter,
AST.ObjectGetter,
AST.ObjectSetter,
], function(output) {
output.add_mapping(this.start, this.key.name);
});
DEFMAP([ AST_ObjectProperty ], function(output) {
DEFMAP([ AST.ObjectProperty ], function(output) {
output.add_mapping(this.start, this.key);
});
})();

View File

@ -54,72 +54,7 @@ var all = utils.all;
var HOP = utils.HOP;
var merge = utils.merge;
var ast = require("./ast");
var AST_Token = ast.AST_Token;
var AST_Debugger = ast.AST_Debugger;
var AST_Directive = ast.AST_Directive;
var AST_SimpleStatement = ast.AST_SimpleStatement;
var AST_BlockStatement = ast.AST_BlockStatement;
var AST_EmptyStatement = ast.AST_EmptyStatement;
var AST_LabeledStatement = ast.AST_LabeledStatement;
var AST_IterationStatement = ast.AST_IterationStatement;
var AST_Do = ast.AST_Do;
var AST_While = ast.AST_While;
var AST_For = ast.AST_For;
var AST_ForIn = ast.AST_ForIn;
var AST_With = ast.AST_With;
var AST_Toplevel = ast.AST_Toplevel;
var AST_Lambda = ast.AST_Lambda;
var AST_Accessor = ast.AST_Accessor;
var AST_Function = ast.AST_Function;
var AST_Defun = ast.AST_Defun;
var AST_Return = ast.AST_Return;
var AST_Throw = ast.AST_Throw;
var AST_Break = ast.AST_Break;
var AST_Continue = ast.AST_Continue;
var AST_If = ast.AST_If;
var AST_Switch = ast.AST_Switch;
var AST_Default = ast.AST_Default;
var AST_Case = ast.AST_Case;
var AST_Try = ast.AST_Try;
var AST_Catch = ast.AST_Catch;
var AST_Finally = ast.AST_Finally;
var AST_Var = ast.AST_Var;
var AST_VarDef = ast.AST_VarDef;
var AST_Call = ast.AST_Call;
var AST_New = ast.AST_New;
var AST_Sequence = ast.AST_Sequence;
var AST_PropAccess = ast.AST_PropAccess;
var AST_Dot = ast.AST_Dot;
var AST_Sub = ast.AST_Sub;
var AST_UnaryPrefix = ast.AST_UnaryPrefix;
var AST_UnaryPostfix = ast.AST_UnaryPostfix;
var AST_Binary = ast.AST_Binary;
var AST_Conditional = ast.AST_Conditional;
var AST_Assign = ast.AST_Assign;
var AST_Array = ast.AST_Array;
var AST_Object = ast.AST_Object;
var AST_ObjectKeyVal = ast.AST_ObjectKeyVal;
var AST_ObjectSetter = ast.AST_ObjectSetter;
var AST_ObjectGetter = ast.AST_ObjectGetter;
var AST_SymbolAccessor = ast.AST_SymbolAccessor;
var AST_SymbolDeclaration = ast.AST_SymbolDeclaration;
var AST_SymbolVar = ast.AST_SymbolVar;
var AST_SymbolFunarg = ast.AST_SymbolFunarg;
var AST_SymbolDefun = ast.AST_SymbolDefun;
var AST_SymbolLambda = ast.AST_SymbolLambda;
var AST_SymbolCatch = ast.AST_SymbolCatch;
var AST_Label = ast.AST_Label;
var AST_SymbolRef = ast.AST_SymbolRef;
var AST_LabelRef = ast.AST_LabelRef;
var AST_This = ast.AST_This;
var AST_String = ast.AST_String;
var AST_Number = ast.AST_Number;
var AST_RegExp = ast.AST_RegExp;
var AST_Null = ast.AST_Null;
var AST_Hole = ast.AST_Hole;
var AST_False = ast.AST_False;
var AST_True = ast.AST_True;
var AST = require("./ast");
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
var KEYWORDS_ATOM = 'false null true';
@ -399,7 +334,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
ret.comments_after = S.comments_before = [];
}
S.newline_before = false;
return new AST_Token(ret);
return new AST.Token(ret);
}
function skip_whitespace() {
@ -910,7 +845,7 @@ function parse($TEXT, options) {
}
}
var dir = S.in_directives, stat = simple_statement();
return dir ? new AST_Directive(stat.body) : stat;
return dir ? new AST.Directive(stat.body) : stat;
case "num":
case "regexp":
case "operator":
@ -925,7 +860,7 @@ function parse($TEXT, options) {
case "punc":
switch (S.token.value) {
case "{":
return new AST_BlockStatement({
return new AST.BlockStatement({
start : S.token,
body : block_(),
end : prev()
@ -936,7 +871,7 @@ function parse($TEXT, options) {
case ";":
S.in_directives = false;
next();
return new AST_EmptyStatement();
return new AST.EmptyStatement();
default:
unexpected();
}
@ -945,16 +880,16 @@ function parse($TEXT, options) {
switch (S.token.value) {
case "break":
next();
return break_cont(AST_Break);
return break_cont(AST.Break);
case "continue":
next();
return break_cont(AST_Continue);
return break_cont(AST.Continue);
case "debugger":
next();
semicolon();
return new AST_Debugger();
return new AST.Debugger();
case "do":
next();
@ -962,14 +897,14 @@ function parse($TEXT, options) {
expect_token("keyword", "while");
var condition = parenthesised();
semicolon(true);
return new AST_Do({
return new AST.Do({
body : body,
condition : condition
});
case "while":
next();
return new AST_While({
return new AST.While({
condition : parenthesised(),
body : in_loop(statement)
});
@ -983,7 +918,7 @@ function parse($TEXT, options) {
croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
}
next();
return function_(AST_Defun);
return function_(AST.Defun);
case "if":
next();
@ -1000,13 +935,13 @@ function parse($TEXT, options) {
value = expression(true);
semicolon();
}
return new AST_Return({
return new AST.Return({
value: value
});
case "switch":
next();
return new AST_Switch({
return new AST.Switch({
expression : parenthesised(),
body : in_loop(switch_body_)
});
@ -1017,7 +952,7 @@ function parse($TEXT, options) {
croak("Illegal newline after 'throw'");
var value = expression(true);
semicolon();
return new AST_Throw({
return new AST.Throw({
value: value
});
@ -1036,7 +971,7 @@ function parse($TEXT, options) {
croak("Strict mode may not include a with statement");
}
next();
return new AST_With({
return new AST.With({
expression : parenthesised(),
body : statement()
});
@ -1046,7 +981,7 @@ function parse($TEXT, options) {
});
function labeled_statement() {
var label = as_symbol(AST_Label);
var label = as_symbol(AST.Label);
if (!all(S.labels, function(l) {
return l.name != label.name;
})) {
@ -1060,29 +995,29 @@ function parse($TEXT, options) {
S.labels.push(label);
var stat = statement();
S.labels.pop();
if (!(stat instanceof AST_IterationStatement)) {
if (!(stat instanceof AST.IterationStatement)) {
// check for `continue` that refers to this label.
// those should be reported as syntax errors.
// https://github.com/mishoo/UglifyJS2/issues/287
label.references.forEach(function(ref) {
if (ref instanceof AST_Continue) {
if (ref instanceof AST.Continue) {
ref = ref.label.start;
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
ref.line, ref.col, ref.pos);
}
});
}
return new AST_LabeledStatement({ body: stat, label: label });
return new AST.LabeledStatement({ body: stat, label: label });
}
function simple_statement(tmp) {
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
return new AST.SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
}
function break_cont(type) {
var label = null, ldef;
if (!can_insert_semicolon()) {
label = as_symbol(AST_LabelRef, true);
label = as_symbol(AST.LabelRef, true);
}
if (label != null) {
ldef = find_if(function(l) {
@ -1105,7 +1040,7 @@ function parse($TEXT, options) {
? (next(), var_(true))
: expression(true, true);
if (is("operator", "in")) {
if (init instanceof AST_Var) {
if (init instanceof AST.Var) {
if (init.definitions.length > 1)
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
} else if (!is_assignable(init)) {
@ -1124,7 +1059,7 @@ function parse($TEXT, options) {
expect(";");
var step = is("punc", ")") ? null : expression(true);
expect(")");
return new AST_For({
return new AST.For({
init : init,
condition : test,
step : step,
@ -1135,7 +1070,7 @@ function parse($TEXT, options) {
function for_in(init) {
var obj = expression(true);
expect(")");
return new AST_ForIn({
return new AST.ForIn({
init : init,
object : obj,
body : in_loop(statement)
@ -1143,17 +1078,17 @@ function parse($TEXT, options) {
}
var function_ = function(ctor) {
var in_statement = ctor === AST_Defun;
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
var in_statement = ctor === AST.Defun;
var name = is("name") ? as_symbol(in_statement ? AST.SymbolDefun : AST.SymbolLambda) : null;
if (in_statement && !name)
unexpected();
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
if (name && ctor !== AST.Accessor && !(name instanceof AST.SymbolDeclaration))
unexpected(prev());
expect("(");
var argnames = [];
for (var first = true; !is("punc", ")");) {
if (first) first = false; else expect(",");
argnames.push(as_symbol(AST_SymbolFunarg));
argnames.push(as_symbol(AST.SymbolFunarg));
}
next();
var loop = S.in_loop;
@ -1185,7 +1120,7 @@ function parse($TEXT, options) {
next();
belse = statement();
}
return new AST_If({
return new AST.If({
condition : cond,
body : body,
alternative : belse
@ -1211,7 +1146,7 @@ function parse($TEXT, options) {
if (is("keyword", "case")) {
if (branch) branch.end = prev();
cur = [];
branch = new AST_Case({
branch = new AST.Case({
start : (tmp = S.token, next(), tmp),
expression : expression(true),
body : cur
@ -1222,7 +1157,7 @@ function parse($TEXT, options) {
else if (is("keyword", "default")) {
if (branch) branch.end = prev();
cur = [];
branch = new AST_Default({
branch = new AST.Default({
start : (tmp = S.token, next(), expect(":"), tmp),
body : cur
});
@ -1244,9 +1179,9 @@ function parse($TEXT, options) {
var start = S.token;
next();
expect("(");
var name = as_symbol(AST_SymbolCatch);
var name = as_symbol(AST.SymbolCatch);
expect(")");
bcatch = new AST_Catch({
bcatch = new AST.Catch({
start : start,
argname : name,
body : block_(),
@ -1256,7 +1191,7 @@ function parse($TEXT, options) {
if (is("keyword", "finally")) {
var start = S.token;
next();
bfinally = new AST_Finally({
bfinally = new AST.Finally({
start : start,
body : block_(),
end : prev()
@ -1264,7 +1199,7 @@ function parse($TEXT, options) {
}
if (!bcatch && !bfinally)
croak("Missing catch/finally blocks");
return new AST_Try({
return new AST.Try({
body : body,
bcatch : bcatch,
bfinally : bfinally
@ -1274,9 +1209,9 @@ function parse($TEXT, options) {
function vardefs(no_in) {
var a = [];
for (;;) {
a.push(new AST_VarDef({
a.push(new AST.VarDef({
start : S.token,
name : as_symbol(AST_SymbolVar),
name : as_symbol(AST.SymbolVar),
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
end : prev()
}));
@ -1288,7 +1223,7 @@ function parse($TEXT, options) {
}
var var_ = function(no_in) {
return new AST_Var({
return new AST.Var({
start : prev(),
definitions : vardefs(no_in),
end : prev()
@ -1305,7 +1240,7 @@ function parse($TEXT, options) {
} else {
args = [];
}
var call = new AST_New({
var call = new AST.New({
start : start,
expression : newexp,
args : args,
@ -1319,13 +1254,13 @@ function parse($TEXT, options) {
var tok = S.token, ret;
switch (tok.type) {
case "name":
ret = _make_symbol(AST_SymbolRef);
ret = _make_symbol(AST.SymbolRef);
break;
case "num":
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
ret = new AST.Number({ start: tok, end: tok, value: tok.value });
break;
case "string":
ret = new AST_String({
ret = new AST.String({
start : tok,
end : tok,
value : tok.value,
@ -1333,18 +1268,18 @@ function parse($TEXT, options) {
});
break;
case "regexp":
ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
ret = new AST.RegExp({ start: tok, end: tok, value: tok.value });
break;
case "atom":
switch (tok.value) {
case "false":
ret = new AST_False({ start: tok, end: tok });
ret = new AST.False({ start: tok, end: tok });
break;
case "true":
ret = new AST_True({ start: tok, end: tok });
ret = new AST.True({ start: tok, end: tok });
break;
case "null":
ret = new AST_Null({ start: tok, end: tok });
ret = new AST.Null({ start: tok, end: tok });
break;
}
break;
@ -1382,7 +1317,7 @@ function parse($TEXT, options) {
[].push.apply(ex.end.comments_after, end.comments_after);
end.comments_after = ex.end.comments_after;
ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex);
if (ex instanceof AST.Call) mark_pure(ex);
return subscripts(ex, allow_calls);
case "[":
return subscripts(array_(), allow_calls);
@ -1393,7 +1328,7 @@ function parse($TEXT, options) {
}
if (is("keyword", "function")) {
next();
var func = function_(AST_Function);
var func = function_(AST.Function);
func.start = start;
func.end = prev();
return subscripts(func, allow_calls);
@ -1410,7 +1345,7 @@ function parse($TEXT, options) {
if (first) first = false; else expect(",");
if (allow_trailing_comma && is("punc", closing)) break;
if (is("punc", ",") && allow_empty) {
a.push(new AST_Hole({ start: S.token, end: S.token }));
a.push(new AST.Hole({ start: S.token, end: S.token }));
} else {
a.push(expression(false));
}
@ -1421,13 +1356,13 @@ function parse($TEXT, options) {
var array_ = embed_tokens(function() {
expect("[");
return new AST_Array({
return new AST.Array({
elements: expr_list("]", !options.strict, true)
});
});
var create_accessor = embed_tokens(function() {
return function_(AST_Accessor);
return function_(AST.Accessor);
});
var object_ = embed_tokens(function() {
@ -1442,13 +1377,13 @@ function parse($TEXT, options) {
var type = start.type;
var name = as_property_name();
if (type == "name" && !is("punc", ":")) {
var key = new AST_SymbolAccessor({
var key = new AST.SymbolAccessor({
start: S.token,
name: "" + as_property_name(),
end: prev()
});
if (name == "get") {
a.push(new AST_ObjectGetter({
a.push(new AST.ObjectGetter({
start : start,
key : key,
value : create_accessor(),
@ -1457,7 +1392,7 @@ function parse($TEXT, options) {
continue;
}
if (name == "set") {
a.push(new AST_ObjectSetter({
a.push(new AST.ObjectSetter({
start : start,
key : key,
value : create_accessor(),
@ -1467,7 +1402,7 @@ function parse($TEXT, options) {
}
}
expect(":");
a.push(new AST_ObjectKeyVal({
a.push(new AST.ObjectKeyVal({
start : start,
quote : start.quote,
key : "" + name,
@ -1476,7 +1411,7 @@ function parse($TEXT, options) {
}));
}
next();
return new AST_Object({ properties: a });
return new AST.Object({ properties: a });
});
function as_property_name() {
@ -1505,7 +1440,7 @@ function parse($TEXT, options) {
function _make_symbol(type) {
var name = S.token.value;
return new (name == "this" ? AST_This : type)({
return new (name == "this" ? AST.This : type)({
name : String(name),
start : S.token,
end : S.token
@ -1523,7 +1458,7 @@ function parse($TEXT, options) {
return null;
}
var sym = _make_symbol(type);
if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) {
if (S.input.has_directive("use strict") && sym instanceof AST.SymbolDeclaration) {
strict_verify_symbol(sym);
}
next();
@ -1547,7 +1482,7 @@ function parse($TEXT, options) {
var start = expr.start;
if (is("punc", ".")) {
next();
return subscripts(new AST_Dot({
return subscripts(new AST.Dot({
start : start,
expression : expr,
property : as_name(),
@ -1558,7 +1493,7 @@ function parse($TEXT, options) {
next();
var prop = expression(true);
expect("]");
return subscripts(new AST_Sub({
return subscripts(new AST.Sub({
start : start,
expression : expr,
property : prop,
@ -1567,7 +1502,7 @@ function parse($TEXT, options) {
}
if (allow_calls && is("punc", "(")) {
next();
var call = new AST_Call({
var call = new AST.Call({
start : start,
expression : expr,
args : expr_list(")"),
@ -1584,14 +1519,14 @@ function parse($TEXT, options) {
if (is("operator") && UNARY_PREFIX[start.value]) {
next();
handle_regexp();
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
var ex = make_unary(AST.UnaryPrefix, start, maybe_unary(allow_calls));
ex.start = start;
ex.end = prev();
return ex;
}
var val = expr_atom(allow_calls);
while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
val = make_unary(AST_UnaryPostfix, S.token, val);
val = make_unary(AST.UnaryPostfix, S.token, val);
val.start = start;
val.end = S.token;
next();
@ -1608,7 +1543,7 @@ function parse($TEXT, options) {
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
break;
case "delete":
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
if (expr instanceof AST.SymbolRef && S.input.has_directive("use strict"))
croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
break;
}
@ -1622,7 +1557,7 @@ function parse($TEXT, options) {
if (prec != null && prec > min_prec) {
next();
var right = expr_op(maybe_unary(true), prec, no_in);
return expr_op(new AST_Binary({
return expr_op(new AST.Binary({
start : left.start,
left : left,
operator : op,
@ -1644,7 +1579,7 @@ function parse($TEXT, options) {
next();
var yes = expression(false);
expect(":");
return new AST_Conditional({
return new AST.Conditional({
start : start,
condition : expr,
consequent : yes,
@ -1656,7 +1591,7 @@ function parse($TEXT, options) {
};
function is_assignable(expr) {
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
return expr instanceof AST.PropAccess || expr instanceof AST.SymbolRef;
}
var maybe_assign = function(no_in) {
@ -1665,7 +1600,7 @@ function parse($TEXT, options) {
if (is("operator") && ASSIGNMENT[val]) {
if (is_assignable(left)) {
next();
return new AST_Assign({
return new AST.Assign({
start : start,
left : left,
operator : val,
@ -1687,7 +1622,7 @@ function parse($TEXT, options) {
next();
commas = true;
}
return exprs.length == 1 ? exprs[0] : new AST_Sequence({
return exprs.length == 1 ? exprs[0] : new AST.Sequence({
start : start,
expressions : exprs,
end : peek()
@ -1718,7 +1653,7 @@ function parse($TEXT, options) {
toplevel.body = toplevel.body.concat(body);
toplevel.end = end;
} else {
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
toplevel = new AST.Toplevel({ start: start, body: body, end: end });
}
return toplevel;
}();

View File

@ -52,17 +52,9 @@ var merge = utils.merge;
var scope = require("./scope");
var base54 = scope.base54;
var ast = require("./ast");
var TreeWalker = ast.TreeWalker;
var TreeTransformer = ast.TreeTransformer;
var AST_Call = ast.AST_Call;
var AST_Sequence = ast.AST_Sequence;
var AST_Dot = ast.AST_Dot;
var AST_Sub = ast.AST_Sub;
var AST_Conditional = ast.AST_Conditional;
var AST_ObjectProperty = ast.AST_ObjectProperty;
var AST_ObjectKeyVal = ast.AST_ObjectKeyVal;
var AST_String = ast.AST_String;
var AST = require("./ast");
var TreeWalker = AST.TreeWalker;
var TreeTransformer = AST.TreeTransformer;
function find_builtins(reserved) {
// NaN will be included due to Number.NaN
@ -94,9 +86,9 @@ function reserve_quoted_keys(ast, reserved) {
}
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectKeyVal && node.quote) {
if (node instanceof AST.ObjectKeyVal && node.quote) {
add(node.key);
} else if (node instanceof AST_Sub) {
} else if (node instanceof AST.Sub) {
addStrings(node.property, add);
}
}));
@ -104,11 +96,11 @@ function reserve_quoted_keys(ast, reserved) {
function addStrings(node, add) {
node.walk(new TreeWalker(function(node) {
if (node instanceof AST_Sequence) {
if (node instanceof AST.Sequence) {
addStrings(node.tail_node(), add);
} else if (node instanceof AST_String) {
} else if (node instanceof AST.String) {
add(node.value);
} else if (node instanceof AST_Conditional) {
} else if (node instanceof AST.Conditional) {
addStrings(node.consequent, add);
addStrings(node.alternative, add);
}
@ -158,20 +150,20 @@ function mangle_properties(ast, options) {
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectKeyVal) {
if (node instanceof AST.ObjectKeyVal) {
add(node.key);
}
else if (node instanceof AST_ObjectProperty) {
else if (node instanceof AST.ObjectProperty) {
// setter or getter, since KeyVal is handled above
add(node.key.name);
}
else if (node instanceof AST_Dot) {
else if (node instanceof AST.Dot) {
add(node.property);
}
else if (node instanceof AST_Sub) {
else if (node instanceof AST.Sub) {
addStrings(node.property, add);
}
else if (node instanceof AST_Call
else if (node instanceof AST.Call
&& node.expression.print_to_string() == "Object.defineProperty") {
addStrings(node.args[1], add);
}
@ -179,20 +171,20 @@ function mangle_properties(ast, options) {
// step 2: transform the tree, renaming properties
return ast.transform(new TreeTransformer(function(node) {
if (node instanceof AST_ObjectKeyVal) {
if (node instanceof AST.ObjectKeyVal) {
node.key = mangle(node.key);
}
else if (node instanceof AST_ObjectProperty) {
else if (node instanceof AST.ObjectProperty) {
// setter or getter
node.key.name = mangle(node.key.name);
}
else if (node instanceof AST_Dot) {
else if (node instanceof AST.Dot) {
node.property = mangle(node.property);
}
else if (!options.keep_quoted && node instanceof AST_Sub) {
else if (!options.keep_quoted && node instanceof AST.Sub) {
node.property = mangleStrings(node.property);
}
else if (node instanceof AST_Call
else if (node instanceof AST.Call
&& node.expression.print_to_string() == "Object.defineProperty") {
node.args[1] = mangleStrings(node.args[1]);
}
@ -256,14 +248,14 @@ function mangle_properties(ast, options) {
function mangleStrings(node) {
return node.transform(new TreeTransformer(function(node) {
if (node instanceof AST_Sequence) {
if (node instanceof AST.Sequence) {
var last = node.expressions.length - 1;
node.expressions[last] = mangleStrings(node.expressions[last]);
}
else if (node instanceof AST_String) {
else if (node instanceof AST.String) {
node.value = mangle(node.value);
}
else if (node instanceof AST_Conditional) {
else if (node instanceof AST.Conditional) {
node.consequent = mangleStrings(node.consequent);
node.alternative = mangleStrings(node.alternative);
}

View File

@ -52,32 +52,8 @@ var makePredicate = utils.makePredicate;
var Dictionary = utils.Dictionary;
var merge = utils.merge;
var ast = require("./ast");
var TreeWalker = ast.TreeWalker;
var AST_Node = ast.AST_Node;
var AST_LabeledStatement = ast.AST_LabeledStatement;
var AST_With = ast.AST_With;
var AST_Scope = ast.AST_Scope;
var AST_Toplevel = ast.AST_Toplevel;
var AST_Lambda = ast.AST_Lambda;
var AST_Function = ast.AST_Function;
var AST_Defun = ast.AST_Defun;
var AST_LoopControl = ast.AST_LoopControl;
var AST_Catch = ast.AST_Catch;
var AST_Call = ast.AST_Call;
var AST_Sequence = ast.AST_Sequence;
var AST_Dot = ast.AST_Dot;
var AST_Sub = ast.AST_Sub;
var AST_Conditional = ast.AST_Conditional;
var AST_Symbol = ast.AST_Symbol;
var AST_SymbolVar = ast.AST_SymbolVar;
var AST_SymbolFunarg = ast.AST_SymbolFunarg;
var AST_SymbolDefun = ast.AST_SymbolDefun;
var AST_SymbolLambda = ast.AST_SymbolLambda;
var AST_SymbolCatch = ast.AST_SymbolCatch;
var AST_Label = ast.AST_Label;
var AST_SymbolRef = ast.AST_SymbolRef;
var AST_String = ast.AST_String;
var AST = require("./ast");
var TreeWalker = AST.TreeWalker;
var parse = require("./parse");
var is_identifier = parse.is_identifier;
@ -107,8 +83,8 @@ SymbolDef.prototype = {
|| this.undeclared
|| !options.eval && this.scope.pinned()
|| options.keep_fnames
&& (this.orig[0] instanceof AST_SymbolLambda
|| this.orig[0] instanceof AST_SymbolDefun);
&& (this.orig[0] instanceof AST.SymbolLambda
|| this.orig[0] instanceof AST.SymbolDefun);
},
mangle: function(options) {
var cache = options.cache && options.cache.props;
@ -131,7 +107,7 @@ SymbolDef.prototype = {
}
};
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
AST.Toplevel.DEFMETHOD("figure_out_scope", function(options) {
options = defaults(options, {
cache: null,
ie8: false,
@ -142,15 +118,15 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
var scope = self.parent_scope = null;
var defun = null;
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_Catch) {
if (node instanceof AST.Catch) {
var save_scope = scope;
scope = new AST_Scope(node);
scope = new AST.Scope(node);
scope.init_scope_vars(save_scope);
descend();
scope = save_scope;
return true;
}
if (node instanceof AST_Scope) {
if (node instanceof AST.Scope) {
node.init_scope_vars(scope);
var save_scope = scope;
var save_defun = defun;
@ -160,30 +136,30 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
defun = save_defun;
return true; // don't descend again in TreeWalker
}
if (node instanceof AST_With) {
if (node instanceof AST.With) {
for (var s = scope; s; s = s.parent_scope)
s.uses_with = true;
return;
}
if (node instanceof AST_Symbol) {
if (node instanceof AST.Symbol) {
node.scope = scope;
}
if (node instanceof AST_Label) {
if (node instanceof AST.Label) {
node.thedef = node;
node.references = [];
}
if (node instanceof AST_SymbolLambda) {
if (node instanceof AST.SymbolLambda) {
defun.def_function(node, node.name == "arguments" ? undefined : defun);
}
else if (node instanceof AST_SymbolDefun) {
else if (node instanceof AST.SymbolDefun) {
// Careful here, the scope where this should be defined is
// the parent scope. The reason is that we enter a new
// scope when we encounter the AST_Defun node (which is
// instanceof AST_Scope) but we get to the symbol a bit
// scope when we encounter the AST.Defun node (which is
// instanceof AST.Scope) but we get to the symbol a bit
// later.
(node.scope = defun.parent_scope).def_function(node, defun);
}
else if (node instanceof AST_SymbolVar) {
else if (node instanceof AST.SymbolVar) {
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
if (defun !== scope) {
node.mark_enclosed(options);
@ -194,7 +170,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
node.reference(options);
}
}
else if (node instanceof AST_SymbolCatch) {
else if (node instanceof AST.SymbolCatch) {
scope.def_variable(node).defun = defun;
}
});
@ -203,13 +179,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 2: find back references and eval
self.globals = new Dictionary();
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_LoopControl && node.label) {
if (node instanceof AST.LoopControl && node.label) {
node.label.thedef.references.push(node);
return true;
}
if (node instanceof AST_SymbolRef) {
if (node instanceof AST.SymbolRef) {
var name = node.name;
if (name == "eval" && tw.parent() instanceof AST_Call) {
if (name == "eval" && tw.parent() instanceof AST.Call) {
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
s.uses_eval = true;
}
@ -217,7 +193,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
var sym = node.scope.find_variable(name);
if (!sym) {
sym = self.def_global(node);
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
} else if (sym.scope instanceof AST.Lambda && name == "arguments") {
sym.scope.uses_arguments = true;
}
node.thedef = sym;
@ -226,7 +202,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
// ensure mangling works if catch reuses a scope variable
var def;
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
if (node instanceof AST.SymbolCatch && (def = node.definition().redefined())) {
var s = node.scope;
while (s) {
push_uniq(s.enclosed, def);
@ -240,7 +216,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 3: fix up any scoping issue with IE8
if (options.ie8) {
self.walk(new TreeWalker(function(node, descend) {
if (node instanceof AST_SymbolCatch) {
if (node instanceof AST.SymbolCatch) {
var name = node.name;
var refs = node.thedef.references;
var scope = node.thedef.defun;
@ -257,7 +233,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
});
AST_Toplevel.DEFMETHOD("def_global", function(node) {
AST.Toplevel.DEFMETHOD("def_global", function(node) {
var globals = this.globals, name = node.name;
if (globals.has(name)) {
return globals.get(name);
@ -270,9 +246,9 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
}
});
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
AST.Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
this.variables = new Dictionary(); // map name to AST.SymbolVar (variables defined in this scope; includes functions)
this.functions = new Dictionary(); // map name to AST.SymbolDefun (functions defined in this scope)
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
this.parent_scope = parent_scope; // the parent scope
@ -280,17 +256,17 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
this.cname = -1; // the current index for mangling functions/variables
});
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
AST.Lambda.DEFMETHOD("init_scope_vars", function() {
AST.Scope.prototype.init_scope_vars.apply(this, arguments);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
this.def_variable(new AST.SymbolFunarg({
name: "arguments",
start: this.start,
end: this.end
}));
});
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
AST.Symbol.DEFMETHOD("mark_enclosed", function(options) {
var def = this.definition();
var s = this.scope;
while (s) {
@ -305,29 +281,29 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
}
});
AST_Symbol.DEFMETHOD("reference", function(options) {
AST.Symbol.DEFMETHOD("reference", function(options) {
this.definition().references.push(this);
this.mark_enclosed(options);
});
AST_Scope.DEFMETHOD("find_variable", function(name) {
if (name instanceof AST_Symbol) name = name.name;
AST.Scope.DEFMETHOD("find_variable", function(name) {
if (name instanceof AST.Symbol) name = name.name;
return this.variables.get(name)
|| (this.parent_scope && this.parent_scope.find_variable(name));
});
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
AST.Scope.DEFMETHOD("def_function", function(symbol, init) {
var def = this.def_variable(symbol, init);
if (!def.init || def.init instanceof AST_Defun) def.init = init;
if (!def.init || def.init instanceof AST.Defun) def.init = init;
this.functions.set(symbol.name, def);
return def;
});
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
AST.Scope.DEFMETHOD("def_variable", function(symbol, init) {
var def = this.variables.get(symbol.name);
if (def) {
def.orig.push(symbol);
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST.Function)) {
def.init = init;
}
} else {
@ -357,7 +333,7 @@ function next_mangled_name(scope, options, def) {
// #179, #326
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
// a function expression's argument cannot shadow the function expression's name
if (scope instanceof AST_Function && scope.name && def.orig[0] instanceof AST_SymbolFunarg) {
if (scope instanceof AST.Function && scope.name && def.orig[0] instanceof AST.SymbolFunarg) {
var tricky_def = scope.name.definition();
// the function's mangled_name is null when keep_fnames is true
names[tricky_def.mangled_name || tricky_def.name] = true;
@ -389,29 +365,29 @@ function next_mangled_name(scope, options, def) {
holes.push(scope.cname);
}
scope.names_in_use[name] = true;
if (options.ie8 && def.orig[0] instanceof AST_SymbolLambda) {
if (options.ie8 && def.orig[0] instanceof AST.SymbolLambda) {
names_in_use(scope.parent_scope, options)[name] = true;
}
return name;
}
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
AST.Symbol.DEFMETHOD("unmangleable", function(options) {
var def = this.definition();
return !def || def.unmangleable(options);
});
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", return_false);
AST.Label.DEFMETHOD("unmangleable", return_false);
AST_Symbol.DEFMETHOD("unreferenced", function() {
AST.Symbol.DEFMETHOD("unreferenced", function() {
return !this.definition().references.length && !this.scope.pinned();
});
AST_Symbol.DEFMETHOD("definition", function() {
AST.Symbol.DEFMETHOD("definition", function() {
return this.thedef;
});
AST_Symbol.DEFMETHOD("global", function() {
AST.Symbol.DEFMETHOD("global", function() {
return this.definition().global;
});
@ -430,13 +406,13 @@ function _default_mangler_options(options) {
return options;
}
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
AST.Toplevel.DEFMETHOD("mangle_names", function(options) {
options = _default_mangler_options(options);
// We only need to mangle declaration nodes. Special logic wired
// into the code generator will display the mangled name if it's
// present (and for AST_SymbolRef-s it'll use the mangled name of
// the AST_SymbolDeclaration that it points to).
// present (and for AST.SymbolRef-s it'll use the mangled name of
// the AST.SymbolDeclaration that it points to).
var lname = -1;
if (options.cache && options.cache.props) {
@ -448,28 +424,28 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
var redefined = [];
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_LabeledStatement) {
// lname is incremented when we get to the AST_Label
if (node instanceof AST.LabeledStatement) {
// lname is incremented when we get to the AST.Label
var save_nesting = lname;
descend();
lname = save_nesting;
return true; // don't descend again in TreeWalker
}
if (node instanceof AST_Scope) {
if (node instanceof AST.Scope) {
descend();
if (options.cache && node instanceof AST_Toplevel) {
if (options.cache && node instanceof AST.Toplevel) {
node.globals.each(mangle);
}
node.variables.each(mangle);
return true;
}
if (node instanceof AST_Label) {
if (node instanceof AST.Label) {
var name;
do name = base54(++lname); while (!is_identifier(name));
node.mangled_name = name;
return true;
}
if (!options.ie8 && node instanceof AST_Catch) {
if (!options.ie8 && node instanceof AST.Catch) {
var def = node.argname.definition();
var redef = def.redefined();
if (redef) {
@ -497,14 +473,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
}
});
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
AST.Toplevel.DEFMETHOD("find_colliding_names", function(options) {
var cache = options.cache && options.cache.props;
var avoid = Object.create(null);
options.reserved.forEach(to_avoid);
this.globals.each(add_def);
this.walk(new TreeWalker(function(node) {
if (node instanceof AST_Scope) node.variables.each(add_def);
if (node instanceof AST_SymbolCatch) add_def(node.definition());
if (node instanceof AST.Scope) node.variables.each(add_def);
if (node instanceof AST.SymbolCatch) add_def(node.definition());
}));
return avoid;
@ -520,7 +496,7 @@ AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
}
});
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
AST.Toplevel.DEFMETHOD("expand_names", function(options) {
base54.reset();
base54.sort();
options = _default_mangler_options(options);
@ -528,8 +504,8 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
var cname = 0;
this.globals.each(rename);
this.walk(new TreeWalker(function(node) {
if (node instanceof AST_Scope) node.variables.each(rename);
if (node instanceof AST_SymbolCatch) rename(node.definition());
if (node instanceof AST.Scope) node.variables.each(rename);
if (node instanceof AST.SymbolCatch) rename(node.definition());
}));
function next_name() {
@ -555,40 +531,40 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
}
});
AST_Node.DEFMETHOD("tail_node", return_this);
AST_Sequence.DEFMETHOD("tail_node", function() {
AST.Node.DEFMETHOD("tail_node", return_this);
AST.Sequence.DEFMETHOD("tail_node", function() {
return this.expressions[this.expressions.length - 1];
});
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
AST.Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
options = _default_mangler_options(options);
base54.reset();
try {
AST_Node.prototype.print = function(stream, force_parens) {
AST.Node.prototype.print = function(stream, force_parens) {
this._print(stream, force_parens);
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
if (this instanceof AST.Symbol && !this.unmangleable(options)) {
base54.consider(this.name, -1);
} else if (options.properties) {
if (this instanceof AST_Dot) {
if (this instanceof AST.Dot) {
base54.consider(this.property, -1);
} else if (this instanceof AST_Sub) {
} else if (this instanceof AST.Sub) {
skip_string(this.property);
}
}
};
base54.consider(this.print_to_string(), 1);
} finally {
AST_Node.prototype.print = AST_Node.prototype._print;
AST.Node.prototype.print = AST.Node.prototype._print;
}
base54.sort();
function skip_string(node) {
if (node instanceof AST_String) {
if (node instanceof AST.String) {
base54.consider(node.value, -1);
} else if (node instanceof AST_Conditional) {
} else if (node instanceof AST.Conditional) {
skip_string(node.consequent);
skip_string(node.alternative);
} else if (node instanceof AST_Sequence) {
} else if (node instanceof AST.Sequence) {
skip_string(node.tail_node());
}
}

View File

@ -594,7 +594,7 @@ describe("bin/uglifyjs", function() {
exec(command, function(err, stdout) {
if (err) throw err;
var ast = JSON.parse(stdout);
assert.strictEqual(ast._class, "AST_Toplevel");
assert.strictEqual(ast._class, "AST.Toplevel");
assert.ok(Array.isArray(ast.body));
done();
});

View File

@ -10,7 +10,7 @@ describe("spidermonkey export/import sanity test", function() {
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
uglifyjs + " -p spidermonkey -cm";
exec(command, function(err, stdout) {
exec(command, {maxBuffer: 1024 * 300}, function(err, stdout) {
if (err) throw err;
eval(stdout);

View File

@ -1,6 +1,4 @@
var orig = require("../tools/node");
// Get all AST-nodes
orig.utils.merge(orig, orig.ast);
orig.SourceMap = require("../lib/sourcemap").SourceMap;
orig.base54 = orig.utils.base54;
orig.defaults = orig.utils.defaults;

View File

@ -38,9 +38,11 @@ UglifyJS.FILES.forEach(function(filepath){
if (exportNames.length == 0)
return;
// Use (utils.)merge instead of Object.assign for (very) old node
var exports = "merge(exports, {\n" + exportNames.map(function(name){
return UglifyJS.string_template(' {name} : {name},', { name: name });
}).join("\n") + "\n});";
var exports = "merge(exports, {\n" + exportNames.map(
name => UglifyJS.string_template(' {name} : {name},', { name: name })
).concat(exportNames.filter(name => name.indexOf("AST_") == 0).map(
name => UglifyJS.string_template(' {expName} : {name},', { expName: name.substr(4), name: name })
)).join("\n") + "\n});";
var imports = exportNames.map(function(name){
return UglifyJS.string_template(UglifyJS.string_template('var {name} = {fn}.{name};', { name: name, fn: filename}));
});

View File

@ -17,22 +17,11 @@ var FILES = UglifyJS.FILES = [
return require.resolve(file);
});
/*new Function("MOZ_SourceMap", "exports", function() {
var code = FILES.map(function(file) {
return fs.readFileSync(file, "utf8");
});
code.push("exports.describe_ast = " + describe_ast.toString());
return code.join("\n\n");
}())(
require("source-map"),
UglifyJS
);*/
var utils = require("../lib/utils");
var output = require("../lib/output");
var OutputStream = output.OutputStream;
var minify = require("../lib/minify").minify;
var ast = require("../lib/ast");
var AST = require("../lib/ast");
var compress = require("../lib/compress");
var parse = require("../lib/parse");
var propmangle = require("../lib/propmangle");
@ -42,22 +31,28 @@ require("../lib/mozilla-ast");
exports.utils = utils;
exports.OutputStream = OutputStream;
exports.minify = minify;
exports.ast = ast;
exports.AST = AST;
exports.parser = parse;
exports.parse = parse.parse;
exports.Compressor = compress.Compressor;
exports.Dictionary = utils.Dictionary;
exports.TreeWalker = ast.TreeWalker;
exports.TreeTransformer = ast.TreeTransformer;
exports.TreeWalker = AST.TreeWalker;
exports.TreeTransformer = AST.TreeTransformer;
exports.push_uniq = utils.push_uniq;
exports.string_template = utils.string_template;
exports.describe_ast = describe_ast;
exports.propmangle = propmangle;
// Backwards compatibility: Add all AST_
for (var name in AST) if (utils.HOP(AST, name)) {
if (name.indexOf("AST_") == 0)
exports[name] = AST[name];
}
function describe_ast() {
var out = OutputStream({ beautify: true });
function doitem(ctor) {
out.print("AST_" + ctor.TYPE);
out.print("AST." + ctor.TYPE);
var props = ctor.SELF_PROPS.filter(function(prop) {
return !/^\$/.test(prop);
});
@ -85,7 +80,7 @@ function describe_ast() {
});
}
};
doitem(AST_Node);
doitem(AST.Node);
return out + "\n";
}