Beispiel #1
0
        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;
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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();
        }
Beispiel #8
0
        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;
            }
        }
Beispiel #9
0
        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();
        }