UNPKG

7.99 kBJavaScriptView Raw
1/***********************************************************************
2
3 A JavaScript tokenizer / parser / beautifier / compressor.
4 https://github.com/mishoo/UglifyJS
5
6 -------------------------------- (C) ---------------------------------
7
8 Author: Mihai Bazon
9 <mihai.bazon@gmail.com>
10 http://mihai.bazon.net/blog
11
12 Distributed under the BSD license:
13
14 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
15
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
18 are met:
19
20 * Redistributions of source code must retain the above
21 copyright notice, this list of conditions and the following
22 disclaimer.
23
24 * Redistributions in binary form must reproduce the above
25 copyright notice, this list of conditions and the following
26 disclaimer in the documentation and/or other materials
27 provided with the distribution.
28
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
30 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
33 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
39 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 SUCH DAMAGE.
41
42 ***********************************************************************/
43
44"use strict";
45
46function characters(str) {
47 return str.split("");
48}
49
50function member(name, array) {
51 return array.indexOf(name) >= 0;
52}
53
54function find_if(func, array) {
55 for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
56}
57
58function repeat_string(str, i) {
59 if (i <= 0) return "";
60 if (i == 1) return str;
61 var d = repeat_string(str, i >> 1);
62 d += d;
63 return i & 1 ? d + str : d;
64}
65
66function configure_error_stack(fn) {
67 Object.defineProperty(fn.prototype, "stack", {
68 get: function() {
69 var err = new Error(this.message);
70 err.name = this.name;
71 try {
72 throw err;
73 } catch (e) {
74 return e.stack;
75 }
76 }
77 });
78}
79
80function DefaultsError(msg, defs) {
81 this.message = msg;
82 this.defs = defs;
83}
84DefaultsError.prototype = Object.create(Error.prototype);
85DefaultsError.prototype.constructor = DefaultsError;
86DefaultsError.prototype.name = "DefaultsError";
87configure_error_stack(DefaultsError);
88
89function defaults(args, defs, croak) {
90 if (croak) for (var i in args) {
91 if (HOP(args, i) && !HOP(defs, i)) throw new DefaultsError("`" + i + "` is not a supported option", defs);
92 }
93 for (var i in args) {
94 if (HOP(args, i)) defs[i] = args[i];
95 }
96 return defs;
97}
98
99function merge(obj, ext) {
100 var count = 0;
101 for (var i in ext) if (HOP(ext, i)) {
102 obj[i] = ext[i];
103 count++;
104 }
105 return count;
106}
107
108function noop() {}
109function return_false() { return false; }
110function return_true() { return true; }
111function return_this() { return this; }
112function return_null() { return null; }
113
114var List = (function() {
115 function List(a, f) {
116 var ret = [];
117 for (var i = 0; i < a.length; i++) {
118 var val = f(a[i], i);
119 if (val === skip) continue;
120 if (val instanceof Splice) {
121 ret.push.apply(ret, val.v);
122 } else {
123 ret.push(val);
124 }
125 }
126 return ret;
127 }
128 List.is_op = function(val) {
129 return val === skip || val instanceof Splice;
130 };
131 List.splice = function(val) {
132 return new Splice(val);
133 };
134 var skip = List.skip = {};
135 function Splice(val) {
136 this.v = val;
137 }
138 return List;
139})();
140
141function push_uniq(array, el) {
142 if (array.indexOf(el) < 0) return array.push(el);
143}
144
145function string_template(text, props) {
146 return text.replace(/\{([^{}]+)\}/g, function(str, p) {
147 var value = props[p];
148 return value instanceof AST_Node ? value.print_to_string() : value;
149 });
150}
151
152function remove(array, el) {
153 var index = array.indexOf(el);
154 if (index >= 0) array.splice(index, 1);
155}
156
157function makePredicate(words) {
158 if (!Array.isArray(words)) words = words.split(" ");
159 var map = Object.create(null);
160 words.forEach(function(word) {
161 map[word] = true;
162 });
163 return map;
164}
165
166function all(array, predicate) {
167 for (var i = array.length; --i >= 0;)
168 if (!predicate(array[i], i))
169 return false;
170 return true;
171}
172
173function Dictionary() {
174 this._values = Object.create(null);
175 this._size = 0;
176}
177Dictionary.prototype = {
178 set: function(key, val) {
179 if (!this.has(key)) ++this._size;
180 this._values["$" + key] = val;
181 return this;
182 },
183 add: function(key, val) {
184 if (this.has(key)) {
185 this.get(key).push(val);
186 } else {
187 this.set(key, [ val ]);
188 }
189 return this;
190 },
191 get: function(key) { return this._values["$" + key] },
192 del: function(key) {
193 if (this.has(key)) {
194 --this._size;
195 delete this._values["$" + key];
196 }
197 return this;
198 },
199 has: function(key) { return ("$" + key) in this._values },
200 all: function(predicate) {
201 for (var i in this._values)
202 if (!predicate(this._values[i], i.substr(1)))
203 return false;
204 return true;
205 },
206 each: function(f) {
207 for (var i in this._values)
208 f(this._values[i], i.substr(1));
209 },
210 size: function() {
211 return this._size;
212 },
213 map: function(f) {
214 var ret = [];
215 for (var i in this._values)
216 ret.push(f(this._values[i], i.substr(1)));
217 return ret;
218 },
219 clone: function() {
220 var ret = new Dictionary();
221 for (var i in this._values)
222 ret._values[i] = this._values[i];
223 ret._size = this._size;
224 return ret;
225 },
226 toObject: function() { return this._values }
227};
228Dictionary.fromObject = function(obj) {
229 var dict = new Dictionary();
230 dict._size = merge(dict._values, obj);
231 return dict;
232};
233
234function HOP(obj, prop) {
235 return Object.prototype.hasOwnProperty.call(obj, prop);
236}
237
238// return true if the node at the top of the stack (that means the
239// innermost node in the current output) is lexically the first in
240// a statement.
241function first_in_statement(stack, arrow, export_default) {
242 var node = stack.parent(-1);
243 for (var i = 0, p; p = stack.parent(i++); node = p) {
244 if (is_arrow(p)) {
245 return arrow && p.value === node;
246 } else if (p instanceof AST_Binary) {
247 if (p.left === node) continue;
248 } else if (p.TYPE == "Call") {
249 if (p.expression === node) continue;
250 } else if (p instanceof AST_Conditional) {
251 if (p.condition === node) continue;
252 } else if (p instanceof AST_ExportDefault) {
253 return export_default;
254 } else if (p instanceof AST_PropAccess) {
255 if (p.expression === node) continue;
256 } else if (p instanceof AST_Sequence) {
257 if (p.expressions[0] === node) continue;
258 } else if (p instanceof AST_SimpleStatement) {
259 return true;
260 } else if (p instanceof AST_Template) {
261 if (p.tag === node) continue;
262 } else if (p instanceof AST_UnaryPostfix) {
263 if (p.expression === node) continue;
264 }
265 return false;
266 }
267}