protected void VisitAsyncForeachStatement() { ForeachStatement foreachStatement = this.ForeachStatement; if (foreachStatement.EmbeddedStatement is EmptyStatement) { return; } var oldValue = this.Emitter.ReplaceAwaiterByVar; var jumpStatements = this.Emitter.JumpStatements; this.Emitter.JumpStatements = new List <IJumpInfo>(); this.WriteAwaiters(foreachStatement.InExpression); bool containsAwaits = false; var awaiters = this.GetAwaiters(foreachStatement.EmbeddedStatement); if (awaiters != null && awaiters.Length > 0) { containsAwaits = true; } this.Emitter.ReplaceAwaiterByVar = true; if (!containsAwaits) { this.VisitForeachStatement(oldValue); return; } //var iteratorName = this.GetNextIteratorName(); var iteratorName = this.AddLocal(this.GetTempVarName(), null, AstType.Null); //this.WriteVar(); this.Write(iteratorName, " = ", JS.Funcs.BRIDGE_GET_ENUMERATOR); this.WriteOpenParentheses(); foreachStatement.InExpression.AcceptVisitor(this.Emitter); this.Emitter.ReplaceAwaiterByVar = oldValue; this.WriteCloseParentheses(); this.WriteSemiColon(); this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteIf(); this.WriteOpenParentheses(); this.Write(iteratorName); this.WriteDot(); this.Write(JS.Funcs.MOVE_NEXT); this.WriteOpenCloseParentheses(); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.PushLocals(); var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType); this.WriteVar(); this.Write(varName + " = "); var rr = this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter) as ForEachResolveResult; string castCode = this.GetCastCode(rr.ElementType, rr.ElementVariable.Type); if (castCode != null) { this.EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT + "()", castCode); } else if (this.CastMethod != null) { this.Write(BridgeTypes.ToJsName(this.CastMethod.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, this.CastMethod).GetOverloadName()); this.WriteOpenParentheses(); this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT + "()"); this.WriteCloseParentheses(); } else { var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type); if (needCast) { this.Write(JS.Funcs.BRIDGE_CAST); this.WriteOpenParentheses(); } this.Write(iteratorName); this.WriteDot(); this.Write(JS.Funcs.GET_CURRENT); this.WriteOpenCloseParentheses(); if (needCast) { this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")"); } } this.WriteSemiColon(); this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement; var writer = this.SaveWriter(); this.Emitter.AsyncBlock.AddAsyncStep(); this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement; var startCount = this.Emitter.AsyncBlock.Steps.Count; if (block != null) { block.AcceptChildren(this.Emitter); } else { foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter); } IAsyncStep loopStep = null; if (this.Emitter.AsyncBlock.Steps.Count > startCount) { loopStep = this.Emitter.AsyncBlock.Steps.Last(); loopStep.JumpToStep = conditionStep.Step; } this.RestoreWriter(writer); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); } this.PopLocals(); this.WriteNewLine(); this.EndBlock(); this.WriteNewLine(); var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); conditionStep.JumpToStep = nextStep.Step; if (this.Emitter.JumpStatements.Count > 0) { this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in this.Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step); } } this.Emitter.JumpStatements = jumpStatements; }
protected void VisitAsyncForeachStatement() { ForeachStatement foreachStatement = this.ForeachStatement; if (foreachStatement.EmbeddedStatement is EmptyStatement) { return; } var oldValue = this.Emitter.ReplaceAwaiterByVar; var jumpStatements = this.Emitter.JumpStatements; this.Emitter.JumpStatements = new List <IJumpInfo>(); this.WriteAwaiters(foreachStatement.InExpression); bool containsAwaits = false; var awaiters = this.GetAwaiters(foreachStatement.EmbeddedStatement); if (awaiters != null && awaiters.Length > 0) { containsAwaits = true; } this.Emitter.ReplaceAwaiterByVar = true; if (!containsAwaits) { this.VisitForeachStatement(oldValue); return; } var iteratorName = this.AddLocal(this.GetTempVarName(), null, AstType.Null); var for_rr = (ForEachResolveResult)this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter); var get_rr = for_rr.GetEnumeratorCall as InvocationResolveResult; var in_rr = this.Emitter.Resolver.ResolveNode(foreachStatement.InExpression, this.Emitter); var inline = get_rr != null?this.Emitter.GetInline(get_rr.Member) : null; var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) && !in_rr.Type.IsKnownType(KnownTypeCode.Array); var isGenericEnumerable = for_rr.CollectionType.IsParameterized && for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable"; var emitInline = checkEnum && !isGenericEnumerable && inline != null; this.Write(iteratorName, " = "); if (!emitInline) { this.Write(JS.Funcs.BRIDGE_GET_ENUMERATOR); this.WriteOpenParentheses(); foreachStatement.InExpression.AcceptVisitor(this.Emitter); } if (checkEnum) { if (for_rr.CollectionType.IsParameterized && for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable") { this.WriteComma(false); this.Write(BridgeTypes.ToJsName(((ParameterizedType)for_rr.CollectionType).TypeArguments[0], this.Emitter)); } else if (get_rr != null) { if (inline != null) { var argsInfo = new ArgumentsInfo(this.Emitter, foreachStatement.InExpression, get_rr); new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit(); } else { var name = OverloadsCollection.Create(this.Emitter, get_rr.Member).GetOverloadName(); if (name != "getEnumerator" && name != "System$Collections$IEnumerable$getEnumerator") { this.WriteComma(false); this.WriteScript(name); } } } } this.Emitter.ReplaceAwaiterByVar = oldValue; if (!emitInline) { this.WriteCloseParentheses(); } this.WriteSemiColon(); this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteIf(); this.WriteOpenParentheses(); this.Write(iteratorName); this.WriteDot(); this.Write(JS.Funcs.MOVE_NEXT); this.WriteOpenCloseParentheses(); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.PushLocals(); var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType); this.WriteVar(); this.Write(varName + " = "); var rr = this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter) as ForEachResolveResult; string castCode = this.GetCastCode(rr.ElementType, rr.ElementVariable.Type); if (castCode != null) { this.EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT + "()", castCode); } else if (this.CastMethod != null) { this.Write(BridgeTypes.ToJsName(this.CastMethod.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, this.CastMethod).GetOverloadName()); this.WriteOpenParentheses(); this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT + "()"); this.WriteCloseParentheses(); } else { var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type); if (needCast) { this.Write(JS.Funcs.BRIDGE_CAST); this.WriteOpenParentheses(); } this.Write(iteratorName); this.WriteDot(); this.Write(JS.Funcs.GET_CURRENT); this.WriteOpenCloseParentheses(); if (needCast) { this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")"); } } this.WriteSemiColon(); this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement; var writer = this.SaveWriter(); this.Emitter.AsyncBlock.AddAsyncStep(); this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement; var startCount = this.Emitter.AsyncBlock.Steps.Count; if (block != null) { block.AcceptChildren(this.Emitter); } else { foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter); } IAsyncStep loopStep = null; if (this.Emitter.AsyncBlock.Steps.Count > startCount) { loopStep = this.Emitter.AsyncBlock.Steps.Last(); loopStep.JumpToStep = conditionStep.Step; } this.RestoreWriter(writer); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); } this.PopLocals(); this.WriteNewLine(); this.EndBlock(); this.WriteNewLine(); var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); conditionStep.JumpToStep = nextStep.Step; if (this.Emitter.JumpStatements.Count > 0) { this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in this.Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step); } } this.Emitter.JumpStatements = jumpStatements; }
protected void VisitIfElseStatement() { IfElseStatement ifElseStatement = this.IfElseStatement; var awaiters = this.GetAwaiters(ifElseStatement); if (awaiters == null || awaiters.Length == 0) { this.WriteIf(); this.WriteOpenParentheses(); ifElseStatement.Condition.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(); this.EmitBlockOrIndentedLine(ifElseStatement.TrueStatement); if (ifElseStatement.FalseStatement != null && !ifElseStatement.FalseStatement.IsNull) { this.WriteElse(); this.EmitBlockOrIndentedLine(ifElseStatement.FalseStatement); } return; } this.WriteAwaiters(ifElseStatement.Condition); this.WriteIf(); this.WriteOpenParentheses(); var oldValue = this.Emitter.ReplaceAwaiterByVar; this.Emitter.ReplaceAwaiterByVar = true; ifElseStatement.Condition.AcceptVisitor(this.Emitter); this.Emitter.ReplaceAwaiterByVar = oldValue; this.WriteCloseParentheses(); int startCount = 0; int elseCount = 0; IAsyncStep trueStep = null; IAsyncStep elseStep = null; if (this.Emitter.IsAsync) { startCount = this.Emitter.AsyncBlock.Steps.Count; this.EmittedAsyncSteps = this.Emitter.AsyncBlock.EmittedAsyncSteps; this.Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>(); this.Emitter.IgnoreBlock = ifElseStatement.TrueStatement; this.WriteSpace(); this.BeginBlock(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); var writer = this.SaveWriter(); var bodyStep = this.Emitter.AsyncBlock.AddAsyncStep(); ifElseStatement.TrueStatement.AcceptVisitor(this.Emitter); if (this.Emitter.AsyncBlock.Steps.Count > startCount) { trueStep = this.Emitter.AsyncBlock.Steps.Last(); } if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true)) { this.WriteNewLine(); } this.EndBlock(); this.WriteSpace(); elseCount = this.Emitter.AsyncBlock.Steps.Count; } else { this.EmitBlockOrIndentedLine(ifElseStatement.TrueStatement); } if (ifElseStatement.FalseStatement != null && !ifElseStatement.FalseStatement.IsNull) { this.WriteElse(); if (this.Emitter.IsAsync) { this.Emitter.IgnoreBlock = ifElseStatement.FalseStatement; this.WriteSpace(); this.BeginBlock(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); var writer = this.SaveWriter(); var bodyStep = this.Emitter.AsyncBlock.AddAsyncStep(); ifElseStatement.FalseStatement.AcceptVisitor(this.Emitter); if (this.Emitter.AsyncBlock.Steps.Count > elseCount) { elseStep = this.Emitter.AsyncBlock.Steps.Last(); } if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true)) { this.WriteNewLine(); } this.EndBlock(); this.WriteSpace(); } else { this.EmitBlockOrIndentedLine(ifElseStatement.FalseStatement); } } if (this.Emitter.IsAsync && this.Emitter.AsyncBlock.Steps.Count > startCount) { if (this.Emitter.AsyncBlock.Steps.Count <= elseCount && !AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.WriteNewLine(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); if (trueStep != null) { trueStep.JumpToStep = nextStep.Step; } if (elseStep != null) { elseStep.JumpToStep = nextStep.Step; } } else if (this.Emitter.IsAsync) { this.WriteNewLine(); } if (this.Emitter.IsAsync) { this.Emitter.AsyncBlock.EmittedAsyncSteps = this.EmittedAsyncSteps; } }
protected void VisitAsyncForeachStatement() { ForeachStatement foreachStatement = this.ForeachStatement; if (foreachStatement.EmbeddedStatement is EmptyStatement) { return; } var oldValue = this.Emitter.ReplaceAwaiterByVar; var jumpStatements = this.Emitter.JumpStatements; this.Emitter.JumpStatements = new List <IJumpInfo>(); this.WriteAwaiters(foreachStatement.InExpression); bool containsAwaits = false; var awaiters = this.GetAwaiters(foreachStatement.EmbeddedStatement); if (awaiters != null && awaiters.Length > 0) { containsAwaits = true; } this.Emitter.ReplaceAwaiterByVar = true; if (!containsAwaits) { this.VisitForeachStatement(oldValue); return; } //var iteratorName = this.GetNextIteratorName(); var iteratorName = this.AddLocal(this.GetTempVarName(), AstType.Null); //this.WriteVar(); this.Write(iteratorName, " = ", Bridge.Translator.Emitter.ROOT); this.WriteDot(); this.Write(Bridge.Translator.Emitter.ENUMERATOR); this.WriteOpenParentheses(); foreachStatement.InExpression.AcceptVisitor(this.Emitter); this.Emitter.ReplaceAwaiterByVar = oldValue; this.WriteCloseParentheses(); this.WriteSemiColon(); this.WriteNewLine(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteIf(); this.WriteOpenParentheses(); this.Write(iteratorName); this.WriteDot(); this.Write(Bridge.Translator.Emitter.MOVE_NEXT); this.WriteOpenCloseParentheses(); this.WriteCloseParentheses(); this.WriteSpace(); this.BeginBlock(); this.PushLocals(); var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableType); this.WriteVar(); this.Write(varName, " = ", iteratorName); this.WriteDot(); this.Write(Bridge.Translator.Emitter.GET_CURRENT); this.WriteOpenCloseParentheses(); this.WriteSemiColon(); this.WriteNewLine(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement; var writer = this.SaveWriter(); var bodyStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement; var startCount = this.Emitter.AsyncBlock.Steps.Count; if (block != null) { block.AcceptChildren(this.Emitter); } else { foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter); } IAsyncStep loopStep = null; if (this.Emitter.AsyncBlock.Steps.Count > startCount) { loopStep = this.Emitter.AsyncBlock.Steps.Last(); loopStep.JumpToStep = conditionStep.Step; } this.RestoreWriter(writer); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.Write("$step = " + conditionStep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); } this.PopLocals(); this.WriteNewLine(); this.EndBlock(); this.WriteNewLine(); var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); conditionStep.JumpToStep = nextStep.Step; if (this.Emitter.JumpStatements.Count > 0) { this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in this.Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step); } } this.Emitter.JumpStatements = jumpStatements; }
protected void InjectSteps() { foreach (var label in this.JumpLabels) { var tostep = this.Steps.First(s => s.Node == label.Node); label.Output.Replace(Helpers.PrefixDollar("{", label.Node.GetHashCode(), "}"), tostep.Step.ToString()); } for (int i = 0; i < this.Steps.Count; i++) { var step = this.Steps[i]; if (i != 0) { this.WriteNewLine(); } var output = step.Output.ToString(); var cleanOutput = this.RemoveTokens(output); this.Write("case " + i + ": "); this.BeginBlock(); bool addNewLine = false; if (!string.IsNullOrWhiteSpace(cleanOutput)) { if (addNewLine) { this.WriteNewLine(); } this.Write(this.WriteIndentToString(output.TrimEnd())); } if (!this.IsOnlyWhitespaceOnPenultimateLine(false)) { addNewLine = true; } if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(cleanOutput)) { if (addNewLine) { this.WriteNewLine(); } this.Write(JS.Vars.ASYNC_STEP + " = " + step.JumpToStep + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(cleanOutput)) { var tostep = this.Steps.First(s => s.Node == step.JumpToNode); if (addNewLine) { this.WriteNewLine(); } this.Write(JS.Vars.ASYNC_STEP + " = " + tostep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(cleanOutput)) { if (addNewLine) { this.WriteNewLine(); } } this.WriteNewLine(); this.EndBlock(); } this.WriteNewLine(); this.Write("default: "); this.BeginBlock(); this.Write("return false;"); this.WriteNewLine(); this.EndBlock(); }
protected void VisitAsyncForStatement() { ForStatement forStatement = this.ForStatement; var oldValue = this.Emitter.ReplaceAwaiterByVar; var jumpStatements = this.Emitter.JumpStatements; this.Emitter.JumpStatements = new List <IJumpInfo>(); this.PushLocals(); bool newLine = false; foreach (var item in forStatement.Initializers) { if (newLine) { this.WriteNewLine(); } item.AcceptVisitor(this.Emitter); newLine = true; } this.RemovePenultimateEmptyLines(true); this.WriteNewLine(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteAwaiters(forStatement.Condition); this.Emitter.ReplaceAwaiterByVar = true; var lastConditionStep = this.Emitter.AsyncBlock.Steps.Last(); this.WriteIf(); this.WriteOpenParentheses(true); forStatement.Condition.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(true); this.Emitter.ReplaceAwaiterByVar = oldValue; this.WriteSpace(); this.BeginBlock(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.EmittedAsyncSteps = this.Emitter.AsyncBlock.EmittedAsyncSteps; this.Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>(); var writer = this.SaveWriter(); var bodyStep = this.Emitter.AsyncBlock.AddAsyncStep(); this.Emitter.IgnoreBlock = forStatement.EmbeddedStatement; var startCount = this.Emitter.AsyncBlock.Steps.Count; forStatement.EmbeddedStatement.AcceptVisitor(this.Emitter); IAsyncStep loopStep = null; if (this.Emitter.AsyncBlock.Steps.Count > startCount) { loopStep = this.Emitter.AsyncBlock.Steps.Last(); } this.RestoreWriter(writer); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.WriteNewLine(); this.Write("$step = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); } else { this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); } if (this.Emitter.IsAsync) { this.Emitter.AsyncBlock.EmittedAsyncSteps = this.EmittedAsyncSteps; } IAsyncStep iteratorsStep = this.Emitter.AsyncBlock.AddAsyncStep(); /*foreach (var item in forStatement.Iterators) * { * this.WriteAwaiters(item); * }*/ var lastIteratorStep = this.Emitter.AsyncBlock.Steps.Last(); if (loopStep != null) { loopStep.JumpToStep = iteratorsStep.Step; } lastIteratorStep.JumpToStep = conditionStep.Step; this.Emitter.ReplaceAwaiterByVar = true; var beforeStepsCount = this.Emitter.AsyncBlock.Steps.Count; foreach (var item in forStatement.Iterators) { item.AcceptVisitor(this.Emitter); if (this.Emitter.Output.ToString().TrimEnd().Last() != ';') { this.WriteSemiColon(); } this.WriteNewLine(); } if (beforeStepsCount < this.Emitter.AsyncBlock.Steps.Count) { this.Emitter.AsyncBlock.Steps.Last().JumpToStep = conditionStep.Step; } this.Emitter.ReplaceAwaiterByVar = oldValue; this.PopLocals(); var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); lastConditionStep.JumpToStep = nextStep.Step; if (this.Emitter.JumpStatements.Count > 0) { this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in this.Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : iteratorsStep.Step); } } this.Emitter.JumpStatements = jumpStatements; }
protected void InjectSteps() { foreach (var label in this.JumpLabels) { var tostep = this.Steps.First(s => s.Node == label.Node); label.Output.Replace(Helpers.PrefixDollar("{", label.Node.GetHashCode(), "}"), tostep.Step.ToString()); } for (int i = 0; i < this.Steps.Count; i++) { var step = this.Steps[i]; if (i != 0) { this.WriteNewLine(); } var output = step.Output.ToString(); if (string.IsNullOrWhiteSpace(output) && step.JumpToStep == (i + 1) && step.FromTaskNumber < 0) { continue; } this.Write("case " + i + ": "); this.BeginBlock(); bool addNewLine = false; if (step.FromTaskNumber > -1) { var expression = this.AwaitExpressions[step.FromTaskNumber - 1]; if (this.IsTaskResult(expression)) { this.Write(string.Format("{0}{1} = {2}{1}.{3}();", JS.Vars.ASYNC_TASK_RESULT, step.FromTaskNumber, JS.Vars.ASYNC_TASK, JS.Funcs.GET_AWAITED_RESULT)); } else { this.Write(string.Format("{0}{1}.{2}();", JS.Vars.ASYNC_TASK, step.FromTaskNumber, JS.Funcs.GET_AWAITED_RESULT)); } addNewLine = true; } if (!string.IsNullOrWhiteSpace(output)) { if (addNewLine) { this.WriteNewLine(); } this.Write(this.WriteIndentToString(output.TrimEnd())); } if (!this.IsOnlyWhitespaceOnPenultimateLine(false)) { addNewLine = true; } if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(output)) { if (addNewLine) { this.WriteNewLine(); } this.Write(JS.Vars.ASYNC_STEP + " = " + step.JumpToStep + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(output)) { var tostep = this.Steps.First(s => s.Node == step.JumpToNode); if (addNewLine) { this.WriteNewLine(); } this.Write(JS.Vars.ASYNC_STEP + " = " + tostep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(output)) { if (addNewLine) { this.WriteNewLine(); } if (this.IsTaskReturn) { this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(null);"); this.WriteNewLine(); } this.Write("return;"); } this.WriteNewLine(); this.EndBlock(); } this.WriteNewLine(); this.Write("default: "); this.BeginBlock(); if (this.IsTaskReturn) { this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(null);"); this.WriteNewLine(); } this.Write("return;"); this.WriteNewLine(); this.EndBlock(); }
internal void WriteAsyncConditionalExpression(int index) { if (this.Emitter.AsyncBlock.WrittenAwaitExpressions.Contains(this.ConditionalExpression)) { return; } this.Emitter.AsyncBlock.WrittenAwaitExpressions.Add(this.ConditionalExpression); this.WriteAwaiters(this.ConditionalExpression.Condition); this.WriteIf(); this.WriteOpenParentheses(); var oldValue = this.Emitter.ReplaceAwaiterByVar; var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling; this.Emitter.ReplaceAwaiterByVar = true; this.Emitter.AsyncExpressionHandling = true; this.ConditionalExpression.Condition.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; int startCount = 0; int elseCount = 0; IAsyncStep trueStep = null; IAsyncStep elseStep = null; startCount = this.Emitter.AsyncBlock.Steps.Count; this.EmittedAsyncSteps = this.Emitter.AsyncBlock.EmittedAsyncSteps; this.Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>(); var taskResultVar = JS.Vars.ASYNC_TASK_RESULT + index; if (!this.Emitter.Locals.ContainsKey(taskResultVar)) { this.AddLocal(taskResultVar, null, AstType.Null); } this.WriteSpace(); this.BeginBlock(); this.Write($"{JS.Vars.ASYNC_STEP} = {this.Emitter.AsyncBlock.Step};"); this.WriteNewLine(); this.Write("continue;"); var writer = this.SaveWriter(); this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteAwaiters(this.ConditionalExpression.TrueExpression); oldValue = this.Emitter.ReplaceAwaiterByVar; oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling; this.Emitter.ReplaceAwaiterByVar = true; this.Emitter.AsyncExpressionHandling = true; this.Write(taskResultVar + " = "); this.ConditionalExpression.TrueExpression.AcceptVisitor(this.Emitter); this.WriteSemiColon(); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; if (this.Emitter.AsyncBlock.Steps.Count > startCount) { trueStep = this.Emitter.AsyncBlock.Steps.Last(); } if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true)) { this.WriteNewLine(); } this.EndBlock(); this.WriteSpace(); elseCount = this.Emitter.AsyncBlock.Steps.Count; this.WriteSpace(); this.WriteElse(); this.BeginBlock(); this.Write($"{JS.Vars.ASYNC_STEP} = {this.Emitter.AsyncBlock.Step};"); this.WriteNewLine(); this.Write("continue;"); writer = this.SaveWriter(); this.Emitter.AsyncBlock.AddAsyncStep(); this.WriteAwaiters(this.ConditionalExpression.FalseExpression); oldValue = this.Emitter.ReplaceAwaiterByVar; oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling; this.Emitter.ReplaceAwaiterByVar = true; this.Emitter.AsyncExpressionHandling = true; this.Write(taskResultVar + " = "); this.ConditionalExpression.FalseExpression.AcceptVisitor(this.Emitter); this.WriteSemiColon(); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; if (this.Emitter.AsyncBlock.Steps.Count > elseCount) { elseStep = this.Emitter.AsyncBlock.Steps.Last(); } if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true)) { this.WriteNewLine(); } this.EndBlock(); this.WriteSpace(); if (this.Emitter.IsAsync && this.Emitter.AsyncBlock.Steps.Count > startCount) { if (this.Emitter.AsyncBlock.Steps.Count <= elseCount && !AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.WriteNewLine(); this.Write($"{JS.Vars.ASYNC_STEP} = {this.Emitter.AsyncBlock.Step};"); this.WriteNewLine(); this.Write("continue;"); } var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); if (trueStep != null) { trueStep.JumpToStep = nextStep.Step; } if (elseStep != null) { elseStep.JumpToStep = nextStep.Step; } } else if (this.Emitter.IsAsync) { this.WriteNewLine(); } if (this.Emitter.IsAsync) { this.Emitter.AsyncBlock.EmittedAsyncSteps = this.EmittedAsyncSteps; } }
protected void VisitAsyncWhileStatement() { var oldValue = this.Emitter.ReplaceAwaiterByVar; var jumpStatements = this.Emitter.JumpStatements; this.Emitter.JumpStatements = new List <IJumpInfo>(); IAsyncStep conditionStep = null; var lastStep = this.Emitter.AsyncBlock.Steps.Last(); if (string.IsNullOrWhiteSpace(lastStep.Output.ToString())) { conditionStep = lastStep; } else { lastStep.JumpToStep = this.Emitter.AsyncBlock.Step; conditionStep = this.Emitter.AsyncBlock.AddAsyncStep(); } this.WriteAwaiters(this.WhileStatement.Condition); this.Emitter.ReplaceAwaiterByVar = true; this.WriteIf(); this.WriteOpenParentheses(true); this.WhileStatement.Condition.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(true); this.Emitter.ReplaceAwaiterByVar = oldValue; this.WriteSpace(); this.BeginBlock(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); var writer = this.SaveWriter(); this.Emitter.AsyncBlock.AddAsyncStep(); this.Emitter.IgnoreBlock = this.WhileStatement.EmbeddedStatement; var startCount = this.Emitter.AsyncBlock.Steps.Count; this.WhileStatement.EmbeddedStatement.AcceptVisitor(this.Emitter); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } this.RestoreWriter(writer); this.WriteNewLine(); this.EndBlock(); this.WriteSpace(); if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString())) { this.WriteNewLine(); this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } var nextStep = this.Emitter.AsyncBlock.AddAsyncStep(); conditionStep.JumpToStep = nextStep.Step; if (this.Emitter.JumpStatements.Count > 0) { this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in this.Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step); } } this.Emitter.JumpStatements = jumpStatements; }
protected void InjectSteps() { foreach (var label in this.JumpLabels) { var tostep = this.Steps.First(s => s.Node == label.Node); label.Output.Replace("${" + label.Node.GetHashCode() + "}", tostep.Step.ToString()); } for (int i = 0; i < this.Steps.Count; i++) { var step = this.Steps[i]; if (i != 0) { this.WriteNewLine(); } this.Write("case " + i + ": "); var output = step.Output.ToString(); if (string.IsNullOrWhiteSpace(output) && step.JumpToStep == (i + 1)) { continue; } this.BeginBlock(); bool addNewLine = false; if (step.FromTaskNumber > -1) { var expression = this.AwaitExpressions[step.FromTaskNumber - 1]; if (this.IsTaskResult(expression)) { this.Write(string.Format("$taskResult{0} = $task{0}.getResult();", step.FromTaskNumber)); } else { this.Write(string.Format("$task{0}.getResult();", step.FromTaskNumber)); } addNewLine = true; } if (!string.IsNullOrWhiteSpace(output)) { if (addNewLine) { this.WriteNewLine(); } this.Write(this.WriteIndentToString(output.TrimEnd())); } if (!this.IsOnlyWhitespaceOnPenultimateLine(false)) { addNewLine = true; } if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(output)) { if (addNewLine) { this.WriteNewLine(); } this.Write("$step = " + step.JumpToStep + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(output)) { var tostep = this.Steps.First(s => s.Node == step.JumpToNode); if (addNewLine) { this.WriteNewLine(); } this.Write("$step = " + tostep.Step + ";"); this.WriteNewLine(); this.Write("continue;"); } else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(output)) { if (addNewLine) { this.WriteNewLine(); } if (this.IsTaskReturn) { this.Write("$returnTask.setResult(null);"); this.WriteNewLine(); } this.Write("return;"); } this.WriteNewLine(); this.EndBlock(); } this.WriteNewLine(); this.Write("default: "); this.BeginBlock(); if (this.IsTaskReturn) { this.Write("$returnTask.setResult(null);"); this.WriteNewLine(); } this.Write("return;"); this.WriteNewLine(); this.EndBlock(); }