"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalGetResultValue = InternalGetResultValue; exports.LoopContinues = LoopContinues; exports.ForInOfHeadEvaluation = ForInOfHeadEvaluation; exports.ForInOfBodyEvaluation = ForInOfBodyEvaluation; exports.default = function (ast, strictCode, env, realm, labelSet) { var left = ast.left, right = ast.right, body = ast.body; try { if (left.type === "VariableDeclaration") { if (left.kind === "var") { // for (var ForBinding o fAssignmentExpression) Statement // 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate). var keyResult = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode); (0, _invariant2.default)(keyResult instanceof _index.ObjectValue); // 2. Return ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, varBinding, labelSet). return ForInOfBodyEvaluation(realm, env, left.declarations[0].id, body, keyResult, "varBinding", labelSet, strictCode); } else { // for (ForDeclaration of AssignmentExpression) Statement // 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate). var _keyResult = ForInOfHeadEvaluation(realm, env, _singletons.Environment.BoundNames(realm, left), right, "iterate", strictCode); (0, _invariant2.default)(_keyResult instanceof _index.ObjectValue); // 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, lexicalBinding, labelSet). return ForInOfBodyEvaluation(realm, env, left, body, _keyResult, "lexicalBinding", labelSet, strictCode); } } else { // for (LeftHandSideExpression of AssignmentExpression) Statement // 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate). var _keyResult2 = ForInOfHeadEvaluation(realm, env, [], right, "iterate", strictCode); (0, _invariant2.default)(_keyResult2 instanceof _index.ObjectValue); // 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, assignment, labelSet). return ForInOfBodyEvaluation(realm, env, left, body, _keyResult2, "assignment", labelSet, strictCode); } } catch (e) { if (e instanceof _completions.BreakCompletion) { if (!e.target) return (0, _index2.UpdateEmpty)(realm, e, realm.intrinsics.undefined).value; } throw e; } }; var _errors = require("../errors.js"); var _environment = require("../environment.js"); var _completions = require("../completions.js"); var _index = require("../values/index.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _index2 = require("../methods/index.js"); var _singletons = require("../singletons.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ function InternalGetResultValue(realm, result) { if (result instanceof _completions.AbruptCompletion) { return result.value; } else { return result; } } // ECMA262 13.7.1.2 function LoopContinues(realm, completion, labelSet) { // 1. If completion.[[Type]] is normal, return true. if (completion instanceof _index.Value) return true; (0, _invariant2.default)(completion instanceof _completions.AbruptCompletion); // 2. If completion.[[Type]] is not continue, return false. if (!(completion instanceof _completions.ContinueCompletion)) return false; // 3. If completion.[[Target]] is empty, return true. if (!completion.target) return true; // 4. If completion.[[Target]] is an element of labelSet, return true. if (labelSet != null && labelSet.indexOf(completion.target) >= 0) return true; // 5. Return false. return false; } // ECMA262 13.7.5.10 function BindingInstantiation(realm, ast, env) { // ast = ForDeclaration : LetOrConst ForBinding // 1. Let envRec be environment's EnvironmentRecord. var envRec = env.environmentRecord; // 2. Assert: envRec is a declarative Environment Record. (0, _invariant2.default)(envRec instanceof _environment.DeclarativeEnvironmentRecord); // 3. For each element name of the BoundNames of ForBinding do var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _singletons.Environment.BoundNames(realm, ast)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var name = _step.value; // a. If IsConstantDeclaration of LetOrConst is true, then if (ast.kind === "const") { // i. Perform ! envRec.CreateImmutableBinding(name, true). envRec.CreateImmutableBinding(name, true); } else { // b. // i. Perform ! envRec.CreateMutableBinding(name, false). envRec.CreateMutableBinding(name, false); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } // ECMA262 13.7.5.12 function ForInOfHeadEvaluation(realm, env, TDZnames, expr, iterationKind, strictCode) { // 1. Let oldEnv be the running execution context's LexicalEnvironment. var oldEnv = realm.getRunningContext().lexicalEnvironment; // 2. If TDZnames is not an empty List, then if (TDZnames.length) { // a. Assert: TDZnames has no duplicate entries. // b. Let TDZ be NewDeclarativeEnvironment(oldEnv). var TDZ = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv); // c. Let TDZEnvRec be TDZ's EnvironmentRecord. var TDZEnvRec = TDZ.environmentRecord; // d. For each string name in TDZnames, do var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = TDZnames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var name = _step2.value; // i. Perform ! TDZEnvRec.CreateMutableBinding(name, false). TDZEnvRec.CreateMutableBinding(name, false); } // e. Set the running execution context's LexicalEnvironment to TDZ. } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } realm.getRunningContext().lexicalEnvironment = TDZ; env = TDZ; } var exprRef = void 0; try { // 3. Let exprRef be the result of evaluating expr. exprRef = env.evaluate(expr, strictCode); } finally { // 4. Set the running execution context's LexicalEnvironment to oldEnv. var lexEnv = realm.getRunningContext().lexicalEnvironment; if (lexEnv !== oldEnv) realm.onDestroyScope(lexEnv); realm.getRunningContext().lexicalEnvironment = oldEnv; } env = oldEnv; // 5. Let exprValue be ? GetValue(exprRef). var exprValue = _singletons.Environment.GetValue(realm, exprRef); // 6. If iterationKind is enumerate, then if (iterationKind === "enumerate") { // a. If exprValue.[[Value]] is null or undefined, then if (exprValue instanceof _index.NullValue || exprValue instanceof _index.UndefinedValue) { // i. Return Completion{[[Type]]: break, [[Value]]: empty, [[Target]]: empty}. throw new _completions.BreakCompletion(realm.intrinsics.empty, expr.loc, undefined); } // b. Let obj be ToObject(exprValue). var obj = _singletons.To.ToObjectPartial(realm, exprValue); // c. Return ? EnumerateObjectProperties(obj). if (obj.isPartialObject() || obj instanceof _index.AbstractObjectValue) { return obj; } else { return _singletons.Properties.EnumerateObjectProperties(realm, obj); } } else { // 8. Else, // 1. Assert: iterationKind is iterate. (0, _invariant2.default)(iterationKind === "iterate", "expected iterationKind to be iterate"); if (exprValue instanceof _index.AbstractValue) { var error = new _errors.CompilerDiagnostic("for of loops over unknown collections are not yet supported", expr.loc, "PP0014", "FatalError"); realm.handleError(error); throw new _errors.FatalError(); } // 1. Return ? GetIterator(exprValue). return (0, _index2.GetIterator)(realm, exprValue); } } // ECMA262 13.7.5.13 function ForInOfBodyEvaluation(realm, env, lhs, stmt, iterator, lhsKind, labelSet, strictCode) { // 1. Let oldEnv be the running execution context's LexicalEnvironment. var oldEnv = realm.getRunningContext().lexicalEnvironment; // 2. Let V be undefined. var V = realm.intrinsics.undefined; // 3. Let destructuring be IsDestructuring of lhs. var destructuring = _singletons.Environment.IsDestructuring(lhs); // 4. If destructuring is true and if lhsKind is assignment, then if (destructuring && lhsKind === "assignment") { // a. Assert: lhs is a LeftHandSideExpression. (0, _invariant2.default)(lhs.type !== "VariableDeclaration"); // b. Let assignmentPattern be the parse of the source text corresponding to lhs using AssignmentPattern as the goal symbol. } // 5. Repeat while (true) { // a. Let nextResult be ? IteratorStep(iterator). var nextResult = (0, _index2.IteratorStep)(realm, iterator); // b. If nextResult is false, return NormalCompletion(V). if (!nextResult) return V; // c. Let nextValue be ? IteratorValue(nextResult). var nextValue = (0, _index2.IteratorValue)(realm, nextResult); // d. If lhsKind is either assignment or varBinding, then var iterationEnv = void 0; var lhsRef = void 0; if (lhsKind === "assignment" || lhsKind === "varBinding") { // i. If destructuring is false, then if (!destructuring) { // 1. Let lhsRef be the result of evaluating lhs. (It may be evaluated repeatedly.) lhsRef = env.evaluateCompletion(lhs, strictCode); } } else { // e. Else, // i. Assert: lhsKind is lexicalBinding. (0, _invariant2.default)(lhsKind === "lexicalBinding", "expected lhsKind to be lexicalBinding"); (0, _invariant2.default)(lhs.type === "VariableDeclaration"); // ii. Assert: lhs is a ForDeclaration. // iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv). iterationEnv = _singletons.Environment.NewDeclarativeEnvironment(realm, oldEnv); // iv. Perform BindingInstantiation for lhs passing iterationEnv as the argument. BindingInstantiation(realm, lhs, iterationEnv); // v. Set the running execution context's LexicalEnvironment to iterationEnv. realm.getRunningContext().lexicalEnvironment = iterationEnv; env = iterationEnv; // vi. If destructuring is false, then if (!destructuring) { var names = _singletons.Environment.BoundNames(realm, lhs); // 1. Assert: lhs binds a single name. (0, _invariant2.default)(names.length === 1, "expected single name"); // 2. Let lhsName be the sole element of BoundNames of lhs. var lhsName = names[0]; // 3. Let lhsRef be ! ResolveBinding(lhsName). lhsRef = _singletons.Environment.ResolveBinding(realm, lhsName, strictCode); } } // f. If destructuring is false, then var status = void 0; try { if (!destructuring) { // i. If lhsRef is an abrupt completion, then if (lhsRef instanceof _completions.AbruptCompletion) { // 1. Let status be lhsRef. status = lhsRef; } else if (lhsKind === "lexicalBinding") { // ii. Else if lhsKind is lexicalBinding, then // 1. Let status be InitializeReferencedBinding(lhsRef, nextValue). (0, _invariant2.default)(lhsRef instanceof _environment.Reference); status = _singletons.Environment.InitializeReferencedBinding(realm, lhsRef, nextValue); } else { // iii. Else, // 1. Let status be PutValue(lhsRef, nextValue). (0, _invariant2.default)(lhsRef !== undefined); status = _singletons.Properties.PutValue(realm, lhsRef, nextValue); } } else { // g. Else, // i. If lhsKind is assignment, then if (lhsKind === "assignment") { (0, _invariant2.default)(lhs.type === "ArrayPattern" || lhs.type === "ObjectPattern"); // 1. Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument. status = (0, _index2.DestructuringAssignmentEvaluation)(realm, lhs, nextValue, strictCode, iterationEnv || env); } else if (lhsKind === "varBinding") { // ii. Else if lhsKind is varBinding, then // 1. Assert: lhs is a ForBinding. // 2. Let status be the result of performing BindingInitialization for lhs passing nextValue and undefined as the arguments. status = _singletons.Environment.BindingInitialization(realm, lhs, nextValue, strictCode, undefined); } else { // iii. Else, // 1. Assert: lhsKind is lexicalBinding. (0, _invariant2.default)(lhsKind === "lexicalBinding"); // 2. Assert: lhs is a ForDeclaration. // 3. Let status be the result of performing BindingInitialization for lhs passing nextValue and iterationEnv as arguments. (0, _invariant2.default)(iterationEnv !== undefined); status = _singletons.Environment.BindingInitialization(realm, lhs, nextValue, strictCode, iterationEnv); } } } catch (e) { if (e instanceof _completions.AbruptCompletion) { status = e; } else { throw e; } } // h. If status is an abrupt completion, then if (status instanceof _completions.AbruptCompletion) { // i. Set the running execution context's LexicalEnvironment to oldEnv. realm.getRunningContext().lexicalEnvironment = oldEnv; // ii. Return ? IteratorClose(iterator, status). throw (0, _index2.IteratorClose)(realm, iterator, status); } // i. Let result be the result of evaluating stmt. var result = env.evaluateCompletion(stmt, strictCode); (0, _invariant2.default)(result instanceof _index.Value || result instanceof _completions.AbruptCompletion); // j. Set the running execution context's LexicalEnvironment to oldEnv. var lexEnv = realm.getRunningContext().lexicalEnvironment; if (lexEnv !== oldEnv) realm.onDestroyScope(lexEnv); realm.getRunningContext().lexicalEnvironment = oldEnv; env = oldEnv; // k. If LoopContinues(result, labelSet) is false, return ? IteratorClose(iterator, UpdateEmpty(result, V)). if (!LoopContinues(realm, result, labelSet)) { (0, _invariant2.default)(result instanceof _completions.AbruptCompletion); result = (0, _index2.UpdateEmpty)(realm, result, V); (0, _invariant2.default)(result instanceof _completions.AbruptCompletion); throw (0, _index2.IteratorClose)(realm, iterator, result); } // l. If result.[[Value]] is not empty, let V be result.[[Value]]. var resultValue = InternalGetResultValue(realm, result); if (!(resultValue instanceof _index.EmptyValue)) V = resultValue; } /* istanbul ignore next */ (0, _invariant2.default)(false); // can't get here but there is no other way to make Flow happy } // ECMA262 13.7.5.11 //# sourceMappingURL=ForOfStatement.js.map