UNPKG

10.3 kBJavaScriptView Raw
1import {
2 AST_Accessor,
3 AST_Array,
4 AST_Arrow,
5 AST_Await,
6 AST_BigInt,
7 AST_Binary,
8 AST_Block,
9 AST_Break,
10 AST_Call,
11 AST_Case,
12 AST_Class,
13 AST_ClassProperty,
14 AST_ConciseMethod,
15 AST_Conditional,
16 AST_Const,
17 AST_Continue,
18 AST_Debugger,
19 AST_Default,
20 AST_Defun,
21 AST_Destructuring,
22 AST_Directive,
23 AST_Do,
24 AST_Dot,
25 AST_EmptyStatement,
26 AST_Expansion,
27 AST_Export,
28 AST_False,
29 AST_For,
30 AST_ForIn,
31 AST_Function,
32 AST_Hole,
33 AST_If,
34 AST_Import,
35 AST_ImportMeta,
36 AST_Infinity,
37 AST_LabeledStatement,
38 AST_Let,
39 AST_NameMapping,
40 AST_NaN,
41 AST_New,
42 AST_NewTarget,
43 AST_Node,
44 AST_Null,
45 AST_Number,
46 AST_Object,
47 AST_ObjectKeyVal,
48 AST_ObjectGetter,
49 AST_ObjectSetter,
50 AST_RegExp,
51 AST_Return,
52 AST_Sequence,
53 AST_String,
54 AST_Sub,
55 AST_Super,
56 AST_Switch,
57 AST_Symbol,
58 AST_SymbolClassProperty,
59 AST_SymbolExportForeign,
60 AST_SymbolImportForeign,
61 AST_SymbolRef,
62 AST_SymbolDeclaration,
63 AST_TemplateSegment,
64 AST_TemplateString,
65 AST_This,
66 AST_Throw,
67 AST_Toplevel,
68 AST_True,
69 AST_Try,
70 AST_Catch,
71 AST_Finally,
72 AST_Unary,
73 AST_Undefined,
74 AST_Var,
75 AST_VarDef,
76 AST_While,
77 AST_With,
78 AST_Yield,
79 walk_parent
80} from "./ast.js";
81import { first_in_statement } from "./utils/first_in_statement.js";
82
83let mangle_options = undefined;
84AST_Node.prototype.size = function (compressor, stack) {
85 mangle_options = compressor && compressor.mangle_options;
86
87 let size = 0;
88 walk_parent(this, (node, info) => {
89 size += node._size(info);
90 }, stack || (compressor && compressor.stack));
91
92 // just to save a bit of memory
93 mangle_options = undefined;
94
95 return size;
96};
97
98AST_Node.prototype._size = () => 0;
99
100AST_Debugger.prototype._size = () => 8;
101
102AST_Directive.prototype._size = function () {
103 // TODO string encoding stuff
104 return 2 + this.value.length;
105};
106
107const list_overhead = (array) => array.length && array.length - 1;
108
109AST_Block.prototype._size = function () {
110 return 2 + list_overhead(this.body);
111};
112
113AST_Toplevel.prototype._size = function() {
114 return list_overhead(this.body);
115};
116
117AST_EmptyStatement.prototype._size = () => 1;
118
119AST_LabeledStatement.prototype._size = () => 2; // x:
120
121AST_Do.prototype._size = () => 9;
122
123AST_While.prototype._size = () => 7;
124
125AST_For.prototype._size = () => 8;
126
127AST_ForIn.prototype._size = () => 8;
128// AST_ForOf inherits ^
129
130AST_With.prototype._size = () => 6;
131
132AST_Expansion.prototype._size = () => 3;
133
134/*#__INLINE__*/
135const lambda_modifiers = func =>
136 (func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
137
138AST_Accessor.prototype._size = function () {
139 return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body);
140};
141
142AST_Function.prototype._size = function (info) {
143 const first = !!first_in_statement(info);
144 return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body);
145};
146
147AST_Defun.prototype._size = function () {
148 return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body);
149};
150
151AST_Arrow.prototype._size = function () {
152 let args_and_arrow = 2 + list_overhead(this.argnames);
153
154 if (
155 !(
156 this.argnames.length === 1
157 && this.argnames[0] instanceof AST_Symbol
158 )
159 ) {
160 args_and_arrow += 2;
161 }
162
163 return lambda_modifiers(this) + args_and_arrow + (Array.isArray(this.body) ? list_overhead(this.body) : this.body._size());
164};
165
166AST_Destructuring.prototype._size = () => 2;
167
168AST_TemplateString.prototype._size = function () {
169 return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */
170};
171
172AST_TemplateSegment.prototype._size = function () {
173 return this.value.length;
174};
175
176AST_Return.prototype._size = function () {
177 return this.value ? 7 : 6;
178};
179
180AST_Throw.prototype._size = () => 6;
181
182AST_Break.prototype._size = function () {
183 return this.label ? 6 : 5;
184};
185
186AST_Continue.prototype._size = function () {
187 return this.label ? 9 : 8;
188};
189
190AST_If.prototype._size = () => 4;
191
192AST_Switch.prototype._size = function () {
193 return 8 + list_overhead(this.body);
194};
195
196AST_Case.prototype._size = function () {
197 return 5 + list_overhead(this.body);
198};
199
200AST_Default.prototype._size = function () {
201 return 8 + list_overhead(this.body);
202};
203
204AST_Try.prototype._size = function () {
205 return 3 + list_overhead(this.body);
206};
207
208AST_Catch.prototype._size = function () {
209 let size = 7 + list_overhead(this.body);
210 if (this.argname) {
211 size += 2;
212 }
213 return size;
214};
215
216AST_Finally.prototype._size = function () {
217 return 7 + list_overhead(this.body);
218};
219
220/*#__INLINE__*/
221const def_size = (size, def) => size + list_overhead(def.definitions);
222
223AST_Var.prototype._size = function () {
224 return def_size(4, this);
225};
226
227AST_Let.prototype._size = function () {
228 return def_size(4, this);
229};
230
231AST_Const.prototype._size = function () {
232 return def_size(6, this);
233};
234
235AST_VarDef.prototype._size = function () {
236 return this.value ? 1 : 0;
237};
238
239AST_NameMapping.prototype._size = function () {
240 // foreign name isn't mangled
241 return this.name ? 4 : 0;
242};
243
244AST_Import.prototype._size = function () {
245 // import
246 let size = 6;
247
248 if (this.imported_name) size += 1;
249
250 // from
251 if (this.imported_name || this.imported_names) size += 5;
252
253 // braces, and the commas
254 if (this.imported_names) {
255 size += 2 + list_overhead(this.imported_names);
256 }
257
258 return size;
259};
260
261AST_ImportMeta.prototype._size = () => 11;
262
263AST_Export.prototype._size = function () {
264 let size = 7 + (this.is_default ? 8 : 0);
265
266 if (this.exported_value) {
267 size += this.exported_value._size();
268 }
269
270 if (this.exported_names) {
271 // Braces and commas
272 size += 2 + list_overhead(this.exported_names);
273 }
274
275 if (this.module_name) {
276 // "from "
277 size += 5;
278 }
279
280 return size;
281};
282
283AST_Call.prototype._size = function () {
284 if (this.optional) {
285 return 4 + list_overhead(this.args);
286 }
287 return 2 + list_overhead(this.args);
288};
289
290AST_New.prototype._size = function () {
291 return 6 + list_overhead(this.args);
292};
293
294AST_Sequence.prototype._size = function () {
295 return list_overhead(this.expressions);
296};
297
298AST_Dot.prototype._size = function () {
299 if (this.optional) {
300 return this.property.length + 2;
301 }
302 return this.property.length + 1;
303};
304
305AST_Sub.prototype._size = function () {
306 return this.optional ? 4 : 2;
307};
308
309AST_Unary.prototype._size = function () {
310 if (this.operator === "typeof") return 7;
311 if (this.operator === "void") return 5;
312 return this.operator.length;
313};
314
315AST_Binary.prototype._size = function (info) {
316 if (this.operator === "in") return 4;
317
318 let size = this.operator.length;
319
320 if (
321 (this.operator === "+" || this.operator === "-")
322 && this.right instanceof AST_Unary && this.right.operator === this.operator
323 ) {
324 // 1+ +a > needs space between the +
325 size += 1;
326 }
327
328 if (this.needs_parens(info)) {
329 size += 2;
330 }
331
332 return size;
333};
334
335AST_Conditional.prototype._size = () => 3;
336
337AST_Array.prototype._size = function () {
338 return 2 + list_overhead(this.elements);
339};
340
341AST_Object.prototype._size = function (info) {
342 let base = 2;
343 if (first_in_statement(info)) {
344 base += 2; // parens
345 }
346 return base + list_overhead(this.properties);
347};
348
349/*#__INLINE__*/
350const key_size = key =>
351 typeof key === "string" ? key.length : 0;
352
353AST_ObjectKeyVal.prototype._size = function () {
354 return key_size(this.key) + 1;
355};
356
357/*#__INLINE__*/
358const static_size = is_static => is_static ? 7 : 0;
359
360AST_ObjectGetter.prototype._size = function () {
361 return 5 + static_size(this.static) + key_size(this.key);
362};
363
364AST_ObjectSetter.prototype._size = function () {
365 return 5 + static_size(this.static) + key_size(this.key);
366};
367
368AST_ConciseMethod.prototype._size = function () {
369 return static_size(this.static) + key_size(this.key) + lambda_modifiers(this);
370};
371
372AST_Class.prototype._size = function () {
373 return (
374 (this.name ? 8 : 7)
375 + (this.extends ? 8 : 0)
376 );
377};
378
379AST_ClassProperty.prototype._size = function () {
380 return (
381 static_size(this.static)
382 + (typeof this.key === "string" ? this.key.length + 2 : 0)
383 + (this.value ? 1 : 0)
384 );
385};
386
387AST_Symbol.prototype._size = function () {
388 return !mangle_options || this.definition().unmangleable(mangle_options)
389 ? this.name.length
390 : 1;
391};
392
393// TODO take propmangle into account
394AST_SymbolClassProperty.prototype._size = function () {
395 return this.name.length;
396};
397
398AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () {
399 const { name, thedef } = this;
400
401 if (thedef && thedef.global) return name.length;
402
403 if (name === "arguments") return 9;
404
405 return AST_Symbol.prototype._size.call(this);
406};
407
408AST_NewTarget.prototype._size = () => 10;
409
410AST_SymbolImportForeign.prototype._size = function () {
411 return this.name.length;
412};
413
414AST_SymbolExportForeign.prototype._size = function () {
415 return this.name.length;
416};
417
418AST_This.prototype._size = () => 4;
419
420AST_Super.prototype._size = () => 5;
421
422AST_String.prototype._size = function () {
423 return this.value.length + 2;
424};
425
426AST_Number.prototype._size = function () {
427 const { value } = this;
428 if (value === 0) return 1;
429 if (value > 0 && Math.floor(value) === value) {
430 return Math.floor(Math.log10(value) + 1);
431 }
432 return value.toString().length;
433};
434
435AST_BigInt.prototype._size = function () {
436 return this.value.length;
437};
438
439AST_RegExp.prototype._size = function () {
440 return this.value.toString().length;
441};
442
443AST_Null.prototype._size = () => 4;
444
445AST_NaN.prototype._size = () => 3;
446
447AST_Undefined.prototype._size = () => 6; // "void 0"
448
449AST_Hole.prototype._size = () => 0; // comma is taken into account
450
451AST_Infinity.prototype._size = () => 8;
452
453AST_True.prototype._size = () => 4;
454
455AST_False.prototype._size = () => 5;
456
457AST_Await.prototype._size = () => 6;
458
459AST_Yield.prototype._size = () => 6;