[6a3a178] | 1 | /***********************************************************************
|
---|
| 2 |
|
---|
| 3 | A JavaScript tokenizer / parser / beautifier / compressor.
|
---|
| 4 | https://github.com/mishoo/UglifyJS2
|
---|
| 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 |
|
---|
| 46 | function characters(str) {
|
---|
| 47 | return str.split("");
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | function member(name, array) {
|
---|
| 51 | return array.includes(name);
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | class DefaultsError extends Error {
|
---|
| 55 | constructor(msg, defs) {
|
---|
| 56 | super();
|
---|
| 57 |
|
---|
| 58 | this.name = "DefaultsError";
|
---|
| 59 | this.message = msg;
|
---|
| 60 | this.defs = defs;
|
---|
| 61 | }
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | function defaults(args, defs, croak) {
|
---|
| 65 | if (args === true) {
|
---|
| 66 | args = {};
|
---|
| 67 | } else if (args != null && typeof args === "object") {
|
---|
| 68 | args = {...args};
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | const ret = args || {};
|
---|
| 72 |
|
---|
| 73 | if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
---|
| 74 | throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | for (const i in defs) if (HOP(defs, i)) {
|
---|
| 78 | if (!args || !HOP(args, i)) {
|
---|
| 79 | ret[i] = defs[i];
|
---|
| 80 | } else if (i === "ecma") {
|
---|
| 81 | let ecma = args[i] | 0;
|
---|
| 82 | if (ecma > 5 && ecma < 2015) ecma += 2009;
|
---|
| 83 | ret[i] = ecma;
|
---|
| 84 | } else {
|
---|
| 85 | ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
---|
| 86 | }
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | return ret;
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | function noop() {}
|
---|
| 93 | function return_false() { return false; }
|
---|
| 94 | function return_true() { return true; }
|
---|
| 95 | function return_this() { return this; }
|
---|
| 96 | function return_null() { return null; }
|
---|
| 97 |
|
---|
| 98 | var MAP = (function() {
|
---|
| 99 | function MAP(a, f, backwards) {
|
---|
| 100 | var ret = [], top = [], i;
|
---|
| 101 | function doit() {
|
---|
| 102 | var val = f(a[i], i);
|
---|
| 103 | var is_last = val instanceof Last;
|
---|
| 104 | if (is_last) val = val.v;
|
---|
| 105 | if (val instanceof AtTop) {
|
---|
| 106 | val = val.v;
|
---|
| 107 | if (val instanceof Splice) {
|
---|
| 108 | top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
|
---|
| 109 | } else {
|
---|
| 110 | top.push(val);
|
---|
| 111 | }
|
---|
| 112 | } else if (val !== skip) {
|
---|
| 113 | if (val instanceof Splice) {
|
---|
| 114 | ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
|
---|
| 115 | } else {
|
---|
| 116 | ret.push(val);
|
---|
| 117 | }
|
---|
| 118 | }
|
---|
| 119 | return is_last;
|
---|
| 120 | }
|
---|
| 121 | if (Array.isArray(a)) {
|
---|
| 122 | if (backwards) {
|
---|
| 123 | for (i = a.length; --i >= 0;) if (doit()) break;
|
---|
| 124 | ret.reverse();
|
---|
| 125 | top.reverse();
|
---|
| 126 | } else {
|
---|
| 127 | for (i = 0; i < a.length; ++i) if (doit()) break;
|
---|
| 128 | }
|
---|
| 129 | } else {
|
---|
| 130 | for (i in a) if (HOP(a, i)) if (doit()) break;
|
---|
| 131 | }
|
---|
| 132 | return top.concat(ret);
|
---|
| 133 | }
|
---|
| 134 | MAP.at_top = function(val) { return new AtTop(val); };
|
---|
| 135 | MAP.splice = function(val) { return new Splice(val); };
|
---|
| 136 | MAP.last = function(val) { return new Last(val); };
|
---|
| 137 | var skip = MAP.skip = {};
|
---|
| 138 | function AtTop(val) { this.v = val; }
|
---|
| 139 | function Splice(val) { this.v = val; }
|
---|
| 140 | function Last(val) { this.v = val; }
|
---|
| 141 | return MAP;
|
---|
| 142 | })();
|
---|
| 143 |
|
---|
| 144 | function make_node(ctor, orig, props) {
|
---|
| 145 | if (!props) props = {};
|
---|
| 146 | if (orig) {
|
---|
| 147 | if (!props.start) props.start = orig.start;
|
---|
| 148 | if (!props.end) props.end = orig.end;
|
---|
| 149 | }
|
---|
| 150 | return new ctor(props);
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 | function push_uniq(array, el) {
|
---|
| 154 | if (!array.includes(el))
|
---|
| 155 | array.push(el);
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | function string_template(text, props) {
|
---|
| 159 | return text.replace(/{(.+?)}/g, function(str, p) {
|
---|
| 160 | return props && props[p];
|
---|
| 161 | });
|
---|
| 162 | }
|
---|
| 163 |
|
---|
| 164 | function remove(array, el) {
|
---|
| 165 | for (var i = array.length; --i >= 0;) {
|
---|
| 166 | if (array[i] === el) array.splice(i, 1);
|
---|
| 167 | }
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | function mergeSort(array, cmp) {
|
---|
| 171 | if (array.length < 2) return array.slice();
|
---|
| 172 | function merge(a, b) {
|
---|
| 173 | var r = [], ai = 0, bi = 0, i = 0;
|
---|
| 174 | while (ai < a.length && bi < b.length) {
|
---|
| 175 | cmp(a[ai], b[bi]) <= 0
|
---|
| 176 | ? r[i++] = a[ai++]
|
---|
| 177 | : r[i++] = b[bi++];
|
---|
| 178 | }
|
---|
| 179 | if (ai < a.length) r.push.apply(r, a.slice(ai));
|
---|
| 180 | if (bi < b.length) r.push.apply(r, b.slice(bi));
|
---|
| 181 | return r;
|
---|
| 182 | }
|
---|
| 183 | function _ms(a) {
|
---|
| 184 | if (a.length <= 1)
|
---|
| 185 | return a;
|
---|
| 186 | var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
---|
| 187 | left = _ms(left);
|
---|
| 188 | right = _ms(right);
|
---|
| 189 | return merge(left, right);
|
---|
| 190 | }
|
---|
| 191 | return _ms(array);
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 | function makePredicate(words) {
|
---|
| 195 | if (!Array.isArray(words)) words = words.split(" ");
|
---|
| 196 |
|
---|
| 197 | return new Set(words.sort());
|
---|
| 198 | }
|
---|
| 199 |
|
---|
| 200 | function map_add(map, key, value) {
|
---|
| 201 | if (map.has(key)) {
|
---|
| 202 | map.get(key).push(value);
|
---|
| 203 | } else {
|
---|
| 204 | map.set(key, [ value ]);
|
---|
| 205 | }
|
---|
| 206 | }
|
---|
| 207 |
|
---|
| 208 | function map_from_object(obj) {
|
---|
| 209 | var map = new Map();
|
---|
| 210 | for (var key in obj) {
|
---|
| 211 | if (HOP(obj, key) && key.charAt(0) === "$") {
|
---|
| 212 | map.set(key.substr(1), obj[key]);
|
---|
| 213 | }
|
---|
| 214 | }
|
---|
| 215 | return map;
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | function map_to_object(map) {
|
---|
| 219 | var obj = Object.create(null);
|
---|
| 220 | map.forEach(function (value, key) {
|
---|
| 221 | obj["$" + key] = value;
|
---|
| 222 | });
|
---|
| 223 | return obj;
|
---|
| 224 | }
|
---|
| 225 |
|
---|
| 226 | function HOP(obj, prop) {
|
---|
| 227 | return Object.prototype.hasOwnProperty.call(obj, prop);
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | function keep_name(keep_setting, name) {
|
---|
| 231 | return keep_setting === true
|
---|
| 232 | || (keep_setting instanceof RegExp && keep_setting.test(name));
|
---|
| 233 | }
|
---|
| 234 |
|
---|
| 235 | var lineTerminatorEscape = {
|
---|
| 236 | "\0": "0",
|
---|
| 237 | "\n": "n",
|
---|
| 238 | "\r": "r",
|
---|
| 239 | "\u2028": "u2028",
|
---|
| 240 | "\u2029": "u2029",
|
---|
| 241 | };
|
---|
| 242 | function regexp_source_fix(source) {
|
---|
| 243 | // V8 does not escape line terminators in regexp patterns in node 12
|
---|
| 244 | // We'll also remove literal \0
|
---|
| 245 | return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
|
---|
| 246 | var escaped = source[offset - 1] == "\\"
|
---|
| 247 | && (source[offset - 2] != "\\"
|
---|
| 248 | || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
|
---|
| 249 | return (escaped ? "" : "\\") + lineTerminatorEscape[match];
|
---|
| 250 | });
|
---|
| 251 | }
|
---|
| 252 | const all_flags = "gimuy";
|
---|
| 253 | function sort_regexp_flags(flags) {
|
---|
| 254 | const existing_flags = new Set(flags.split(""));
|
---|
| 255 | let out = "";
|
---|
| 256 | for (const flag of all_flags) {
|
---|
| 257 | if (existing_flags.has(flag)) {
|
---|
| 258 | out += flag;
|
---|
| 259 | existing_flags.delete(flag);
|
---|
| 260 | }
|
---|
| 261 | }
|
---|
| 262 | if (existing_flags.size) {
|
---|
| 263 | // Flags Terser doesn't know about
|
---|
| 264 | existing_flags.forEach(flag => { out += flag; });
|
---|
| 265 | }
|
---|
| 266 | return out;
|
---|
| 267 | }
|
---|
| 268 |
|
---|
| 269 | function has_annotation(node, annotation) {
|
---|
| 270 | return node._annotations & annotation;
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | function set_annotation(node, annotation) {
|
---|
| 274 | node._annotations |= annotation;
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | export {
|
---|
| 278 | characters,
|
---|
| 279 | defaults,
|
---|
| 280 | HOP,
|
---|
| 281 | keep_name,
|
---|
| 282 | make_node,
|
---|
| 283 | makePredicate,
|
---|
| 284 | map_add,
|
---|
| 285 | map_from_object,
|
---|
| 286 | map_to_object,
|
---|
| 287 | MAP,
|
---|
| 288 | member,
|
---|
| 289 | mergeSort,
|
---|
| 290 | noop,
|
---|
| 291 | push_uniq,
|
---|
| 292 | regexp_source_fix,
|
---|
| 293 | remove,
|
---|
| 294 | return_false,
|
---|
| 295 | return_null,
|
---|
| 296 | return_this,
|
---|
| 297 | return_true,
|
---|
| 298 | sort_regexp_flags,
|
---|
| 299 | string_template,
|
---|
| 300 | has_annotation,
|
---|
| 301 | set_annotation
|
---|
| 302 | };
|
---|