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