1 | import { Parser } from 'acorn';
|
2 | import acornJsx from 'acorn-jsx';
|
3 | import acornDynamicImport from 'acorn-dynamic-import';
|
4 | import MagicString from 'magic-string';
|
5 | import rewritePattern from 'regexpu-core';
|
6 |
|
7 |
|
8 |
|
9 | function toJSON(node) {
|
10 | var obj = {};
|
11 |
|
12 | Object.keys(node).forEach(key => {
|
13 | if (
|
14 | key === 'parent' ||
|
15 | key === 'program' ||
|
16 | key === 'keys' ||
|
17 | key === '__wrapped'
|
18 | )
|
19 | { return; }
|
20 |
|
21 | if (Array.isArray(node[key])) {
|
22 | obj[key] = node[key].map(toJSON);
|
23 | } else if (node[key] && node[key].toJSON) {
|
24 | obj[key] = node[key].toJSON();
|
25 | } else {
|
26 | obj[key] = node[key];
|
27 | }
|
28 | });
|
29 |
|
30 | return obj;
|
31 | }
|
32 |
|
33 | class Node {
|
34 | ancestor(level) {
|
35 | var node = this;
|
36 | while (level--) {
|
37 | node = node.parent;
|
38 | if (!node) { return null; }
|
39 | }
|
40 |
|
41 | return node;
|
42 | }
|
43 |
|
44 | contains(node) {
|
45 | while (node) {
|
46 | if (node === this) { return true; }
|
47 | node = node.parent;
|
48 | }
|
49 |
|
50 | return false;
|
51 | }
|
52 |
|
53 | findLexicalBoundary() {
|
54 | return this.parent.findLexicalBoundary();
|
55 | }
|
56 |
|
57 | findNearest(type) {
|
58 | if (typeof type === 'string') { type = new RegExp(`^${type}$`); }
|
59 | if (type.test(this.type)) { return this; }
|
60 | return this.parent.findNearest(type);
|
61 | }
|
62 |
|
63 | unparenthesizedParent() {
|
64 | var node = this.parent;
|
65 | while (node && node.type === 'ParenthesizedExpression') {
|
66 | node = node.parent;
|
67 | }
|
68 | return node;
|
69 | }
|
70 |
|
71 | unparenthesize() {
|
72 | var node = this;
|
73 | while (node.type === 'ParenthesizedExpression') {
|
74 | node = node.expression;
|
75 | }
|
76 | return node;
|
77 | }
|
78 |
|
79 | findScope(functionScope) {
|
80 | return this.parent.findScope(functionScope);
|
81 | }
|
82 |
|
83 | getIndentation() {
|
84 | return this.parent.getIndentation();
|
85 | }
|
86 |
|
87 | initialise(transforms) {
|
88 | for (var i = 0, list = this.keys; i < list.length; i += 1) {
|
89 | var key = list[i];
|
90 |
|
91 | var value = this[key];
|
92 |
|
93 | if (Array.isArray(value)) {
|
94 | value.forEach(node => node && node.initialise(transforms));
|
95 | } else if (value && typeof value === 'object') {
|
96 | value.initialise(transforms);
|
97 | }
|
98 | }
|
99 | }
|
100 |
|
101 | toJSON() {
|
102 | return toJSON(this);
|
103 | }
|
104 |
|
105 | toString() {
|
106 | return this.program.magicString.original.slice(this.start, this.end);
|
107 | }
|
108 |
|
109 | transpile(code, transforms) {
|
110 | for (var i = 0, list = this.keys; i < list.length; i += 1) {
|
111 | var key = list[i];
|
112 |
|
113 | var value = this[key];
|
114 |
|
115 | if (Array.isArray(value)) {
|
116 | value.forEach(node => node && node.transpile(code, transforms));
|
117 | } else if (value && typeof value === 'object') {
|
118 | value.transpile(code, transforms);
|
119 | }
|
120 | }
|
121 | }
|
122 | }
|
123 |
|
124 | function extractNames(node) {
|
125 | var names = [];
|
126 | extractors[node.type](names, node);
|
127 | return names;
|
128 | }
|
129 |
|
130 | var extractors = {
|
131 | Identifier(names, node) {
|
132 | names.push(node);
|
133 | },
|
134 |
|
135 | ObjectPattern(names, node) {
|
136 | for (var i = 0, list = node.properties; i < list.length; i += 1) {
|
137 | var prop = list[i];
|
138 |
|
139 | extractors[prop.type](names, prop);
|
140 | }
|
141 | },
|
142 |
|
143 | Property(names, node) {
|
144 | extractors[node.value.type](names, node.value);
|
145 | },
|
146 |
|
147 | ArrayPattern(names, node) {
|
148 | for (var i = 0, list = node.elements; i < list.length; i += 1) {
|
149 | var element = list[i];
|
150 |
|
151 | if (element) { extractors[element.type](names, element); }
|
152 | }
|
153 | },
|
154 |
|
155 | RestElement(names, node) {
|
156 | extractors[node.argument.type](names, node.argument);
|
157 | },
|
158 |
|
159 | AssignmentPattern(names, node) {
|
160 | extractors[node.left.type](names, node.left);
|
161 | }
|
162 | };
|
163 |
|
164 | var reserved = Object.create(null);
|
165 | 'do if in for let new try var case else enum eval null this true void with await break catch class const false super throw while yield delete export import public return static switch typeof default extends finally package private continue debugger function arguments interface protected implements instanceof'
|
166 | .split(' ')
|
167 | .forEach(word => (reserved[word] = true));
|
168 |
|
169 | function Scope(options) {
|
170 | options = options || {};
|
171 |
|
172 | this.parent = options.parent;
|
173 | this.isBlockScope = !!options.block;
|
174 | this.createDeclarationCallback = options.declare;
|
175 |
|
176 | var scope = this;
|
177 | while (scope.isBlockScope) { scope = scope.parent; }
|
178 | this.functionScope = scope;
|
179 |
|
180 | this.identifiers = [];
|
181 | this.declarations = Object.create(null);
|
182 | this.references = Object.create(null);
|
183 | this.blockScopedDeclarations = this.isBlockScope ? null : Object.create(null);
|
184 | this.aliases = Object.create(null);
|
185 | }
|
186 |
|
187 | Scope.prototype = {
|
188 | addDeclaration(node, kind) {
|
189 | for (var i = 0, list = extractNames(node); i < list.length; i += 1) {
|
190 | var identifier = list[i];
|
191 |
|
192 | var name = identifier.name;
|
193 |
|
194 | var declaration = { name, node: identifier, kind, instances: [] };
|
195 | this.declarations[name] = declaration;
|
196 |
|
197 | if (this.isBlockScope) {
|
198 | if (!this.functionScope.blockScopedDeclarations[name])
|
199 | { this.functionScope.blockScopedDeclarations[name] = []; }
|
200 | this.functionScope.blockScopedDeclarations[name].push(declaration);
|
201 | }
|
202 | }
|
203 | },
|
204 |
|
205 | addReference(identifier) {
|
206 | if (this.consolidated) {
|
207 | this.consolidateReference(identifier);
|
208 | } else {
|
209 | this.identifiers.push(identifier);
|
210 | }
|
211 | },
|
212 |
|
213 | consolidate() {
|
214 | for (var i = 0; i < this.identifiers.length; i += 1) {
|
215 |
|
216 | var identifier = this.identifiers[i];
|
217 | this.consolidateReference(identifier);
|
218 | }
|
219 |
|
220 | this.consolidated = true;
|
221 | },
|
222 |
|
223 | consolidateReference(identifier) {
|
224 | var declaration = this.declarations[identifier.name];
|
225 | if (declaration) {
|
226 | declaration.instances.push(identifier);
|
227 | } else {
|
228 | this.references[identifier.name] = true;
|
229 | if (this.parent) { this.parent.addReference(identifier); }
|
230 | }
|
231 | },
|
232 |
|
233 | contains(name) {
|
234 | return (
|
235 | this.declarations[name] ||
|
236 | (this.parent ? this.parent.contains(name) : false)
|
237 | );
|
238 | },
|
239 |
|
240 | createIdentifier(base) {
|
241 | if (typeof base === 'number') { base = base.toString(); }
|
242 |
|
243 | base = base
|
244 | .replace(/\s/g, '')
|
245 | .replace(/\[([^\]]+)\]/g, '_$1')
|
246 | .replace(/[^a-zA-Z0-9_$]/g, '_')
|
247 | .replace(/_{2,}/, '_');
|
248 |
|
249 | var name = base;
|
250 | var counter = 1;
|
251 |
|
252 | while (
|
253 | this.declarations[name] ||
|
254 | this.references[name] ||
|
255 | this.aliases[name] ||
|
256 | name in reserved
|
257 | ) {
|
258 | name = `${base}$${counter++}`;
|
259 | }
|
260 |
|
261 | this.aliases[name] = true;
|
262 | return name;
|
263 | },
|
264 |
|
265 | createDeclaration(base) {
|
266 | var id = this.createIdentifier(base);
|
267 | this.createDeclarationCallback(id);
|
268 | return id;
|
269 | },
|
270 |
|
271 | findDeclaration(name) {
|
272 | return (
|
273 | this.declarations[name] ||
|
274 | (this.parent && this.parent.findDeclaration(name))
|
275 | );
|
276 | },
|
277 |
|
278 |
|
279 | resolveName(name) {
|
280 | var declaration = this.findDeclaration(name);
|
281 | return declaration ? declaration.name : name;
|
282 | }
|
283 | };
|
284 |
|
285 | function locate(source, index) {
|
286 | var lines = source.split('\n');
|
287 | var len = lines.length;
|
288 |
|
289 | var lineStart = 0;
|
290 | var i;
|
291 |
|
292 | for (i = 0; i < len; i += 1) {
|
293 | var line = lines[i];
|
294 | var lineEnd = lineStart + line.length + 1;
|
295 |
|
296 | if (lineEnd > index) {
|
297 | return { line: i + 1, column: index - lineStart, char: i };
|
298 | }
|
299 |
|
300 | lineStart = lineEnd;
|
301 | }
|
302 |
|
303 | throw new Error('Could not determine location of character');
|
304 | }
|
305 |
|
306 | function pad(num, len) {
|
307 | var result = String(num);
|
308 | return result + repeat(' ', len - result.length);
|
309 | }
|
310 |
|
311 | function repeat(str, times) {
|
312 | var result = '';
|
313 | while (times--) { result += str; }
|
314 | return result;
|
315 | }
|
316 |
|
317 | function getSnippet(source, loc, length) {
|
318 | if ( length === void 0 ) length = 1;
|
319 |
|
320 | var first = Math.max(loc.line - 5, 0);
|
321 | var last = loc.line;
|
322 |
|
323 | var numDigits = String(last).length;
|
324 |
|
325 | var lines = source.split('\n').slice(first, last);
|
326 |
|
327 | var lastLine = lines[lines.length - 1];
|
328 | var offset = lastLine.slice(0, loc.column).replace(/\t/g, ' ').length;
|
329 |
|
330 | var snippet = lines
|
331 | .map((line, i) => `${pad(i + first + 1, numDigits)} : ${line.replace(/\t/g, ' ')}`)
|
332 | .join('\n');
|
333 |
|
334 | snippet += '\n' + repeat(' ', numDigits + 3 + offset) + repeat('^', length);
|
335 |
|
336 | return snippet;
|
337 | }
|
338 |
|
339 | class CompileError extends Error {
|
340 | constructor(message, node) {
|
341 | super(message);
|
342 |
|
343 | this.name = 'CompileError';
|
344 | if (!node) {
|
345 | return;
|
346 | }
|
347 |
|
348 | var source = node.program.magicString.original;
|
349 | var loc = locate(source, node.start);
|
350 |
|
351 | this.message = message + ` (${loc.line}:${loc.column})`;
|
352 |
|
353 | this.stack = new Error().stack.replace(
|
354 | new RegExp(`.+new ${this.name}.+\\n`, 'm'),
|
355 | ''
|
356 | );
|
357 |
|
358 | this.loc = loc;
|
359 | this.snippet = getSnippet(source, loc, node.end - node.start);
|
360 | }
|
361 |
|
362 | toString() {
|
363 | return `${this.name}: ${this.message}\n${this.snippet}`;
|
364 | }
|
365 |
|
366 | static missingTransform(feature, transformKey, node, dangerousKey) {
|
367 | if ( dangerousKey === void 0 ) dangerousKey = null;
|
368 |
|
369 | var maybeDangerous = dangerousKey ? `, or \`transforms: { ${dangerousKey}: true }\` if you know what you're doing` : '';
|
370 | throw new CompileError(`Transforming ${feature} is not ${dangerousKey ? "fully supported" : "implemented"}. Use \`transforms: { ${transformKey}: false }\` to skip transformation and disable this error${maybeDangerous}.`, node);
|
371 | }
|
372 | }
|
373 |
|
374 | function findIndex(array, fn) {
|
375 | for (var i = 0; i < array.length; i += 1) {
|
376 | if (fn(array[i], i)) { return i; }
|
377 | }
|
378 |
|
379 | return -1;
|
380 | }
|
381 |
|
382 | var handlers = {
|
383 | Identifier: destructureIdentifier,
|
384 | AssignmentPattern: destructureAssignmentPattern,
|
385 | ArrayPattern: destructureArrayPattern,
|
386 | ObjectPattern: destructureObjectPattern
|
387 | };
|
388 |
|
389 | function destructure(
|
390 | code,
|
391 | createIdentifier,
|
392 | resolveName,
|
393 | node,
|
394 | ref,
|
395 | inline,
|
396 | statementGenerators
|
397 | ) {
|
398 | handlers[node.type](code, createIdentifier, resolveName, node, ref, inline, statementGenerators);
|
399 | }
|
400 |
|
401 | function destructureIdentifier(
|
402 | code,
|
403 | createIdentifier,
|
404 | resolveName,
|
405 | node,
|
406 | ref,
|
407 | inline,
|
408 | statementGenerators
|
409 | ) {
|
410 | statementGenerators.push((start, prefix, suffix) => {
|
411 | code.overwrite(node.start, node.end, (inline ? prefix : `${prefix}var `) + resolveName(node) + ` = ${ref}${suffix}`);
|
412 | code.move(node.start, node.end, start);
|
413 | });
|
414 | }
|
415 |
|
416 | function destructureMemberExpression(
|
417 | code,
|
418 | createIdentifier,
|
419 | resolveName,
|
420 | node,
|
421 | ref,
|
422 | inline,
|
423 | statementGenerators
|
424 | ) {
|
425 | statementGenerators.push((start, prefix, suffix) => {
|
426 | code.prependRight(node.start, inline ? prefix : `${prefix}var `);
|
427 | code.appendLeft(node.end, ` = ${ref}${suffix}`);
|
428 | code.move(node.start, node.end, start);
|
429 | });
|
430 | }
|
431 |
|
432 | function destructureAssignmentPattern(
|
433 | code,
|
434 | createIdentifier,
|
435 | resolveName,
|
436 | node,
|
437 | ref,
|
438 | inline,
|
439 | statementGenerators
|
440 | ) {
|
441 | var isIdentifier = node.left.type === 'Identifier';
|
442 | var name = isIdentifier ? node.left.name : ref;
|
443 |
|
444 | if (!inline) {
|
445 | statementGenerators.push((start, prefix, suffix) => {
|
446 | code.prependRight(
|
447 | node.left.end,
|
448 | `${prefix}if ( ${name} === void 0 ) ${name}`
|
449 | );
|
450 | code.move(node.left.end, node.right.end, start);
|
451 | code.appendLeft(node.right.end, suffix);
|
452 | });
|
453 | }
|
454 |
|
455 | if (!isIdentifier) {
|
456 | destructure(code, createIdentifier, resolveName, node.left, ref, inline, statementGenerators);
|
457 | }
|
458 | }
|
459 |
|
460 | function destructureArrayPattern(
|
461 | code,
|
462 | createIdentifier,
|
463 | resolveName,
|
464 | node,
|
465 | ref,
|
466 | inline,
|
467 | statementGenerators
|
468 | ) {
|
469 | var c = node.start;
|
470 |
|
471 | node.elements.forEach((element, i) => {
|
472 | if (!element) { return; }
|
473 |
|
474 | if (element.type === 'RestElement') {
|
475 | handleProperty(
|
476 | code,
|
477 | createIdentifier,
|
478 | resolveName,
|
479 | c,
|
480 | element.argument,
|
481 | `${ref}.slice(${i})`,
|
482 | inline,
|
483 | statementGenerators
|
484 | );
|
485 | } else {
|
486 | handleProperty(
|
487 | code,
|
488 | createIdentifier,
|
489 | resolveName,
|
490 | c,
|
491 | element,
|
492 | `${ref}[${i}]`,
|
493 | inline,
|
494 | statementGenerators
|
495 | );
|
496 | }
|
497 | c = element.end;
|
498 | });
|
499 |
|
500 | code.remove(c, node.end);
|
501 | }
|
502 |
|
503 | function destructureObjectPattern(
|
504 | code,
|
505 | createIdentifier,
|
506 | resolveName,
|
507 | node,
|
508 | ref,
|
509 | inline,
|
510 | statementGenerators
|
511 | ) {
|
512 | var c = node.start;
|
513 |
|
514 | var nonRestKeys = [];
|
515 | node.properties.forEach(prop => {
|
516 | var value;
|
517 | var content;
|
518 | if (prop.type === 'Property') {
|
519 | content = prop.value;
|
520 | if (!prop.computed && prop.key.type === 'Identifier') {
|
521 | value = `${ref}.${prop.key.name}`;
|
522 | nonRestKeys.push(`"${prop.key.name}"`);
|
523 | } else if (!prop.computed && prop.key.type === 'Literal') {
|
524 | value = `${ref}[${prop.key.raw}]`;
|
525 | nonRestKeys.push(JSON.stringify(String(prop.key.value)));
|
526 | } else {
|
527 | var expr = code.slice(prop.key.start, prop.key.end);
|
528 | value = `${ref}[${expr}]`;
|
529 | nonRestKeys.push(`String(${expr})`);
|
530 | }
|
531 | } else if (prop.type === 'RestElement') {
|
532 | content = prop.argument;
|
533 | value = createIdentifier('rest');
|
534 | statementGenerators.push((start, prefix, suffix) => {
|
535 | var helper = prop.program.getObjectWithoutPropertiesHelper(code);
|
536 | code.overwrite(
|
537 | prop.start,
|
538 | (c = prop.argument.start),
|
539 | (inline ? prefix : `${prefix}var `) + `${value} = ${helper}( ${ref}, [${nonRestKeys.join(', ')}] )${suffix}`
|
540 | );
|
541 | code.move(prop.start, c, start);
|
542 | });
|
543 | } else {
|
544 | throw new CompileError(
|
545 | this,
|
546 | `Unexpected node of type ${prop.type} in object pattern`
|
547 | );
|
548 | }
|
549 | handleProperty(code, createIdentifier, resolveName, c, content, value, inline, statementGenerators);
|
550 | c = prop.end;
|
551 | });
|
552 |
|
553 | code.remove(c, node.end);
|
554 | }
|
555 |
|
556 | function handleProperty(
|
557 | code,
|
558 | createIdentifier,
|
559 | resolveName,
|
560 | c,
|
561 | node,
|
562 | value,
|
563 | inline,
|
564 | statementGenerators
|
565 | ) {
|
566 | switch (node.type) {
|
567 | case 'Identifier': {
|
568 | code.remove(c, node.start);
|
569 | destructureIdentifier(
|
570 | code,
|
571 | createIdentifier,
|
572 | resolveName,
|
573 | node,
|
574 | value,
|
575 | inline,
|
576 | statementGenerators
|
577 | );
|
578 | break;
|
579 | }
|
580 |
|
581 | case 'MemberExpression':
|
582 | code.remove(c, node.start);
|
583 | destructureMemberExpression(
|
584 | code,
|
585 | createIdentifier,
|
586 | resolveName,
|
587 | node,
|
588 | value,
|
589 | true,
|
590 | statementGenerators
|
591 | );
|
592 | break;
|
593 |
|
594 | case 'AssignmentPattern': {
|
595 | var name;
|
596 |
|
597 | var isIdentifier = node.left.type === 'Identifier';
|
598 |
|
599 | if (isIdentifier) {
|
600 | name = resolveName(node.left);
|
601 | } else {
|
602 | name = createIdentifier(value);
|
603 | }
|
604 |
|
605 | statementGenerators.push((start, prefix, suffix) => {
|
606 | if (inline) {
|
607 | code.prependRight(
|
608 | node.right.start,
|
609 | `${name} = ${value}, ${name} = ${name} === void 0 ? `
|
610 | );
|
611 | code.appendLeft(node.right.end, ` : ${name}${suffix}`);
|
612 | } else {
|
613 | code.prependRight(
|
614 | node.right.start,
|
615 | `${prefix}var ${name} = ${value}; if ( ${name} === void 0 ) ${name} = `
|
616 | );
|
617 | code.appendLeft(node.right.end, suffix);
|
618 | }
|
619 |
|
620 | code.move(node.right.start, node.right.end, start);
|
621 | });
|
622 |
|
623 | if (isIdentifier) {
|
624 | code.remove(c, node.right.start);
|
625 | } else {
|
626 | code.remove(c, node.left.start);
|
627 | code.remove(node.left.end, node.right.start);
|
628 | handleProperty(
|
629 | code,
|
630 | createIdentifier,
|
631 | resolveName,
|
632 | c,
|
633 | node.left,
|
634 | name,
|
635 | inline,
|
636 | statementGenerators
|
637 | );
|
638 | }
|
639 |
|
640 | break;
|
641 | }
|
642 |
|
643 | case 'ObjectPattern': {
|
644 | code.remove(c, (c = node.start));
|
645 |
|
646 | var ref = value;
|
647 | if (node.properties.length > 1) {
|
648 | ref = createIdentifier(value);
|
649 |
|
650 | statementGenerators.push((start, prefix, suffix) => {
|
651 |
|
652 |
|
653 | code.prependRight(node.start, (inline ? '' : `${prefix}var `) + `${ref} = `);
|
654 | code.overwrite(node.start, (c = node.start + 1), value);
|
655 | code.appendLeft(c, suffix);
|
656 |
|
657 | code.overwrite(
|
658 | node.start,
|
659 | (c = node.start + 1),
|
660 | (inline ? '' : `${prefix}var `) + `${ref} = ${value}${suffix}`
|
661 | );
|
662 | code.move(node.start, c, start);
|
663 | });
|
664 | }
|
665 |
|
666 | destructureObjectPattern(
|
667 | code,
|
668 | createIdentifier,
|
669 | resolveName,
|
670 | node,
|
671 | ref,
|
672 | inline,
|
673 | statementGenerators
|
674 | );
|
675 |
|
676 | break;
|
677 | }
|
678 |
|
679 | case 'ArrayPattern': {
|
680 | code.remove(c, (c = node.start));
|
681 |
|
682 | if (node.elements.filter(Boolean).length > 1) {
|
683 | var ref$1 = createIdentifier(value);
|
684 |
|
685 | statementGenerators.push((start, prefix, suffix) => {
|
686 | code.prependRight(node.start, (inline ? '' : `${prefix}var `) + `${ref$1} = `);
|
687 | code.overwrite(node.start, (c = node.start + 1), value, {
|
688 | contentOnly: true
|
689 | });
|
690 | code.appendLeft(c, suffix);
|
691 |
|
692 | code.move(node.start, c, start);
|
693 | });
|
694 |
|
695 | node.elements.forEach((element, i) => {
|
696 | if (!element) { return; }
|
697 |
|
698 | if (element.type === 'RestElement') {
|
699 | handleProperty(
|
700 | code,
|
701 | createIdentifier,
|
702 | resolveName,
|
703 | c,
|
704 | element.argument,
|
705 | `${ref$1}.slice(${i})`,
|
706 | inline,
|
707 | statementGenerators
|
708 | );
|
709 | } else {
|
710 | handleProperty(
|
711 | code,
|
712 | createIdentifier,
|
713 | resolveName,
|
714 | c,
|
715 | element,
|
716 | `${ref$1}[${i}]`,
|
717 | inline,
|
718 | statementGenerators
|
719 | );
|
720 | }
|
721 | c = element.end;
|
722 | });
|
723 | } else {
|
724 | var index = findIndex(node.elements, Boolean);
|
725 | var element = node.elements[index];
|
726 | if (element.type === 'RestElement') {
|
727 | handleProperty(
|
728 | code,
|
729 | createIdentifier,
|
730 | resolveName,
|
731 | c,
|
732 | element.argument,
|
733 | `${value}.slice(${index})`,
|
734 | inline,
|
735 | statementGenerators
|
736 | );
|
737 | } else {
|
738 | handleProperty(
|
739 | code,
|
740 | createIdentifier,
|
741 | resolveName,
|
742 | c,
|
743 | element,
|
744 | `${value}[${index}]`,
|
745 | inline,
|
746 | statementGenerators
|
747 | );
|
748 | }
|
749 | c = element.end;
|
750 | }
|
751 |
|
752 | code.remove(c, node.end);
|
753 | break;
|
754 | }
|
755 |
|
756 | default: {
|
757 | throw new Error(`Unexpected node type in destructuring (${node.type})`);
|
758 | }
|
759 | }
|
760 | }
|
761 |
|
762 | function isUseStrict(node) {
|
763 | if (!node) { return false; }
|
764 | if (node.type !== 'ExpressionStatement') { return false; }
|
765 | if (node.expression.type !== 'Literal') { return false; }
|
766 | return node.expression.value === 'use strict';
|
767 | }
|
768 |
|
769 | class BlockStatement extends Node {
|
770 | createScope() {
|
771 | this.parentIsFunction = /Function/.test(this.parent.type);
|
772 | this.isFunctionBlock = this.parentIsFunction || this.parent.type === 'Root';
|
773 | this.scope = new Scope({
|
774 | block: !this.isFunctionBlock,
|
775 | parent: this.parent.findScope(false),
|
776 | declare: id => this.createdDeclarations.push(id)
|
777 | });
|
778 |
|
779 | if (this.parentIsFunction) {
|
780 | this.parent.params.forEach(node => {
|
781 | this.scope.addDeclaration(node, 'param');
|
782 | });
|
783 | }
|
784 | }
|
785 |
|
786 | initialise(transforms) {
|
787 | this.thisAlias = null;
|
788 | this.argumentsAlias = null;
|
789 | this.defaultParameters = [];
|
790 | this.createdDeclarations = [];
|
791 |
|
792 |
|
793 |
|
794 |
|
795 |
|
796 | if (!this.scope) { this.createScope(); }
|
797 |
|
798 | this.body.forEach(node => node.initialise(transforms));
|
799 |
|
800 | this.scope.consolidate();
|
801 | }
|
802 |
|
803 | findLexicalBoundary() {
|
804 | if (this.type === 'Program') { return this; }
|
805 | if (/^Function/.test(this.parent.type)) { return this; }
|
806 |
|
807 | return this.parent.findLexicalBoundary();
|
808 | }
|
809 |
|
810 | findScope(functionScope) {
|
811 | if (functionScope && !this.isFunctionBlock)
|
812 | { return this.parent.findScope(functionScope); }
|
813 | return this.scope;
|
814 | }
|
815 |
|
816 | getArgumentsAlias() {
|
817 | if (!this.argumentsAlias) {
|
818 | this.argumentsAlias = this.scope.createIdentifier('arguments');
|
819 | }
|
820 |
|
821 | return this.argumentsAlias;
|
822 | }
|
823 |
|
824 | getArgumentsArrayAlias() {
|
825 | if (!this.argumentsArrayAlias) {
|
826 | this.argumentsArrayAlias = this.scope.createIdentifier('argsArray');
|
827 | }
|
828 |
|
829 | return this.argumentsArrayAlias;
|
830 | }
|
831 |
|
832 | getThisAlias() {
|
833 | if (!this.thisAlias) {
|
834 | this.thisAlias = this.scope.createIdentifier('this');
|
835 | }
|
836 |
|
837 | return this.thisAlias;
|
838 | }
|
839 |
|
840 | getIndentation() {
|
841 | if (this.indentation === undefined) {
|
842 | var source = this.program.magicString.original;
|
843 |
|
844 | var useOuter = this.synthetic || !this.body.length;
|
845 | var c = useOuter ? this.start : this.body[0].start;
|
846 |
|
847 | while (c && source[c] !== '\n') { c -= 1; }
|
848 |
|
849 | this.indentation = '';
|
850 |
|
851 |
|
852 | while (true) {
|
853 | c += 1;
|
854 | var char = source[c];
|
855 |
|
856 | if (char !== ' ' && char !== '\t') { break; }
|
857 |
|
858 | this.indentation += char;
|
859 | }
|
860 |
|
861 | var indentString = this.program.magicString.getIndentString();
|
862 |
|
863 |
|
864 | var parent = this.parent;
|
865 | while (parent) {
|
866 | if (parent.kind === 'constructor' && !parent.parent.parent.superClass) {
|
867 | this.indentation = this.indentation.replace(indentString, '');
|
868 | }
|
869 |
|
870 | parent = parent.parent;
|
871 | }
|
872 |
|
873 | if (useOuter) { this.indentation += indentString; }
|
874 | }
|
875 |
|
876 | return this.indentation;
|
877 | }
|
878 |
|
879 | transpile(code, transforms) {
|
880 | var indentation = this.getIndentation();
|
881 |
|
882 | var introStatementGenerators = [];
|
883 |
|
884 | if (this.argumentsAlias) {
|
885 | introStatementGenerators.push((start, prefix, suffix) => {
|
886 | var assignment = `${prefix}var ${this.argumentsAlias} = arguments${
|
887 | suffix
|
888 | }`;
|
889 | code.appendLeft(start, assignment);
|
890 | });
|
891 | }
|
892 |
|
893 | if (this.thisAlias) {
|
894 | introStatementGenerators.push((start, prefix, suffix) => {
|
895 | var assignment = `${prefix}var ${this.thisAlias} = this${suffix}`;
|
896 | code.appendLeft(start, assignment);
|
897 | });
|
898 | }
|
899 |
|
900 | if (this.argumentsArrayAlias) {
|
901 | introStatementGenerators.push((start, prefix, suffix) => {
|
902 | var i = this.scope.createIdentifier('i');
|
903 | var assignment = `${prefix}var ${i} = arguments.length, ${
|
904 | this.argumentsArrayAlias
|
905 | } = Array(${i});\n${indentation}while ( ${i}-- ) ${
|
906 | this.argumentsArrayAlias
|
907 | }[${i}] = arguments[${i}]${suffix}`;
|
908 | code.appendLeft(start, assignment);
|
909 | });
|
910 | }
|
911 |
|
912 | if (/Function/.test(this.parent.type)) {
|
913 | this.transpileParameters(
|
914 | this.parent.params,
|
915 | code,
|
916 | transforms,
|
917 | indentation,
|
918 | introStatementGenerators
|
919 | );
|
920 | } else if ('CatchClause' === this.parent.type) {
|
921 | this.transpileParameters(
|
922 | [this.parent.param],
|
923 | code,
|
924 | transforms,
|
925 | indentation,
|
926 | introStatementGenerators
|
927 | );
|
928 | }
|
929 |
|
930 | if (transforms.letConst && this.isFunctionBlock) {
|
931 | this.transpileBlockScopedIdentifiers(code);
|
932 | }
|
933 |
|
934 | super.transpile(code, transforms);
|
935 |
|
936 | if (this.createdDeclarations.length) {
|
937 | introStatementGenerators.push((start, prefix, suffix) => {
|
938 | var assignment = `${prefix}var ${this.createdDeclarations.join(', ')}${suffix}`;
|
939 | code.appendLeft(start, assignment);
|
940 | });
|
941 | }
|
942 |
|
943 | if (this.synthetic) {
|
944 | if (this.parent.type === 'ArrowFunctionExpression') {
|
945 | var expr = this.body[0];
|
946 |
|
947 | if (introStatementGenerators.length) {
|
948 | code
|
949 | .appendLeft(this.start, `{`)
|
950 | .prependRight(this.end, `${this.parent.getIndentation()}}`);
|
951 |
|
952 | code.prependRight(expr.start, `\n${indentation}return `);
|
953 | code.appendLeft(expr.end, `;\n`);
|
954 | } else if (transforms.arrow) {
|
955 | code.prependRight(expr.start, `{ return `);
|
956 | code.appendLeft(expr.end, `; }`);
|
957 | }
|
958 | } else if (introStatementGenerators.length) {
|
959 | code.prependRight(this.start, `{`).appendLeft(this.end, `}`);
|
960 | }
|
961 | }
|
962 |
|
963 | var start;
|
964 | if (isUseStrict(this.body[0])) {
|
965 | start = this.body[0].end;
|
966 | } else if (this.synthetic || this.parent.type === 'Root') {
|
967 | start = this.start;
|
968 | } else {
|
969 | start = this.start + 1;
|
970 | }
|
971 |
|
972 | var prefix = `\n${indentation}`;
|
973 | var suffix = ';';
|
974 | introStatementGenerators.forEach((fn, i) => {
|
975 | if (i === introStatementGenerators.length - 1) { suffix = `;\n`; }
|
976 | fn(start, prefix, suffix);
|
977 | });
|
978 | }
|
979 |
|
980 | transpileParameters(params, code, transforms, indentation, introStatementGenerators) {
|
981 | params.forEach(param => {
|
982 | if (
|
983 | param.type === 'AssignmentPattern' &&
|
984 | param.left.type === 'Identifier'
|
985 | ) {
|
986 | if (transforms.defaultParameter) {
|
987 | introStatementGenerators.push((start, prefix, suffix) => {
|
988 | var lhs = `${prefix}if ( ${param.left.name} === void 0 ) ${
|
989 | param.left.name
|
990 | }`;
|
991 |
|
992 | code
|
993 | .prependRight(param.left.end, lhs)
|
994 | .move(param.left.end, param.right.end, start)
|
995 | .appendLeft(param.right.end, suffix);
|
996 | });
|
997 | }
|
998 | } else if (param.type === 'RestElement') {
|
999 | if (transforms.spreadRest) {
|
1000 | introStatementGenerators.push((start, prefix, suffix) => {
|
1001 | var penultimateParam = params[params.length - 2];
|
1002 |
|
1003 | if (penultimateParam) {
|
1004 | code.remove(
|
1005 | penultimateParam ? penultimateParam.end : param.start,
|
1006 | param.end
|
1007 | );
|
1008 | } else {
|
1009 | var start$1 = param.start,
|
1010 | end = param.end;
|
1011 |
|
1012 | while (/\s/.test(code.original[start$1 - 1])) { start$1 -= 1; }
|
1013 | while (/\s/.test(code.original[end])) { end += 1; }
|
1014 |
|
1015 | code.remove(start$1, end);
|
1016 | }
|
1017 |
|
1018 | var name = param.argument.name;
|
1019 | var len = this.scope.createIdentifier('len');
|
1020 | var count = params.length - 1;
|
1021 |
|
1022 | if (count) {
|
1023 | code.prependRight(
|
1024 | start,
|
1025 | `${prefix}var ${name} = [], ${len} = arguments.length - ${
|
1026 | count
|
1027 | };\n${indentation}while ( ${len}-- > 0 ) ${name}[ ${
|
1028 | len
|
1029 | } ] = arguments[ ${len} + ${count} ]${suffix}`
|
1030 | );
|
1031 | } else {
|
1032 | code.prependRight(
|
1033 | start,
|
1034 | `${prefix}var ${name} = [], ${len} = arguments.length;\n${
|
1035 | indentation
|
1036 | }while ( ${len}-- ) ${name}[ ${len} ] = arguments[ ${len} ]${
|
1037 | suffix
|
1038 | }`
|
1039 | );
|
1040 | }
|
1041 | });
|
1042 | }
|
1043 | } else if (param.type !== 'Identifier') {
|
1044 | if (transforms.parameterDestructuring) {
|
1045 | var ref = this.scope.createIdentifier('ref');
|
1046 | destructure(
|
1047 | code,
|
1048 | id => this.scope.createIdentifier(id),
|
1049 | (ref) => {
|
1050 | var name = ref.name;
|
1051 |
|
1052 | return this.scope.resolveName(name);
|
1053 | },
|
1054 | param,
|
1055 | ref,
|
1056 | false,
|
1057 | introStatementGenerators
|
1058 | );
|
1059 | code.prependRight(param.start, ref);
|
1060 | }
|
1061 | }
|
1062 | });
|
1063 | }
|
1064 |
|
1065 | transpileBlockScopedIdentifiers(code) {
|
1066 | Object.keys(this.scope.blockScopedDeclarations).forEach(name => {
|
1067 | var declarations = this.scope.blockScopedDeclarations[name];
|
1068 |
|
1069 | for (var i$2 = 0, list$2 = declarations; i$2 < list$2.length; i$2 += 1) {
|
1070 | var declaration = list$2[i$2];
|
1071 |
|
1072 | var cont = false;
|
1073 |
|
1074 | if (declaration.kind === 'for.let') {
|
1075 |
|
1076 | var forStatement = declaration.node.findNearest('ForStatement');
|
1077 |
|
1078 | if (forStatement.shouldRewriteAsFunction) {
|
1079 | var outerAlias = this.scope.createIdentifier(name);
|
1080 | var innerAlias = forStatement.reassigned[name]
|
1081 | ? this.scope.createIdentifier(name)
|
1082 | : name;
|
1083 |
|
1084 | declaration.name = outerAlias;
|
1085 | code.overwrite(
|
1086 | declaration.node.start,
|
1087 | declaration.node.end,
|
1088 | outerAlias,
|
1089 | { storeName: true }
|
1090 | );
|
1091 |
|
1092 | forStatement.aliases[name] = {
|
1093 | outer: outerAlias,
|
1094 | inner: innerAlias
|
1095 | };
|
1096 |
|
1097 | for (var i = 0, list = declaration.instances; i < list.length; i += 1) {
|
1098 | var identifier = list[i];
|
1099 |
|
1100 | var alias = forStatement.body.contains(identifier)
|
1101 | ? innerAlias
|
1102 | : outerAlias;
|
1103 |
|
1104 | if (name !== alias) {
|
1105 | code.overwrite(identifier.start, identifier.end, alias, {
|
1106 | storeName: true
|
1107 | });
|
1108 | }
|
1109 | }
|
1110 |
|
1111 | cont = true;
|
1112 | }
|
1113 | }
|
1114 |
|
1115 | if (!cont) {
|
1116 | var alias$1 = this.scope.createIdentifier(name);
|
1117 |
|
1118 | if (name !== alias$1) {
|
1119 | var declarationParent = declaration.node.parent;
|
1120 | declaration.name = alias$1;
|
1121 | code.overwrite(
|
1122 | declaration.node.start,
|
1123 | declaration.node.end,
|
1124 | alias$1,
|
1125 | { storeName: true }
|
1126 | );
|
1127 | if (declarationParent.type === 'Property' && declarationParent.shorthand) {
|
1128 | declarationParent.shorthand = false;
|
1129 | code.prependLeft(declaration.node.start, `${name}: `);
|
1130 | }
|
1131 |
|
1132 | for (var i$1 = 0, list$1 = declaration.instances; i$1 < list$1.length; i$1 += 1) {
|
1133 | var identifier$1 = list$1[i$1];
|
1134 |
|
1135 | identifier$1.rewritten = true;
|
1136 | var identifierParent = identifier$1.parent;
|
1137 | code.overwrite(identifier$1.start, identifier$1.end, alias$1, {
|
1138 | storeName: true
|
1139 | });
|
1140 | if (identifierParent.type === 'Property' && identifierParent.shorthand) {
|
1141 | identifierParent.shorthand = false;
|
1142 | code.prependLeft(identifier$1.start, `${name}: `);
|
1143 | }
|
1144 | }
|
1145 | }
|
1146 | }
|
1147 | }
|
1148 | });
|
1149 | }
|
1150 | }
|
1151 |
|
1152 | function isArguments(node) {
|
1153 | return node.type === 'Identifier' && node.name === 'arguments';
|
1154 | }
|
1155 |
|
1156 | function inlineSpreads(
|
1157 | code,
|
1158 | node,
|
1159 | elements
|
1160 | ) {
|
1161 | var i = elements.length;
|
1162 |
|
1163 | while (i--) {
|
1164 | var element = elements[i];
|
1165 | if (!element || element.type !== 'SpreadElement') {
|
1166 | continue;
|
1167 | }
|
1168 | var argument = element.argument;
|
1169 | if (argument.type !== 'ArrayExpression') {
|
1170 | continue;
|
1171 | }
|
1172 | var subelements = argument.elements;
|
1173 | if (subelements.some(subelement => subelement === null)) {
|
1174 |
|
1175 |
|
1176 |
|
1177 |
|
1178 |
|
1179 | continue;
|
1180 | }
|
1181 |
|
1182 | var isLast = i === elements.length - 1;
|
1183 | if (subelements.length === 0) {
|
1184 | code.remove(
|
1185 | isLast && i !== 0
|
1186 | ? elements[i - 1].end
|
1187 | : element.start,
|
1188 | isLast
|
1189 | ? node.end - 1
|
1190 | : elements[i + 1].start);
|
1191 | } else {
|
1192 |
|
1193 |
|
1194 | code.remove(element.start, subelements[0].start);
|
1195 | code.remove(
|
1196 |
|
1197 | subelements[subelements.length - 1].end,
|
1198 |
|
1199 | isLast
|
1200 | ? node.end - 1
|
1201 | : element.end
|
1202 | );
|
1203 | }
|
1204 | elements.splice.apply(elements, [ i, 1 ].concat( subelements ));
|
1205 | i += subelements.length;
|
1206 | }
|
1207 | }
|
1208 |
|
1209 |
|
1210 |
|
1211 |
|
1212 |
|
1213 |
|
1214 |
|
1215 |
|
1216 | function needsParentheses(node) {
|
1217 | switch (node.type) {
|
1218 |
|
1219 |
|
1220 | case 'ArrayExpression':
|
1221 | case 'CallExpression':
|
1222 | case 'Identifier':
|
1223 | case 'ParenthesizedExpression':
|
1224 | case 'ThisExpression':
|
1225 | return false;
|
1226 | default:
|
1227 | return true;
|
1228 | }
|
1229 | }
|
1230 |
|
1231 | function spread(
|
1232 | code,
|
1233 | elements,
|
1234 | start,
|
1235 | argumentsArrayAlias,
|
1236 | isNew
|
1237 | ) {
|
1238 | var i = elements.length;
|
1239 | var firstSpreadIndex = -1;
|
1240 |
|
1241 | while (i--) {
|
1242 | var element$1 = elements[i];
|
1243 | if (element$1 && element$1.type === 'SpreadElement') {
|
1244 | if (isArguments(element$1.argument)) {
|
1245 | code.overwrite(
|
1246 | element$1.argument.start,
|
1247 | element$1.argument.end,
|
1248 | argumentsArrayAlias
|
1249 | );
|
1250 | }
|
1251 |
|
1252 | firstSpreadIndex = i;
|
1253 | }
|
1254 | }
|
1255 |
|
1256 | if (firstSpreadIndex === -1) { return false; }
|
1257 |
|
1258 | if (isNew) {
|
1259 | for (i = 0; i < elements.length; i += 1) {
|
1260 | var element$2 = elements[i];
|
1261 | if (element$2.type === 'SpreadElement') {
|
1262 | code.remove(element$2.start, element$2.argument.start);
|
1263 | } else {
|
1264 | code.prependRight(element$2.start, '[');
|
1265 | code.prependRight(element$2.end, ']');
|
1266 | }
|
1267 | }
|
1268 |
|
1269 | return true;
|
1270 | }
|
1271 |
|
1272 | var element = elements[firstSpreadIndex];
|
1273 | var previousElement = elements[firstSpreadIndex - 1];
|
1274 |
|
1275 | if (!previousElement) {
|
1276 |
|
1277 | var addClosingParen;
|
1278 | if (start !== element.start) {
|
1279 | if ((addClosingParen = needsParentheses(element.argument))) {
|
1280 | code.overwrite(start, element.start, '( ');
|
1281 | } else {
|
1282 | code.remove(start, element.start);
|
1283 | }
|
1284 | } else if (element.parent.type === 'CallExpression') {
|
1285 |
|
1286 |
|
1287 |
|
1288 | addClosingParen = needsParentheses(element.argument);
|
1289 | } else {
|
1290 |
|
1291 | throw new CompileError(
|
1292 | 'Unsupported spread construct, please raise an issue at https://github.com/bublejs/buble/issues',
|
1293 | element
|
1294 | );
|
1295 | }
|
1296 | code.overwrite(element.end, elements[1].start,
|
1297 | addClosingParen ? ' ).concat( ' : '.concat( ');
|
1298 | } else {
|
1299 | code.overwrite(previousElement.end, element.start, ' ].concat( ');
|
1300 | }
|
1301 |
|
1302 | for (i = firstSpreadIndex; i < elements.length; i += 1) {
|
1303 | element = elements[i];
|
1304 |
|
1305 | if (element) {
|
1306 | if (element.type === 'SpreadElement') {
|
1307 | code.remove(element.start, element.argument.start);
|
1308 | } else {
|
1309 | code.appendLeft(element.start, '[');
|
1310 | code.appendLeft(element.end, ']');
|
1311 | }
|
1312 | }
|
1313 | }
|
1314 |
|
1315 | return true;
|
1316 | }
|
1317 |
|
1318 | class ArrayExpression extends Node {
|
1319 | initialise(transforms) {
|
1320 | if (transforms.spreadRest && this.elements.length) {
|
1321 | var lexicalBoundary = this.findLexicalBoundary();
|
1322 |
|
1323 | var i = this.elements.length;
|
1324 | while (i--) {
|
1325 | var element = this.elements[i];
|
1326 | if (
|
1327 | element &&
|
1328 | element.type === 'SpreadElement' &&
|
1329 | isArguments(element.argument)
|
1330 | ) {
|
1331 | this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
|
1332 | }
|
1333 | }
|
1334 | }
|
1335 |
|
1336 | super.initialise(transforms);
|
1337 | }
|
1338 |
|
1339 | transpile(code, transforms) {
|
1340 | super.transpile(code, transforms);
|
1341 |
|
1342 | if (transforms.spreadRest) {
|
1343 | inlineSpreads(code, this, this.elements);
|
1344 |
|
1345 | if (this.elements.length) {
|
1346 | var lastElement = this.elements[this.elements.length - 1];
|
1347 | if (
|
1348 | lastElement &&
|
1349 | /\s*,/.test(code.original.slice(lastElement.end, this.end))
|
1350 | ) {
|
1351 | code.overwrite(lastElement.end, this.end - 1, ' ');
|
1352 | }
|
1353 | }
|
1354 |
|
1355 | if (this.elements.length === 1) {
|
1356 | var element = this.elements[0];
|
1357 |
|
1358 | if (element && element.type === 'SpreadElement') {
|
1359 |
|
1360 | if (isArguments(element.argument)) {
|
1361 | code.overwrite(
|
1362 | this.start,
|
1363 | this.end,
|
1364 | `[].concat( ${this.argumentsArrayAlias} )`
|
1365 | );
|
1366 | } else {
|
1367 | code.overwrite(this.start, element.argument.start, '[].concat( ');
|
1368 | code.overwrite(element.end, this.end, ' )');
|
1369 | }
|
1370 | }
|
1371 | } else {
|
1372 | var hasSpreadElements = spread(
|
1373 | code,
|
1374 | this.elements,
|
1375 | this.start,
|
1376 | this.argumentsArrayAlias
|
1377 | );
|
1378 |
|
1379 | if (hasSpreadElements) {
|
1380 | code.overwrite(this.end - 1, this.end, ')');
|
1381 | }
|
1382 | }
|
1383 | }
|
1384 | }
|
1385 | }
|
1386 |
|
1387 | function removeTrailingComma(code, c) {
|
1388 | while (code.original[c] !== ')') {
|
1389 | if (code.original[c] === ',') {
|
1390 | code.remove(c, c + 1);
|
1391 | return;
|
1392 | }
|
1393 |
|
1394 | if (code.original[c] === '/') {
|
1395 | if (code.original[c + 1] === '/') {
|
1396 | c = code.original.indexOf('\n', c);
|
1397 | } else {
|
1398 | c = code.original.indexOf('*/', c) + 1;
|
1399 | }
|
1400 | }
|
1401 | c += 1;
|
1402 | }
|
1403 | }
|
1404 |
|
1405 | class ArrowFunctionExpression extends Node {
|
1406 | initialise(transforms) {
|
1407 | if (this.async && transforms.asyncAwait) {
|
1408 | CompileError.missingTransform("async arrow functions", "asyncAwait", this);
|
1409 | }
|
1410 | this.body.createScope();
|
1411 | super.initialise(transforms);
|
1412 | }
|
1413 |
|
1414 | transpile(code, transforms) {
|
1415 | var openParensPos = this.start;
|
1416 | for (var end = (this.body || this.params[0]).start - 1; code.original[openParensPos] !== '(' && openParensPos < end;) {
|
1417 | ++openParensPos;
|
1418 | }
|
1419 | if (code.original[openParensPos] !== '(') { openParensPos = -1; }
|
1420 | var naked = openParensPos === -1;
|
1421 |
|
1422 | if (transforms.arrow || this.needsArguments(transforms)) {
|
1423 |
|
1424 | var charIndex = this.body.start;
|
1425 | while (code.original[charIndex] !== '=') {
|
1426 | charIndex -= 1;
|
1427 | }
|
1428 | code.remove(charIndex, this.body.start);
|
1429 |
|
1430 | super.transpile(code, transforms);
|
1431 |
|
1432 |
|
1433 | if (naked) {
|
1434 | code.prependRight(this.params[0].start, '(');
|
1435 | code.appendLeft(this.params[0].end, ')');
|
1436 | }
|
1437 |
|
1438 |
|
1439 | var standalone = this.parent && this.parent.type === 'ExpressionStatement';
|
1440 | var start, text = standalone ? '!' : '';
|
1441 | if (this.async) { text += 'async '; }
|
1442 | text += 'function';
|
1443 | if (!standalone) { text += ' '; }
|
1444 | if (naked) {
|
1445 | start = this.params[0].start;
|
1446 | } else {
|
1447 | start = openParensPos;
|
1448 | }
|
1449 |
|
1450 | if (start > this.start) {
|
1451 | code.overwrite(this.start, start, text);
|
1452 | } else {
|
1453 | code.prependRight(this.start, text);
|
1454 | }
|
1455 | } else {
|
1456 | super.transpile(code, transforms);
|
1457 | }
|
1458 |
|
1459 | if (transforms.trailingFunctionCommas && this.params.length && !naked) {
|
1460 | removeTrailingComma(code, this.params[this.params.length - 1].end);
|
1461 | }
|
1462 | }
|
1463 |
|
1464 |
|
1465 | needsArguments(transforms) {
|
1466 | return (
|
1467 | transforms.spreadRest &&
|
1468 | this.params.filter(param => param.type === 'RestElement').length > 0
|
1469 | );
|
1470 | }
|
1471 | }
|
1472 |
|
1473 | function checkConst(identifier, scope) {
|
1474 | var declaration = scope.findDeclaration(identifier.name);
|
1475 | if (declaration && declaration.kind === 'const') {
|
1476 | throw new CompileError(`${identifier.name} is read-only`, identifier);
|
1477 | }
|
1478 | }
|
1479 |
|
1480 | class AssignmentExpression extends Node {
|
1481 | initialise(transforms) {
|
1482 | if (this.left.type === 'Identifier') {
|
1483 | var declaration = this.findScope(false).findDeclaration(this.left.name);
|
1484 |
|
1485 | var statement = declaration && declaration.node.ancestor(3);
|
1486 | if (
|
1487 | statement &&
|
1488 | statement.type === 'ForStatement' &&
|
1489 | statement.body.contains(this)
|
1490 | ) {
|
1491 | statement.reassigned[this.left.name] = true;
|
1492 | }
|
1493 | }
|
1494 |
|
1495 | super.initialise(transforms);
|
1496 | }
|
1497 |
|
1498 | transpile(code, transforms) {
|
1499 | if (this.left.type === 'Identifier') {
|
1500 |
|
1501 |
|
1502 | checkConst(this.left, this.findScope(false));
|
1503 | }
|
1504 |
|
1505 | if (this.operator === '**=' && transforms.exponentiation) {
|
1506 | this.transpileExponentiation(code, transforms);
|
1507 | } else if (/Pattern/.test(this.left.type) && transforms.destructuring) {
|
1508 | this.transpileDestructuring(code);
|
1509 | }
|
1510 |
|
1511 | super.transpile(code, transforms);
|
1512 | }
|
1513 |
|
1514 | transpileDestructuring(code) {
|
1515 | var writeScope = this.findScope(true);
|
1516 | var lookupScope = this.findScope(false);
|
1517 | var assign = writeScope.createDeclaration('assign');
|
1518 | code.appendRight(this.left.end, `(${assign}`);
|
1519 |
|
1520 | code.appendLeft(this.right.end, ', ');
|
1521 | var statementGenerators = [];
|
1522 | destructure(
|
1523 | code,
|
1524 | id => writeScope.createDeclaration(id),
|
1525 | node => {
|
1526 | var name = lookupScope.resolveName(node.name);
|
1527 | checkConst(node, lookupScope);
|
1528 | return name;
|
1529 | },
|
1530 | this.left,
|
1531 | assign,
|
1532 | true,
|
1533 | statementGenerators
|
1534 | );
|
1535 |
|
1536 | var suffix = ', ';
|
1537 | statementGenerators.forEach((fn, j) => {
|
1538 | if (j === statementGenerators.length - 1) {
|
1539 | suffix = '';
|
1540 | }
|
1541 |
|
1542 | fn(this.end, '', suffix);
|
1543 | });
|
1544 |
|
1545 | if (this.unparenthesizedParent().type === 'ExpressionStatement') {
|
1546 |
|
1547 | code.prependRight(this.end, `)`);
|
1548 | } else {
|
1549 |
|
1550 | code.appendRight(this.end, `, ${assign})`);
|
1551 | }
|
1552 | }
|
1553 |
|
1554 | transpileExponentiation(code) {
|
1555 | var scope = this.findScope(false);
|
1556 |
|
1557 |
|
1558 | var charIndex = this.left.end;
|
1559 | while (code.original[charIndex] !== '*') { charIndex += 1; }
|
1560 | code.remove(charIndex, charIndex + 2);
|
1561 |
|
1562 |
|
1563 |
|
1564 |
|
1565 | var base;
|
1566 |
|
1567 | var left = this.left.unparenthesize();
|
1568 |
|
1569 | if (left.type === 'Identifier') {
|
1570 | base = scope.resolveName(left.name);
|
1571 | } else if (left.type === 'MemberExpression') {
|
1572 | var object;
|
1573 | var needsObjectVar = false;
|
1574 | var property;
|
1575 | var needsPropertyVar = false;
|
1576 |
|
1577 | var statement = this.findNearest(/(?:Statement|Declaration)$/);
|
1578 | var i0 = statement.getIndentation();
|
1579 |
|
1580 | if (left.property.type === 'Identifier') {
|
1581 | property = left.computed
|
1582 | ? scope.resolveName(left.property.name)
|
1583 | : left.property.name;
|
1584 | } else {
|
1585 | property = scope.createDeclaration('property');
|
1586 | needsPropertyVar = true;
|
1587 | }
|
1588 |
|
1589 | if (left.object.type === 'Identifier') {
|
1590 | object = scope.resolveName(left.object.name);
|
1591 | } else {
|
1592 | object = scope.createDeclaration('object');
|
1593 | needsObjectVar = true;
|
1594 | }
|
1595 |
|
1596 | if (left.start === statement.start) {
|
1597 | if (needsObjectVar && needsPropertyVar) {
|
1598 | code.prependRight(statement.start, `${object} = `);
|
1599 | code.overwrite(
|
1600 | left.object.end,
|
1601 | left.property.start,
|
1602 | `;\n${i0}${property} = `
|
1603 | );
|
1604 | code.overwrite(
|
1605 | left.property.end,
|
1606 | left.end,
|
1607 | `;\n${i0}${object}[${property}]`
|
1608 | );
|
1609 | } else if (needsObjectVar) {
|
1610 | code.prependRight(statement.start, `${object} = `);
|
1611 | code.appendLeft(left.object.end, `;\n${i0}`);
|
1612 | code.appendLeft(left.object.end, object);
|
1613 | } else if (needsPropertyVar) {
|
1614 | code.prependRight(left.property.start, `${property} = `);
|
1615 | code.appendLeft(left.property.end, `;\n${i0}`);
|
1616 | code.move(left.property.start, left.property.end, this.start);
|
1617 |
|
1618 | code.appendLeft(left.object.end, `[${property}]`);
|
1619 | code.remove(left.object.end, left.property.start);
|
1620 | code.remove(left.property.end, left.end);
|
1621 | }
|
1622 | } else {
|
1623 | if (needsObjectVar && needsPropertyVar) {
|
1624 | code.prependRight(left.start, `( ${object} = `);
|
1625 | code.overwrite(
|
1626 | left.object.end,
|
1627 | left.property.start,
|
1628 | `, ${property} = `
|
1629 | );
|
1630 | code.overwrite(
|
1631 | left.property.end,
|
1632 | left.end,
|
1633 | `, ${object}[${property}]`
|
1634 | );
|
1635 | } else if (needsObjectVar) {
|
1636 | code.prependRight(left.start, `( ${object} = `);
|
1637 | code.appendLeft(left.object.end, `, ${object}`);
|
1638 | } else if (needsPropertyVar) {
|
1639 | code.prependRight(left.property.start, `( ${property} = `);
|
1640 | code.appendLeft(left.property.end, `, `);
|
1641 | code.move(left.property.start, left.property.end, left.start);
|
1642 |
|
1643 | code.overwrite(left.object.end, left.property.start, `[${property}]`);
|
1644 | code.remove(left.property.end, left.end);
|
1645 | }
|
1646 |
|
1647 | if (needsPropertyVar) {
|
1648 | code.appendLeft(this.end, ` )`);
|
1649 | }
|
1650 | }
|
1651 |
|
1652 | base =
|
1653 | object +
|
1654 | (left.computed || needsPropertyVar ? `[${property}]` : `.${property}`);
|
1655 | }
|
1656 |
|
1657 | code.prependRight(this.right.start, `Math.pow( ${base}, `);
|
1658 | code.appendLeft(this.right.end, ` )`);
|
1659 | }
|
1660 | }
|
1661 |
|
1662 | class AwaitExpression extends Node {
|
1663 | initialise(transforms) {
|
1664 | if (transforms.asyncAwait) {
|
1665 | CompileError.missingTransform("await", "asyncAwait", this);
|
1666 | }
|
1667 | super.initialise(transforms);
|
1668 | }
|
1669 | }
|
1670 |
|
1671 | class BinaryExpression extends Node {
|
1672 | transpile(code, transforms) {
|
1673 | if (this.operator === '**' && transforms.exponentiation) {
|
1674 | code.prependRight(this.start, `Math.pow( `);
|
1675 | code.overwrite(this.left.end, this.right.start, `, `);
|
1676 | code.appendLeft(this.end, ` )`);
|
1677 | }
|
1678 | super.transpile(code, transforms);
|
1679 | }
|
1680 | }
|
1681 |
|
1682 | var loopStatement = /(?:For(?:In|Of)?|While)Statement/;
|
1683 |
|
1684 | class BreakStatement extends Node {
|
1685 | initialise() {
|
1686 | var loop = this.findNearest(loopStatement);
|
1687 | var switchCase = this.findNearest('SwitchCase');
|
1688 |
|
1689 | if (loop && (!switchCase || loop.depth > switchCase.depth)) {
|
1690 | loop.canBreak = true;
|
1691 | this.loop = loop;
|
1692 | }
|
1693 | }
|
1694 |
|
1695 | transpile(code) {
|
1696 | if (this.loop && this.loop.shouldRewriteAsFunction) {
|
1697 | if (this.label)
|
1698 | { throw new CompileError(
|
1699 | 'Labels are not currently supported in a loop with locally-scoped variables',
|
1700 | this
|
1701 | ); }
|
1702 | code.overwrite(this.start, this.start + 5, `return 'break'`);
|
1703 | }
|
1704 | }
|
1705 | }
|
1706 |
|
1707 | class CallExpression extends Node {
|
1708 | initialise(transforms) {
|
1709 | if (transforms.spreadRest && this.arguments.length > 1) {
|
1710 | var lexicalBoundary = this.findLexicalBoundary();
|
1711 |
|
1712 | var i = this.arguments.length;
|
1713 | while (i--) {
|
1714 | var arg = this.arguments[i];
|
1715 | if (arg.type === 'SpreadElement' && isArguments(arg.argument)) {
|
1716 | this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
|
1717 | }
|
1718 | }
|
1719 | }
|
1720 |
|
1721 | super.initialise(transforms);
|
1722 | }
|
1723 |
|
1724 | transpile(code, transforms) {
|
1725 | if (transforms.spreadRest && this.arguments.length) {
|
1726 | inlineSpreads(code, this, this.arguments);
|
1727 |
|
1728 | }
|
1729 |
|
1730 | if (transforms.spreadRest && this.arguments.length) {
|
1731 | var hasSpreadElements = false;
|
1732 | var context;
|
1733 |
|
1734 | var firstArgument = this.arguments[0];
|
1735 |
|
1736 | if (this.arguments.length === 1) {
|
1737 | if (firstArgument.type === 'SpreadElement') {
|
1738 | code.remove(firstArgument.start, firstArgument.argument.start);
|
1739 | hasSpreadElements = true;
|
1740 | }
|
1741 | } else {
|
1742 | hasSpreadElements = spread(
|
1743 | code,
|
1744 | this.arguments,
|
1745 | firstArgument.start,
|
1746 | this.argumentsArrayAlias
|
1747 | );
|
1748 | }
|
1749 |
|
1750 | if (hasSpreadElements) {
|
1751 |
|
1752 |
|
1753 | var _super = null;
|
1754 | if (this.callee.type === 'Super') {
|
1755 | _super = this.callee;
|
1756 | } else if (
|
1757 | this.callee.type === 'MemberExpression' &&
|
1758 | this.callee.object.type === 'Super'
|
1759 | ) {
|
1760 | _super = this.callee.object;
|
1761 | }
|
1762 |
|
1763 | if (!_super && this.callee.type === 'MemberExpression') {
|
1764 | if (this.callee.object.type === 'Identifier') {
|
1765 | context = this.callee.object.name;
|
1766 | } else {
|
1767 | context = this.findScope(true).createDeclaration('ref');
|
1768 | var callExpression = this.callee.object;
|
1769 | code.prependRight(callExpression.start, `(${context} = `);
|
1770 | code.appendLeft(callExpression.end, `)`);
|
1771 | }
|
1772 | } else {
|
1773 | context = 'void 0';
|
1774 | }
|
1775 |
|
1776 | code.appendLeft(this.callee.end, '.apply');
|
1777 |
|
1778 | if (_super) {
|
1779 | _super.noCall = true;
|
1780 |
|
1781 | if (this.arguments.length > 1) {
|
1782 | if (firstArgument.type === 'SpreadElement') {
|
1783 | if (needsParentheses(firstArgument.argument)) {
|
1784 | code.prependRight(firstArgument.start, `( `);
|
1785 | }
|
1786 | } else {
|
1787 | code.prependRight(firstArgument.start, `[ `);
|
1788 | }
|
1789 |
|
1790 | code.appendLeft(
|
1791 | this.arguments[this.arguments.length - 1].end,
|
1792 | ' )'
|
1793 | );
|
1794 | }
|
1795 | } else if (this.arguments.length === 1) {
|
1796 | code.prependRight(firstArgument.start, `${context}, `);
|
1797 | } else {
|
1798 | if (firstArgument.type === 'SpreadElement') {
|
1799 | if (needsParentheses(firstArgument.argument)) {
|
1800 | code.appendLeft(firstArgument.start, `${context}, ( `);
|
1801 | } else {
|
1802 | code.appendLeft(firstArgument.start, `${context}, `);
|
1803 | }
|
1804 | } else {
|
1805 | code.appendLeft(firstArgument.start, `${context}, [ `);
|
1806 | }
|
1807 |
|
1808 | code.appendLeft(this.arguments[this.arguments.length - 1].end, ' )');
|
1809 | }
|
1810 | }
|
1811 | }
|
1812 |
|
1813 | if (transforms.trailingFunctionCommas && this.arguments.length) {
|
1814 | removeTrailingComma(code, this.arguments[this.arguments.length - 1].end);
|
1815 | }
|
1816 |
|
1817 | super.transpile(code, transforms);
|
1818 | }
|
1819 | }
|
1820 |
|
1821 | class CatchClause extends Node {
|
1822 | initialise(transforms) {
|
1823 | this.createdDeclarations = [];
|
1824 | this.scope = new Scope({
|
1825 | block: true,
|
1826 | parent: this.parent.findScope(false),
|
1827 | declare: id => this.createdDeclarations.push(id)
|
1828 | });
|
1829 |
|
1830 | this.scope.addDeclaration(this.param, 'catch');
|
1831 |
|
1832 | super.initialise(transforms);
|
1833 | this.scope.consolidate();
|
1834 | }
|
1835 |
|
1836 | findScope(functionScope) {
|
1837 | return functionScope
|
1838 | ? this.parent.findScope(functionScope)
|
1839 | : this.scope;
|
1840 | }
|
1841 | }
|
1842 |
|
1843 |
|
1844 | class ClassBody extends Node {
|
1845 | transpile(code, transforms, inFunctionExpression, superName) {
|
1846 | if (transforms.classes) {
|
1847 | var name = this.parent.name;
|
1848 |
|
1849 | var indentStr = code.getIndentString();
|
1850 | var i0 =
|
1851 | this.getIndentation() + (inFunctionExpression ? indentStr : '');
|
1852 | var i1 = i0 + indentStr;
|
1853 |
|
1854 | var constructorIndex = findIndex(
|
1855 | this.body,
|
1856 | node => node.kind === 'constructor'
|
1857 | );
|
1858 | var constructor = this.body[constructorIndex];
|
1859 |
|
1860 | var introBlock = '';
|
1861 | var outroBlock = '';
|
1862 |
|
1863 | if (this.body.length) {
|
1864 | code.remove(this.start, this.body[0].start);
|
1865 | code.remove(this.body[this.body.length - 1].end, this.end);
|
1866 | } else {
|
1867 | code.remove(this.start, this.end);
|
1868 | }
|
1869 |
|
1870 | if (constructor) {
|
1871 | constructor.value.body.isConstructorBody = true;
|
1872 |
|
1873 | var previousMethod = this.body[constructorIndex - 1];
|
1874 | var nextMethod = this.body[constructorIndex + 1];
|
1875 |
|
1876 | // ensure constructor is first
|
1877 | if (constructorIndex > 0) {
|
1878 | code.remove(previousMethod.end, constructor.start);
|
1879 | code.move(
|
1880 | constructor.start,
|
1881 | nextMethod ? nextMethod.start : this.end - 1,
|
1882 | this.body[0].start
|
1883 | );
|
1884 | }
|
1885 |
|
1886 | if (!inFunctionExpression) { code.appendLeft(constructor.end, ';'); }
|
1887 | }
|
1888 |
|
1889 | var namedFunctions =
|
1890 | this.program.options.namedFunctionExpressions !== false;
|
1891 | var namedConstructor =
|
1892 | namedFunctions ||
|
1893 | this.parent.superClass ||
|
1894 | this.parent.type !== 'ClassDeclaration';
|
1895 | if (this.parent.superClass) {
|
1896 | var inheritanceBlock = `if ( ${superName} ) ${name}.__proto__ = ${
|
1897 | superName
|
1898 | };\n${i0}${name}.prototype = Object.create( ${superName} && ${
|
1899 | superName
|
1900 | }.prototype );\n${i0}${name}.prototype.constructor = ${name};`;
|
1901 |
|
1902 | if (constructor) {
|
1903 | introBlock += `\n\n${i0}` + inheritanceBlock;
|
1904 | } else {
|
1905 | var fn =
|
1906 | `function ${name} () {` +
|
1907 | (superName
|
1908 | ? `\n${i1}${superName}.apply(this, arguments);\n${i0}}`
|
1909 | : `}`) +
|
1910 | (inFunctionExpression ? '' : ';') +
|
1911 | (this.body.length ? `\n\n${i0}` : '');
|
1912 |
|
1913 | inheritanceBlock = fn + inheritanceBlock;
|
1914 | introBlock += inheritanceBlock + `\n\n${i0}`;
|
1915 | }
|
1916 | } else if (!constructor) {
|
1917 | var fn$1 = 'function ' + (namedConstructor ? name + ' ' : '') + '() {}';
|
1918 | if (this.parent.type === 'ClassDeclaration') { fn$1 += ';'; }
|
1919 | if (this.body.length) { fn$1 += `\n\n${i0}`; }
|
1920 |
|
1921 | introBlock += fn$1;
|
1922 | }
|
1923 |
|
1924 | var scope = this.findScope(false);
|
1925 |
|
1926 | var prototypeGettersAndSetters = [];
|
1927 | var staticGettersAndSetters = [];
|
1928 | var prototypeAccessors;
|
1929 | var staticAccessors;
|
1930 |
|
1931 | this.body.forEach((method, i) => {
|
1932 | if ((method.kind === 'get' || method.kind === 'set') && transforms.getterSetter) {
|
1933 | CompileError.missingTransform("getters and setters", "getterSetter", method);
|
1934 | }
|
1935 |
|
1936 | if (method.kind === 'constructor') {
|
1937 | var constructorName = namedConstructor ? ' ' + name : '';
|
1938 | code.overwrite(
|
1939 | method.key.start,
|
1940 | method.key.end,
|
1941 | `function${constructorName}`
|
1942 | );
|
1943 | return;
|
1944 | }
|
1945 |
|
1946 | if (method.static) {
|
1947 | var len = code.original[method.start + 6] == ' ' ? 7 : 6;
|
1948 | code.remove(method.start, method.start + len);
|
1949 | }
|
1950 |
|
1951 | var isAccessor = method.kind !== 'method';
|
1952 | var lhs;
|
1953 |
|
1954 | var methodName = method.key.name;
|
1955 | if (
|
1956 | reserved[methodName] ||
|
1957 | method.value.body.scope.references[methodName]
|
1958 | ) {
|
1959 | methodName = scope.createIdentifier(methodName);
|
1960 | }
|
1961 |
|
1962 |
|
1963 |
|
1964 | var fake_computed = false;
|
1965 | if (!method.computed && method.key.type === 'Literal') {
|
1966 | fake_computed = true;
|
1967 | method.computed = true;
|
1968 | }
|
1969 |
|
1970 | if (isAccessor) {
|
1971 | if (method.computed) {
|
1972 | throw new Error(
|
1973 | 'Computed accessor properties are not currently supported'
|
1974 | );
|
1975 | }
|
1976 |
|
1977 | code.remove(method.start, method.key.start);
|
1978 |
|
1979 | if (method.static) {
|
1980 | if (!~staticGettersAndSetters.indexOf(method.key.name))
|
1981 | { staticGettersAndSetters.push(method.key.name); }
|
1982 | if (!staticAccessors)
|
1983 | { staticAccessors = scope.createIdentifier('staticAccessors'); }
|
1984 |
|
1985 | lhs = `${staticAccessors}`;
|
1986 | } else {
|
1987 | if (!~prototypeGettersAndSetters.indexOf(method.key.name))
|
1988 | { prototypeGettersAndSetters.push(method.key.name); }
|
1989 | if (!prototypeAccessors)
|
1990 | { prototypeAccessors = scope.createIdentifier('prototypeAccessors'); }
|
1991 |
|
1992 | lhs = `${prototypeAccessors}`;
|
1993 | }
|
1994 | } else {
|
1995 | lhs = method.static ? `${name}` : `${name}.prototype`;
|
1996 | }
|
1997 |
|
1998 | if (!method.computed) { lhs += '.'; }
|
1999 |
|
2000 | var insertNewlines =
|
2001 | (constructorIndex > 0 && i === constructorIndex + 1) ||
|
2002 | (i === 0 && constructorIndex === this.body.length - 1);
|
2003 |
|
2004 | if (insertNewlines) { lhs = `\n\n${i0}${lhs}`; }
|
2005 |
|
2006 | var c = method.key.end;
|
2007 | if (method.computed) {
|
2008 | if (fake_computed) {
|
2009 | code.prependRight(method.key.start, '[');
|
2010 | code.appendLeft(method.key.end, ']');
|
2011 | } else {
|
2012 | while (code.original[c] !== ']') { c += 1; }
|
2013 | c += 1;
|
2014 | }
|
2015 | }
|
2016 |
|
2017 | var funcName =
|
2018 | method.computed || isAccessor || !namedFunctions
|
2019 | ? ''
|
2020 | : `${methodName} `;
|
2021 | var rhs =
|
2022 | (isAccessor ? `.${method.kind}` : '') +
|
2023 | ` = ${method.value.async ? 'async ' : ''}function` +
|
2024 | (method.value.generator ? '* ' : ' ') +
|
2025 | funcName;
|
2026 | code.remove(c, method.value.start);
|
2027 | code.prependRight(method.value.start, rhs);
|
2028 | code.appendLeft(method.end, ';');
|
2029 |
|
2030 | if (method.value.generator) { code.remove(method.start, method.key.start); }
|
2031 |
|
2032 | var start = method.key.start;
|
2033 | if (method.computed && !fake_computed) {
|
2034 | while (code.original[start] != '[') {
|
2035 | --start;
|
2036 | }
|
2037 | }
|
2038 | if (method.start < start) {
|
2039 | code.overwrite(method.start, start, lhs);
|
2040 | } else {
|
2041 | code.prependRight(method.start, lhs);
|
2042 | }
|
2043 | });
|
2044 |
|
2045 | if (prototypeGettersAndSetters.length || staticGettersAndSetters.length) {
|
2046 | var intro = [];
|
2047 | var outro = [];
|
2048 |
|
2049 | if (prototypeGettersAndSetters.length) {
|
2050 | intro.push(
|
2051 | `var ${prototypeAccessors} = { ${prototypeGettersAndSetters
|
2052 | .map(name => `${name}: { configurable: true }`)
|
2053 | .join(',')} };`
|
2054 | );
|
2055 | outro.push(
|
2056 | `Object.defineProperties( ${name}.prototype, ${
|
2057 | prototypeAccessors
|
2058 | } );`
|
2059 | );
|
2060 | }
|
2061 |
|
2062 | if (staticGettersAndSetters.length) {
|
2063 | intro.push(
|
2064 | `var ${staticAccessors} = { ${staticGettersAndSetters
|
2065 | .map(name => `${name}: { configurable: true }`)
|
2066 | .join(',')} };`
|
2067 | );
|
2068 | outro.push(`Object.defineProperties( ${name}, ${staticAccessors} );`);
|
2069 | }
|
2070 |
|
2071 | if (constructor) { introBlock += `\n\n${i0}`; }
|
2072 | introBlock += intro.join(`\n${i0}`);
|
2073 | if (!constructor) { introBlock += `\n\n${i0}`; }
|
2074 |
|
2075 | outroBlock += `\n\n${i0}` + outro.join(`\n${i0}`);
|
2076 | }
|
2077 |
|
2078 | if (constructor) {
|
2079 | code.appendLeft(constructor.end, introBlock);
|
2080 | } else {
|
2081 | code.prependRight(this.start, introBlock);
|
2082 | }
|
2083 |
|
2084 | code.appendLeft(this.end, outroBlock);
|
2085 | }
|
2086 |
|
2087 | super.transpile(code, transforms);
|
2088 | }
|
2089 | }
|
2090 |
|
2091 |
|
2092 |
|
2093 |
|
2094 |
|
2095 | function deindent(node, code) {
|
2096 | var start = node.start;
|
2097 | var end = node.end;
|
2098 |
|
2099 | var indentStr = code.getIndentString();
|
2100 | var indentStrLen = indentStr.length;
|
2101 | var indentStart = start - indentStrLen;
|
2102 |
|
2103 | if (
|
2104 | !node.program.indentExclusions[indentStart] &&
|
2105 | code.original.slice(indentStart, start) === indentStr
|
2106 | ) {
|
2107 | code.remove(indentStart, start);
|
2108 | }
|
2109 |
|
2110 | var pattern = new RegExp(indentStr + '\\S', 'g');
|
2111 | var slice = code.original.slice(start, end);
|
2112 | var match;
|
2113 |
|
2114 | while ((match = pattern.exec(slice))) {
|
2115 | var removeStart = start + match.index;
|
2116 | if (!node.program.indentExclusions[removeStart]) {
|
2117 | code.remove(removeStart, removeStart + indentStrLen);
|
2118 | }
|
2119 | }
|
2120 | }
|
2121 |
|
2122 | class ClassDeclaration extends Node {
|
2123 | initialise(transforms) {
|
2124 | if (this.id) {
|
2125 | this.name = this.id.name;
|
2126 | this.findScope(true).addDeclaration(this.id, 'class');
|
2127 | } else {
|
2128 | this.name = this.findScope(true).createIdentifier("defaultExport");
|
2129 | }
|
2130 |
|
2131 | super.initialise(transforms);
|
2132 | }
|
2133 |
|
2134 | transpile(code, transforms) {
|
2135 | if (transforms.classes) {
|
2136 | if (!this.superClass) { deindent(this.body, code); }
|
2137 |
|
2138 | var superName =
|
2139 | this.superClass && (this.superClass.name || 'superclass');
|
2140 |
|
2141 | var i0 = this.getIndentation();
|
2142 | var i1 = i0 + code.getIndentString();
|
2143 |
|
2144 |
|
2145 |
|
2146 | var isExportDefaultDeclaration = this.parent.type === 'ExportDefaultDeclaration';
|
2147 |
|
2148 | if (isExportDefaultDeclaration) {
|
2149 | code.remove(this.parent.start, this.start);
|
2150 | }
|
2151 |
|
2152 | var c = this.start;
|
2153 | if (this.id) {
|
2154 | code.overwrite(c, this.id.start, 'var ');
|
2155 | c = this.id.end;
|
2156 | } else {
|
2157 | code.prependLeft(c, `var ${this.name}`);
|
2158 | }
|
2159 |
|
2160 | if (this.superClass) {
|
2161 | if (this.superClass.end === this.body.start) {
|
2162 | code.remove(c, this.superClass.start);
|
2163 | code.appendLeft(c, ` = /*@__PURE__*/(function (${superName}) {\n${i1}`);
|
2164 | } else {
|
2165 | code.overwrite(c, this.superClass.start, ' = ');
|
2166 | code.overwrite(
|
2167 | this.superClass.end,
|
2168 | this.body.start,
|
2169 | `/*@__PURE__*/(function (${superName}) {\n${i1}`
|
2170 | );
|
2171 | }
|
2172 | } else {
|
2173 | if (c === this.body.start) {
|
2174 | code.appendLeft(c, ' = ');
|
2175 | } else {
|
2176 | code.overwrite(c, this.body.start, ' = ');
|
2177 | }
|
2178 | }
|
2179 |
|
2180 | this.body.transpile(code, transforms, !!this.superClass, superName);
|
2181 |
|
2182 | var syntheticDefaultExport =
|
2183 | isExportDefaultDeclaration
|
2184 | ? `\n\n${i0}export default ${this.name};`
|
2185 | : '';
|
2186 | if (this.superClass) {
|
2187 | code.appendLeft(this.end, `\n\n${i1}return ${this.name};\n${i0}}(`);
|
2188 | code.move(this.superClass.start, this.superClass.end, this.end);
|
2189 | code.prependRight(this.end, `));${syntheticDefaultExport}`);
|
2190 | } else if (syntheticDefaultExport) {
|
2191 | code.prependRight(this.end, syntheticDefaultExport);
|
2192 | }
|
2193 | } else {
|
2194 | this.body.transpile(code, transforms, false, null);
|
2195 | }
|
2196 | }
|
2197 | }
|
2198 |
|
2199 | class ClassExpression extends Node {
|
2200 | initialise(transforms) {
|
2201 | this.name = (this.id
|
2202 | ? this.id.name
|
2203 | : this.parent.type === 'VariableDeclarator'
|
2204 | ? this.parent.id.name
|
2205 | : this.parent.type !== 'AssignmentExpression'
|
2206 | ? null
|
2207 | : this.parent.left.type === 'Identifier'
|
2208 | ? this.parent.left.name
|
2209 | : this.parent.left.type === 'MemberExpression'
|
2210 | ? this.parent.left.property.name
|
2211 | : null) || this.findScope(true).createIdentifier('anonymous');
|
2212 |
|
2213 | super.initialise(transforms);
|
2214 | }
|
2215 |
|
2216 | transpile(code, transforms) {
|
2217 | if (transforms.classes) {
|
2218 | var superName = this.superClass && (this.superClass.name || 'superclass');
|
2219 | if (superName === this.name) {
|
2220 | superName = this.findScope(true).createIdentifier(this.name);
|
2221 | }
|
2222 |
|
2223 | var i0 = this.getIndentation();
|
2224 | var i1 = i0 + code.getIndentString();
|
2225 |
|
2226 | if (this.superClass) {
|
2227 | code.remove(this.start, this.superClass.start);
|
2228 | code.remove(this.superClass.end, this.body.start);
|
2229 | code.appendRight(this.start, `/*@__PURE__*/(function (${superName}) {\n${i1}`);
|
2230 | } else {
|
2231 | code.overwrite(this.start, this.body.start, `/*@__PURE__*/(function () {\n${i1}`);
|
2232 | }
|
2233 |
|
2234 | this.body.transpile(code, transforms, true, superName);
|
2235 |
|
2236 | var superClass = '';
|
2237 | if (this.superClass) {
|
2238 | superClass = code.slice(this.superClass.start, this.superClass.end);
|
2239 | code.remove(this.superClass.start, this.superClass.end);
|
2240 | }
|
2241 | code.appendLeft(this.end, `\n\n${i1}return ${this.name};\n${i0}}(${superClass}))`);
|
2242 | } else {
|
2243 | this.body.transpile(code, transforms, false);
|
2244 | }
|
2245 | }
|
2246 | }
|
2247 |
|
2248 | class ContinueStatement extends Node {
|
2249 | transpile(code) {
|
2250 | var loop = this.findNearest(loopStatement);
|
2251 | if (loop.shouldRewriteAsFunction) {
|
2252 | if (this.label)
|
2253 | { throw new CompileError(
|
2254 | 'Labels are not currently supported in a loop with locally-scoped variables',
|
2255 | this
|
2256 | ); }
|
2257 | code.overwrite(this.start, this.start + 8, 'return');
|
2258 | }
|
2259 | }
|
2260 | }
|
2261 |
|
2262 | class ExportDefaultDeclaration extends Node {
|
2263 | initialise(transforms) {
|
2264 | if (transforms.moduleExport)
|
2265 | { CompileError.missingTransform("export", "moduleExport", this); }
|
2266 | super.initialise(transforms);
|
2267 | }
|
2268 | }
|
2269 |
|
2270 | class ExportNamedDeclaration extends Node {
|
2271 | initialise(transforms) {
|
2272 | if (transforms.moduleExport)
|
2273 | { CompileError.missingTransform("export", "moduleExport", this); }
|
2274 | super.initialise(transforms);
|
2275 | }
|
2276 | }
|
2277 |
|
2278 | class LoopStatement extends Node {
|
2279 | findScope(functionScope) {
|
2280 | return functionScope || !this.createdScope
|
2281 | ? this.parent.findScope(functionScope)
|
2282 | : this.body.scope;
|
2283 | }
|
2284 |
|
2285 | initialise(transforms) {
|
2286 | this.body.createScope();
|
2287 | this.createdScope = true;
|
2288 |
|
2289 |
|
2290 | this.reassigned = Object.create(null);
|
2291 | this.aliases = Object.create(null);
|
2292 |
|
2293 | this.thisRefs = [];
|
2294 |
|
2295 | super.initialise(transforms);
|
2296 | if (this.scope) {
|
2297 | this.scope.consolidate();
|
2298 | }
|
2299 |
|
2300 | var declarations = Object.assign({}, this.body.scope.declarations);
|
2301 | if (this.scope) {
|
2302 | Object.assign(declarations, this.scope.declarations);
|
2303 | }
|
2304 |
|
2305 | if (transforms.letConst) {
|
2306 |
|
2307 |
|
2308 | var names = Object.keys(declarations);
|
2309 |
|
2310 | var i = names.length;
|
2311 | while (i--) {
|
2312 | var name = names[i];
|
2313 | var declaration = declarations[name];
|
2314 |
|
2315 | var j = declaration.instances.length;
|
2316 | while (j--) {
|
2317 | var instance = declaration.instances[j];
|
2318 | var nearestFunctionExpression = instance.findNearest(/Function/);
|
2319 |
|
2320 | if (
|
2321 | nearestFunctionExpression &&
|
2322 | nearestFunctionExpression.depth > this.depth
|
2323 | ) {
|
2324 | this.shouldRewriteAsFunction = true;
|
2325 | for (var i$1 = 0, list = this.thisRefs; i$1 < list.length; i$1 += 1) {
|
2326 | var node = list[i$1];
|
2327 |
|
2328 | node.alias = node.alias || node.findLexicalBoundary().getThisAlias();
|
2329 | }
|
2330 | break;
|
2331 | }
|
2332 | }
|
2333 |
|
2334 | if (this.shouldRewriteAsFunction) { break; }
|
2335 | }
|
2336 | }
|
2337 | }
|
2338 |
|
2339 | transpile(code, transforms) {
|
2340 | var needsBlock =
|
2341 | this.type != 'ForOfStatement' &&
|
2342 | (this.body.type !== 'BlockStatement' ||
|
2343 | (this.body.type === 'BlockStatement' && this.body.synthetic));
|
2344 |
|
2345 | if (this.shouldRewriteAsFunction) {
|
2346 | var i0 = this.getIndentation();
|
2347 | var i1 = i0 + code.getIndentString();
|
2348 |
|
2349 | var argString = this.args ? ` ${this.args.join(', ')} ` : '';
|
2350 | var paramString = this.params ? ` ${this.params.join(', ')} ` : '';
|
2351 |
|
2352 | var functionScope = this.findScope(true);
|
2353 | var loop = functionScope.createIdentifier('loop');
|
2354 |
|
2355 | var before =
|
2356 | `var ${loop} = function (${paramString}) ` +
|
2357 | (this.body.synthetic ? `{\n${i0}${code.getIndentString()}` : '');
|
2358 | var after = (this.body.synthetic ? `\n${i0}}` : '') + `;\n\n${i0}`;
|
2359 |
|
2360 | code.prependRight(this.body.start, before);
|
2361 | code.appendLeft(this.body.end, after);
|
2362 | code.move(this.start, this.body.start, this.body.end);
|
2363 |
|
2364 | if (this.canBreak || this.canReturn) {
|
2365 | var returned = functionScope.createIdentifier('returned');
|
2366 |
|
2367 | var insert = `{\n${i1}var ${returned} = ${loop}(${argString});\n`;
|
2368 | if (this.canBreak)
|
2369 | { insert += `\n${i1}if ( ${returned} === 'break' ) break;`; }
|
2370 | if (this.canReturn)
|
2371 | { insert += `\n${i1}if ( ${returned} ) return ${returned}.v;`; }
|
2372 | insert += `\n${i0}}`;
|
2373 |
|
2374 | code.prependRight(this.body.end, insert);
|
2375 | } else {
|
2376 | var callExpression = `${loop}(${argString});`;
|
2377 |
|
2378 | if (this.type === 'DoWhileStatement') {
|
2379 | code.overwrite(
|
2380 | this.start,
|
2381 | this.body.start,
|
2382 | `do {\n${i1}${callExpression}\n${i0}}`
|
2383 | );
|
2384 | } else {
|
2385 | code.prependRight(this.body.end, callExpression);
|
2386 | }
|
2387 | }
|
2388 | } else if (needsBlock) {
|
2389 | code.appendLeft(this.body.start, '{ ');
|
2390 | code.prependRight(this.body.end, ' }');
|
2391 | }
|
2392 |
|
2393 | super.transpile(code, transforms);
|
2394 | }
|
2395 | }
|
2396 |
|
2397 | class ForStatement extends LoopStatement {
|
2398 | initialise(transforms) {
|
2399 | this.createdDeclarations = [];
|
2400 |
|
2401 | this.scope = new Scope({
|
2402 | block: true,
|
2403 | parent: this.parent.findScope(false),
|
2404 | declare: id => this.createdDeclarations.push(id)
|
2405 | });
|
2406 |
|
2407 | super.initialise(transforms);
|
2408 | }
|
2409 |
|
2410 | findScope(functionScope) {
|
2411 | return functionScope
|
2412 | ? this.parent.findScope(functionScope)
|
2413 | : this.scope;
|
2414 | }
|
2415 |
|
2416 | transpile(code, transforms) {
|
2417 | var i1 = this.getIndentation() + code.getIndentString();
|
2418 |
|
2419 | if (this.shouldRewriteAsFunction) {
|
2420 |
|
2421 | var names = this.init && this.init.type === 'VariableDeclaration'
|
2422 | ? this.init.declarations.map(declarator => extractNames(declarator.id))
|
2423 | : [];
|
2424 |
|
2425 | var aliases = this.aliases;
|
2426 |
|
2427 | this.args = names.map(
|
2428 | name => (name in this.aliases ? this.aliases[name].outer : name)
|
2429 | );
|
2430 | this.params = names.map(
|
2431 | name => (name in this.aliases ? this.aliases[name].inner : name)
|
2432 | );
|
2433 |
|
2434 | var updates = Object.keys(this.reassigned).map(
|
2435 | name => `${aliases[name].outer} = ${aliases[name].inner};`
|
2436 | );
|
2437 |
|
2438 | if (updates.length) {
|
2439 | if (this.body.synthetic) {
|
2440 | code.appendLeft(this.body.body[0].end, `; ${updates.join(` `)}`);
|
2441 | } else {
|
2442 | var lastStatement = this.body.body[this.body.body.length - 1];
|
2443 | code.appendLeft(
|
2444 | lastStatement.end,
|
2445 | `\n\n${i1}${updates.join(`\n${i1}`)}`
|
2446 | );
|
2447 | }
|
2448 | }
|
2449 | }
|
2450 |
|
2451 | super.transpile(code, transforms);
|
2452 | }
|
2453 | }
|
2454 |
|
2455 | class ForInStatement extends LoopStatement {
|
2456 | initialise(transforms) {
|
2457 | this.createdDeclarations = [];
|
2458 |
|
2459 | this.scope = new Scope({
|
2460 | block: true,
|
2461 | parent: this.parent.findScope(false),
|
2462 | declare: id => this.createdDeclarations.push(id)
|
2463 | });
|
2464 |
|
2465 | super.initialise(transforms);
|
2466 | }
|
2467 |
|
2468 | findScope(functionScope) {
|
2469 | return functionScope
|
2470 | ? this.parent.findScope(functionScope)
|
2471 | : this.scope;
|
2472 | }
|
2473 |
|
2474 | transpile(code, transforms) {
|
2475 | var hasDeclaration = this.left.type === 'VariableDeclaration';
|
2476 |
|
2477 | if (this.shouldRewriteAsFunction) {
|
2478 |
|
2479 | var names = hasDeclaration
|
2480 | ? this.left.declarations.map(declarator => extractNames(declarator.id))
|
2481 | : [];
|
2482 |
|
2483 | this.args = names.map(
|
2484 | name => (name in this.aliases ? this.aliases[name].outer : name)
|
2485 | );
|
2486 | this.params = names.map(
|
2487 | name => (name in this.aliases ? this.aliases[name].inner : name)
|
2488 | );
|
2489 | }
|
2490 |
|
2491 | super.transpile(code, transforms);
|
2492 |
|
2493 | var maybePattern = hasDeclaration ? this.left.declarations[0].id : this.left;
|
2494 | if (maybePattern.type !== 'Identifier' && maybePattern.type !== 'MemberExpression') {
|
2495 | this.destructurePattern(code, maybePattern, hasDeclaration);
|
2496 | }
|
2497 | }
|
2498 |
|
2499 | destructurePattern(code, pattern, isDeclaration) {
|
2500 | var scope = this.findScope(true);
|
2501 | var i0 = this.getIndentation();
|
2502 | var i1 = i0 + code.getIndentString();
|
2503 |
|
2504 | var ref = scope.createIdentifier('ref');
|
2505 |
|
2506 | var bodyStart = this.body.body.length ? this.body.body[0].start : this.body.start + 1;
|
2507 |
|
2508 | code.move(pattern.start, pattern.end, bodyStart);
|
2509 |
|
2510 | code.prependRight(pattern.end, isDeclaration ? ref : `var ${ref}`);
|
2511 |
|
2512 | var statementGenerators = [];
|
2513 | destructure(
|
2514 | code,
|
2515 | id => scope.createIdentifier(id),
|
2516 | (ref) => {
|
2517 | var name = ref.name;
|
2518 |
|
2519 | return scope.resolveName(name);
|
2520 | },
|
2521 | pattern,
|
2522 | ref,
|
2523 | false,
|
2524 | statementGenerators
|
2525 | );
|
2526 |
|
2527 | var suffix = `;\n${i1}`;
|
2528 | statementGenerators.forEach((fn, i) => {
|
2529 | if (i === statementGenerators.length - 1) {
|
2530 | suffix = `;\n\n${i1}`;
|
2531 | }
|
2532 |
|
2533 | fn(bodyStart, '', suffix);
|
2534 | });
|
2535 | }
|
2536 | }
|
2537 |
|
2538 | class ForOfStatement extends LoopStatement {
|
2539 | initialise(transforms) {
|
2540 | if (transforms.forOf && !transforms.dangerousForOf)
|
2541 | { CompileError.missingTransform("for-of statements", "forOf", this, "dangerousForOf"); }
|
2542 | if (this.await && transforms.asyncAwait)
|
2543 | { CompileError.missingTransform("for-await-of statements", "asyncAwait", this); }
|
2544 |
|
2545 | this.createdDeclarations = [];
|
2546 |
|
2547 | this.scope = new Scope({
|
2548 | block: true,
|
2549 | parent: this.parent.findScope(false),
|
2550 | declare: id => this.createdDeclarations.push(id)
|
2551 | });
|
2552 |
|
2553 | super.initialise(transforms);
|
2554 | }
|
2555 |
|
2556 | findScope(functionScope) {
|
2557 | return functionScope
|
2558 | ? this.parent.findScope(functionScope)
|
2559 | : this.scope;
|
2560 | }
|
2561 |
|
2562 | transpile(code, transforms) {
|
2563 | super.transpile(code, transforms);
|
2564 | if (!transforms.dangerousForOf) { return; }
|
2565 |
|
2566 |
|
2567 | if (!this.body.body[0]) {
|
2568 | if (
|
2569 | this.left.type === 'VariableDeclaration' &&
|
2570 | this.left.kind === 'var'
|
2571 | ) {
|
2572 | code.remove(this.start, this.left.start);
|
2573 | code.appendLeft(this.left.end, ';');
|
2574 | code.remove(this.left.end, this.end);
|
2575 | } else {
|
2576 | code.remove(this.start, this.end);
|
2577 | }
|
2578 |
|
2579 | return;
|
2580 | }
|
2581 |
|
2582 | var scope = this.findScope(true);
|
2583 | var i0 = this.getIndentation();
|
2584 | var i1 = i0 + code.getIndentString();
|
2585 |
|
2586 | var key = scope.createIdentifier('i');
|
2587 | var list = scope.createIdentifier('list');
|
2588 |
|
2589 | if (this.body.synthetic) {
|
2590 | code.prependRight(this.left.start, `{\n${i1}`);
|
2591 | code.appendLeft(this.body.body[0].end, `\n${i0}}`);
|
2592 | }
|
2593 |
|
2594 | var bodyStart = this.body.body[0].start;
|
2595 |
|
2596 | code.remove(this.left.end, this.right.start);
|
2597 | code.move(this.left.start, this.left.end, bodyStart);
|
2598 |
|
2599 | code.prependRight(this.right.start, `var ${key} = 0, ${list} = `);
|
2600 | code.appendLeft(this.right.end, `; ${key} < ${list}.length; ${key} += 1`);
|
2601 |
|
2602 | var isDeclaration = this.left.type === 'VariableDeclaration';
|
2603 | var maybeDestructuring = isDeclaration ? this.left.declarations[0].id : this.left;
|
2604 | if (maybeDestructuring.type !== 'Identifier') {
|
2605 | var statementGenerators = [];
|
2606 | var ref = scope.createIdentifier('ref');
|
2607 | destructure(
|
2608 | code,
|
2609 | id => scope.createIdentifier(id),
|
2610 | (ref) => {
|
2611 | var name = ref.name;
|
2612 |
|
2613 | return scope.resolveName(name);
|
2614 | },
|
2615 | maybeDestructuring,
|
2616 | ref,
|
2617 | !isDeclaration,
|
2618 | statementGenerators
|
2619 | );
|
2620 |
|
2621 | var suffix = `;\n${i1}`;
|
2622 | statementGenerators.forEach((fn, i) => {
|
2623 | if (i === statementGenerators.length - 1) {
|
2624 | suffix = `;\n\n${i1}`;
|
2625 | }
|
2626 |
|
2627 | fn(bodyStart, '', suffix);
|
2628 | });
|
2629 |
|
2630 | if (isDeclaration) {
|
2631 | code.appendLeft(this.left.start + this.left.kind.length + 1, ref);
|
2632 | code.appendLeft(this.left.end, ` = ${list}[${key}];\n${i1}`);
|
2633 | } else {
|
2634 | code.appendLeft(this.left.end, `var ${ref} = ${list}[${key}];\n${i1}`);
|
2635 | }
|
2636 | } else {
|
2637 | code.appendLeft(this.left.end, ` = ${list}[${key}];\n\n${i1}`);
|
2638 | }
|
2639 | }
|
2640 | }
|
2641 |
|
2642 | class FunctionDeclaration extends Node {
|
2643 | initialise(transforms) {
|
2644 | if (this.generator && transforms.generator) {
|
2645 | CompileError.missingTransform("generators", "generator", this);
|
2646 | }
|
2647 | if (this.async && transforms.asyncAwait) {
|
2648 | CompileError.missingTransform("async functions", "asyncAwait", this);
|
2649 | }
|
2650 |
|
2651 | this.body.createScope();
|
2652 |
|
2653 | if (this.id) {
|
2654 | this.findScope(true).addDeclaration(this.id, 'function');
|
2655 | }
|
2656 | super.initialise(transforms);
|
2657 | }
|
2658 |
|
2659 | transpile(code, transforms) {
|
2660 | super.transpile(code, transforms);
|
2661 | if (transforms.trailingFunctionCommas && this.params.length) {
|
2662 | removeTrailingComma(code, this.params[this.params.length - 1].end);
|
2663 | }
|
2664 | }
|
2665 | }
|
2666 |
|
2667 | class FunctionExpression extends Node {
|
2668 | initialise(transforms) {
|
2669 | if (this.generator && transforms.generator) {
|
2670 | CompileError.missingTransform("generators", "generator", this);
|
2671 | }
|
2672 | if (this.async && transforms.asyncAwait) {
|
2673 | CompileError.missingTransform("async functions", "asyncAwait", this);
|
2674 | }
|
2675 |
|
2676 | this.body.createScope();
|
2677 |
|
2678 | if (this.id) {
|
2679 |
|
2680 | this.body.scope.addDeclaration(this.id, 'function');
|
2681 | }
|
2682 |
|
2683 | super.initialise(transforms);
|
2684 |
|
2685 | var parent = this.parent;
|
2686 | var methodName;
|
2687 |
|
2688 | if (
|
2689 | transforms.conciseMethodProperty &&
|
2690 | parent.type === 'Property' &&
|
2691 | parent.kind === 'init' &&
|
2692 | parent.method &&
|
2693 | parent.key.type === 'Identifier'
|
2694 | ) {
|
2695 |
|
2696 | methodName = parent.key.name;
|
2697 | } else if (
|
2698 | transforms.classes &&
|
2699 | parent.type === 'MethodDefinition' &&
|
2700 | parent.kind === 'method' &&
|
2701 | parent.key.type === 'Identifier'
|
2702 | ) {
|
2703 |
|
2704 | methodName = parent.key.name;
|
2705 | } else if (this.id && this.id.type === 'Identifier') {
|
2706 |
|
2707 | methodName = this.id.alias || this.id.name;
|
2708 | }
|
2709 |
|
2710 | if (methodName) {
|
2711 | for (var i$1 = 0, list$1 = this.params; i$1 < list$1.length; i$1 += 1) {
|
2712 | var param = list$1[i$1];
|
2713 |
|
2714 | if (param.type === 'Identifier' && methodName === param.name) {
|
2715 |
|
2716 |
|
2717 |
|
2718 |
|
2719 | var scope = this.body.scope;
|
2720 | var declaration = scope.declarations[methodName];
|
2721 |
|
2722 | var alias = scope.createIdentifier(methodName);
|
2723 | param.alias = alias;
|
2724 |
|
2725 | for (var i = 0, list = declaration.instances; i < list.length; i += 1) {
|
2726 | var identifier = list[i];
|
2727 |
|
2728 | identifier.alias = alias;
|
2729 | }
|
2730 |
|
2731 | break;
|
2732 | }
|
2733 | }
|
2734 | }
|
2735 | }
|
2736 |
|
2737 | transpile(code, transforms) {
|
2738 | super.transpile(code, transforms);
|
2739 | if (transforms.trailingFunctionCommas && this.params.length) {
|
2740 | removeTrailingComma(code, this.params[this.params.length - 1].end);
|
2741 | }
|
2742 | }
|
2743 | }
|
2744 |
|
2745 | function isReference(node, parent) {
|
2746 | if (node.type === 'MemberExpression') {
|
2747 | return !node.computed && isReference(node.object, node);
|
2748 | }
|
2749 |
|
2750 | if (node.type === 'Identifier') {
|
2751 |
|
2752 |
|
2753 |
|
2754 | if (!parent) { return true; }
|
2755 |
|
2756 | if (/(Function|Class)Expression/.test(parent.type)) { return false; }
|
2757 |
|
2758 | if (parent.type === 'VariableDeclarator') { return node === parent.init; }
|
2759 |
|
2760 |
|
2761 | if (
|
2762 | parent.type === 'MemberExpression' ||
|
2763 | parent.type === 'MethodDefinition'
|
2764 | ) {
|
2765 | return parent.computed || node === parent.object;
|
2766 | }
|
2767 |
|
2768 | if (parent.type === 'ArrayPattern') { return false; }
|
2769 |
|
2770 |
|
2771 | if (parent.type === 'Property') {
|
2772 | if (parent.parent.type === 'ObjectPattern') { return false; }
|
2773 | return parent.computed || node === parent.value;
|
2774 | }
|
2775 |
|
2776 |
|
2777 | if (parent.type === 'MethodDefinition') { return false; }
|
2778 |
|
2779 |
|
2780 | if (parent.type === 'ExportSpecifier' && node !== parent.local)
|
2781 | { return false; }
|
2782 |
|
2783 | return true;
|
2784 | }
|
2785 | }
|
2786 |
|
2787 | class Identifier extends Node {
|
2788 | findScope(functionScope) {
|
2789 | if (this.parent.params && ~this.parent.params.indexOf(this)) {
|
2790 | return this.parent.body.scope;
|
2791 | }
|
2792 |
|
2793 | if (this.parent.type === 'FunctionExpression' && this === this.parent.id) {
|
2794 | return this.parent.body.scope;
|
2795 | }
|
2796 |
|
2797 | return this.parent.findScope(functionScope);
|
2798 | }
|
2799 |
|
2800 | initialise(transforms) {
|
2801 | if (this.isLabel()) {
|
2802 | return;
|
2803 | }
|
2804 |
|
2805 | if (isReference(this, this.parent)) {
|
2806 | if (
|
2807 | transforms.arrow &&
|
2808 | this.name === 'arguments' &&
|
2809 | !this.findScope(false).contains(this.name)
|
2810 | ) {
|
2811 | var lexicalBoundary = this.findLexicalBoundary();
|
2812 | var arrowFunction = this.findNearest('ArrowFunctionExpression');
|
2813 | var loop = this.findNearest(loopStatement);
|
2814 |
|
2815 | if (arrowFunction && arrowFunction.depth > lexicalBoundary.depth) {
|
2816 | this.alias = lexicalBoundary.getArgumentsAlias();
|
2817 | }
|
2818 |
|
2819 | if (
|
2820 | loop &&
|
2821 | loop.body.contains(this) &&
|
2822 | loop.depth > lexicalBoundary.depth
|
2823 | ) {
|
2824 | this.alias = lexicalBoundary.getArgumentsAlias();
|
2825 | }
|
2826 | }
|
2827 |
|
2828 | this.findScope(false).addReference(this);
|
2829 | }
|
2830 | }
|
2831 |
|
2832 | isLabel() {
|
2833 | switch (this.parent.type) {
|
2834 | case 'BreakStatement': return true;
|
2835 | case 'ContinueStatement': return true;
|
2836 | case 'LabeledStatement': return true;
|
2837 | default: return false;
|
2838 | }
|
2839 | }
|
2840 |
|
2841 | transpile(code) {
|
2842 | if (this.alias) {
|
2843 | code.overwrite(this.start, this.end, this.alias, {
|
2844 | storeName: true,
|
2845 | contentOnly: true
|
2846 | });
|
2847 | }
|
2848 | }
|
2849 | }
|
2850 |
|
2851 | class IfStatement extends Node {
|
2852 | initialise(transforms) {
|
2853 | super.initialise(transforms);
|
2854 | }
|
2855 |
|
2856 | transpile(code, transforms) {
|
2857 | if (
|
2858 | this.consequent.type !== 'BlockStatement' ||
|
2859 | (this.consequent.type === 'BlockStatement' && this.consequent.synthetic)
|
2860 | ) {
|
2861 | code.appendLeft(this.consequent.start, '{ ');
|
2862 | code.prependRight(this.consequent.end, ' }');
|
2863 | }
|
2864 |
|
2865 | if (
|
2866 | this.alternate &&
|
2867 | this.alternate.type !== 'IfStatement' &&
|
2868 | (this.alternate.type !== 'BlockStatement' ||
|
2869 | (this.alternate.type === 'BlockStatement' && this.alternate.synthetic))
|
2870 | ) {
|
2871 | code.appendLeft(this.alternate.start, '{ ');
|
2872 | code.prependRight(this.alternate.end, ' }');
|
2873 | }
|
2874 |
|
2875 | super.transpile(code, transforms);
|
2876 | }
|
2877 | }
|
2878 |
|
2879 | class Import extends Node {
|
2880 | initialise(transforms) {
|
2881 | if (transforms.moduleImport) {
|
2882 | CompileError.missingTransform("dynamic import expressions", "moduleImport", this);
|
2883 | }
|
2884 | super.initialise(transforms);
|
2885 | }
|
2886 | }
|
2887 |
|
2888 | class ImportDeclaration extends Node {
|
2889 | initialise(transforms) {
|
2890 | if (transforms.moduleImport)
|
2891 | { CompileError.missingTransform("import", "moduleImport", this); }
|
2892 | super.initialise(transforms);
|
2893 | }
|
2894 | }
|
2895 |
|
2896 | class ImportDefaultSpecifier extends Node {
|
2897 | initialise(transforms) {
|
2898 | this.findScope(true).addDeclaration(this.local, 'import');
|
2899 | super.initialise(transforms);
|
2900 | }
|
2901 | }
|
2902 |
|
2903 | class ImportSpecifier extends Node {
|
2904 | initialise(transforms) {
|
2905 | this.findScope(true).addDeclaration(this.local, 'import');
|
2906 | super.initialise(transforms);
|
2907 | }
|
2908 | }
|
2909 |
|
2910 | var hasDashes = val => /-/.test(val);
|
2911 |
|
2912 | var formatKey = key => (hasDashes(key) ? `'${key}'` : key);
|
2913 |
|
2914 | var formatVal = val => (val ? '' : 'true');
|
2915 |
|
2916 | class JSXAttribute extends Node {
|
2917 | transpile(code, transforms) {
|
2918 | var ref = this.name;
|
2919 | var start = ref.start;
|
2920 | var name = ref.name;
|
2921 |
|
2922 |
|
2923 | var end = this.value ? this.value.start : this.name.end;
|
2924 |
|
2925 | code.overwrite(start, end, `${formatKey(name)}: ${formatVal(this.value)}`);
|
2926 |
|
2927 | super.transpile(code, transforms);
|
2928 | }
|
2929 | }
|
2930 |
|
2931 | function containsNewLine(node) {
|
2932 | return (
|
2933 | node.type === 'JSXText' && !/\S/.test(node.value) && /\n/.test(node.value)
|
2934 | );
|
2935 | }
|
2936 |
|
2937 | class JSXClosingElement extends Node {
|
2938 | transpile(code) {
|
2939 | var spaceBeforeParen = true;
|
2940 |
|
2941 | var lastChild = this.parent.children[this.parent.children.length - 1];
|
2942 |
|
2943 |
|
2944 |
|
2945 |
|
2946 | if (
|
2947 | (lastChild && containsNewLine(lastChild)) ||
|
2948 | this.parent.openingElement.attributes.length
|
2949 | ) {
|
2950 | spaceBeforeParen = false;
|
2951 | }
|
2952 |
|
2953 | code.overwrite(this.start, this.end, spaceBeforeParen ? ' )' : ')');
|
2954 | }
|
2955 | }
|
2956 |
|
2957 | function containsNewLine$1(node) {
|
2958 | return (
|
2959 | node.type === 'JSXText' && !/\S/.test(node.value) && /\n/.test(node.value)
|
2960 | );
|
2961 | }
|
2962 |
|
2963 | class JSXClosingFragment extends Node {
|
2964 | transpile(code) {
|
2965 | var spaceBeforeParen = true;
|
2966 |
|
2967 | var lastChild = this.parent.children[this.parent.children.length - 1];
|
2968 |
|
2969 |
|
2970 | if (lastChild && containsNewLine$1(lastChild)) {
|
2971 | spaceBeforeParen = false;
|
2972 | }
|
2973 |
|
2974 | code.overwrite(this.start, this.end, spaceBeforeParen ? ' )' : ')');
|
2975 | }
|
2976 | }
|
2977 |
|
2978 | function normalise(str, removeTrailingWhitespace) {
|
2979 |
|
2980 | if (removeTrailingWhitespace && /\n/.test(str)) {
|
2981 | str = str.replace(/[ \f\n\r\t\v]+$/, '');
|
2982 | }
|
2983 |
|
2984 | str = str
|
2985 | .replace(/^\n\r?[ \f\n\r\t\v]+/, '')
|
2986 | .replace(/[ \f\n\r\t\v]*\n\r?[ \f\n\r\t\v]*/gm, ' ');
|
2987 |
|
2988 |
|
2989 | return JSON.stringify(str);
|
2990 | }
|
2991 |
|
2992 | class JSXElement extends Node {
|
2993 | transpile(code, transforms) {
|
2994 | super.transpile(code, transforms);
|
2995 |
|
2996 | var children = this.children.filter(child => {
|
2997 | if (child.type !== 'JSXText') { return true; }
|
2998 |
|
2999 |
|
3000 | return /[^ \f\n\r\t\v]/.test(child.raw) || !/\n/.test(child.raw);
|
3001 | });
|
3002 |
|
3003 | if (children.length) {
|
3004 | var c = (this.openingElement || this.openingFragment).end;
|
3005 |
|
3006 | var i;
|
3007 | for (i = 0; i < children.length; i += 1) {
|
3008 | var child = children[i];
|
3009 |
|
3010 | if (
|
3011 | child.type === 'JSXExpressionContainer' &&
|
3012 | child.expression.type === 'JSXEmptyExpression'
|
3013 | ) ; else {
|
3014 | var tail =
|
3015 | code.original[c] === '\n' && child.type !== 'JSXText' ? '' : ' ';
|
3016 | code.appendLeft(c, `,${tail}`);
|
3017 | }
|
3018 |
|
3019 | if (child.type === 'JSXText') {
|
3020 | var str = normalise(child.value, i === children.length - 1);
|
3021 | code.overwrite(child.start, child.end, str);
|
3022 | }
|
3023 |
|
3024 | c = child.end;
|
3025 | }
|
3026 | }
|
3027 | }
|
3028 | }
|
3029 |
|
3030 | class JSXExpressionContainer extends Node {
|
3031 | transpile(code, transforms) {
|
3032 | code.remove(this.start, this.expression.start);
|
3033 | code.remove(this.expression.end, this.end);
|
3034 |
|
3035 | super.transpile(code, transforms);
|
3036 | }
|
3037 | }
|
3038 |
|
3039 | class JSXFragment extends JSXElement {
|
3040 | }
|
3041 |
|
3042 | class JSXOpeningElement extends Node {
|
3043 | transpile(code, transforms) {
|
3044 | super.transpile(code, transforms);
|
3045 |
|
3046 | code.overwrite(this.start, this.name.start, `${this.program.jsx}( `);
|
3047 |
|
3048 | var html =
|
3049 | this.name.type === 'JSXIdentifier' &&
|
3050 | this.name.name[0] === this.name.name[0].toLowerCase();
|
3051 | if (html) { code.prependRight(this.name.start, `'`); }
|
3052 |
|
3053 | var len = this.attributes.length;
|
3054 | var c = this.name.end;
|
3055 |
|
3056 | if (len) {
|
3057 | var i;
|
3058 |
|
3059 | var hasSpread = false;
|
3060 | for (i = 0; i < len; i += 1) {
|
3061 | if (this.attributes[i].type === 'JSXSpreadAttribute') {
|
3062 | hasSpread = true;
|
3063 | break;
|
3064 | }
|
3065 | }
|
3066 |
|
3067 | c = this.attributes[0].end;
|
3068 |
|
3069 | for (i = 0; i < len; i += 1) {
|
3070 | var attr = this.attributes[i];
|
3071 |
|
3072 | if (i > 0) {
|
3073 | if (attr.start === c) { code.prependRight(c, ', '); }
|
3074 | else { code.overwrite(c, attr.start, ', '); }
|
3075 | }
|
3076 |
|
3077 | if (hasSpread && attr.type !== 'JSXSpreadAttribute') {
|
3078 | var lastAttr = this.attributes[i - 1];
|
3079 | var nextAttr = this.attributes[i + 1];
|
3080 |
|
3081 | if (!lastAttr || lastAttr.type === 'JSXSpreadAttribute') {
|
3082 | code.prependRight(attr.start, '{ ');
|
3083 | }
|
3084 |
|
3085 | if (!nextAttr || nextAttr.type === 'JSXSpreadAttribute') {
|
3086 | code.appendLeft(attr.end, ' }');
|
3087 | }
|
3088 | }
|
3089 |
|
3090 | c = attr.end;
|
3091 | }
|
3092 |
|
3093 | var after;
|
3094 | var before;
|
3095 | if (hasSpread) {
|
3096 | if (len === 1) {
|
3097 | before = html ? `',` : ',';
|
3098 | } else {
|
3099 | if (!this.program.options.objectAssign) {
|
3100 | throw new CompileError(
|
3101 | "Mixed JSX attributes ending in spread requires specified objectAssign option with 'Object.assign' or polyfill helper.",
|
3102 | this
|
3103 | );
|
3104 | }
|
3105 | before = html
|
3106 | ? `', ${this.program.options.objectAssign}({},`
|
3107 | : `, ${this.program.options.objectAssign}({},`;
|
3108 | after = ')';
|
3109 | }
|
3110 | } else {
|
3111 | before = html ? `', {` : ', {';
|
3112 | after = ' }';
|
3113 | }
|
3114 |
|
3115 | code.prependRight(this.name.end, before);
|
3116 |
|
3117 | if (after) {
|
3118 | code.appendLeft(this.attributes[len - 1].end, after);
|
3119 | }
|
3120 | } else {
|
3121 | code.appendLeft(this.name.end, html ? `', null` : `, null`);
|
3122 | c = this.name.end;
|
3123 | }
|
3124 |
|
3125 | if (this.selfClosing) {
|
3126 | code.overwrite(c, this.end, this.attributes.length ? `)` : ` )`);
|
3127 | } else {
|
3128 | code.remove(c, this.end);
|
3129 | }
|
3130 | }
|
3131 | }
|
3132 |
|
3133 | class JSXOpeningFragment extends Node {
|
3134 | transpile(code) {
|
3135 | code.overwrite(this.start, this.end, `${this.program.jsx}( ${this.program.jsxFragment}, null`);
|
3136 | }
|
3137 | }
|
3138 |
|
3139 | class JSXSpreadAttribute extends Node {
|
3140 | transpile(code, transforms) {
|
3141 | code.remove(this.start, this.argument.start);
|
3142 | code.remove(this.argument.end, this.end);
|
3143 |
|
3144 | super.transpile(code, transforms);
|
3145 | }
|
3146 | }
|
3147 |
|
3148 | var nonAsciiLsOrPs = /[\u2028-\u2029]/g;
|
3149 |
|
3150 | class Literal extends Node {
|
3151 | initialise() {
|
3152 | if (typeof this.value === 'string') {
|
3153 | this.program.indentExclusionElements.push(this);
|
3154 | }
|
3155 | }
|
3156 |
|
3157 | transpile(code, transforms) {
|
3158 | if (transforms.numericLiteral) {
|
3159 | if (this.raw.match(/^0[bo]/i)) {
|
3160 | code.overwrite(this.start, this.end, String(this.value), {
|
3161 | storeName: true,
|
3162 | contentOnly: true
|
3163 | });
|
3164 | }
|
3165 | }
|
3166 |
|
3167 | if (this.regex) {
|
3168 | var ref = this.regex;
|
3169 | var pattern = ref.pattern;
|
3170 | var flags = ref.flags;
|
3171 |
|
3172 | if (transforms.stickyRegExp && /y/.test(flags))
|
3173 | { CompileError.missingTransform('the regular expression sticky flag', 'stickyRegExp', this); }
|
3174 | if (transforms.unicodeRegExp && /u/.test(flags)) {
|
3175 | code.overwrite(
|
3176 | this.start,
|
3177 | this.end,
|
3178 | `/${rewritePattern(pattern, flags)}/${flags.replace('u', '')}`,
|
3179 | {
|
3180 | contentOnly: true
|
3181 | }
|
3182 | );
|
3183 | }
|
3184 | } else if (typeof this.value === "string" && this.value.match(nonAsciiLsOrPs)) {
|
3185 | code.overwrite(
|
3186 | this.start,
|
3187 | this.end,
|
3188 | this.raw.replace(nonAsciiLsOrPs, m => m == '\u2028' ? '\\u2028' : '\\u2029'),
|
3189 | {
|
3190 | contentOnly: true
|
3191 | }
|
3192 | );
|
3193 | }
|
3194 | }
|
3195 | }
|
3196 |
|
3197 | class MemberExpression extends Node {
|
3198 | transpile(code, transforms) {
|
3199 | if (transforms.reservedProperties && reserved[this.property.name]) {
|
3200 | code.overwrite(this.object.end, this.property.start, `['`);
|
3201 | code.appendLeft(this.property.end, `']`);
|
3202 | }
|
3203 |
|
3204 | super.transpile(code, transforms);
|
3205 | }
|
3206 | }
|
3207 |
|
3208 | class NewExpression extends Node {
|
3209 | initialise(transforms) {
|
3210 | if (transforms.spreadRest && this.arguments.length) {
|
3211 | var lexicalBoundary = this.findLexicalBoundary();
|
3212 |
|
3213 | var i = this.arguments.length;
|
3214 | while (i--) {
|
3215 | var arg = this.arguments[i];
|
3216 | if (arg.type === 'SpreadElement' && isArguments(arg.argument)) {
|
3217 | this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
|
3218 | break;
|
3219 | }
|
3220 | }
|
3221 | }
|
3222 |
|
3223 | super.initialise(transforms);
|
3224 | }
|
3225 |
|
3226 | transpile(code, transforms) {
|
3227 | super.transpile(code, transforms);
|
3228 |
|
3229 | if (transforms.spreadRest && this.arguments.length) {
|
3230 | inlineSpreads(code, this, this.arguments);
|
3231 |
|
3232 | }
|
3233 |
|
3234 | if (transforms.spreadRest && this.arguments.length) {
|
3235 | var firstArgument = this.arguments[0];
|
3236 | var isNew = true;
|
3237 | var hasSpreadElements = spread(
|
3238 | code,
|
3239 | this.arguments,
|
3240 | firstArgument.start,
|
3241 | this.argumentsArrayAlias,
|
3242 | isNew
|
3243 | );
|
3244 |
|
3245 | if (hasSpreadElements) {
|
3246 | code.prependRight(
|
3247 | this.start + 'new'.length,
|
3248 | ' (Function.prototype.bind.apply('
|
3249 | );
|
3250 | code.overwrite(
|
3251 | this.callee.end,
|
3252 | firstArgument.start,
|
3253 | ', [ null ].concat( '
|
3254 | );
|
3255 | code.appendLeft(this.end, ' ))');
|
3256 | }
|
3257 | }
|
3258 |
|
3259 | if (this.arguments.length) {
|
3260 | removeTrailingComma(code, this.arguments[this.arguments.length - 1].end);
|
3261 | }
|
3262 | }
|
3263 | }
|
3264 |
|
3265 | class ObjectExpression extends Node {
|
3266 | transpile(code, transforms) {
|
3267 | var ref;
|
3268 |
|
3269 | super.transpile(code, transforms);
|
3270 |
|
3271 | var firstPropertyStart = this.start + 1;
|
3272 | var spreadPropertyCount = 0;
|
3273 | var computedPropertyCount = 0;
|
3274 | var firstSpreadProperty = null;
|
3275 | var firstComputedProperty = null;
|
3276 |
|
3277 | for (var i = 0; i < this.properties.length; ++i) {
|
3278 | var prop = this.properties[i];
|
3279 | if (prop.type === 'SpreadElement') {
|
3280 |
|
3281 | var argument = prop.argument;
|
3282 | if (
|
3283 | argument.type === 'ObjectExpression' || (
|
3284 | argument.type === 'Literal' &&
|
3285 | typeof argument.value !== 'string'
|
3286 | )
|
3287 | ) {
|
3288 | if (argument.type === 'ObjectExpression' && argument.properties.length > 0) {
|
3289 |
|
3290 |
|
3291 | code.remove(prop.start, argument.properties[0].start);
|
3292 | code.remove(argument.properties[argument.properties.length - 1].end, prop.end);
|
3293 | (ref = this.properties).splice.apply(ref, [ i, 1 ].concat( argument.properties ));
|
3294 | i--;
|
3295 | } else {
|
3296 |
|
3297 |
|
3298 |
|
3299 | code.remove(prop.start, i === this.properties.length - 1
|
3300 | ? prop.end
|
3301 | : this.properties[i + 1].start);
|
3302 | this.properties.splice(i, 1);
|
3303 | i--;
|
3304 | }
|
3305 | } else {
|
3306 | spreadPropertyCount += 1;
|
3307 | if (firstSpreadProperty === null) { firstSpreadProperty = i; }
|
3308 | }
|
3309 | } else if (prop.computed && transforms.computedProperty) {
|
3310 | computedPropertyCount += 1;
|
3311 | if (firstComputedProperty === null) { firstComputedProperty = i; }
|
3312 | }
|
3313 | }
|
3314 |
|
3315 | if (spreadPropertyCount && !transforms.objectRestSpread && !(computedPropertyCount && transforms.computedProperty)) {
|
3316 | spreadPropertyCount = 0;
|
3317 | firstSpreadProperty = null;
|
3318 | } else if (spreadPropertyCount) {
|
3319 | if (!this.program.options.objectAssign) {
|
3320 | throw new CompileError(
|
3321 | "Object spread operator requires specified objectAssign option with 'Object.assign' or polyfill helper.",
|
3322 | this
|
3323 | );
|
3324 | }
|
3325 | var i$1 = this.properties.length;
|
3326 | while (i$1--) {
|
3327 | var prop$1 = this.properties[i$1];
|
3328 |
|
3329 |
|
3330 | if (prop$1.type === 'Property' && !computedPropertyCount) {
|
3331 | var lastProp = this.properties[i$1 - 1];
|
3332 | var nextProp = this.properties[i$1 + 1];
|
3333 |
|
3334 | if (!lastProp || lastProp.type !== 'Property') {
|
3335 | code.prependRight(prop$1.start, '{');
|
3336 | }
|
3337 |
|
3338 | if (!nextProp || nextProp.type !== 'Property') {
|
3339 | code.appendLeft(prop$1.end, '}');
|
3340 | }
|
3341 | }
|
3342 |
|
3343 |
|
3344 | if (prop$1.type === 'SpreadElement') {
|
3345 | code.remove(prop$1.start, prop$1.argument.start);
|
3346 | code.remove(prop$1.argument.end, prop$1.end);
|
3347 | }
|
3348 | }
|
3349 |
|
3350 |
|
3351 | firstPropertyStart = this.properties[0].start;
|
3352 | if (!computedPropertyCount) {
|
3353 | code.overwrite(
|
3354 | this.start,
|
3355 | firstPropertyStart,
|
3356 | `${this.program.options.objectAssign}({}, `
|
3357 | );
|
3358 | code.overwrite(
|
3359 | this.properties[this.properties.length - 1].end,
|
3360 | this.end,
|
3361 | ')'
|
3362 | );
|
3363 | } else if (this.properties[0].type === 'SpreadElement') {
|
3364 | code.overwrite(
|
3365 | this.start,
|
3366 | firstPropertyStart,
|
3367 | `${this.program.options.objectAssign}({}, `
|
3368 | );
|
3369 | code.remove(this.end - 1, this.end);
|
3370 | code.appendRight(this.end, ')');
|
3371 | } else {
|
3372 | code.prependLeft(this.start, `${this.program.options.objectAssign}(`);
|
3373 | code.appendRight(this.end, ')');
|
3374 | }
|
3375 | }
|
3376 |
|
3377 | if (computedPropertyCount && transforms.computedProperty) {
|
3378 | var i0 = this.getIndentation();
|
3379 |
|
3380 | var isSimpleAssignment;
|
3381 | var name;
|
3382 |
|
3383 | if (
|
3384 | this.parent.type === 'VariableDeclarator' &&
|
3385 | this.parent.parent.declarations.length === 1 &&
|
3386 | this.parent.id.type === 'Identifier'
|
3387 | ) {
|
3388 | isSimpleAssignment = true;
|
3389 | name = this.parent.id.alias || this.parent.id.name;
|
3390 | } else if (
|
3391 | this.parent.type === 'AssignmentExpression' &&
|
3392 | this.parent.parent.type === 'ExpressionStatement' &&
|
3393 | this.parent.left.type === 'Identifier'
|
3394 | ) {
|
3395 | isSimpleAssignment = true;
|
3396 | name = this.parent.left.alias || this.parent.left.name;
|
3397 | } else if (
|
3398 | this.parent.type === 'AssignmentPattern' &&
|
3399 | this.parent.left.type === 'Identifier'
|
3400 | ) {
|
3401 | isSimpleAssignment = true;
|
3402 | name = this.parent.left.alias || this.parent.left.name;
|
3403 | }
|
3404 |
|
3405 | if (spreadPropertyCount) { isSimpleAssignment = false; }
|
3406 |
|
3407 |
|
3408 | name = this.findScope(false).resolveName(name);
|
3409 |
|
3410 | var start = firstPropertyStart;
|
3411 | var end = this.end;
|
3412 |
|
3413 | if (isSimpleAssignment) ; else {
|
3414 | if (
|
3415 | firstSpreadProperty === null ||
|
3416 | firstComputedProperty < firstSpreadProperty
|
3417 | ) {
|
3418 | name = this.findScope(true).createDeclaration('obj');
|
3419 |
|
3420 | code.prependRight(this.start, `( ${name} = `);
|
3421 | } else { name = null; }
|
3422 | }
|
3423 |
|
3424 | var len = this.properties.length;
|
3425 | var lastComputedProp;
|
3426 | var sawNonComputedProperty = false;
|
3427 | var isFirst = true;
|
3428 |
|
3429 | for (var i$2 = 0; i$2 < len; i$2 += 1) {
|
3430 | var prop$2 = this.properties[i$2];
|
3431 | var moveStart = i$2 > 0 ? this.properties[i$2 - 1].end : start;
|
3432 |
|
3433 | if (
|
3434 | prop$2.type === 'Property' &&
|
3435 | (prop$2.computed || (lastComputedProp && !spreadPropertyCount))
|
3436 | ) {
|
3437 | if (i$2 === 0) { moveStart = this.start + 1; }
|
3438 | lastComputedProp = prop$2;
|
3439 |
|
3440 | if (!name) {
|
3441 | name = this.findScope(true).createDeclaration('obj');
|
3442 |
|
3443 | var propId = name + (prop$2.computed ? '' : '.');
|
3444 | code.appendRight(prop$2.start, `( ${name} = {}, ${propId}`);
|
3445 | } else {
|
3446 | var propId$1 =
|
3447 | (isSimpleAssignment ? `;\n${i0}${name}` : `, ${name}`) +
|
3448 | (prop$2.key.type === 'Literal' || prop$2.computed ? '' : '.');
|
3449 |
|
3450 | if (moveStart < prop$2.start) {
|
3451 | code.overwrite(moveStart, prop$2.start, propId$1);
|
3452 | } else {
|
3453 | code.prependRight(prop$2.start, propId$1);
|
3454 | }
|
3455 | }
|
3456 |
|
3457 | var c = prop$2.key.end;
|
3458 | if (prop$2.computed) {
|
3459 | while (code.original[c] !== ']') { c += 1; }
|
3460 | c += 1;
|
3461 | }
|
3462 | if (prop$2.key.type === 'Literal' && !prop$2.computed) {
|
3463 | code.overwrite(
|
3464 | prop$2.start,
|
3465 | prop$2.value.start,
|
3466 | '[' + code.slice(prop$2.start, prop$2.key.end) + '] = '
|
3467 | );
|
3468 | } else if (prop$2.shorthand || (prop$2.method && !prop$2.computed && transforms.conciseMethodProperty)) {
|
3469 |
|
3470 | code.overwrite(
|
3471 | prop$2.key.start,
|
3472 | prop$2.key.end,
|
3473 | code.slice(prop$2.key.start, prop$2.key.end).replace(/:/, ' =')
|
3474 | );
|
3475 | } else {
|
3476 | if (prop$2.value.start > c) { code.remove(c, prop$2.value.start); }
|
3477 | code.prependLeft(c, ' = ');
|
3478 | }
|
3479 |
|
3480 |
|
3481 |
|
3482 | if (prop$2.method && (prop$2.computed || !transforms.conciseMethodProperty)) {
|
3483 | if (prop$2.value.generator) { code.remove(prop$2.start, prop$2.key.start); }
|
3484 | code.prependRight(prop$2.value.start, `function${prop$2.value.generator ? '*' : ''} `);
|
3485 | }
|
3486 | } else if (prop$2.type === 'SpreadElement') {
|
3487 | if (name && i$2 > 0) {
|
3488 | if (!lastComputedProp) {
|
3489 | lastComputedProp = this.properties[i$2 - 1];
|
3490 | }
|
3491 | code.appendLeft(lastComputedProp.end, `, ${name} )`);
|
3492 |
|
3493 | lastComputedProp = null;
|
3494 | name = null;
|
3495 | }
|
3496 | } else {
|
3497 | if (!isFirst && spreadPropertyCount) {
|
3498 |
|
3499 | code.prependRight(prop$2.start, '{');
|
3500 | code.appendLeft(prop$2.end, '}');
|
3501 | }
|
3502 | sawNonComputedProperty = true;
|
3503 | }
|
3504 | if (isFirst && (prop$2.type === 'SpreadElement' || prop$2.computed)) {
|
3505 | var beginEnd = sawNonComputedProperty
|
3506 | ? this.properties[this.properties.length - 1].end
|
3507 | : this.end - 1;
|
3508 |
|
3509 | if (code.original[beginEnd] == ',') { ++beginEnd; }
|
3510 | var closing = code.slice(beginEnd, end);
|
3511 | code.prependLeft(moveStart, closing);
|
3512 | code.remove(beginEnd, end);
|
3513 | isFirst = false;
|
3514 | }
|
3515 |
|
3516 |
|
3517 | var c$1 = prop$2.end;
|
3518 | if (i$2 < len - 1 && !sawNonComputedProperty) {
|
3519 | while (code.original[c$1] !== ',') { c$1 += 1; }
|
3520 | } else if (i$2 == len - 1) { c$1 = this.end; }
|
3521 | if (prop$2.end != c$1) { code.overwrite(prop$2.end, c$1, '', {contentOnly: true}); }
|
3522 | }
|
3523 |
|
3524 | if (!isSimpleAssignment && name) {
|
3525 | code.appendLeft(lastComputedProp.end, `, ${name} )`);
|
3526 | }
|
3527 | }
|
3528 | }
|
3529 | }
|
3530 |
|
3531 | class Property extends Node {
|
3532 | initialise(transforms) {
|
3533 | if ((this.kind === 'get' || this.kind === 'set') && transforms.getterSetter) {
|
3534 | CompileError.missingTransform("getters and setters", "getterSetter", this);
|
3535 | }
|
3536 | super.initialise(transforms);
|
3537 | }
|
3538 |
|
3539 | transpile(code, transforms) {
|
3540 | super.transpile(code, transforms);
|
3541 |
|
3542 | if (
|
3543 | transforms.conciseMethodProperty &&
|
3544 | !this.computed &&
|
3545 | this.parent.type !== 'ObjectPattern'
|
3546 | ) {
|
3547 | if (this.shorthand) {
|
3548 | code.prependRight(this.start, `${this.key.name}: `);
|
3549 | } else if (this.method) {
|
3550 | var name = '';
|
3551 | if (this.program.options.namedFunctionExpressions !== false) {
|
3552 | if (
|
3553 | this.key.type === 'Literal' &&
|
3554 | typeof this.key.value === 'number'
|
3555 | ) {
|
3556 | name = '';
|
3557 | } else if (this.key.type === 'Identifier') {
|
3558 | if (
|
3559 | reserved[this.key.name] ||
|
3560 | !/^[a-z_$][a-z0-9_$]*$/i.test(this.key.name) ||
|
3561 | this.value.body.scope.references[this.key.name]
|
3562 | ) {
|
3563 | name = this.findScope(true).createIdentifier(this.key.name);
|
3564 | } else {
|
3565 | name = this.key.name;
|
3566 | }
|
3567 | } else {
|
3568 | name = this.findScope(true).createIdentifier(this.key.value);
|
3569 | }
|
3570 | name = ' ' + name;
|
3571 | }
|
3572 |
|
3573 | if (this.start < this.key.start) { code.remove(this.start, this.key.start); }
|
3574 | code.appendLeft(
|
3575 | this.key.end,
|
3576 | `: ${this.value.async ? 'async ' : ''}function${this.value.generator ? '*' : ''}${name}`
|
3577 | );
|
3578 | }
|
3579 | }
|
3580 |
|
3581 | if (transforms.reservedProperties && reserved[this.key.name]) {
|
3582 | code.prependRight(this.key.start, `'`);
|
3583 | code.appendLeft(this.key.end, `'`);
|
3584 | }
|
3585 | }
|
3586 | }
|
3587 |
|
3588 | class ReturnStatement extends Node {
|
3589 | initialise(transforms) {
|
3590 | this.loop = this.findNearest(loopStatement);
|
3591 | this.nearestFunction = this.findNearest(/Function/);
|
3592 |
|
3593 | if (
|
3594 | this.loop &&
|
3595 | (!this.nearestFunction || this.loop.depth > this.nearestFunction.depth)
|
3596 | ) {
|
3597 | this.loop.canReturn = true;
|
3598 | this.shouldWrap = true;
|
3599 | }
|
3600 |
|
3601 | if (this.argument) { this.argument.initialise(transforms); }
|
3602 | }
|
3603 |
|
3604 | transpile(code, transforms) {
|
3605 | var shouldWrap =
|
3606 | this.shouldWrap && this.loop && this.loop.shouldRewriteAsFunction;
|
3607 |
|
3608 | if (this.argument) {
|
3609 | if (shouldWrap) { code.prependRight(this.argument.start, `{ v: `); }
|
3610 | this.argument.transpile(code, transforms);
|
3611 | if (shouldWrap) { code.appendLeft(this.argument.end, ` }`); }
|
3612 | } else if (shouldWrap) {
|
3613 | code.appendLeft(this.start + 6, ' {}');
|
3614 | }
|
3615 | }
|
3616 | }
|
3617 |
|
3618 | class Super extends Node {
|
3619 | initialise(transforms) {
|
3620 | if (transforms.classes) {
|
3621 | this.method = this.findNearest('MethodDefinition');
|
3622 | if (!this.method)
|
3623 | { throw new CompileError('use of super outside class method', this); }
|
3624 |
|
3625 | var parentClass = this.findNearest('ClassBody').parent;
|
3626 | this.superClassName =
|
3627 | parentClass.superClass && (parentClass.superClass.name || 'superclass');
|
3628 |
|
3629 | if (!this.superClassName)
|
3630 | { throw new CompileError('super used in base class', this); }
|
3631 |
|
3632 | this.isCalled =
|
3633 | this.parent.type === 'CallExpression' && this === this.parent.callee;
|
3634 |
|
3635 | if (this.method.kind !== 'constructor' && this.isCalled) {
|
3636 | throw new CompileError(
|
3637 | 'super() not allowed outside class constructor',
|
3638 | this
|
3639 | );
|
3640 | }
|
3641 |
|
3642 | this.isMember = this.parent.type === 'MemberExpression';
|
3643 |
|
3644 | if (!this.isCalled && !this.isMember) {
|
3645 | throw new CompileError(
|
3646 | 'Unexpected use of `super` (expected `super(...)` or `super.*`)',
|
3647 | this
|
3648 | );
|
3649 | }
|
3650 | }
|
3651 |
|
3652 | if (transforms.arrow) {
|
3653 | var lexicalBoundary = this.findLexicalBoundary();
|
3654 | var arrowFunction = this.findNearest('ArrowFunctionExpression');
|
3655 | var loop = this.findNearest(loopStatement);
|
3656 |
|
3657 | if (arrowFunction && arrowFunction.depth > lexicalBoundary.depth) {
|
3658 | this.thisAlias = lexicalBoundary.getThisAlias();
|
3659 | }
|
3660 |
|
3661 | if (
|
3662 | loop &&
|
3663 | loop.body.contains(this) &&
|
3664 | loop.depth > lexicalBoundary.depth
|
3665 | ) {
|
3666 | this.thisAlias = lexicalBoundary.getThisAlias();
|
3667 | }
|
3668 | }
|
3669 | }
|
3670 |
|
3671 | transpile(code, transforms) {
|
3672 | if (transforms.classes) {
|
3673 | var expression =
|
3674 | this.isCalled || this.method.static
|
3675 | ? this.superClassName
|
3676 | : `${this.superClassName}.prototype`;
|
3677 |
|
3678 | code.overwrite(this.start, this.end, expression, {
|
3679 | storeName: true,
|
3680 | contentOnly: true
|
3681 | });
|
3682 |
|
3683 | var callExpression = this.isCalled ? this.parent : this.parent.parent;
|
3684 |
|
3685 | if (callExpression && callExpression.type === 'CallExpression') {
|
3686 | if (!this.noCall) {
|
3687 |
|
3688 | code.appendLeft(callExpression.callee.end, '.call');
|
3689 | }
|
3690 |
|
3691 | var thisAlias = this.thisAlias || 'this';
|
3692 |
|
3693 | if (callExpression.arguments.length) {
|
3694 | code.appendLeft(callExpression.arguments[0].start, `${thisAlias}, `);
|
3695 | } else {
|
3696 | code.appendLeft(callExpression.end - 1, `${thisAlias}`);
|
3697 | }
|
3698 | }
|
3699 | }
|
3700 | }
|
3701 | }
|
3702 |
|
3703 | class TaggedTemplateExpression extends Node {
|
3704 | initialise(transforms) {
|
3705 | if (
|
3706 | transforms.templateString &&
|
3707 | !transforms.dangerousTaggedTemplateString
|
3708 | ) {
|
3709 | CompileError.missingTransform(
|
3710 | "tagged template strings", "templateString", this, "dangerousTaggedTemplateString"
|
3711 | );
|
3712 | }
|
3713 |
|
3714 | super.initialise(transforms);
|
3715 | }
|
3716 |
|
3717 | transpile(code, transforms) {
|
3718 | if (transforms.templateString && transforms.dangerousTaggedTemplateString) {
|
3719 | var ordered = this.quasi.expressions
|
3720 | .concat(this.quasi.quasis)
|
3721 | .sort((a, b) => a.start - b.start);
|
3722 |
|
3723 | var program = this.program;
|
3724 | var rootScope = program.body.scope;
|
3725 |
|
3726 |
|
3727 | var templateStrings = this.quasi.quasis.map(quasi =>
|
3728 | JSON.stringify(quasi.value.cooked)
|
3729 | ).join(', ');
|
3730 |
|
3731 | var templateObject = this.program.templateLiteralQuasis[templateStrings];
|
3732 | if (!templateObject) {
|
3733 | templateObject = rootScope.createIdentifier('templateObject');
|
3734 | code.prependLeft(this.program.prependAt, `var ${templateObject} = Object.freeze([${templateStrings}]);\n`);
|
3735 |
|
3736 | this.program.templateLiteralQuasis[templateStrings] = templateObject;
|
3737 | }
|
3738 |
|
3739 | code.overwrite(
|
3740 | this.tag.end,
|
3741 | ordered[0].start,
|
3742 | `(${templateObject}`
|
3743 | );
|
3744 |
|
3745 | var lastIndex = ordered[0].start;
|
3746 | ordered.forEach(node => {
|
3747 | if (node.type === 'TemplateElement') {
|
3748 | code.remove(lastIndex, node.end);
|
3749 | } else {
|
3750 | code.overwrite(lastIndex, node.start, ', ');
|
3751 | }
|
3752 |
|
3753 | lastIndex = node.end;
|
3754 | });
|
3755 |
|
3756 | code.overwrite(lastIndex, this.end, ')');
|
3757 | }
|
3758 |
|
3759 | super.transpile(code, transforms);
|
3760 | }
|
3761 | }
|
3762 |
|
3763 | class TemplateElement extends Node {
|
3764 | initialise() {
|
3765 | this.program.indentExclusionElements.push(this);
|
3766 | }
|
3767 | }
|
3768 |
|
3769 | class TemplateLiteral extends Node {
|
3770 | transpile(code, transforms) {
|
3771 | super.transpile(code, transforms);
|
3772 |
|
3773 | if (
|
3774 | transforms.templateString &&
|
3775 | this.parent.type !== 'TaggedTemplateExpression'
|
3776 | ) {
|
3777 | var ordered = this.expressions
|
3778 | .concat(this.quasis)
|
3779 | .sort((a, b) => a.start - b.start || a.end - b.end)
|
3780 | .filter((node, i) => {
|
3781 |
|
3782 | if (node.type !== 'TemplateElement') { return true; }
|
3783 |
|
3784 |
|
3785 | if (node.value.raw) { return true; }
|
3786 |
|
3787 |
|
3788 | return !i;
|
3789 | });
|
3790 |
|
3791 |
|
3792 |
|
3793 |
|
3794 |
|
3795 | if (ordered.length >= 3) {
|
3796 | var first = ordered[0];
|
3797 | var third = ordered[2];
|
3798 | if (
|
3799 | first.type === 'TemplateElement' &&
|
3800 | first.value.raw === '' &&
|
3801 | third.type === 'TemplateElement'
|
3802 | ) {
|
3803 | ordered.shift();
|
3804 | }
|
3805 | }
|
3806 |
|
3807 | var parenthesise =
|
3808 | (this.quasis.length !== 1 || this.expressions.length !== 0) &&
|
3809 | this.parent.type !== 'TemplateLiteral' &&
|
3810 | this.parent.type !== 'AssignmentExpression' &&
|
3811 | this.parent.type !== 'AssignmentPattern' &&
|
3812 | this.parent.type !== 'VariableDeclarator' &&
|
3813 | (this.parent.type !== 'BinaryExpression' ||
|
3814 | this.parent.operator !== '+');
|
3815 |
|
3816 | if (parenthesise) { code.appendRight(this.start, '('); }
|
3817 |
|
3818 | var lastIndex = this.start;
|
3819 |
|
3820 | ordered.forEach((node, i) => {
|
3821 | var prefix = i === 0 ? (parenthesise ? '(' : '') : ' + ';
|
3822 |
|
3823 | if (node.type === 'TemplateElement') {
|
3824 | code.overwrite(
|
3825 | lastIndex,
|
3826 | node.end,
|
3827 | prefix + JSON.stringify(node.value.cooked)
|
3828 | );
|
3829 | } else {
|
3830 | var parenthesise$1 = node.type !== 'Identifier';
|
3831 |
|
3832 | if (parenthesise$1) { prefix += '('; }
|
3833 |
|
3834 | code.remove(lastIndex, node.start);
|
3835 |
|
3836 | if (prefix) { code.prependRight(node.start, prefix); }
|
3837 | if (parenthesise$1) { code.appendLeft(node.end, ')'); }
|
3838 | }
|
3839 |
|
3840 | lastIndex = node.end;
|
3841 | });
|
3842 |
|
3843 | if (parenthesise) { code.appendLeft(lastIndex, ')'); }
|
3844 | code.overwrite(lastIndex, this.end, "", { contentOnly: true });
|
3845 | }
|
3846 | }
|
3847 | }
|
3848 |
|
3849 | class ThisExpression extends Node {
|
3850 | initialise(transforms) {
|
3851 | var lexicalBoundary = this.findLexicalBoundary();
|
3852 |
|
3853 | if (transforms.letConst) {
|
3854 |
|
3855 |
|
3856 | var node = this.findNearest(loopStatement);
|
3857 | while (node && node.depth > lexicalBoundary.depth) {
|
3858 | node.thisRefs.push(this);
|
3859 | node = node.parent.findNearest(loopStatement);
|
3860 | }
|
3861 | }
|
3862 |
|
3863 | if (transforms.arrow) {
|
3864 | var arrowFunction = this.findNearest('ArrowFunctionExpression');
|
3865 |
|
3866 | if (arrowFunction && arrowFunction.depth > lexicalBoundary.depth) {
|
3867 | this.alias = lexicalBoundary.getThisAlias();
|
3868 | }
|
3869 | }
|
3870 | }
|
3871 |
|
3872 | transpile(code) {
|
3873 | if (this.alias) {
|
3874 | code.overwrite(this.start, this.end, this.alias, {
|
3875 | storeName: true,
|
3876 | contentOnly: true
|
3877 | });
|
3878 | }
|
3879 | }
|
3880 | }
|
3881 |
|
3882 | class UpdateExpression extends Node {
|
3883 | initialise(transforms) {
|
3884 | if (this.argument.type === 'Identifier') {
|
3885 | var declaration = this.findScope(false).findDeclaration(
|
3886 | this.argument.name
|
3887 | );
|
3888 |
|
3889 | var statement = declaration && declaration.node.ancestor(3);
|
3890 | if (
|
3891 | statement &&
|
3892 | statement.type === 'ForStatement' &&
|
3893 | statement.body.contains(this)
|
3894 | ) {
|
3895 | statement.reassigned[this.argument.name] = true;
|
3896 | }
|
3897 | }
|
3898 |
|
3899 | super.initialise(transforms);
|
3900 | }
|
3901 |
|
3902 | transpile(code, transforms) {
|
3903 | if (this.argument.type === 'Identifier') {
|
3904 |
|
3905 |
|
3906 | checkConst(this.argument, this.findScope(false));
|
3907 | }
|
3908 | super.transpile(code, transforms);
|
3909 | }
|
3910 | }
|
3911 |
|
3912 | class VariableDeclaration extends Node {
|
3913 | initialise(transforms) {
|
3914 | this.scope = this.findScope(this.kind === 'var');
|
3915 | this.declarations.forEach(declarator => declarator.initialise(transforms));
|
3916 | }
|
3917 |
|
3918 | transpile(code, transforms) {
|
3919 | var i0 = this.getIndentation();
|
3920 | var kind = this.kind;
|
3921 |
|
3922 | if (transforms.letConst && kind !== 'var') {
|
3923 | kind = 'var';
|
3924 | code.overwrite(this.start, this.start + this.kind.length, kind, {
|
3925 | contentOnly: true,
|
3926 | storeName: true
|
3927 | });
|
3928 | }
|
3929 |
|
3930 | if (transforms.destructuring && this.parent.type !== 'ForOfStatement' && this.parent.type !== 'ForInStatement') {
|
3931 | var c = this.start;
|
3932 | var lastDeclaratorIsPattern;
|
3933 |
|
3934 | this.declarations.forEach((declarator, i) => {
|
3935 | declarator.transpile(code, transforms);
|
3936 |
|
3937 | if (declarator.id.type === 'Identifier') {
|
3938 | if (i > 0 && this.declarations[i - 1].id.type !== 'Identifier') {
|
3939 | code.overwrite(c, declarator.id.start, `var `);
|
3940 | }
|
3941 | } else {
|
3942 | var inline = loopStatement.test(this.parent.type);
|
3943 |
|
3944 | if (i === 0) {
|
3945 | code.remove(c, declarator.id.start);
|
3946 | } else {
|
3947 | code.overwrite(c, declarator.id.start, `;\n${i0}`);
|
3948 | }
|
3949 |
|
3950 | var simple =
|
3951 | declarator.init.type === 'Identifier' && !declarator.init.rewritten;
|
3952 |
|
3953 | var name = simple
|
3954 | ? (declarator.init.alias || declarator.init.name)
|
3955 | : declarator.findScope(true).createIdentifier('ref');
|
3956 |
|
3957 | c = declarator.start;
|
3958 |
|
3959 | var statementGenerators = [];
|
3960 |
|
3961 | if (simple) {
|
3962 | code.remove(declarator.id.end, declarator.end);
|
3963 | } else {
|
3964 | statementGenerators.push((start, prefix, suffix) => {
|
3965 | code.prependRight(declarator.id.end, `var ${name}`);
|
3966 | code.appendLeft(declarator.init.end, `${suffix}`);
|
3967 | code.move(declarator.id.end, declarator.end, start);
|
3968 | });
|
3969 | }
|
3970 |
|
3971 | var scope = declarator.findScope(false);
|
3972 | destructure(
|
3973 | code,
|
3974 | id => scope.createIdentifier(id),
|
3975 | (ref) => {
|
3976 | var name = ref.name;
|
3977 |
|
3978 | return scope.resolveName(name);
|
3979 | },
|
3980 | declarator.id,
|
3981 | name,
|
3982 | inline,
|
3983 | statementGenerators
|
3984 | );
|
3985 |
|
3986 | var prefix = inline ? 'var ' : '';
|
3987 | var suffix = inline ? `, ` : `;\n${i0}`;
|
3988 | statementGenerators.forEach((fn, j) => {
|
3989 | if (
|
3990 | i === this.declarations.length - 1 &&
|
3991 | j === statementGenerators.length - 1
|
3992 | ) {
|
3993 | suffix = inline ? '' : ';';
|
3994 | }
|
3995 |
|
3996 | fn(declarator.start, j === 0 ? prefix : '', suffix);
|
3997 | });
|
3998 | }
|
3999 |
|
4000 | c = declarator.end;
|
4001 | lastDeclaratorIsPattern = declarator.id.type !== 'Identifier';
|
4002 | });
|
4003 |
|
4004 | if (lastDeclaratorIsPattern && this.end > c) {
|
4005 | code.overwrite(c, this.end, '', { contentOnly: true });
|
4006 | }
|
4007 | } else {
|
4008 | this.declarations.forEach(declarator => {
|
4009 | declarator.transpile(code, transforms);
|
4010 | });
|
4011 | }
|
4012 | }
|
4013 | }
|
4014 |
|
4015 | class VariableDeclarator extends Node {
|
4016 | initialise(transforms) {
|
4017 | var kind = this.parent.kind;
|
4018 | if (kind === 'let' && this.parent.parent.type === 'ForStatement') {
|
4019 | kind = 'for.let';
|
4020 | }
|
4021 |
|
4022 | this.parent.scope.addDeclaration(this.id, kind);
|
4023 | super.initialise(transforms);
|
4024 | }
|
4025 |
|
4026 | transpile(code, transforms) {
|
4027 | if (!this.init && transforms.letConst && this.parent.kind !== 'var') {
|
4028 | var inLoop = this.findNearest(
|
4029 | /Function|^For(In|Of)?Statement|^(?:Do)?WhileStatement/
|
4030 | );
|
4031 | if (
|
4032 | inLoop &&
|
4033 | !/Function/.test(inLoop.type) &&
|
4034 | !this.isLeftDeclaratorOfLoop()
|
4035 | ) {
|
4036 | code.appendLeft(this.id.end, ' = (void 0)');
|
4037 | }
|
4038 | }
|
4039 |
|
4040 | if (this.id) { this.id.transpile(code, transforms); }
|
4041 | if (this.init) { this.init.transpile(code, transforms); }
|
4042 | }
|
4043 |
|
4044 | isLeftDeclaratorOfLoop() {
|
4045 | return (
|
4046 | this.parent &&
|
4047 | this.parent.type === 'VariableDeclaration' &&
|
4048 | this.parent.parent &&
|
4049 | (this.parent.parent.type === 'ForInStatement' ||
|
4050 | this.parent.parent.type === 'ForOfStatement') &&
|
4051 | this.parent.parent.left &&
|
4052 | this.parent.parent.left.declarations[0] === this
|
4053 | );
|
4054 | }
|
4055 | }
|
4056 |
|
4057 | var types = {
|
4058 | ArrayExpression,
|
4059 | ArrowFunctionExpression,
|
4060 | AssignmentExpression,
|
4061 | AwaitExpression,
|
4062 | BinaryExpression,
|
4063 | BreakStatement,
|
4064 | CallExpression,
|
4065 | CatchClause,
|
4066 | ClassBody,
|
4067 | ClassDeclaration,
|
4068 | ClassExpression,
|
4069 | ContinueStatement,
|
4070 | DoWhileStatement: LoopStatement,
|
4071 | ExportNamedDeclaration,
|
4072 | ExportDefaultDeclaration,
|
4073 | ForStatement,
|
4074 | ForInStatement,
|
4075 | ForOfStatement,
|
4076 | FunctionDeclaration,
|
4077 | FunctionExpression,
|
4078 | Identifier,
|
4079 | IfStatement,
|
4080 | Import,
|
4081 | ImportDeclaration,
|
4082 | ImportDefaultSpecifier,
|
4083 | ImportSpecifier,
|
4084 | JSXAttribute,
|
4085 | JSXClosingElement,
|
4086 | JSXClosingFragment,
|
4087 | JSXElement,
|
4088 | JSXExpressionContainer,
|
4089 | JSXFragment,
|
4090 | JSXOpeningElement,
|
4091 | JSXOpeningFragment,
|
4092 | JSXSpreadAttribute,
|
4093 | Literal,
|
4094 | MemberExpression,
|
4095 | NewExpression,
|
4096 | ObjectExpression,
|
4097 | Property,
|
4098 | ReturnStatement,
|
4099 | Super,
|
4100 | TaggedTemplateExpression,
|
4101 | TemplateElement,
|
4102 | TemplateLiteral,
|
4103 | ThisExpression,
|
4104 | UpdateExpression,
|
4105 | VariableDeclaration,
|
4106 | VariableDeclarator,
|
4107 | WhileStatement: LoopStatement
|
4108 | };
|
4109 |
|
4110 | var keys = {
|
4111 | Program: ['body'],
|
4112 | Literal: []
|
4113 | };
|
4114 |
|
4115 | var statementsWithBlocks = {
|
4116 | IfStatement: 'consequent',
|
4117 | ForStatement: 'body',
|
4118 | ForInStatement: 'body',
|
4119 | ForOfStatement: 'body',
|
4120 | WhileStatement: 'body',
|
4121 | DoWhileStatement: 'body',
|
4122 | ArrowFunctionExpression: 'body'
|
4123 | };
|
4124 |
|
4125 | function wrap(raw, parent) {
|
4126 | if (!raw) { return; }
|
4127 |
|
4128 | if ('length' in raw) {
|
4129 | var i = raw.length;
|
4130 | while (i--) { wrap(raw[i], parent); }
|
4131 | return;
|
4132 | }
|
4133 |
|
4134 |
|
4135 |
|
4136 | if (raw.__wrapped) { return; }
|
4137 | raw.__wrapped = true;
|
4138 |
|
4139 | if (!keys[raw.type]) {
|
4140 | keys[raw.type] = Object.keys(raw).filter(
|
4141 | key => typeof raw[key] === 'object'
|
4142 | );
|
4143 | }
|
4144 |
|
4145 |
|
4146 | var bodyType = statementsWithBlocks[raw.type];
|
4147 | if (bodyType && raw[bodyType].type !== 'BlockStatement') {
|
4148 | var expression = raw[bodyType];
|
4149 |
|
4150 |
|
4151 |
|
4152 | raw[bodyType] = {
|
4153 | start: expression.start,
|
4154 | end: expression.end,
|
4155 | type: 'BlockStatement',
|
4156 | body: [expression],
|
4157 | synthetic: true
|
4158 | };
|
4159 | }
|
4160 |
|
4161 | raw.parent = parent;
|
4162 | raw.program = parent.program || parent;
|
4163 | raw.depth = parent.depth + 1;
|
4164 | raw.keys = keys[raw.type];
|
4165 | raw.indentation = undefined;
|
4166 |
|
4167 | for (var i$1 = 0, list = keys[raw.type]; i$1 < list.length; i$1 += 1) {
|
4168 | var key = list[i$1];
|
4169 |
|
4170 | wrap(raw[key], raw);
|
4171 | }
|
4172 |
|
4173 | raw.program.magicString.addSourcemapLocation(raw.start);
|
4174 | raw.program.magicString.addSourcemapLocation(raw.end);
|
4175 |
|
4176 | var type =
|
4177 | (raw.type === 'BlockStatement' ? BlockStatement : types[raw.type]) || Node;
|
4178 | raw.__proto__ = type.prototype;
|
4179 | }
|
4180 |
|
4181 | function Program(source, ast, transforms, options) {
|
4182 | this.type = 'Root';
|
4183 |
|
4184 |
|
4185 | this.jsx = options.jsx || 'React.createElement';
|
4186 | this.jsxFragment = options.jsxFragment || 'React.Fragment';
|
4187 | this.options = options;
|
4188 |
|
4189 | this.source = source;
|
4190 | this.magicString = new MagicString(source);
|
4191 |
|
4192 | this.ast = ast;
|
4193 | this.depth = 0;
|
4194 |
|
4195 | wrap((this.body = ast), this);
|
4196 | this.body.__proto__ = BlockStatement.prototype;
|
4197 |
|
4198 | this.templateLiteralQuasis = Object.create(null);
|
4199 | for (var i = 0; i < this.body.body.length; ++i) {
|
4200 | if (!this.body.body[i].directive) {
|
4201 | this.prependAt = this.body.body[i].start;
|
4202 | break;
|
4203 | }
|
4204 | }
|
4205 | this.objectWithoutPropertiesHelper = null;
|
4206 |
|
4207 | this.indentExclusionElements = [];
|
4208 | this.body.initialise(transforms);
|
4209 |
|
4210 | this.indentExclusions = Object.create(null);
|
4211 | for (var i$2 = 0, list = this.indentExclusionElements; i$2 < list.length; i$2 += 1) {
|
4212 | var node = list[i$2];
|
4213 |
|
4214 | for (var i$1 = node.start; i$1 < node.end; i$1 += 1) {
|
4215 | this.indentExclusions[i$1] = true;
|
4216 | }
|
4217 | }
|
4218 |
|
4219 | this.body.transpile(this.magicString, transforms);
|
4220 | }
|
4221 |
|
4222 | Program.prototype = {
|
4223 | export(options) {
|
4224 | if ( options === void 0 ) options = {};
|
4225 |
|
4226 | return {
|
4227 | code: this.magicString.toString(),
|
4228 | map: this.magicString.generateMap({
|
4229 | file: options.file,
|
4230 | source: options.source,
|
4231 | includeContent: options.includeContent !== false
|
4232 | })
|
4233 | };
|
4234 | },
|
4235 |
|
4236 | findNearest() {
|
4237 | return null;
|
4238 | },
|
4239 |
|
4240 | findScope() {
|
4241 | return null;
|
4242 | },
|
4243 |
|
4244 | getObjectWithoutPropertiesHelper(code) {
|
4245 | if (!this.objectWithoutPropertiesHelper) {
|
4246 | this.objectWithoutPropertiesHelper = this.body.scope.createIdentifier('objectWithoutProperties');
|
4247 | code.prependLeft(this.prependAt, `function ${this.objectWithoutPropertiesHelper} (obj, exclude) { ` +
|
4248 | `var target = {}; for (var k in obj) ` +
|
4249 | `if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) ` +
|
4250 | `target[k] = obj[k]; return target; }\n`
|
4251 | );
|
4252 | }
|
4253 | return this.objectWithoutPropertiesHelper;
|
4254 | }
|
4255 | };
|
4256 |
|
4257 | var matrix = {
|
4258 | chrome: {
|
4259 | 48: 0b00010010101000110011111,
|
4260 | 49: 0b00010011111001111111111,
|
4261 | 50: 0b00010111111001111111111,
|
4262 | 51: 0b00010111111001111111111,
|
4263 | 52: 0b00011111111001111111111,
|
4264 | 53: 0b00011111111001111111111,
|
4265 | 54: 0b00011111111001111111111,
|
4266 | 55: 0b01011111111001111111111,
|
4267 | 56: 0b01011111111001111111111,
|
4268 | 57: 0b01011111111001111111111,
|
4269 | 58: 0b01111111111001111111111,
|
4270 | 59: 0b01111111111001111111111,
|
4271 | 60: 0b11111111111001111111111,
|
4272 | 61: 0b11111111111001111111111,
|
4273 | 62: 0b11111111111001111111111,
|
4274 | 63: 0b11111111111001111111111,
|
4275 | 64: 0b11111111111001111111111,
|
4276 | 65: 0b11111111111001111111111,
|
4277 | 66: 0b11111111111001111111111,
|
4278 | 67: 0b11111111111001111111111,
|
4279 | 68: 0b11111111111001111111111,
|
4280 | 69: 0b11111111111001111111111,
|
4281 | 70: 0b11111111111001111111111,
|
4282 | 71: 0b11111111111001111111111
|
4283 | },
|
4284 | firefox: {
|
4285 | 43: 0b00010011101000110111011,
|
4286 | 44: 0b00010011101000110111011,
|
4287 | 45: 0b00010011101000110111111,
|
4288 | 46: 0b00010111101000110111111,
|
4289 | 47: 0b00010111101000111111111,
|
4290 | 48: 0b00010111101000111111111,
|
4291 | 49: 0b00010111101000111111111,
|
4292 | 50: 0b00010111101000111111111,
|
4293 | 51: 0b00010111101001111111111,
|
4294 | 52: 0b01111111111001111111111,
|
4295 | 53: 0b01111111111001111111111,
|
4296 | 54: 0b01111111111001111111111,
|
4297 | 55: 0b11111111111001111111111,
|
4298 | 56: 0b11111111111001111111111,
|
4299 | 57: 0b11111111111001111111111,
|
4300 | 58: 0b11111111111001111111111,
|
4301 | 59: 0b11111111111001111111111,
|
4302 | 60: 0b11111111111001111111111,
|
4303 | 61: 0b11111111111001111111111,
|
4304 | 62: 0b11111111111001111111111,
|
4305 | 63: 0b11111111111001111111111,
|
4306 | 64: 0b11111111111001111111111
|
4307 | },
|
4308 | safari: {
|
4309 | 8: 0b00010000000000000001001,
|
4310 | 9: 0b00010010001000011011101,
|
4311 | 10: 0b00110111111001111111111,
|
4312 | '10.1': 0b01111111111001111111111,
|
4313 | 11: 0b01111111111001111111111,
|
4314 | '11.1': 0b11111111111001111111111,
|
4315 | 12: 0b11111111111001111111111
|
4316 | },
|
4317 | ie: {
|
4318 | 8: 0b00000000000000000000000,
|
4319 | 9: 0b00010000000000000000001,
|
4320 | 10: 0b00010000000000000000001,
|
4321 | 11: 0b00010000000000000000001
|
4322 | },
|
4323 | edge: {
|
4324 | 12: 0b00010010101000010011011,
|
4325 | 13: 0b00010111101000110011111,
|
4326 | 14: 0b00111111101001111111111,
|
4327 | 15: 0b01111111101001111111111,
|
4328 | 16: 0b01111111101001111111111,
|
4329 | 17: 0b01111111101001111111111,
|
4330 | 18: 0b01111111101001111111111,
|
4331 | 19: 0b01111111101001111111111
|
4332 | },
|
4333 | node: {
|
4334 | '0.10': 0b00010000000000000000001,
|
4335 | '0.12': 0b00010000000000010000001,
|
4336 | 4: 0b00010010001000110011111,
|
4337 | 5: 0b00010010001000110011111,
|
4338 | 6: 0b00010111111001111111111,
|
4339 | 8: 0b01111111111001111111111,
|
4340 | '8.3': 0b11111111111001111111111,
|
4341 | '8.7': 0b11111111111001111111111,
|
4342 | '8.10': 0b11111111111001111111111
|
4343 | }
|
4344 | };
|
4345 |
|
4346 | var features = [
|
4347 | 'getterSetter',
|
4348 | 'arrow',
|
4349 | 'classes',
|
4350 | 'computedProperty',
|
4351 | 'conciseMethodProperty',
|
4352 | 'defaultParameter',
|
4353 | 'destructuring',
|
4354 | 'forOf',
|
4355 | 'generator',
|
4356 | 'letConst',
|
4357 | 'moduleExport',
|
4358 | 'moduleImport',
|
4359 | 'numericLiteral',
|
4360 | 'parameterDestructuring',
|
4361 | 'spreadRest',
|
4362 | 'stickyRegExp',
|
4363 | 'templateString',
|
4364 | 'unicodeRegExp',
|
4365 |
|
4366 |
|
4367 | 'exponentiation',
|
4368 |
|
4369 |
|
4370 |
|
4371 | 'reservedProperties',
|
4372 |
|
4373 | 'trailingFunctionCommas',
|
4374 | 'asyncAwait',
|
4375 | 'objectRestSpread'
|
4376 | ];
|
4377 |
|
4378 | var version = "0.20.0";
|
4379 |
|
4380 | var parser = Parser.extend(acornDynamicImport, acornJsx());
|
4381 |
|
4382 | var dangerousTransforms = ['dangerousTaggedTemplateString', 'dangerousForOf'];
|
4383 |
|
4384 | function target(target) {
|
4385 | var targets = Object.keys(target);
|
4386 | var bitmask = targets.length
|
4387 | ? 0b11111111111111111111111
|
4388 | : 0b00010000000000000000001;
|
4389 |
|
4390 | Object.keys(target).forEach(environment => {
|
4391 | var versions = matrix[environment];
|
4392 | if (!versions)
|
4393 | { throw new Error(
|
4394 | `Unknown environment '${environment}'. Please raise an issue at https://github.com/bublejs/buble/issues`
|
4395 | ); }
|
4396 |
|
4397 | var targetVersion = target[environment];
|
4398 | if (!(targetVersion in versions))
|
4399 | { throw new Error(
|
4400 | `Support data exists for the following versions of ${environment}: ${Object.keys(
|
4401 | versions
|
4402 | ).join(
|
4403 | ', '
|
4404 | )}. Please raise an issue at https://github.com/bublejs/buble/issues`
|
4405 | ); }
|
4406 | var support = versions[targetVersion];
|
4407 |
|
4408 | bitmask &= support;
|
4409 | });
|
4410 |
|
4411 | var transforms = Object.create(null);
|
4412 | features.forEach((name, i) => {
|
4413 | transforms[name] = !(bitmask & (1 << i));
|
4414 | });
|
4415 |
|
4416 | dangerousTransforms.forEach(name => {
|
4417 | transforms[name] = false;
|
4418 | });
|
4419 |
|
4420 | return transforms;
|
4421 | }
|
4422 |
|
4423 | function transform(source, options) {
|
4424 | if ( options === void 0 ) options = {};
|
4425 |
|
4426 | var ast;
|
4427 | var jsx = null;
|
4428 |
|
4429 | try {
|
4430 | ast = parser.parse(source, {
|
4431 | ecmaVersion: 10,
|
4432 | preserveParens: true,
|
4433 | sourceType: 'module',
|
4434 | allowAwaitOutsideFunction: true,
|
4435 | allowReturnOutsideFunction: true,
|
4436 | allowHashBang: true,
|
4437 | onComment: (block, text) => {
|
4438 | if (!jsx) {
|
4439 | var match = /@jsx\s+([^\s]+)/.exec(text);
|
4440 | if (match) { jsx = match[1]; }
|
4441 | }
|
4442 | }
|
4443 | });
|
4444 | options.jsx = jsx || options.jsx;
|
4445 | } catch (err) {
|
4446 | err.snippet = getSnippet(source, err.loc);
|
4447 | err.toString = () => `${err.name}: ${err.message}\n${err.snippet}`;
|
4448 | throw err;
|
4449 | }
|
4450 |
|
4451 | var transforms = target(options.target || {});
|
4452 | Object.keys(options.transforms || {}).forEach(name => {
|
4453 | if (name === 'modules') {
|
4454 | if (!('moduleImport' in options.transforms))
|
4455 | { transforms.moduleImport = options.transforms.modules; }
|
4456 | if (!('moduleExport' in options.transforms))
|
4457 | { transforms.moduleExport = options.transforms.modules; }
|
4458 | return;
|
4459 | }
|
4460 |
|
4461 | if (!(name in transforms)) { throw new Error(`Unknown transform '${name}'`); }
|
4462 | transforms[name] = options.transforms[name];
|
4463 | });
|
4464 | if (options.objectAssign === true) { options.objectAssign = 'Object.assign'; }
|
4465 | return new Program(source, ast, transforms, options).export(options);
|
4466 | }
|
4467 |
|
4468 | export { version as VERSION, target, transform };
|
4469 |
|