You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					225 lines
				
				7.4 KiB
			
		
		
			
		
	
	
					225 lines
				
				7.4 KiB
			| 
											3 years ago
										 | "use strict"; | ||
|  | 
 | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |   value: true | ||
|  | }); | ||
|  | exports.default = void 0; | ||
|  | 
 | ||
|  | var _helperPluginUtils = require("@babel/helper-plugin-utils"); | ||
|  | 
 | ||
|  | var _core = require("@babel/core"); | ||
|  | 
 | ||
|  | var _noHelperImplementation = require("./no-helper-implementation"); | ||
|  | 
 | ||
|  | function buildLoopBody(path, declar, newBody) { | ||
|  |   let block; | ||
|  |   const bodyPath = path.get("body"); | ||
|  |   const body = newBody != null ? newBody : bodyPath.node; | ||
|  | 
 | ||
|  |   if (_core.types.isBlockStatement(body) && Object.keys(path.getBindingIdentifiers()).some(id => bodyPath.scope.hasOwnBinding(id))) { | ||
|  |     block = _core.types.blockStatement([declar, body]); | ||
|  |   } else { | ||
|  |     block = _core.types.toBlock(body); | ||
|  |     block.body.unshift(declar); | ||
|  |   } | ||
|  | 
 | ||
|  |   return block; | ||
|  | } | ||
|  | 
 | ||
|  | var _default = (0, _helperPluginUtils.declare)((api, options) => { | ||
|  |   var _options$assumeArray, _options$allowArrayLi, _api$assumption; | ||
|  | 
 | ||
|  |   api.assertVersion(7); | ||
|  |   { | ||
|  |     const { | ||
|  |       assumeArray, | ||
|  |       allowArrayLike, | ||
|  |       loose | ||
|  |     } = options; | ||
|  | 
 | ||
|  |     if (loose === true && assumeArray === true) { | ||
|  |       throw new Error(`The loose and assumeArray options cannot be used together in @babel/plugin-transform-for-of`); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (assumeArray === true && allowArrayLike === true) { | ||
|  |       throw new Error(`The assumeArray and allowArrayLike options cannot be used together in @babel/plugin-transform-for-of`); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (allowArrayLike && /^7\.\d\./.test(api.version)) { | ||
|  |       throw new Error(`The allowArrayLike is only supported when using @babel/core@^7.10.0`); | ||
|  |     } | ||
|  |   } | ||
|  |   const iterableIsArray = (_options$assumeArray = options.assumeArray) != null ? _options$assumeArray : !options.loose && api.assumption("iterableIsArray"); | ||
|  |   const arrayLikeIsIterable = (_options$allowArrayLi = options.allowArrayLike) != null ? _options$allowArrayLi : api.assumption("arrayLikeIsIterable"); | ||
|  |   const skipteratorClosing = (_api$assumption = api.assumption("skipForOfIteratorClosing")) != null ? _api$assumption : options.loose; | ||
|  | 
 | ||
|  |   if (iterableIsArray && arrayLikeIsIterable) { | ||
|  |     throw new Error(`The "iterableIsArray" and "arrayLikeIsIterable" assumptions are not compatible.`); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (iterableIsArray) { | ||
|  |     return { | ||
|  |       name: "transform-for-of", | ||
|  |       visitor: { | ||
|  |         ForOfStatement(path) { | ||
|  |           const { | ||
|  |             scope | ||
|  |           } = path; | ||
|  |           const { | ||
|  |             left, | ||
|  |             right, | ||
|  |             await: isAwait | ||
|  |           } = path.node; | ||
|  | 
 | ||
|  |           if (isAwait) { | ||
|  |             return; | ||
|  |           } | ||
|  | 
 | ||
|  |           const i = scope.generateUidIdentifier("i"); | ||
|  |           let array = scope.maybeGenerateMemoised(right, true); | ||
|  |           const inits = [_core.types.variableDeclarator(i, _core.types.numericLiteral(0))]; | ||
|  | 
 | ||
|  |           if (array) { | ||
|  |             inits.push(_core.types.variableDeclarator(array, right)); | ||
|  |           } else { | ||
|  |             array = right; | ||
|  |           } | ||
|  | 
 | ||
|  |           const item = _core.types.memberExpression(_core.types.cloneNode(array), _core.types.cloneNode(i), true); | ||
|  | 
 | ||
|  |           let assignment; | ||
|  | 
 | ||
|  |           if (_core.types.isVariableDeclaration(left)) { | ||
|  |             assignment = left; | ||
|  |             assignment.declarations[0].init = item; | ||
|  |           } else { | ||
|  |             assignment = _core.types.expressionStatement(_core.types.assignmentExpression("=", left, item)); | ||
|  |           } | ||
|  | 
 | ||
|  |           path.replaceWith(_core.types.forStatement(_core.types.variableDeclaration("let", inits), _core.types.binaryExpression("<", _core.types.cloneNode(i), _core.types.memberExpression(_core.types.cloneNode(array), _core.types.identifier("length"))), _core.types.updateExpression("++", _core.types.cloneNode(i)), buildLoopBody(path, assignment))); | ||
|  |         } | ||
|  | 
 | ||
|  |       } | ||
|  |     }; | ||
|  |   } | ||
|  | 
 | ||
|  |   const buildForOfArray = (0, _core.template)`
 | ||
|  |     for (var KEY = 0, NAME = ARR; KEY < NAME.length; KEY++) BODY; | ||
|  |   `;
 | ||
|  |   const buildForOfNoIteratorClosing = _core.template.statements`
 | ||
|  |     for (var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT, ARRAY_LIKE_IS_ITERABLE), STEP_KEY; | ||
|  |         !(STEP_KEY = ITERATOR_HELPER()).done;) BODY; | ||
|  |   `;
 | ||
|  |   const buildForOf = _core.template.statements`
 | ||
|  |     var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT, ARRAY_LIKE_IS_ITERABLE), STEP_KEY; | ||
|  |     try { | ||
|  |       for (ITERATOR_HELPER.s(); !(STEP_KEY = ITERATOR_HELPER.n()).done;) BODY; | ||
|  |     } catch (err) { | ||
|  |       ITERATOR_HELPER.e(err); | ||
|  |     } finally { | ||
|  |       ITERATOR_HELPER.f(); | ||
|  |     } | ||
|  |   `;
 | ||
|  |   const builder = skipteratorClosing ? { | ||
|  |     build: buildForOfNoIteratorClosing, | ||
|  |     helper: "createForOfIteratorHelperLoose", | ||
|  |     getContainer: nodes => nodes | ||
|  |   } : { | ||
|  |     build: buildForOf, | ||
|  |     helper: "createForOfIteratorHelper", | ||
|  |     getContainer: nodes => nodes[1].block.body | ||
|  |   }; | ||
|  | 
 | ||
|  |   function _ForOfStatementArray(path) { | ||
|  |     const { | ||
|  |       node, | ||
|  |       scope | ||
|  |     } = path; | ||
|  |     const right = scope.generateUidIdentifierBasedOnNode(node.right, "arr"); | ||
|  |     const iterationKey = scope.generateUidIdentifier("i"); | ||
|  |     const loop = buildForOfArray({ | ||
|  |       BODY: node.body, | ||
|  |       KEY: iterationKey, | ||
|  |       NAME: right, | ||
|  |       ARR: node.right | ||
|  |     }); | ||
|  | 
 | ||
|  |     _core.types.inherits(loop, node); | ||
|  | 
 | ||
|  |     const iterationValue = _core.types.memberExpression(_core.types.cloneNode(right), _core.types.cloneNode(iterationKey), true); | ||
|  | 
 | ||
|  |     let declar; | ||
|  |     const left = node.left; | ||
|  | 
 | ||
|  |     if (_core.types.isVariableDeclaration(left)) { | ||
|  |       left.declarations[0].init = iterationValue; | ||
|  |       declar = left; | ||
|  |     } else { | ||
|  |       declar = _core.types.expressionStatement(_core.types.assignmentExpression("=", left, iterationValue)); | ||
|  |     } | ||
|  | 
 | ||
|  |     loop.body = buildLoopBody(path, declar, loop.body); | ||
|  |     return loop; | ||
|  |   } | ||
|  | 
 | ||
|  |   return { | ||
|  |     name: "transform-for-of", | ||
|  |     visitor: { | ||
|  |       ForOfStatement(path, state) { | ||
|  |         const right = path.get("right"); | ||
|  | 
 | ||
|  |         if (right.isArrayExpression() || right.isGenericType("Array") || _core.types.isArrayTypeAnnotation(right.getTypeAnnotation())) { | ||
|  |           path.replaceWith(_ForOfStatementArray(path)); | ||
|  |           return; | ||
|  |         } | ||
|  | 
 | ||
|  |         if (!state.availableHelper(builder.helper)) { | ||
|  |           (0, _noHelperImplementation.default)(skipteratorClosing, path, state); | ||
|  |           return; | ||
|  |         } | ||
|  | 
 | ||
|  |         const { | ||
|  |           node, | ||
|  |           parent, | ||
|  |           scope | ||
|  |         } = path; | ||
|  |         const left = node.left; | ||
|  |         let declar; | ||
|  |         const stepKey = scope.generateUid("step"); | ||
|  | 
 | ||
|  |         const stepValue = _core.types.memberExpression(_core.types.identifier(stepKey), _core.types.identifier("value")); | ||
|  | 
 | ||
|  |         if (_core.types.isVariableDeclaration(left)) { | ||
|  |           declar = _core.types.variableDeclaration(left.kind, [_core.types.variableDeclarator(left.declarations[0].id, stepValue)]); | ||
|  |         } else { | ||
|  |           declar = _core.types.expressionStatement(_core.types.assignmentExpression("=", left, stepValue)); | ||
|  |         } | ||
|  | 
 | ||
|  |         const nodes = builder.build({ | ||
|  |           CREATE_ITERATOR_HELPER: state.addHelper(builder.helper), | ||
|  |           ITERATOR_HELPER: scope.generateUidIdentifier("iterator"), | ||
|  |           ARRAY_LIKE_IS_ITERABLE: arrayLikeIsIterable ? _core.types.booleanLiteral(true) : null, | ||
|  |           STEP_KEY: _core.types.identifier(stepKey), | ||
|  |           OBJECT: node.right, | ||
|  |           BODY: buildLoopBody(path, declar) | ||
|  |         }); | ||
|  |         const container = builder.getContainer(nodes); | ||
|  | 
 | ||
|  |         _core.types.inherits(container[0], node); | ||
|  | 
 | ||
|  |         _core.types.inherits(container[0].body, node.body); | ||
|  | 
 | ||
|  |         if (_core.types.isLabeledStatement(parent)) { | ||
|  |           container[0] = _core.types.labeledStatement(parent.label, container[0]); | ||
|  |           path.parentPath.replaceWithMultiple(nodes); | ||
|  |           path.skip(); | ||
|  |         } else { | ||
|  |           path.replaceWithMultiple(nodes); | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |     } | ||
|  |   }; | ||
|  | }); | ||
|  | 
 | ||
|  | exports.default = _default; |