From 1ce651ee147cde15ce2921d3a3b13e3abb25bc1f Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 9 Jun 2018 19:40:40 +0200 Subject: [PATCH] Use standard require --- README.md | 2 +- bin/uglifyjs | 31 ++-- lib/ast.js | 298 ++++++++++++++++++++++++++++++++++---- lib/compress.js | 113 +++++++++++++++ lib/minify.js | 69 ++++++++- lib/mozilla-ast.js | 80 +++++++++- lib/output.js | 90 +++++++++++- lib/parse.js | 117 +++++++++++++++ lib/propmangle.js | 28 ++++ lib/scope.js | 47 ++++++ lib/sourcemap.js | 9 ++ lib/transform.js | 185 ----------------------- lib/utils.js | 47 +++--- test/exports.js | 14 -- test/mocha.js | 1 + test/mocha/cli.js | 2 +- test/node.js | 18 ++- tools/exports.js | 2 + tools/generate-exports.js | 59 ++++++++ tools/node.js | 31 +++- 20 files changed, 967 insertions(+), 276 deletions(-) delete mode 100644 lib/transform.js delete mode 100644 test/exports.js create mode 100644 tools/generate-exports.js diff --git a/README.md b/README.md index 663ce7b4..e2b11fb8 100644 --- a/README.md +++ b/README.md @@ -1047,7 +1047,7 @@ var result = UglifyJS.minify(ast, { Transversal and transformation of the native AST can be performed through [`TreeWalker`](https://github.com/mishoo/UglifyJS2/blob/master/lib/ast.js) and -[`TreeTransformer`](https://github.com/mishoo/UglifyJS2/blob/master/lib/transform.js) +[`TreeTransformer`](https://github.com/mishoo/UglifyJS2/blob/master/lib/ast.js) respectively. ### ESTree / SpiderMonkey AST diff --git a/bin/uglifyjs b/bin/uglifyjs index fb6ae2fb..242eb70b 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -100,7 +100,7 @@ if (program.mangleProps) { if (typeof program.mangleProps != "object") program.mangleProps = {}; if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = []; require("../tools/domprops").forEach(function(name) { - UglifyJS._push_uniq(program.mangleProps.reserved, name); + UglifyJS.push_uniq(program.mangleProps.reserved, name); }); } if (typeof options.mangle != "object") options.mangle = {}; @@ -144,12 +144,23 @@ if (program.verbose) { } else if (program.warn) { options.warnings = true; } +function getVarNameFromPath(filename) { + var name = /((\w|-)+)(\.js)?$/.exec(filename)[1].replace("-", "_"); + return "__" + name + "_exports"; +} if (program.self) { if (program.args.length) { print_error("WARN: Ignoring input files since --self was passed"); } if (!options.wrap) options.wrap = "UglifyJS"; + files["__require_emulation"] = "var __origExports = exports;" + getVarNameFromPath + "function require(filename){return require[getVarNameFromPath(filename)];}"; simple_glob(UglifyJS.FILES).forEach(function(name) { + var exportCode; + if (/exports\.js$/.test(name)) + exportCode = "var exports = __origExports"; + else + exportCode = "var exports = require['" + getVarNameFromPath(name) + "'] = {};"; + files["_" + name + "_exports"] = exportCode; files[convert_path(name)] = read_file(name); }); run(); @@ -171,11 +182,11 @@ if (program.self) { } function convert_ast(fn) { - return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null)); + return UglifyJS.ast.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null)); } function run() { - UglifyJS.AST_Node.warn_function = function(msg) { + UglifyJS.ast.AST_Node.warn_function = function(msg) { print_error("WARN: " + msg); }; var content = program.sourceMap && program.sourceMap.content; @@ -249,9 +260,9 @@ function run() { return value.size() ? value.map(symdef) : undefined; } if (skip_key(key)) return; - if (value instanceof UglifyJS.AST_Token) return; + if (value instanceof UglifyJS.ast.AST_Token) return; if (value instanceof UglifyJS.Dictionary) return; - if (value instanceof UglifyJS.AST_Node) { + if (value instanceof UglifyJS.ast.AST_Node) { var result = { _class: "AST_" + value.TYPE }; @@ -348,27 +359,27 @@ function parse_js(flag) { code: false } }).ast.walk(new UglifyJS.TreeWalker(function(node) { - if (node instanceof UglifyJS.AST_Assign) { + if (node instanceof UglifyJS.ast.AST_Assign) { var name = node.left.print_to_string(); var value = node.right; if (flag) { options[name] = value; - } else if (value instanceof UglifyJS.AST_Array) { + } else if (value instanceof UglifyJS.ast.AST_Array) { options[name] = value.elements.map(to_string); } else { options[name] = to_string(value); } return true; } - if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) { + if (node instanceof UglifyJS.ast.AST_Symbol || node instanceof UglifyJS.ast.AST_PropAccess) { var name = node.print_to_string(); options[name] = true; return true; } - if (!(node instanceof UglifyJS.AST_Sequence)) throw node; + if (!(node instanceof UglifyJS.ast.AST_Sequence)) throw node; function to_string(value) { - return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({ + return value instanceof UglifyJS.ast.AST_Constant ? value.getValue() : value.print_to_string({ quote_keys: true }); } diff --git a/lib/ast.js b/lib/ast.js index c37ba598..37b1c2ba 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -43,6 +43,13 @@ "use strict"; +var utils = require("./utils"); +var noop = utils.noop; +var string_template = utils.string_template; +var HOP = utils.HOP; +var MAP = utils.MAP; +var merge = utils.merge; + function DEFNODE(type, props, methods, base) { if (typeof base === "undefined") base = AST_Node; props = props ? props.split(/\s+/) : []; @@ -323,34 +330,6 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", { $documentation: "The toplevel scope", $propdoc: { globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", - }, - wrap_commonjs: function(name) { - var body = this.body; - 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") { - return MAP.splice(body); - } - })); - return wrapped_tl; - }, - wrap_enclose: function(args_values) { - if (typeof args_values != "string") args_values = ""; - var index = args_values.indexOf(":"); - if (index < 0) index = args_values.length; - var body = this.body; - return parse([ - "(function(", - args_values.slice(0, index), - '){"$ORIG"})(', - args_values.slice(index + 1), - ")" - ].join("")).transform(new TreeTransformer(function(node) { - if (node instanceof AST_Directive && node.value == "$ORIG") { - return MAP.splice(body); - } - })); } }, AST_Scope); @@ -952,3 +931,266 @@ TreeWalker.prototype = { } } }; + +function TreeTransformer(before, after) { + TreeWalker.call(this); + this.before = before; + this.after = after; +} +TreeTransformer.prototype = new TreeWalker; + +(function(DEF) { + function do_list(list, tw) { + return MAP(list, function(node) { + return node.transform(tw, true); + }); + } + + DEF(AST_Node, noop); + DEF(AST_LabeledStatement, function(self, tw) { + self.label = self.label.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_SimpleStatement, function(self, tw) { + self.body = self.body.transform(tw); + }); + DEF(AST_Block, function(self, tw) { + self.body = do_list(self.body, tw); + }); + DEF(AST_Do, function(self, tw) { + self.body = self.body.transform(tw); + self.condition = self.condition.transform(tw); + }); + DEF(AST_While, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_For, function(self, tw) { + if (self.init) self.init = self.init.transform(tw); + if (self.condition) self.condition = self.condition.transform(tw); + if (self.step) self.step = self.step.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_ForIn, function(self, tw) { + self.init = self.init.transform(tw); + self.object = self.object.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_With, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = self.body.transform(tw); + }); + DEF(AST_Exit, function(self, tw) { + if (self.value) self.value = self.value.transform(tw); + }); + DEF(AST_LoopControl, function(self, tw) { + if (self.label) self.label = self.label.transform(tw); + }); + DEF(AST_If, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + if (self.alternative) self.alternative = self.alternative.transform(tw); + }); + DEF(AST_Switch, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Case, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Try, function(self, tw) { + self.body = do_list(self.body, tw); + if (self.bcatch) self.bcatch = self.bcatch.transform(tw); + if (self.bfinally) self.bfinally = self.bfinally.transform(tw); + }); + DEF(AST_Catch, function(self, tw) { + self.argname = self.argname.transform(tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Definitions, function(self, tw) { + self.definitions = do_list(self.definitions, tw); + }); + DEF(AST_VarDef, function(self, tw) { + self.name = self.name.transform(tw); + if (self.value) self.value = self.value.transform(tw); + }); + DEF(AST_Lambda, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + self.argnames = do_list(self.argnames, tw); + self.body = do_list(self.body, tw); + }); + DEF(AST_Call, function(self, tw) { + self.expression = self.expression.transform(tw); + self.args = do_list(self.args, tw); + }); + DEF(AST_Sequence, function(self, tw) { + self.expressions = do_list(self.expressions, tw); + }); + DEF(AST_Dot, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Sub, function(self, tw) { + self.expression = self.expression.transform(tw); + self.property = self.property.transform(tw); + }); + DEF(AST_Unary, function(self, tw) { + self.expression = self.expression.transform(tw); + }); + DEF(AST_Binary, function(self, tw) { + self.left = self.left.transform(tw); + self.right = self.right.transform(tw); + }); + DEF(AST_Conditional, function(self, tw) { + self.condition = self.condition.transform(tw); + self.consequent = self.consequent.transform(tw); + self.alternative = self.alternative.transform(tw); + }); + DEF(AST_Array, function(self, tw) { + self.elements = do_list(self.elements, tw); + }); + DEF(AST_Object, function(self, tw) { + self.properties = do_list(self.properties, tw); + }); + DEF(AST_ObjectProperty, function(self, tw) { + self.value = self.value.transform(tw); + }); +})(function(node, descend) { + node.DEFMETHOD("transform", function(tw, in_list) { + var x, y; + tw.push(this); + if (tw.before) x = tw.before(this, descend, in_list); + if (typeof x === "undefined") { + x = this; + descend(x, tw); + if (tw.after) { + y = tw.after(x, in_list); + if (typeof y !== "undefined") x = y; + } + } + tw.pop(); + return x; + }); +}); + +/*********************************************************************** +/* Helpers +/**********************************************************************/ + +// return true if the node at the top of the stack (that means the +// innermost node in the current output) is lexically the first in +// a statement. +function first_in_statement(stack) { + var node = stack.parent(-1); + for (var i = 0, p; p = stack.parent(i++); node = p) { + if (p.TYPE == "Call") { + if (p.expression === node) continue; + } else if (p instanceof AST_Binary) { + if (p.left === node) continue; + } else if (p instanceof AST_Conditional) { + if (p.condition === node) continue; + } else if (p instanceof AST_PropAccess) { + if (p.expression === node) continue; + } else if (p instanceof AST_Sequence) { + if (p.expressions[0] === node) continue; + } else if (p instanceof AST_Statement) { + return p.body === node; + } else if (p instanceof AST_UnaryPostfix) { + if (p.expression === node) continue; + } + return false; + } +} + +merge(exports, { + DEFNODE : DEFNODE, + AST_Token : AST_Token, + AST_Node : AST_Node, + AST_Statement : AST_Statement, + AST_Debugger : AST_Debugger, + AST_Directive : AST_Directive, + AST_SimpleStatement : AST_SimpleStatement, + walk_body : walk_body, + AST_Block : AST_Block, + AST_BlockStatement : AST_BlockStatement, + AST_EmptyStatement : AST_EmptyStatement, + AST_StatementWithBody : AST_StatementWithBody, + AST_LabeledStatement : AST_LabeledStatement, + AST_IterationStatement : AST_IterationStatement, + AST_DWLoop : AST_DWLoop, + AST_Do : AST_Do, + AST_While : AST_While, + AST_For : AST_For, + AST_ForIn : AST_ForIn, + AST_With : AST_With, + AST_Scope : AST_Scope, + AST_Toplevel : AST_Toplevel, + AST_Lambda : AST_Lambda, + AST_Accessor : AST_Accessor, + AST_Function : AST_Function, + AST_Defun : AST_Defun, + AST_Jump : AST_Jump, + AST_Exit : AST_Exit, + AST_Return : AST_Return, + AST_Throw : AST_Throw, + AST_LoopControl : AST_LoopControl, + AST_Break : AST_Break, + AST_Continue : AST_Continue, + AST_If : AST_If, + AST_Switch : AST_Switch, + AST_SwitchBranch : AST_SwitchBranch, + AST_Default : AST_Default, + AST_Case : AST_Case, + AST_Try : AST_Try, + AST_Catch : AST_Catch, + AST_Finally : AST_Finally, + AST_Definitions : AST_Definitions, + AST_Var : AST_Var, + AST_VarDef : AST_VarDef, + AST_Call : AST_Call, + AST_New : AST_New, + AST_Sequence : AST_Sequence, + AST_PropAccess : AST_PropAccess, + AST_Dot : AST_Dot, + AST_Sub : AST_Sub, + AST_Unary : AST_Unary, + AST_UnaryPrefix : AST_UnaryPrefix, + AST_UnaryPostfix : AST_UnaryPostfix, + AST_Binary : AST_Binary, + AST_Conditional : AST_Conditional, + AST_Assign : AST_Assign, + AST_Array : AST_Array, + AST_Object : AST_Object, + AST_ObjectProperty : AST_ObjectProperty, + AST_ObjectKeyVal : AST_ObjectKeyVal, + AST_ObjectSetter : AST_ObjectSetter, + AST_ObjectGetter : AST_ObjectGetter, + AST_Symbol : AST_Symbol, + AST_SymbolAccessor : AST_SymbolAccessor, + AST_SymbolDeclaration : AST_SymbolDeclaration, + AST_SymbolVar : AST_SymbolVar, + AST_SymbolFunarg : AST_SymbolFunarg, + AST_SymbolDefun : AST_SymbolDefun, + AST_SymbolLambda : AST_SymbolLambda, + AST_SymbolCatch : AST_SymbolCatch, + AST_Label : AST_Label, + AST_SymbolRef : AST_SymbolRef, + AST_LabelRef : AST_LabelRef, + AST_This : AST_This, + AST_Constant : AST_Constant, + AST_String : AST_String, + AST_Number : AST_Number, + AST_RegExp : AST_RegExp, + AST_Atom : AST_Atom, + AST_Null : AST_Null, + AST_NaN : AST_NaN, + AST_Undefined : AST_Undefined, + AST_Hole : AST_Hole, + AST_Infinity : AST_Infinity, + AST_Boolean : AST_Boolean, + AST_False : AST_False, + AST_True : AST_True, + TreeWalker : TreeWalker, + TreeTransformer : TreeTransformer, + first_in_statement : first_in_statement, +}); diff --git a/lib/compress.js b/lib/compress.js index ad01e48c..e4e5e434 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -43,6 +43,115 @@ "use strict"; +var utils = require("./utils"); +var member = utils.member; +var defaults = utils.defaults; +var merge = utils.merge; +var noop = utils.noop; +var return_false = utils.return_false; +var return_true = utils.return_true; +var return_this = utils.return_this; +var return_null = utils.return_null; +var string_template = utils.string_template; +var remove = utils.remove; +var makePredicate = utils.makePredicate; +var all = utils.all; +var Dictionary = utils.Dictionary; +var HOP = utils.HOP; +var MAP = utils.MAP; + +var ast = require("./ast"); +var walk_body = ast.walk_body; +var TreeWalker = ast.TreeWalker; +var TreeTransformer = ast.TreeTransformer; +var first_in_statement = ast.first_in_statement; +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_IterationStatement = ast.AST_IterationStatement; +var AST_DWLoop = ast.AST_DWLoop; +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_Jump = ast.AST_Jump; +var AST_Exit = ast.AST_Exit; +var AST_Return = ast.AST_Return; +var AST_LoopControl = ast.AST_LoopControl; +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_Symbol = ast.AST_Symbol; +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_SymbolRef = ast.AST_SymbolRef; +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_Null = ast.AST_Null; +var AST_NaN = ast.AST_NaN; +var AST_Undefined = ast.AST_Undefined; +var AST_Hole = ast.AST_Hole; +var AST_Infinity = ast.AST_Infinity; +var AST_Boolean = ast.AST_Boolean; +var AST_False = ast.AST_False; +var AST_True = ast.AST_True; + +var parse = require("./parse"); +var is_identifier_string = parse.is_identifier_string; +var JS_Parse_Error = parse.JS_Parse_Error; +var PRECEDENCE = parse.PRECEDENCE; +var parse = parse.parse; + +var OutputStream = require("./output").OutputStream; + +require("./scope") + function Compressor(options, false_by_default) { if (!(this instanceof Compressor)) return new Compressor(options, false_by_default); @@ -6401,3 +6510,7 @@ merge(Compressor.prototype, { return opt; }); }); + +merge(exports, { + Compressor : Compressor, +}); diff --git a/lib/minify.js b/lib/minify.js index d84f6825..31d3bb1c 100644 --- a/lib/minify.js +++ b/lib/minify.js @@ -1,5 +1,30 @@ "use strict"; +var utils = require("./utils"); +var defaults = utils.defaults; +var Dictionary = utils.Dictionary; +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 parse = require("./parse"); +var parse = parse.parse; + +var OutputStream = require("./output").OutputStream; +var Compressor = require("./compress").Compressor; + +var SourceMap = require("./sourcemap").SourceMap; + +var propmangle = require("./propmangle"); +var reserve_quoted_keys = propmangle.reserve_quoted_keys; +var mangle_properties = propmangle.mangle_properties; + var to_ascii = typeof atob == "undefined" ? function(b64) { return new Buffer(b64, "base64").toString(); } : atob; @@ -51,6 +76,35 @@ function to_json(cache) { } function minify(files, options) { + function wrap_commonjs(toplevel_node, name) { + var body = toplevel_node.body; + 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") { + return MAP.splice(body); + } + })); + return wrapped_tl; + } + function wrap_enclose(toplevel_node, args_values) { + if (typeof args_values != "string") args_values = ""; + var index = args_values.indexOf(":"); + if (index < 0) index = args_values.length; + var body = toplevel_node.body; + return parse([ + "(function(", + args_values.slice(0, index), + '){"$ORIG"})(', + args_values.slice(index + 1), + ")" + ].join("")).transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(body); + } + })); + } + var warn_function = AST_Node.warn_function; try { options = defaults(options, { @@ -156,10 +210,10 @@ function minify(files, options) { reserve_quoted_keys(toplevel, quoted_props); } if (options.wrap) { - toplevel = toplevel.wrap_commonjs(options.wrap); + toplevel = wrap_commonjs(toplevel, options.wrap); } if (options.enclose) { - toplevel = toplevel.wrap_enclose(options.enclose); + toplevel = wrap_enclose(toplevel, options.enclose); } if (timings) timings.rename = Date.now(); if (options.rename) { @@ -244,3 +298,14 @@ function minify(files, options) { AST_Node.warn_function = warn_function; } } + +merge(exports, { + to_ascii : to_ascii, + to_base64 : to_base64, + read_source_map : read_source_map, + parse_source_map : parse_source_map, + set_shorthand : set_shorthand, + init_cache : init_cache, + to_json : to_json, + minify : minify, +}); diff --git a/lib/mozilla-ast.js b/lib/mozilla-ast.js index dace808a..1a464ee7 100644 --- a/lib/mozilla-ast.js +++ b/lib/mozilla-ast.js @@ -43,6 +43,84 @@ "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; + (function() { function normalize_directives(body) { var in_directive = true; @@ -540,7 +618,7 @@ //console.log(moz_to_me); moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")( - exports, 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 diff --git a/lib/output.js b/lib/output.js index 1dbc1f6e..19f78fbd 100644 --- a/lib/output.js +++ b/lib/output.js @@ -43,6 +43,88 @@ "use strict"; +var utils = require("./utils"); +var repeat_string = utils.repeat_string; +var defaults = utils.defaults; +var noop = utils.noop; +var return_false = utils.return_false; +var return_true = utils.return_true; +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 parse = require("./parse"); +var is_surrogate_pair_head = parse.is_surrogate_pair_head; +var is_surrogate_pair_tail = parse.is_surrogate_pair_tail; +var is_identifier_char = parse.is_identifier_char; +var is_identifier_string = parse.is_identifier_string; +var PRECEDENCE = parse.PRECEDENCE; +var RESERVED_WORDS = parse.RESERVED_WORDS; + var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/; function is_some_comments(comment) { @@ -1337,7 +1419,7 @@ function OutputStream(options) { output.print_string(key); } else if ("" + +key == key && key >= 0) { output.print(make_num(key)); - } else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) { + } else if (parse.RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) { if (quote && output.option("keep_quoted_props")) { output.print_string(key, quote); } else { @@ -1518,3 +1600,9 @@ function OutputStream(options) { output.add_mapping(this.start, this.key); }); })(); + +merge(exports, { + EXPECT_DIRECTIVE : EXPECT_DIRECTIVE, + is_some_comments : is_some_comments, + OutputStream : OutputStream, +}); diff --git a/lib/parse.js b/lib/parse.js index 29df370c..7f35352e 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -44,6 +44,83 @@ "use strict"; +var utils = require("./utils"); +var characters = utils.characters; +var find_if = utils.find_if; +var configure_error_stack = utils.configure_error_stack; +var defaults = utils.defaults; +var makePredicate = utils.makePredicate; +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 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'; var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield' @@ -1646,3 +1723,43 @@ function parse($TEXT, options) { return toplevel; }(); } + +merge(exports, { + KEYWORDS : KEYWORDS, + KEYWORDS_ATOM : KEYWORDS_ATOM, + RESERVED_WORDS : RESERVED_WORDS, + KEYWORDS_BEFORE_EXPRESSION : KEYWORDS_BEFORE_EXPRESSION, + OPERATOR_CHARS : OPERATOR_CHARS, + RE_HEX_NUMBER : RE_HEX_NUMBER, + RE_OCT_NUMBER : RE_OCT_NUMBER, + OPERATORS : OPERATORS, + WHITESPACE_CHARS : WHITESPACE_CHARS, + NEWLINE_CHARS : NEWLINE_CHARS, + PUNC_BEFORE_EXPRESSION : PUNC_BEFORE_EXPRESSION, + PUNC_CHARS : PUNC_CHARS, + UNICODE : UNICODE, + is_letter : is_letter, + is_surrogate_pair_head : is_surrogate_pair_head, + is_surrogate_pair_tail : is_surrogate_pair_tail, + is_digit : is_digit, + is_alphanumeric_char : is_alphanumeric_char, + is_unicode_digit : is_unicode_digit, + is_unicode_combining_mark : is_unicode_combining_mark, + is_unicode_connector_punctuation : is_unicode_connector_punctuation, + is_identifier : is_identifier, + is_identifier_start : is_identifier_start, + is_identifier_char : is_identifier_char, + is_identifier_string : is_identifier_string, + parse_js_number : parse_js_number, + JS_Parse_Error : JS_Parse_Error, + js_error : js_error, + is_token : is_token, + EX_EOF : EX_EOF, + tokenizer : tokenizer, + UNARY_PREFIX : UNARY_PREFIX, + UNARY_POSTFIX : UNARY_POSTFIX, + ASSIGNMENT : ASSIGNMENT, + PRECEDENCE : PRECEDENCE, + ATOMIC_START_TOKEN : ATOMIC_START_TOKEN, + parse : parse, +}); diff --git a/lib/propmangle.js b/lib/propmangle.js index 7ad4804d..d7bb135f 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -43,6 +43,27 @@ "use strict"; +var utils = require("./utils"); +var defaults = utils.defaults; +var push_uniq = utils.push_uniq; +var Dictionary = utils.Dictionary; +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; + function find_builtins(reserved) { // NaN will be included due to Number.NaN [ @@ -250,3 +271,10 @@ function mangle_properties(ast, options) { })); } } + +merge(exports, { + find_builtins : find_builtins, + reserve_quoted_keys : reserve_quoted_keys, + addStrings : addStrings, + mangle_properties : mangle_properties, +}); diff --git a/lib/scope.js b/lib/scope.js index d4b13d12..bcd5dd67 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -43,6 +43,46 @@ "use strict"; +var utils = require("./utils"); +var defaults = utils.defaults; +var return_false = utils.return_false; +var return_this = utils.return_this; +var push_uniq = utils.push_uniq; +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 parse = require("./parse"); +var is_identifier = parse.is_identifier; +var parse = parse.parse; + function SymbolDef(scope, orig, init) { this.name = orig.name; this.orig = [ orig ]; @@ -597,3 +637,10 @@ var base54 = (function() { } return base54; })(); + +merge(exports, { + SymbolDef : SymbolDef, + names_in_use : names_in_use, + next_mangled_name : next_mangled_name, + base54 : base54, +}); diff --git a/lib/sourcemap.js b/lib/sourcemap.js index 2feec45d..6001160f 100644 --- a/lib/sourcemap.js +++ b/lib/sourcemap.js @@ -43,6 +43,11 @@ "use strict"; +var MOZ_SourceMap = require("source-map"); +var utils = require("./utils"); +var defaults = utils.defaults; +var merge = utils.merge; + // a small wrapper around fitzgen's source-map library function SourceMap(options) { options = defaults(options, { @@ -102,3 +107,7 @@ function SourceMap(options) { } }; } + +merge(exports, { + SourceMap : SourceMap, +}); diff --git a/lib/transform.js b/lib/transform.js deleted file mode 100644 index 5897aa77..00000000 --- a/lib/transform.js +++ /dev/null @@ -1,185 +0,0 @@ -/*********************************************************************** - - A JavaScript tokenizer / parser / beautifier / compressor. - https://github.com/mishoo/UglifyJS2 - - -------------------------------- (C) --------------------------------- - - Author: Mihai Bazon - - http://mihai.bazon.net/blog - - Distributed under the BSD license: - - Copyright 2012 (c) Mihai Bazon - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - ***********************************************************************/ - -"use strict"; - -function TreeTransformer(before, after) { - TreeWalker.call(this); - this.before = before; - this.after = after; -} -TreeTransformer.prototype = new TreeWalker; - -(function(DEF) { - function do_list(list, tw) { - return MAP(list, function(node) { - return node.transform(tw, true); - }); - } - - DEF(AST_Node, noop); - DEF(AST_LabeledStatement, function(self, tw) { - self.label = self.label.transform(tw); - self.body = self.body.transform(tw); - }); - DEF(AST_SimpleStatement, function(self, tw) { - self.body = self.body.transform(tw); - }); - DEF(AST_Block, function(self, tw) { - self.body = do_list(self.body, tw); - }); - DEF(AST_Do, function(self, tw) { - self.body = self.body.transform(tw); - self.condition = self.condition.transform(tw); - }); - DEF(AST_While, function(self, tw) { - self.condition = self.condition.transform(tw); - self.body = self.body.transform(tw); - }); - DEF(AST_For, function(self, tw) { - if (self.init) self.init = self.init.transform(tw); - if (self.condition) self.condition = self.condition.transform(tw); - if (self.step) self.step = self.step.transform(tw); - self.body = self.body.transform(tw); - }); - DEF(AST_ForIn, function(self, tw) { - self.init = self.init.transform(tw); - self.object = self.object.transform(tw); - self.body = self.body.transform(tw); - }); - DEF(AST_With, function(self, tw) { - self.expression = self.expression.transform(tw); - self.body = self.body.transform(tw); - }); - DEF(AST_Exit, function(self, tw) { - if (self.value) self.value = self.value.transform(tw); - }); - DEF(AST_LoopControl, function(self, tw) { - if (self.label) self.label = self.label.transform(tw); - }); - DEF(AST_If, function(self, tw) { - self.condition = self.condition.transform(tw); - self.body = self.body.transform(tw); - if (self.alternative) self.alternative = self.alternative.transform(tw); - }); - DEF(AST_Switch, function(self, tw) { - self.expression = self.expression.transform(tw); - self.body = do_list(self.body, tw); - }); - DEF(AST_Case, function(self, tw) { - self.expression = self.expression.transform(tw); - self.body = do_list(self.body, tw); - }); - DEF(AST_Try, function(self, tw) { - self.body = do_list(self.body, tw); - if (self.bcatch) self.bcatch = self.bcatch.transform(tw); - if (self.bfinally) self.bfinally = self.bfinally.transform(tw); - }); - DEF(AST_Catch, function(self, tw) { - self.argname = self.argname.transform(tw); - self.body = do_list(self.body, tw); - }); - DEF(AST_Definitions, function(self, tw) { - self.definitions = do_list(self.definitions, tw); - }); - DEF(AST_VarDef, function(self, tw) { - self.name = self.name.transform(tw); - if (self.value) self.value = self.value.transform(tw); - }); - DEF(AST_Lambda, function(self, tw) { - if (self.name) self.name = self.name.transform(tw); - self.argnames = do_list(self.argnames, tw); - self.body = do_list(self.body, tw); - }); - DEF(AST_Call, function(self, tw) { - self.expression = self.expression.transform(tw); - self.args = do_list(self.args, tw); - }); - DEF(AST_Sequence, function(self, tw) { - self.expressions = do_list(self.expressions, tw); - }); - DEF(AST_Dot, function(self, tw) { - self.expression = self.expression.transform(tw); - }); - DEF(AST_Sub, function(self, tw) { - self.expression = self.expression.transform(tw); - self.property = self.property.transform(tw); - }); - DEF(AST_Unary, function(self, tw) { - self.expression = self.expression.transform(tw); - }); - DEF(AST_Binary, function(self, tw) { - self.left = self.left.transform(tw); - self.right = self.right.transform(tw); - }); - DEF(AST_Conditional, function(self, tw) { - self.condition = self.condition.transform(tw); - self.consequent = self.consequent.transform(tw); - self.alternative = self.alternative.transform(tw); - }); - DEF(AST_Array, function(self, tw) { - self.elements = do_list(self.elements, tw); - }); - DEF(AST_Object, function(self, tw) { - self.properties = do_list(self.properties, tw); - }); - DEF(AST_ObjectProperty, function(self, tw) { - self.value = self.value.transform(tw); - }); -})(function(node, descend) { - node.DEFMETHOD("transform", function(tw, in_list) { - var x, y; - tw.push(this); - if (tw.before) x = tw.before(this, descend, in_list); - if (typeof x === "undefined") { - x = this; - descend(x, tw); - if (tw.after) { - y = tw.after(x, in_list); - if (typeof y !== "undefined") x = y; - } - } - tw.pop(); - return x; - }); -}); diff --git a/lib/utils.js b/lib/utils.js index ca4b2d4b..2399811d 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -255,27 +255,26 @@ function HOP(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -// return true if the node at the top of the stack (that means the -// innermost node in the current output) is lexically the first in -// a statement. -function first_in_statement(stack) { - var node = stack.parent(-1); - for (var i = 0, p; p = stack.parent(i++); node = p) { - if (p.TYPE == "Call") { - if (p.expression === node) continue; - } else if (p instanceof AST_Binary) { - if (p.left === node) continue; - } else if (p instanceof AST_Conditional) { - if (p.condition === node) continue; - } else if (p instanceof AST_PropAccess) { - if (p.expression === node) continue; - } else if (p instanceof AST_Sequence) { - if (p.expressions[0] === node) continue; - } else if (p instanceof AST_Statement) { - return p.body === node; - } else if (p instanceof AST_UnaryPostfix) { - if (p.expression === node) continue; - } - return false; - } -} +merge(exports, { + characters : characters, + member : member, + find_if : find_if, + repeat_string : repeat_string, + configure_error_stack : configure_error_stack, + DefaultsError : DefaultsError, + defaults : defaults, + merge : merge, + noop : noop, + return_false : return_false, + return_true : return_true, + return_this : return_this, + return_null : return_null, + MAP : MAP, + push_uniq : push_uniq, + string_template : string_template, + remove : remove, + makePredicate : makePredicate, + all : all, + Dictionary : Dictionary, + HOP : HOP, +}); diff --git a/test/exports.js b/test/exports.js deleted file mode 100644 index 997ad513..00000000 --- a/test/exports.js +++ /dev/null @@ -1,14 +0,0 @@ -exports["Compressor"] = Compressor; -exports["JS_Parse_Error"] = JS_Parse_Error; -exports["OutputStream"] = OutputStream; -exports["SourceMap"] = SourceMap; -exports["TreeWalker"] = TreeWalker; -exports["base54"] = base54; -exports["defaults"] = defaults; -exports["mangle_properties"] = mangle_properties; -exports["minify"] = minify; -exports["parse"] = parse; -exports["reserve_quoted_keys"] = reserve_quoted_keys; -exports["string_template"] = string_template; -exports["tokenizer"] = tokenizer; -exports["is_identifier"] = is_identifier; diff --git a/test/mocha.js b/test/mocha.js index 5d65a5a2..bd4a6e28 100644 --- a/test/mocha.js +++ b/test/mocha.js @@ -22,6 +22,7 @@ it = function(title, fn) { tasks.push(fn); }; + fs.readdirSync("test/mocha").filter(function(file) { return /\.js$/.test(file); }).forEach(function(file) { diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 3bc92c30..0745c647 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -11,7 +11,7 @@ describe("bin/uglifyjs", function() { it("should produce a functional build when using --self", function(done) { this.timeout(30000); var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS'; - exec(command, function(err, stdout) { + exec(command, {maxBuffer: 1024 * 300}, function(err, stdout) { if (err) throw err; eval(stdout); assert.strictEqual(typeof WrappedUglifyJS, "object"); diff --git a/test/node.js b/test/node.js index 22bf325d..7db9c6d5 100644 --- a/test/node.js +++ b/test/node.js @@ -1,6 +1,12 @@ -var fs = require("fs"); - -new Function("MOZ_SourceMap", "exports", require("../tools/node").FILES.map(function(file) { - if (/exports\.js$/.test(file)) file = require.resolve("./exports"); - return fs.readFileSync(file, "utf8"); -}).join("\n\n"))(require("source-map"), exports); +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; +orig.mangle_properties = orig.propmangle.mangle_properties; +orig.reserve_quoted_keys = orig.propmangle.reserve_quoted_keys; +orig.JS_Parse_Error = orig.parser.JS_Parse_Error; +orig.tokenizer = orig.parser.tokenizer; +orig.is_identifier = orig.parser.is_identifier; +module.exports = orig; \ No newline at end of file diff --git a/tools/exports.js b/tools/exports.js index c09436ab..72f0561e 100644 --- a/tools/exports.js +++ b/tools/exports.js @@ -1,6 +1,8 @@ +exports["Compressor"] = Compressor; exports["Dictionary"] = Dictionary; exports["TreeWalker"] = TreeWalker; exports["TreeTransformer"] = TreeTransformer; exports["minify"] = minify; exports["parse"] = parse; exports["_push_uniq"] = push_uniq; +exports["string_template"] = string_template; diff --git a/tools/generate-exports.js b/tools/generate-exports.js new file mode 100644 index 00000000..30be127b --- /dev/null +++ b/tools/generate-exports.js @@ -0,0 +1,59 @@ +"use strict"; + +var UglifyJS = require("../tools/node"); +var fs = require("fs"); + +console.log = function (d) { + process.stdout.write(d + '\n'); +}; + +UglifyJS.FILES.forEach(function(filepath){ + var code = fs.readFileSync(filepath, "utf8"); + var filename = filepath.replace(/^.*?([-a-z]+)\.js$/g, "$1"); + + var AST = UglifyJS.parse(code, {filename: filepath}); + + var exportNames = []; + var walker = new UglifyJS.TreeWalker(function(node){ + if (node instanceof UglifyJS.ast.AST_Defun) { + exportNames.push(node.name.name); + } + if (node instanceof UglifyJS.ast.AST_Var) { + var def = node.definitions[0]; + var name = def.name.name; + var value = def.value; + // Skip = foo. + if (value instanceof UglifyJS.ast.AST_Dot && value.property == name) + return true; + // Skip = require(...) + if (value instanceof UglifyJS.ast.AST_Call && value.expression instanceof UglifyJS.ast.AST_SymbolRef && value.expression.name == "require") + return true; + exportNames.push(name); + } + return !(node instanceof UglifyJS.ast.AST_Toplevel); + }); + AST.walk(walker); + // Don't export identifiers starting with underscore + exportNames = exportNames.filter(name => name[0] != "_"); + 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 imports = exportNames.map(function(name){ + return UglifyJS.string_template(UglifyJS.string_template('var {name} = {fn}.{name};', { name: name, fn: filename})); + }); + + console.log("\n// Exports for " + filename); + console.log(exports); + console.log("\n\n// Usage:") + console.log(UglifyJS.string_template('var {fn} = require("../lib/{fn}");', { fn: filename})); + console.log(imports.join("\n")); + + var result = code.replace(/\n+(exports\.\w+ = \w+;\n+)+$/, ""); + result = result.replace(/\n+Object\.assign\(exports, \{[\s\S]*?\}\);\n*$/, ""); + result = result.replace(/\n+merge\(exports, \{[\s\S]*?\}\);\n*$/, ""); + result += "\n\n" + exports + "\n"; + fs.writeFileSync(filepath, result, "utf8"); +}); diff --git a/tools/node.js b/tools/node.js index 2e8f2d5c..174e2b0d 100644 --- a/tools/node.js +++ b/tools/node.js @@ -5,7 +5,6 @@ var FILES = UglifyJS.FILES = [ "../lib/utils.js", "../lib/ast.js", "../lib/parse.js", - "../lib/transform.js", "../lib/scope.js", "../lib/output.js", "../lib/compress.js", @@ -18,7 +17,7 @@ var FILES = UglifyJS.FILES = [ return require.resolve(file); }); -new Function("MOZ_SourceMap", "exports", function() { +/*new Function("MOZ_SourceMap", "exports", function() { var code = FILES.map(function(file) { return fs.readFileSync(file, "utf8"); }); @@ -27,7 +26,33 @@ new Function("MOZ_SourceMap", "exports", function() { }())( 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 compress = require("../lib/compress"); +var parse = require("../lib/parse"); +var propmangle = require("../lib/propmangle"); +require("../lib/mozilla-ast"); + + +exports.utils = utils; +exports.OutputStream = OutputStream; +exports.minify = minify; +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.push_uniq = utils.push_uniq; +exports.string_template = utils.string_template; +exports.describe_ast = describe_ast; +exports.propmangle = propmangle; function describe_ast() { var out = OutputStream({ beautify: true });