source: trip-planner-front/node_modules/terser/lib/propmangle.js@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 11.7 KB
RevLine 
[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/* global global, self */
46
47import {
48 defaults,
49 push_uniq,
50} from "./utils/index.js";
51import { base54 } from "./scope.js";
52import {
53 AST_Binary,
54 AST_Call,
55 AST_ClassPrivateProperty,
56 AST_Conditional,
57 AST_Dot,
58 AST_DotHash,
59 AST_ObjectKeyVal,
60 AST_ObjectProperty,
61 AST_PrivateMethod,
62 AST_Sequence,
63 AST_String,
64 AST_Sub,
65 TreeTransformer,
66 TreeWalker,
67} from "./ast.js";
68import { domprops } from "../tools/domprops.js";
69
70function find_builtins(reserved) {
71 domprops.forEach(add);
72
73 // Compatibility fix for some standard defined globals not defined on every js environment
74 var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
75 var objects = {};
76 var global_ref = typeof global === "object" ? global : self;
77
78 new_globals.forEach(function (new_global) {
79 objects[new_global] = global_ref[new_global] || new Function();
80 });
81
82 [
83 "null",
84 "true",
85 "false",
86 "NaN",
87 "Infinity",
88 "-Infinity",
89 "undefined",
90 ].forEach(add);
91 [ Object, Array, Function, Number,
92 String, Boolean, Error, Math,
93 Date, RegExp, objects.Symbol, ArrayBuffer,
94 DataView, decodeURI, decodeURIComponent,
95 encodeURI, encodeURIComponent, eval, EvalError,
96 Float32Array, Float64Array, Int8Array, Int16Array,
97 Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
98 parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
99 objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
100 Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
101 objects.WeakMap, objects.WeakSet
102 ].forEach(function(ctor) {
103 Object.getOwnPropertyNames(ctor).map(add);
104 if (ctor.prototype) {
105 Object.getOwnPropertyNames(ctor.prototype).map(add);
106 }
107 });
108 function add(name) {
109 reserved.add(name);
110 }
111}
112
113function reserve_quoted_keys(ast, reserved) {
114 function add(name) {
115 push_uniq(reserved, name);
116 }
117
118 ast.walk(new TreeWalker(function(node) {
119 if (node instanceof AST_ObjectKeyVal && node.quote) {
120 add(node.key);
121 } else if (node instanceof AST_ObjectProperty && node.quote) {
122 add(node.key.name);
123 } else if (node instanceof AST_Sub) {
124 addStrings(node.property, add);
125 }
126 }));
127}
128
129function addStrings(node, add) {
130 node.walk(new TreeWalker(function(node) {
131 if (node instanceof AST_Sequence) {
132 addStrings(node.tail_node(), add);
133 } else if (node instanceof AST_String) {
134 add(node.value);
135 } else if (node instanceof AST_Conditional) {
136 addStrings(node.consequent, add);
137 addStrings(node.alternative, add);
138 }
139 return true;
140 }));
141}
142
143function mangle_properties(ast, options) {
144 options = defaults(options, {
145 builtins: false,
146 cache: null,
147 debug: false,
148 keep_quoted: false,
149 only_cache: false,
150 regex: null,
151 reserved: null,
152 undeclared: false,
153 }, true);
154
155 var reserved_option = options.reserved;
156 if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
157 var reserved = new Set(reserved_option);
158 if (!options.builtins) find_builtins(reserved);
159
160 var cname = -1;
161 var cprivate = -1;
162
163 var cache;
164 var private_cache = new Map();
165 if (options.cache) {
166 cache = options.cache.props;
167 cache.forEach(function(mangled_name) {
168 reserved.add(mangled_name);
169 });
170 } else {
171 cache = new Map();
172 }
173
174 var regex = options.regex && new RegExp(options.regex);
175
176 // note debug is either false (disabled), or a string of the debug suffix to use (enabled).
177 // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
178 // the same as passing an empty string.
179 var debug = options.debug !== false;
180 var debug_name_suffix;
181 if (debug) {
182 debug_name_suffix = (options.debug === true ? "" : options.debug);
183 }
184
185 var names_to_mangle = new Set();
186 var unmangleable = new Set();
187 var private_properties = new Set();
188
189 var keep_quoted_strict = options.keep_quoted === "strict";
190
191 // step 1: find candidates to mangle
192 ast.walk(new TreeWalker(function(node) {
193 if (
194 node instanceof AST_ClassPrivateProperty
195 || node instanceof AST_PrivateMethod
196 ) {
197 private_properties.add(node.key.name);
198 } else if (node instanceof AST_DotHash) {
199 private_properties.add(node.property);
200 } else if (node instanceof AST_ObjectKeyVal) {
201 if (typeof node.key == "string" &&
202 (!keep_quoted_strict || !node.quote)) {
203 add(node.key);
204 }
205 } else if (node instanceof AST_ObjectProperty) {
206 // setter or getter, since KeyVal is handled above
207 if (!keep_quoted_strict || !node.key.end.quote) {
208 add(node.key.name);
209 }
210 } else if (node instanceof AST_Dot) {
211 var declared = !!options.undeclared;
212 if (!declared) {
213 var root = node;
214 while (root.expression) {
215 root = root.expression;
216 }
217 declared = !(root.thedef && root.thedef.undeclared);
218 }
219 if (declared &&
220 (!keep_quoted_strict || !node.quote)) {
221 add(node.property);
222 }
223 } else if (node instanceof AST_Sub) {
224 if (!keep_quoted_strict) {
225 addStrings(node.property, add);
226 }
227 } else if (node instanceof AST_Call
228 && node.expression.print_to_string() == "Object.defineProperty") {
229 addStrings(node.args[1], add);
230 } else if (node instanceof AST_Binary && node.operator === "in") {
231 addStrings(node.left, add);
232 }
233 }));
234
235 // step 2: transform the tree, renaming properties
236 return ast.transform(new TreeTransformer(function(node) {
237 if (
238 node instanceof AST_ClassPrivateProperty
239 || node instanceof AST_PrivateMethod
240 ) {
241 node.key.name = mangle_private(node.key.name);
242 } else if (node instanceof AST_DotHash) {
243 node.property = mangle_private(node.property);
244 } else if (node instanceof AST_ObjectKeyVal) {
245 if (typeof node.key == "string" &&
246 (!keep_quoted_strict || !node.quote)) {
247 node.key = mangle(node.key);
248 }
249 } else if (node instanceof AST_ObjectProperty) {
250 // setter, getter, method or class field
251 if (!keep_quoted_strict || !node.key.end.quote) {
252 node.key.name = mangle(node.key.name);
253 }
254 } else if (node instanceof AST_Dot) {
255 if (!keep_quoted_strict || !node.quote) {
256 node.property = mangle(node.property);
257 }
258 } else if (!options.keep_quoted && node instanceof AST_Sub) {
259 node.property = mangleStrings(node.property);
260 } else if (node instanceof AST_Call
261 && node.expression.print_to_string() == "Object.defineProperty") {
262 node.args[1] = mangleStrings(node.args[1]);
263 } else if (node instanceof AST_Binary && node.operator === "in") {
264 node.left = mangleStrings(node.left);
265 }
266 }));
267
268 // only function declarations after this line
269
270 function can_mangle(name) {
271 if (unmangleable.has(name)) return false;
272 if (reserved.has(name)) return false;
273 if (options.only_cache) {
274 return cache.has(name);
275 }
276 if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
277 return true;
278 }
279
280 function should_mangle(name) {
281 if (regex && !regex.test(name)) return false;
282 if (reserved.has(name)) return false;
283 return cache.has(name)
284 || names_to_mangle.has(name);
285 }
286
287 function add(name) {
288 if (can_mangle(name))
289 names_to_mangle.add(name);
290
291 if (!should_mangle(name)) {
292 unmangleable.add(name);
293 }
294 }
295
296 function mangle(name) {
297 if (!should_mangle(name)) {
298 return name;
299 }
300
301 var mangled = cache.get(name);
302 if (!mangled) {
303 if (debug) {
304 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
305 var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
306
307 if (can_mangle(debug_mangled)) {
308 mangled = debug_mangled;
309 }
310 }
311
312 // either debug mode is off, or it is on and we could not use the mangled name
313 if (!mangled) {
314 do {
315 mangled = base54(++cname);
316 } while (!can_mangle(mangled));
317 }
318
319 cache.set(name, mangled);
320 }
321 return mangled;
322 }
323
324 function mangle_private(name) {
325 let mangled = private_cache.get(name);
326 if (!mangled) {
327 mangled = base54(++cprivate);
328 private_cache.set(name, mangled);
329 }
330
331 return mangled;
332 }
333
334 function mangleStrings(node) {
335 return node.transform(new TreeTransformer(function(node) {
336 if (node instanceof AST_Sequence) {
337 var last = node.expressions.length - 1;
338 node.expressions[last] = mangleStrings(node.expressions[last]);
339 } else if (node instanceof AST_String) {
340 node.value = mangle(node.value);
341 } else if (node instanceof AST_Conditional) {
342 node.consequent = mangleStrings(node.consequent);
343 node.alternative = mangleStrings(node.alternative);
344 }
345 return node;
346 }));
347 }
348}
349
350export {
351 reserve_quoted_keys,
352 mangle_properties,
353};
Note: See TracBrowser for help on using the repository browser.