UNPKG

traceur

Version:
803 lines (802 loc) 36.9 kB
"use strict"; function $__interopRequire(id) { id = require(id); return id && id.__esModule && id || {default: id}; } Object.defineProperties(module.exports, { __esModule: {value: true}, CPSTransformer: { enumerable: true, get: function() { return CPSTransformer; } } }); var $__spread = $__interopRequire("traceur/dist/commonjs/runtime/modules/spread.js").default; var $__createClass = $__interopRequire("traceur/dist/commonjs/runtime/modules/createClass.js").default; var $__superConstructor = $__interopRequire("traceur/dist/commonjs/runtime/modules/superConstructor.js").default; var $__superGet = $__interopRequire("traceur/dist/commonjs/runtime/modules/superGet.js").default; var $__getTemplateObject = $__interopRequire("traceur/dist/commonjs/runtime/modules/getTemplateObject.js").default; var AlphaRenamer = require("../AlphaRenamer.js").AlphaRenamer; var BreakContinueTransformer = require("./BreakContinueTransformer.js").BreakContinueTransformer; var $__24 = require("../../syntax/trees/ParseTreeType.js"), BLOCK = $__24.BLOCK, CASE_CLAUSE = $__24.CASE_CLAUSE, CONDITIONAL_EXPRESSION = $__24.CONDITIONAL_EXPRESSION, EXPRESSION_STATEMENT = $__24.EXPRESSION_STATEMENT, PAREN_EXPRESSION = $__24.PAREN_EXPRESSION, STATE_MACHINE = $__24.STATE_MACHINE; var $__25 = require("../../syntax/trees/ParseTrees.js"), AnonBlock = $__25.AnonBlock, Block = $__25.Block, CaseClause = $__25.CaseClause, IfStatement = $__25.IfStatement, SwitchStatement = $__25.SwitchStatement; var CatchState = require("./CatchState.js").CatchState; var ConditionalState = require("./ConditionalState.js").ConditionalState; var ExplodeExpressionTransformer = require("../ExplodeExpressionTransformer.js").ExplodeExpressionTransformer; var FallThroughState = require("./FallThroughState.js").FallThroughState; var FinallyFallThroughState = require("./FinallyFallThroughState.js").FinallyFallThroughState; var FinallyState = require("./FinallyState.js").FinallyState; var FindInFunctionScope = require("../FindInFunctionScope.js").FindInFunctionScope; var ParseTreeTransformer = require("../ParseTreeTransformer.js").ParseTreeTransformer; var StringMap = require("../../util/StringMap.js").StringMap; var TempVarTransformer = require("../TempVarTransformer.js").TempVarTransformer; var assert = require("../../util/assert.js").assert; var $__37 = require("../PlaceholderParser.js"), parseExpression = $__37.parseExpression, parseStatement = $__37.parseStatement, parseStatements = $__37.parseStatements; var State = require("./State.js").State; var StateAllocator = require("./StateAllocator.js").StateAllocator; var StateMachine = require("../../syntax/trees/StateMachine.js").StateMachine; var $__41 = require("./SwitchState.js"), SwitchClause = $__41.SwitchClause, SwitchState = $__41.SwitchState; var TryState = require("./TryState.js").TryState; var $__43 = require("../ParseTreeFactory.js"), createAssignStateStatement = $__43.createAssignStateStatement, createBreakStatement = $__43.createBreakStatement, createCaseClause = $__43.createCaseClause, createDefaultClause = $__43.createDefaultClause, createExpressionStatement = $__43.createExpressionStatement, createFunctionBody = $__43.createFunctionBody, id = $__43.createIdentifierExpression, createMemberExpression = $__43.createMemberExpression, createNumberLiteral = $__43.createNumberLiteral, createSwitchStatement = $__43.createSwitchStatement; var HoistVariablesTransformer = $__interopRequire("../HoistVariablesTransformer.js").default; var LabelState = function() { function LabelState(name, continueState, fallThroughState) { this.name = name; this.continueState = continueState; this.fallThroughState = fallThroughState; } return ($__createClass)(LabelState, {}, {}); }(); var NeedsStateMachine = function($__super) { function NeedsStateMachine() { $__superConstructor(NeedsStateMachine).apply(this, arguments); } return ($__createClass)(NeedsStateMachine, { visitBreakStatement: function(tree) { this.found = true; }, visitContinueStatement: function(tree) { this.found = true; }, visitStateMachine: function(tree) { this.found = true; }, visitYieldExpression: function(tee) { this.found = true; } }, {}, $__super); }(FindInFunctionScope); function needsStateMachine(tree) { var visitor = new NeedsStateMachine(); visitor.visitAny(tree); return visitor.found; } var HoistVariables = function($__super) { function HoistVariables() { $__superConstructor(HoistVariables).call(this, true); } return ($__createClass)(HoistVariables, { prependVariables: function(statements) { return statements; }, prependFunctions: function(statements) { return statements; } }, {}, $__super); }(HoistVariablesTransformer); var CPSTransformer = function($__super) { function CPSTransformer(identifierGenerator, reporter, options) { $__superConstructor(CPSTransformer).call(this, identifierGenerator, reporter, options); this.stateAllocator_ = new StateAllocator(); this.labelSet_ = new StringMap(); this.currentLabel_ = null; this.hoistVariablesTransformer_ = new HoistVariables(); } return ($__createClass)(CPSTransformer, { expressionNeedsStateMachine: function(tree) { return false; }, allocateState: function() { return this.stateAllocator_.allocateState(); }, transformBlock: function(tree) { var labels = this.getLabels_(); var label = this.clearCurrentLabel_(); var transformedTree = $__superGet(this, CPSTransformer.prototype, "transformBlock").call(this, tree); var machine = this.transformStatementList_(transformedTree.statements); if (machine === null) return transformedTree; if (label) { var states = []; for (var i = 0; i < machine.states.length; i++) { var state = machine.states[i]; states.push(state.transformBreakOrContinue(labels)); } machine = new StateMachine(machine.startState, machine.fallThroughState, states, machine.exceptionBlocks); } return machine; }, transformFunctionBody: function(tree) { this.pushTempScope(); var oldLabels = this.clearLabels_(); var transformedTree = $__superGet(this, CPSTransformer.prototype, "transformFunctionBody").call(this, tree); var machine = this.transformStatementList_(transformedTree.statements); this.restoreLabels_(oldLabels); this.popTempScope(); return machine === null ? transformedTree : machine; }, transformStatementList_: function(trees) { var groups = []; var newMachine; for (var i = 0; i < trees.length; i++) { if (trees[i].type === STATE_MACHINE) { groups.push(trees[i]); } else if (needsStateMachine(trees[i])) { newMachine = this.ensureTransformed_(trees[i]); groups.push(newMachine); } else { var last = groups[groups.length - 1]; if (!(last instanceof Array)) groups.push(last = []); last.push(trees[i]); } } if (groups.length === 1 && groups[0] instanceof Array) return null; var machine = null; for (var i$__11 = 0; i$__11 < groups.length; i$__11++) { if (groups[i$__11] instanceof Array) { newMachine = this.statementsToStateMachine_(groups[i$__11]); } else { newMachine = groups[i$__11]; } if (i$__11 === 0) machine = newMachine; else machine = machine.append(newMachine); } return machine; }, needsStateMachine_: function(statements) { if (statements instanceof Array) { for (var i = 0; i < statements.length; i++) { if (needsStateMachine(statements[i])) return true; } return false; } assert(statements instanceof SwitchStatement); return needsStateMachine(statements); }, transformCaseClause: function(tree) { var result = $__superGet(this, CPSTransformer.prototype, "transformCaseClause").call(this, tree); var machine = this.transformStatementList_(result.statements); return machine === null ? result : new CaseClause(null, result.expression, [machine]); }, transformDoWhileStatement: function(tree) { var $__8; var $__6, $__7; var labels = this.getLabels_(); var label = this.clearCurrentLabel_(); var machine, condition, body; if (this.expressionNeedsStateMachine(tree.condition)) { (($__6 = this.expressionToStateMachine(tree.condition), machine = $__6.machine, condition = $__6.expression, $__6)); body = this.transformAny(tree.body); } else { var result = $__superGet(this, CPSTransformer.prototype, "transformDoWhileStatement").call(this, tree); (($__7 = result, condition = $__7.condition, body = $__7.body, $__7)); if (body.type !== STATE_MACHINE) return result; } var loopBodyMachine = this.ensureTransformed_(body); var startState = loopBodyMachine.startState; var conditionState = loopBodyMachine.fallThroughState; var fallThroughState = this.allocateState(); var states = []; this.addLoopBodyStates_(loopBodyMachine, conditionState, fallThroughState, labels, states); if (machine) { machine = machine.replaceStartState(conditionState); conditionState = machine.fallThroughState; ($__8 = states).push.apply($__8, $__spread(machine.states)); } states.push(new ConditionalState(conditionState, startState, fallThroughState, condition)); machine = new StateMachine(startState, fallThroughState, states, loopBodyMachine.exceptionBlocks); if (label) machine = machine.replaceStateId(conditionState, label.continueState); return machine; }, addLoopBodyStates_: function(loopBodyMachine, continueState, breakState, labels, states) { for (var i = 0; i < loopBodyMachine.states.length; i++) { var state = loopBodyMachine.states[i]; states.push(state.transformBreakOrContinue(labels, breakState, continueState)); } }, transformForStatement: function(tree) { var $__8, $__9, $__10; var labels = this.getLabels_(); var label = this.clearCurrentLabel_(); var tmp; var initializer = null, initializerMachine; if (tree.initializer) { if (this.expressionNeedsStateMachine(tree.initializer)) { tmp = this.expressionToStateMachine(tree.initializer); initializer = tmp.expression; initializerMachine = tmp.machine; } else { initializer = this.transformAny(tree.initializer); } } var condition = null, conditionMachine; if (tree.condition) { if (this.expressionNeedsStateMachine(tree.condition)) { tmp = this.expressionToStateMachine(tree.condition); condition = tmp.expression; conditionMachine = tmp.machine; } else { condition = this.transformAny(tree.condition); } } var increment = null, incrementMachine; if (tree.increment) { if (this.expressionNeedsStateMachine(tree.increment)) { tmp = this.expressionToStateMachine(tree.increment); increment = tmp.expression; incrementMachine = tmp.machine; } else { increment = this.transformAny(tree.increment); } } var body = this.transformAny(tree.body); if (initializer === tree.initializer && condition === tree.condition && increment === tree.increment && body === tree.body) { return tree; } if (!initializerMachine && !conditionMachine && !incrementMachine && body.type !== STATE_MACHINE) { return new ForStatement(tree.location, initializer, condition, increment, body); } var loopBodyMachine = this.ensureTransformed_(body); var bodyFallThroughId = loopBodyMachine.fallThroughState; var fallThroughId = this.allocateState(); var startId; var initializerStartId = initializer ? this.allocateState() : State.INVALID_STATE; var conditionStartId = increment ? this.allocateState() : bodyFallThroughId; var loopStartId = loopBodyMachine.startState; var incrementStartId = bodyFallThroughId; var states = []; if (initializer) { startId = initializerStartId; var initialiserFallThroughId; if (condition) initialiserFallThroughId = conditionStartId; else initialiserFallThroughId = loopStartId; var tmpId = initializerStartId; if (initializerMachine) { initializerMachine = initializerMachine.replaceStartState(initializerStartId); tmpId = initializerMachine.fallThroughState; ($__8 = states).push.apply($__8, $__spread(initializerMachine.states)); } states.push(new FallThroughState(tmpId, initialiserFallThroughId, [createExpressionStatement(initializer)])); } if (condition) { if (!initializer) startId = conditionStartId; var tmpId$__12 = conditionStartId; if (conditionMachine) { conditionMachine = conditionMachine.replaceStartState(conditionStartId); tmpId$__12 = conditionMachine.fallThroughState; ($__9 = states).push.apply($__9, $__spread(conditionMachine.states)); } states.push(new ConditionalState(tmpId$__12, loopStartId, fallThroughId, condition)); } if (increment) { var incrementFallThroughId; if (condition) incrementFallThroughId = conditionStartId; else incrementFallThroughId = loopStartId; var tmpId$__13 = incrementStartId; if (incrementMachine) { incrementMachine = incrementMachine.replaceStartState(incrementStartId); tmpId$__13 = incrementMachine.fallThroughState; ($__10 = states).push.apply($__10, $__spread(incrementMachine.states)); } states.push(new FallThroughState(tmpId$__13, incrementFallThroughId, [createExpressionStatement(increment)])); } if (!initializer && !condition) startId = loopStartId; var continueId; if (increment) continueId = incrementStartId; else if (condition) continueId = conditionStartId; else continueId = loopStartId; if (!increment && !condition) { loopBodyMachine = loopBodyMachine.replaceFallThroughState(loopBodyMachine.startState); } this.addLoopBodyStates_(loopBodyMachine, continueId, fallThroughId, labels, states); var machine = new StateMachine(startId, fallThroughId, states, loopBodyMachine.exceptionBlocks); if (label) machine = machine.replaceStateId(continueId, label.continueState); return machine; }, transformForInStatement: function(tree) { return tree; }, transformForOfStatement: function(tree) { throw new Error('for of statements should be transformed before this pass'); }, transformIfStatement: function(tree) { var $__8, $__9, $__10; var $__6, $__7; var machine, condition, ifClause, elseClause; if (this.expressionNeedsStateMachine(tree.condition)) { (($__6 = this.expressionToStateMachine(tree.condition), machine = $__6.machine, condition = $__6.expression, $__6)); ifClause = this.transformAny(tree.ifClause); elseClause = this.transformAny(tree.elseClause); } else { var result = $__superGet(this, CPSTransformer.prototype, "transformIfStatement").call(this, tree); (($__7 = result, condition = $__7.condition, ifClause = $__7.ifClause, elseClause = $__7.elseClause, $__7)); if (ifClause.type !== STATE_MACHINE && (elseClause === null || elseClause.type !== STATE_MACHINE)) { return result; } } ifClause = this.ensureTransformed_(ifClause); elseClause = this.ensureTransformed_(elseClause); var startState = this.allocateState(); var fallThroughState = ifClause.fallThroughState; var ifState = ifClause.startState; var elseState = elseClause === null ? fallThroughState : elseClause.startState; var states = []; var exceptionBlocks = []; states.push(new ConditionalState(startState, ifState, elseState, condition)); ($__8 = states).push.apply($__8, $__spread(ifClause.states)); ($__9 = exceptionBlocks).push.apply($__9, $__spread(ifClause.exceptionBlocks)); if (elseClause !== null) { this.replaceAndAddStates_(elseClause.states, elseClause.fallThroughState, fallThroughState, states); ($__10 = exceptionBlocks).push.apply($__10, $__spread(State.replaceAllStates(elseClause.exceptionBlocks, elseClause.fallThroughState, fallThroughState))); } var ifMachine = new StateMachine(startState, fallThroughState, states, exceptionBlocks); if (machine) ifMachine = machine.append(ifMachine); return ifMachine; }, removeEmptyStates: function(oldStates) { var emptyStates = [], newStates = []; for (var i = 0; i < oldStates.length; i++) { if (oldStates[i] instanceof FallThroughState && oldStates[i].statements.length === 0) { emptyStates.push(oldStates[i]); } else { newStates.push(oldStates[i]); } } for (var i$__14 = 0; i$__14 < newStates.length; i$__14++) { newStates[i$__14] = emptyStates.reduce(function(state, $__6) { var $__7 = $__6, id = $__7.id, fallThroughState = $__7.fallThroughState; return state.replaceState(id, fallThroughState); }, newStates[i$__14]); } return newStates; }, replaceAndAddStates_: function(oldStates, oldState, newState, newStates) { for (var i = 0; i < oldStates.length; i++) { newStates.push(oldStates[i].replaceState(oldState, newState)); } }, transformLabelledStatement: function(tree) { var startState = this.allocateState(); var continueState = this.allocateState(); var fallThroughState = this.allocateState(); var label = new LabelState(tree.name.value, continueState, fallThroughState); var oldLabels = this.addLabel_(label); this.currentLabel_ = label; var result = this.transformAny(tree.statement); if (result === tree.statement) { result = tree; } else if (result.type === STATE_MACHINE) { result = result.replaceStartState(startState); result = result.replaceFallThroughState(fallThroughState); } this.restoreLabels_(oldLabels); return result; }, getLabels_: function() { return this.labelSet_; }, restoreLabels_: function(oldLabels) { this.labelSet_ = oldLabels; }, addLabel_: function(label) { var $__5 = this; var oldLabels = this.labelSet_; var labelSet = new StringMap(); this.labelSet_.forEach(function(k) { return labelSet[k] = $__5.labelSet_[k]; }); labelSet.set(label.name, label); this.labelSet_ = labelSet; return oldLabels; }, clearLabels_: function() { var result = this.labelSet_; this.labelSet_ = new StringMap(); return result; }, clearCurrentLabel_: function() { var result = this.currentLabel_; this.currentLabel_ = null; return result; }, transformSwitchStatement: function(tree) { var $__6, $__7; var labels = this.getLabels_(); var expression, machine, caseClauses; if (this.expressionNeedsStateMachine(tree.expression)) { (($__6 = this.expressionToStateMachine(tree.expression), expression = $__6.expression, machine = $__6.machine, $__6)); caseClauses = this.transformList(tree.caseClauses); } else { var result = $__superGet(this, CPSTransformer.prototype, "transformSwitchStatement").call(this, tree); if (!needsStateMachine(result)) return result; (($__7 = result, expression = $__7.expression, caseClauses = $__7.caseClauses, $__7)); } var startState = this.allocateState(); var fallThroughState = this.allocateState(); var nextState = fallThroughState; var states = []; var clauses = []; var tryStates = []; var hasDefault = false; for (var index = caseClauses.length - 1; index >= 0; index--) { var clause = caseClauses[index]; if (clause.type === CASE_CLAUSE) { var caseClause = clause; nextState = this.addSwitchClauseStates_(nextState, fallThroughState, labels, caseClause.statements, states, tryStates); clauses.push(new SwitchClause(caseClause.expression, nextState)); } else { hasDefault = true; var defaultClause = clause; nextState = this.addSwitchClauseStates_(nextState, fallThroughState, labels, defaultClause.statements, states, tryStates); clauses.push(new SwitchClause(null, nextState)); } } if (!hasDefault) { clauses.push(new SwitchClause(null, fallThroughState)); } states.push(new SwitchState(startState, expression, clauses.reverse())); var switchMachine = new StateMachine(startState, fallThroughState, states.reverse(), tryStates); if (machine) switchMachine = machine.append(switchMachine); return switchMachine; }, addSwitchClauseStates_: function(nextState, fallThroughState, labels, statements, states, tryStates) { var $__8; var machine = this.ensureTransformedList_(statements); for (var i = 0; i < machine.states.length; i++) { var state = machine.states[i]; var transformedState = state.transformBreak(labels, fallThroughState); states.push(transformedState.replaceState(machine.fallThroughState, nextState)); } ($__8 = tryStates).push.apply($__8, $__spread(machine.exceptionBlocks)); return machine.startState; }, transformTryStatement: function(tree) { var result = $__superGet(this, CPSTransformer.prototype, "transformTryStatement").call(this, tree); var $__6 = result, body = $__6.body, catchBlock = $__6.catchBlock, finallyBlock = $__6.finallyBlock; if (body.type !== STATE_MACHINE && (catchBlock === null || catchBlock.catchBody.type !== STATE_MACHINE) && (finallyBlock === null || finallyBlock.block.type !== STATE_MACHINE)) { return result; } var outerCatchState = this.allocateState(); var outerFinallyState = this.allocateState(); var pushTryState = this.statementToStateMachine_(parseStatement($__getTemplateObject(["$ctx.pushTry(\n ", ",\n ", ");"]), (catchBlock && outerCatchState), (finallyBlock && outerFinallyState))); var tryMachine = this.ensureTransformed_(body); tryMachine = pushTryState.append(tryMachine); if (catchBlock !== null) { var popTry = this.statementToStateMachine_(parseStatement($__getTemplateObject(["$ctx.popTry();"]))); tryMachine = tryMachine.append(popTry); var exceptionName = catchBlock.binding.identifierToken.value; var catchMachine = this.ensureTransformed_(catchBlock.catchBody); var catchStart = this.allocateState(); this.addMachineVariable(exceptionName); var states = $__spread(tryMachine.states, [new FallThroughState(catchStart, catchMachine.startState, parseStatements($__getTemplateObject(["\n $ctx.popTry();\n $ctx.maybeUncatchable(); // see RETURN_SENTINEL in runtime\n ", " = $ctx.storedException;"]), id(exceptionName)))]); this.replaceAndAddStates_(catchMachine.states, catchMachine.fallThroughState, tryMachine.fallThroughState, states); tryMachine = new StateMachine(tryMachine.startState, tryMachine.fallThroughState, states, [new CatchState(exceptionName, catchStart, tryMachine.fallThroughState, tryMachine.getAllStateIDs(), tryMachine.exceptionBlocks)]); tryMachine = tryMachine.replaceStateId(catchStart, outerCatchState); } if (finallyBlock !== null) { var finallyMachine = this.ensureTransformed_(finallyBlock.block); var popTry$__15 = this.statementToStateMachine_(parseStatement($__getTemplateObject(["$ctx.popTry();"]))); finallyMachine = popTry$__15.append(finallyMachine); var states$__16 = $__spread(tryMachine.states, finallyMachine.states, [new FinallyFallThroughState(finallyMachine.fallThroughState)]); tryMachine = new StateMachine(tryMachine.startState, tryMachine.fallThroughState, states$__16, [new FinallyState(finallyMachine.startState, finallyMachine.fallThroughState, tryMachine.getAllStateIDs(), tryMachine.exceptionBlocks)]); tryMachine = tryMachine.replaceStateId(finallyMachine.startState, outerFinallyState); } return tryMachine; }, transformWhileStatement: function(tree) { var $__8; var $__6, $__7; var labels = this.getLabels_(); var label = this.clearCurrentLabel_(); var condition, machine, body; if (this.expressionNeedsStateMachine(tree.condition)) { (($__6 = this.expressionToStateMachine(tree.condition), machine = $__6.machine, condition = $__6.expression, $__6)); body = this.transformAny(tree.body); } else { var result = $__superGet(this, CPSTransformer.prototype, "transformWhileStatement").call(this, tree); (($__7 = result, condition = $__7.condition, body = $__7.body, $__7)); if (body.type !== STATE_MACHINE) return result; } var loopBodyMachine = this.ensureTransformed_(body); var startState = loopBodyMachine.fallThroughState; var fallThroughState = this.allocateState(); var states = []; var conditionStart = startState; if (machine) { machine = machine.replaceStartState(startState); conditionStart = machine.fallThroughState; ($__8 = states).push.apply($__8, $__spread(machine.states)); } states.push(new ConditionalState(conditionStart, loopBodyMachine.startState, fallThroughState, condition)); this.addLoopBodyStates_(loopBodyMachine, startState, fallThroughState, labels, states); machine = new StateMachine(startState, fallThroughState, states, loopBodyMachine.exceptionBlocks); if (label) machine = machine.replaceStateId(startState, label.continueState); return machine; }, transformWithStatement: function(tree) { var result = $__superGet(this, CPSTransformer.prototype, "transformWithStatement").call(this, tree); if (result.body.type !== STATE_MACHINE) { return result; } throw new Error('Unreachable - with statement not allowed in strict mode/harmony'); }, generateMachineInnerFunction: function(machine) { var enclosingFinallyState = machine.getEnclosingFinallyMap(); var SwitchStatement = createSwitchStatement(createMemberExpression('$ctx', 'state'), this.transformMachineStates(machine, State.END_STATE, State.RETHROW_STATE, enclosingFinallyState)); return parseExpression($__getTemplateObject(["function($ctx) {\n while (true) ", "\n }"]), SwitchStatement); }, addTempVar: function() { var name = this.getTempIdentifier(); this.addMachineVariable(name); return name; }, addMachineVariable: function(name) { this.hoistVariablesTransformer_.addVariable(name); }, transformCpsFunctionBody: function(tree, runtimeMethod) { var $__8; var functionRef = arguments[2]; var alphaRenamedTree = AlphaRenamer.rename(tree, 'arguments', '$arguments'); var hasArguments = alphaRenamedTree !== tree; var hoistedTree = this.hoistVariablesTransformer_.transformAny(alphaRenamedTree); var maybeMachine = this.transformAny(hoistedTree); if (this.reporter.hadError()) return tree; var machine; if (maybeMachine.type !== STATE_MACHINE) { machine = this.statementsToStateMachine_(maybeMachine.statements); } else { machine = new StateMachine(maybeMachine.startState, maybeMachine.fallThroughState, this.removeEmptyStates(maybeMachine.states), maybeMachine.exceptionBlocks); } machine = machine.replaceFallThroughState(State.END_STATE).replaceStartState(State.START_STATE); var statements = []; if (this.hoistVariablesTransformer_.hasFunctions()) ($__8 = statements).push.apply($__8, $__spread(this.hoistVariablesTransformer_.getFunctions())); if (this.hoistVariablesTransformer_.hasVariables()) statements.push(this.hoistVariablesTransformer_.getVariableStatement()); if (hasArguments) statements.push(parseStatement($__getTemplateObject(["var $arguments = arguments;"]))); if (functionRef) { statements.push(parseStatement($__getTemplateObject(["return ", "(\n ", ",\n ", ", this);"]), runtimeMethod, this.generateMachineInnerFunction(machine), functionRef)); } else { statements.push(parseStatement($__getTemplateObject(["return ", "(\n ", ", this);"]), runtimeMethod, this.generateMachineInnerFunction(machine))); } return createFunctionBody(statements); }, transformFunctionDeclaration: function(tree) { return tree; }, transformFunctionExpression: function(tree) { return tree; }, transformGetAccessor: function(tree) { return tree; }, transformSetAccessor: function(tree) { return tree; }, transformArrowFunction: function(tree) { return tree; }, transformStateMachine: function(tree) { return tree; }, statementToStateMachine_: function(statement) { var statements; if (statement.type === BLOCK) statements = statement.statements; else statements = [statement]; return this.statementsToStateMachine_(statements); }, statementsToStateMachine_: function(statements) { var startState = this.allocateState(); var fallThroughState = this.allocateState(); return this.stateToStateMachine_(new FallThroughState(startState, fallThroughState, statements), fallThroughState); }, stateToStateMachine_: function(newState, fallThroughState) { return new StateMachine(newState.id, fallThroughState, [newState], []); }, transformMachineStates: function(machine, machineEndState, rethrowState, enclosingFinallyState) { var cases = []; for (var i = 0; i < machine.states.length; i++) { var state = machine.states[i]; var stateCase = state.transformMachineState(enclosingFinallyState[state.id], machineEndState, this.reporter); if (stateCase !== null) { cases.push(stateCase); } } this.addFinallyFallThroughDispatches(null, machine.exceptionBlocks, cases); cases.push(createDefaultClause(parseStatements($__getTemplateObject(["return $ctx.end()"])))); return cases; }, addFinallyFallThroughDispatches: function(enclosingFinallyState, tryStates, cases) { for (var i = 0; i < tryStates.length; i++) { var tryState = tryStates[i]; if (tryState.kind === TryState.Kind.FINALLY) { var finallyState = tryState; if (enclosingFinallyState !== null) { var caseClauses = []; var index = 0; for (var j = 0; j < enclosingFinallyState.tryStates.length; j++) { var destination = enclosingFinallyState.tryStates[j]; index++; var statements = void 0; if (index < enclosingFinallyState.tryStates.length) { statements = []; } else { statements = parseStatements($__getTemplateObject(["\n $ctx.state = $ctx.finallyFallThrough;\n $ctx.finallyFallThrough = ", ";\n break;"]), State.INVALID_STATE); } caseClauses.push(createCaseClause(createNumberLiteral(destination), statements)); } caseClauses.push(createDefaultClause([createAssignStateStatement(enclosingFinallyState.finallyState), createBreakStatement()])); cases.push(createCaseClause(createNumberLiteral(finallyState.fallThroughState), [createSwitchStatement(createMemberExpression('$ctx', 'finallyFallThrough'), caseClauses), createBreakStatement()])); } else { cases.push(createCaseClause(createNumberLiteral(finallyState.fallThroughState), parseStatements($__getTemplateObject(["\n $ctx.state = $ctx.finallyFallThrough;\n break;"])))); } this.addFinallyFallThroughDispatches(finallyState, finallyState.nestedTrys, cases); } else { this.addFinallyFallThroughDispatches(enclosingFinallyState, tryState.nestedTrys, cases); } } }, transformVariableDeclarationList: function(tree) { this.reporter.reportError(tree.location, 'Traceur: const/let declarations in a block containing a yield are ' + 'not yet implemented'); return tree; }, maybeTransformStatement_: function(maybeTransformedStatement) { var breakContinueTransformed = new BreakContinueTransformer(this.stateAllocator_).transformAny(maybeTransformedStatement); if (breakContinueTransformed !== maybeTransformedStatement) { breakContinueTransformed = this.transformAny(breakContinueTransformed); } return breakContinueTransformed; }, ensureTransformed_: function(statement) { if (statement === null) { return null; } var maybeTransformed = this.maybeTransformStatement_(statement); return maybeTransformed.type === STATE_MACHINE ? maybeTransformed : this.statementToStateMachine_(maybeTransformed); }, ensureTransformedList_: function(statements) { var maybeTransformedStatements = []; var foundMachine = false; for (var i = 0; i < statements.length; i++) { var statement = statements[i]; var maybeTransformedStatement = this.maybeTransformStatement_(statement); maybeTransformedStatements.push(maybeTransformedStatement); if (maybeTransformedStatement.type === STATE_MACHINE) { foundMachine = true; } } if (!foundMachine) { return this.statementsToStateMachine_(statements); } return this.transformStatementList_(maybeTransformedStatements); }, expressionToStateMachine: function(tree) { var commaExpression = new ExplodeExpressionTransformer(this).transformAny(tree); var statements = new NormalizeCommaExpressionToStatementTransformer().transformAny(commaExpression).statements; var lastStatement = statements.pop(); assert(lastStatement.type === EXPRESSION_STATEMENT); var expression = lastStatement.expression; statements = $__superGet(this, CPSTransformer.prototype, "transformList").call(this, statements); var machine = this.transformStatementList_(statements); return { expression: expression, machine: machine }; } }, {}, $__super); }(TempVarTransformer); var NormalizeCommaExpressionToStatementTransformer = function($__super) { function NormalizeCommaExpressionToStatementTransformer() { $__superConstructor(NormalizeCommaExpressionToStatementTransformer).apply(this, arguments); } return ($__createClass)(NormalizeCommaExpressionToStatementTransformer, { transformCommaExpression: function(tree) { var $__5 = this; var statements = tree.expressions.map(function(expr) { if (expr.type === CONDITIONAL_EXPRESSION) return $__5.transformAny(expr); return createExpressionStatement(expr); }); return new AnonBlock(tree.location, statements); }, transformConditionalExpression: function(tree) { var ifBlock = this.transformAny(tree.left); var elseBlock = this.transformAny(tree.right); return new IfStatement(tree.location, tree.condition, anonBlockToBlock(ifBlock), anonBlockToBlock(elseBlock)); } }, {}, $__super); }(ParseTreeTransformer); function anonBlockToBlock(tree) { if (tree.type === PAREN_EXPRESSION) return anonBlockToBlock(tree.expression); return new Block(tree.location, tree.statements); }