예제 #1
0
        public PushLayersStep(
            BuildConfiguration buildConfiguration,
            ProgressEventDispatcher.Factory progressEventDispatcherFactory,
            AuthenticatePushStep authenticatePushStep,
            IAsyncStep <IReadOnlyList <ICachedLayer> > cachedLayerStep)
        {
            this.buildConfiguration             = buildConfiguration;
            this.progressEventDispatcherFactory = progressEventDispatcherFactory;
            this.authenticatePushStep           = authenticatePushStep;
            this.cachedLayerStep = cachedLayerStep;

            listenableFuture = CallAsync();
        }
예제 #2
0
        public BuildImageStep(
            IBuildConfiguration buildConfiguration,
            ProgressEventDispatcher.Factory progressEventDispatcherFactory,
            IAsyncStep <BaseImageWithAuthorization> pullBaseImageStep,
            IAsyncStep <IReadOnlyList <ICachedLayer> > pullAndCacheBaseImageLayersStep,
            IAsyncStep <IReadOnlyList <ICachedLayer> > buildAndCacheApplicationLayerSteps)
        {
            this.buildConfiguration             = buildConfiguration;
            this.progressEventDispatcherFactory = progressEventDispatcherFactory;
            this.pullBaseImageStep = pullBaseImageStep;
            this.pullAndCacheBaseImageLayersStep = pullAndCacheBaseImageLayersStep;
            buildAndCacheApplicationLayersStep   = buildAndCacheApplicationLayerSteps;

            listenableFuture = CallAsync();
        }
예제 #3
0
        public WriteTarFileStep(
            BuildConfiguration buildConfiguration,
            ProgressEventDispatcher.Factory progressEventDispatcherFactory,
            SystemPath outputPath,
            PullAndCacheBaseImageLayersStep pullAndCacheBaseImageLayersStep,
            IAsyncStep <IReadOnlyList <ICachedLayer> > buildAndCacheApplicationLayersStep,
            BuildImageStep buildImageStep)
        {
            this.buildConfiguration             = buildConfiguration;
            this.progressEventDispatcherFactory = progressEventDispatcherFactory;
            this.outputPath = outputPath;
            this.pullAndCacheBaseImageLayersStep    = pullAndCacheBaseImageLayersStep;
            this.buildAndCacheApplicationLayersStep = buildAndCacheApplicationLayersStep;
            this.buildImageStep = buildImageStep;

            listenableFuture = CallAsync();
        }
예제 #4
0
        private async Task <ImageLayers> BuildFakeLayersToCacheAsync()
        {
            ImageLayers.Builder applicationLayersBuilder = ImageLayers.CreateBuilder();

            IAsyncStep <IReadOnlyList <ICachedLayer> > buildAndCacheApplicationLayersStep =
                BuildAndCacheApplicationLayerStep.MakeList(
                    mockBuildConfiguration,
                    ProgressEventDispatcher.NewRoot(mockEventHandlers, "ignored", 1).NewChildProducer());

            foreach (ICachedLayer applicationLayer in await buildAndCacheApplicationLayersStep.GetFuture().ConfigureAwait(false))

            {
                applicationLayersBuilder.Add(applicationLayer);
            }

            return(applicationLayersBuilder.Build());
        }
예제 #5
0
        public LoadDockerStep(
            BuildConfiguration buildConfiguration,
            ProgressEventDispatcher.Factory progressEventDispatcherFactory,
            DockerClient dockerClient,
            PullAndCacheBaseImageLayersStep pullAndCacheBaseImageLayersStep,
            IAsyncStep <IReadOnlyList <ICachedLayer> > buildAndCacheApplicationLayersStep,
            BuildImageStep buildImageStep)
        {
            this.buildConfiguration             = buildConfiguration;
            this.progressEventDispatcherFactory = progressEventDispatcherFactory;
            this.dockerClient = dockerClient;
            this.pullAndCacheBaseImageLayersStep    = pullAndCacheBaseImageLayersStep;
            this.buildAndCacheApplicationLayersStep = buildAndCacheApplicationLayersStep;
            this.buildImageStep = buildImageStep;

            listenableFuture = CallAsync();
        }
예제 #6
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;

            bool isReferenceLocal = false;

            if (this.Emitter.LocalsMap != null && this.Emitter.LocalsMap.ContainsKey(rr.ElementVariable))
            {
                isReferenceLocal = this.Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v");
            }

            if (isReferenceLocal)
            {
                this.Write("{ v : ");
            }

            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();
                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);
                this.WriteCloseParentheses();
            }
            else
            {
                var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type);
                if (needCast)
                {
                    this.Write(JS.Funcs.BRIDGE_CAST);
                    this.WriteOpenParentheses();
                }

                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName);

                this.WriteDot();
                this.Write(JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);

                if (needCast)
                {
                    this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")");
                }
            }

            if (isReferenceLocal)
            {
                this.Write(" }");
            }

            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;
        }
예제 #7
0
        protected void VisitAsyncTryCatchStatement()
        {
            TryCatchStatement tryCatchStatement = this.TryCatchStatement;

            this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step;

            var          tryStep = this.Emitter.AsyncBlock.AddAsyncStep();
            AsyncTryInfo tryInfo = new AsyncTryInfo();

            tryInfo.StartStep = tryStep.Step;

            this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock;
            tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter);
            tryStep         = this.Emitter.AsyncBlock.Steps.Last();
            tryInfo.EndStep = tryStep.Step;

            List <IAsyncStep> catchSteps = new List <IAsyncStep>();

            foreach (var clause in tryCatchStatement.CatchClauses)
            {
                var catchStep = this.Emitter.AsyncBlock.AddAsyncStep();
                catchSteps.Add(catchStep);

                this.PushLocals();
                var varName = clause.VariableName;

                if (!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName))
                {
                    varName = this.AddLocal(varName, clause.Type);
                }

                tryInfo.CatchBlocks.Add(new Tuple <string, string, int>(varName, clause.Type.IsNull ? "Bridge.Exception" : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step));

                this.Emitter.IgnoreBlock = clause.Body;
                clause.Body.AcceptVisitor(this.Emitter);
                this.PopLocals();
                this.WriteNewLine();
            }

            if (/*tryCatchStatement.CatchClauses.Count == 0 && */ !this.Emitter.Locals.ContainsKey("$e"))
            {
                this.AddLocal("$e", AstType.Null);
            }

            IAsyncStep finalyStep = null;

            if (!tryCatchStatement.FinallyBlock.IsNull)
            {
                finalyStep = this.Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock);
                this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock;
                tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter);

                var finallyNode = this.GetParentFinallyBlock(tryCatchStatement, false);

                this.WriteNewLine();

                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$jumpFromFinally > -1");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node = finallyNode, Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write("$step = $jumpFromFinally;");
                    this.WriteNewLine();
                    this.Write("$jumpFromFinally = null;");
                }

                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("$e");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                this.Write("$returnTask.setError($e);");
                this.WriteNewLine();
                this.WriteReturn(false);
                this.WriteSemiColon();
                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write("Bridge.isDefined($returnValue)");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();

                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel {
                        Node = finallyNode, Output = this.Emitter.Output
                    });
                    this.Write("$step = ${" + hashcode + "};");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write("$returnTask.setResult($returnValue);");
                    this.WriteNewLine();
                    this.WriteReturn(false);
                    this.WriteSemiColon();
                }

                this.WriteNewLine();
                this.EndBlock();

                if (!this.Emitter.Locals.ContainsKey("$e"))
                {
                    this.AddLocal("$e", AstType.Null);
                }
            }

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            if (finalyStep != null)
            {
                tryInfo.FinallyStep = finalyStep.Step;
            }

            if (finalyStep != null)
            {
                finalyStep.JumpToStep = nextStep.Step;
            }

            tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;

            foreach (var step in catchSteps)
            {
                step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;
            }

            this.Emitter.AsyncBlock.TryInfos.Add(tryInfo);
        }
예제 #8
0
        protected void VisitAsyncSwitchSection(SwitchSection switchSection, bool writeElse, string switchKey)
        {
            var list = switchSection.CaseLabels.ToList();

            list.Sort((l1, l2) =>
            {
                if (l1.Expression.IsNull)
                {
                    return(1);
                }

                if (l2.Expression.IsNull)
                {
                    return(-1);
                }

                return(0);
            });

            if (writeElse)
            {
                this.WriteElse();
            }

            if (list.Any(l => l.Expression.IsNull))
            {
                if (!writeElse)
                {
                    this.WriteElse();
                }
            }
            else
            {
                this.WriteIf();
                this.WriteOpenParentheses();

                var oldValue = this.Emitter.ReplaceAwaiterByVar;
                this.Emitter.ReplaceAwaiterByVar = true;
                bool writeOr = false;

                foreach (var label in list)
                {
                    if (writeOr)
                    {
                        this.WriteSpace();
                        this.Write("||");
                        this.WriteSpace();
                    }

                    this.Write(switchKey + " === ");
                    label.Expression.AcceptVisitor(this.Emitter);

                    writeOr = true;
                }

                this.WriteCloseParentheses();
                this.Emitter.ReplaceAwaiterByVar = oldValue;
            }

            if (switchSection.Statements.Count() == 1 && switchSection.Statements.First() is BlockStatement)
            {
                this.Emitter.IgnoreBlock = switchSection.Statements.First();
            }

            int        startCount = this.Emitter.AsyncBlock.Steps.Count;
            IAsyncStep thisStep   = null;

            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();

            switchSection.Statements.AcceptVisitor(this.Emitter);

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                thisStep = this.Emitter.AsyncBlock.Steps.Last();
            }

            if (this.RestoreWriter(writer) && !this.IsOnlyWhitespaceOnPenultimateLine(true))
            {
                this.WriteNewLine();
            }

            this.EndBlock();
            this.WriteNewLine();
        }
예제 #9
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, " = ", iteratorName);

            this.WriteDot();
            this.Write(JS.Funcs.GET_CURRENT);

            this.WriteOpenCloseParentheses();
            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;
        }
예제 #10
0
        protected void VisitAsyncTryCatchStatement()
        {
            TryCatchStatement tryCatchStatement = this.TryCatchStatement;

            this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step;

            var          tryStep = this.Emitter.AsyncBlock.AddAsyncStep();
            AsyncTryInfo tryInfo = new AsyncTryInfo();

            tryInfo.StartStep = tryStep.Step;

            this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock;
            tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter);
            tryStep         = this.Emitter.AsyncBlock.Steps.Last();
            tryInfo.EndStep = tryStep.Step;

            List <IAsyncStep> catchSteps = new List <IAsyncStep>();

            foreach (var clause in tryCatchStatement.CatchClauses)
            {
                var catchStep = this.Emitter.AsyncBlock.AddAsyncStep();
                catchSteps.Add(catchStep);

                this.PushLocals();
                var varName = clause.VariableName;

                if (String.IsNullOrEmpty(varName))
                {
                    varName = "$e";
                }

                if (!this.Emitter.Locals.ContainsKey(varName))
                {
                    varName = this.AddLocal(varName, clause.Type);
                }

                tryInfo.CatchBlocks.Add(new Tuple <string, string, int>(varName, Helpers.TranslateTypeReference(clause.Type, this.Emitter), catchStep.Step));

                this.Emitter.IgnoreBlock = clause.Body;
                clause.Body.AcceptVisitor(this.Emitter);
                this.PopLocals();
            }

            if (tryCatchStatement.CatchClauses.Count == 0 && !this.Emitter.Locals.ContainsKey("$e"))
            {
                this.AddLocal("$e", AstType.Null);
            }

            IAsyncStep finalyStep = null;

            if (!tryCatchStatement.FinallyBlock.IsNull)
            {
                finalyStep = this.Emitter.AsyncBlock.AddAsyncStep();
                this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock;
                tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter);

                if (catchSteps.Count == 0)
                {
                    this.WriteNewLine();
                    this.Write("throw $e;");

                    if (!this.Emitter.Locals.ContainsKey("$e"))
                    {
                        this.AddLocal("$e", AstType.Null);
                    }
                }
            }

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            if (finalyStep != null)
            {
                tryInfo.FinallyStep = finalyStep.Step;
            }

            if (finalyStep != null)
            {
                finalyStep.JumpToStep = nextStep.Step;
            }

            tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;

            foreach (var step in catchSteps)
            {
                step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;
            }

            this.Emitter.AsyncBlock.TryInfos.Add(tryInfo);
        }
예제 #11
0
        protected void VisitAsyncTryCatchStatement()
        {
            TryCatchStatement tryCatchStatement = this.TryCatchStatement;

            this.Emitter.AsyncBlock.Steps.Last().JumpToStep = this.Emitter.AsyncBlock.Step;

            var          tryStep = this.Emitter.AsyncBlock.AddAsyncStep();
            AsyncTryInfo tryInfo = new AsyncTryInfo();

            tryInfo.StartStep = tryStep.Step;

            this.Emitter.IgnoreBlock = tryCatchStatement.TryBlock;
            tryCatchStatement.TryBlock.AcceptVisitor(this.Emitter);
            tryStep         = this.Emitter.AsyncBlock.Steps.Last();
            tryInfo.EndStep = tryStep.Step;

            List <IAsyncStep> catchSteps = new List <IAsyncStep>();

            foreach (var clause in tryCatchStatement.CatchClauses)
            {
                var catchStep = this.Emitter.AsyncBlock.AddAsyncStep();

                this.PushLocals();
                var varName = clause.VariableName;

                if (!String.IsNullOrEmpty(varName) && !this.Emitter.Locals.ContainsKey(varName))
                {
                    varName = this.AddLocal(varName, clause.VariableNameToken, clause.Type);
                }

                this.Emitter.IgnoreBlock = clause.Body;
                clause.Body.AcceptVisitor(this.Emitter);
                Write(JS.Vars.ASYNC_E + " = null;");
                this.PopLocals();
                this.WriteNewLine();

                tryInfo.CatchBlocks.Add(new Tuple <string, string, int, int>(varName, clause.Type.IsNull ? JS.Types.System.Exception.NAME : BridgeTypes.ToJsName(clause.Type, this.Emitter), catchStep.Step, Emitter.AsyncBlock.Steps.Last().Step));
                catchSteps.Add(Emitter.AsyncBlock.Steps.Last());
            }

            if (!this.Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E))
            {
                this.AddLocal(JS.Vars.ASYNC_E, null, AstType.Null);
            }

            IAsyncStep finalyStep = null;

            if (!tryCatchStatement.FinallyBlock.IsNull)
            {
                finalyStep = this.Emitter.AsyncBlock.AddAsyncStep(tryCatchStatement.FinallyBlock);
                this.Emitter.IgnoreBlock = tryCatchStatement.FinallyBlock;
                tryCatchStatement.FinallyBlock.AcceptVisitor(this.Emitter);

                var finallyNode = this.GetParentFinallyBlock(tryCatchStatement, false);

                this.WriteNewLine();

                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write(JS.Vars.ASYNC_JUMP + " > -1");
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();
                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel
                    {
                        Node   = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};"));
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write(JS.Vars.ASYNC_STEP + " = " + JS.Vars.ASYNC_JUMP + ";");
                    this.WriteNewLine();
                    this.Write(JS.Vars.ASYNC_JUMP + " = null;");
                }

                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write(JS.Vars.ASYNC_E);
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();

                if (this.Emitter.AsyncBlock.IsTaskReturn)
                {
                    this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_EXCEPTION + "(" + JS.Vars.ASYNC_E + ");");
                }
                else
                {
                    this.Write("throw " + JS.Vars.ASYNC_E + ";");
                }

                this.WriteNewLine();
                this.WriteReturn(false);
                this.WriteSemiColon();
                this.WriteNewLine();
                this.EndBlock();

                this.WriteSpace();
                this.WriteElse();
                this.WriteIf();
                this.WriteOpenParentheses();
                this.Write(JS.Funcs.BRIDGE_IS_DEFINED);
                this.WriteOpenParentheses();
                this.Write(JS.Vars.ASYNC_RETURN_VALUE);
                this.WriteCloseParentheses();
                this.WriteCloseParentheses();
                this.WriteSpace();
                this.BeginBlock();

                if (finallyNode != null)
                {
                    var hashcode = finallyNode.GetHashCode();
                    this.Emitter.AsyncBlock.JumpLabels.Add(new AsyncJumpLabel
                    {
                        Node   = finallyNode,
                        Output = this.Emitter.Output
                    });
                    this.Write(JS.Vars.ASYNC_STEP + " = " + Helpers.PrefixDollar("{", hashcode, "};"));
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else
                {
                    this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(" + JS.Vars.ASYNC_RETURN_VALUE + ");");
                    this.WriteNewLine();
                    this.WriteReturn(false);
                    this.WriteSemiColon();
                }

                this.WriteNewLine();
                this.EndBlock();

                if (!this.Emitter.Locals.ContainsKey(JS.Vars.ASYNC_E))
                {
                    this.AddLocal(JS.Vars.ASYNC_E, null, AstType.Null);
                }
            }

            var lastFinallyStep = Emitter.AsyncBlock.Steps.Last();

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            if (finalyStep != null)
            {
                tryInfo.FinallyStep        = finalyStep.Step;
                lastFinallyStep.JumpToStep = nextStep.Step;
            }

            tryStep.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;

            foreach (var step in catchSteps)
            {
                step.JumpToStep = finalyStep != null ? finalyStep.Step : nextStep.Step;
            }

            this.Emitter.AsyncBlock.TryInfos.Add(tryInfo);
        }
예제 #12
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();

            var writer = this.SaveWriter();

            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("$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("$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)
            {
                foreach (var jump in this.Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step);
                }
            }

            this.Emitter.JumpStatements = jumpStatements;
        }
예제 #13
0
        internal void WriteAsyncConditionalExpression(int index)
        {
            if (Emitter.AsyncBlock.WrittenAwaitExpressions.Contains(ConditionalExpression))
            {
                return;
            }

            Emitter.AsyncBlock.WrittenAwaitExpressions.Add(ConditionalExpression);

            WriteAwaiters(ConditionalExpression.Condition);

            WriteIf();
            WriteOpenParentheses();

            var oldValue = Emitter.ReplaceAwaiterByVar;
            var oldAsyncExpressionHandling = Emitter.AsyncExpressionHandling;

            Emitter.ReplaceAwaiterByVar     = true;
            Emitter.AsyncExpressionHandling = true;
            ConditionalExpression.Condition.AcceptVisitor(Emitter);
            WriteCloseParentheses();
            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

            int        startCount = 0;
            int        elseCount  = 0;
            IAsyncStep trueStep   = null;
            IAsyncStep elseStep   = null;

            startCount = Emitter.AsyncBlock.Steps.Count;

            EmittedAsyncSteps = Emitter.AsyncBlock.EmittedAsyncSteps;
            Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>();

            var taskResultVar = JS.Vars.ASYNC_TASK_RESULT + index;

            if (!Emitter.Locals.ContainsKey(taskResultVar))
            {
                AddLocal(taskResultVar, null, AstType.Null);
            }

            WriteSpace();
            BeginBlock();
            Write($"{JS.Vars.ASYNC_STEP} = {Emitter.AsyncBlock.Step};");
            WriteNewLine();
            Write("continue;");
            var writer = SaveWriter();

            Emitter.AsyncBlock.AddAsyncStep();

            WriteAwaiters(ConditionalExpression.TrueExpression);

            oldValue = Emitter.ReplaceAwaiterByVar;
            oldAsyncExpressionHandling      = Emitter.AsyncExpressionHandling;
            Emitter.ReplaceAwaiterByVar     = true;
            Emitter.AsyncExpressionHandling = true;
            Write(taskResultVar + " = ");
            ConditionalExpression.TrueExpression.AcceptVisitor(Emitter);
            WriteSemiColon();
            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

            if (Emitter.AsyncBlock.Steps.Count > startCount)
            {
                trueStep = Emitter.AsyncBlock.Steps.Last();
            }

            if (RestoreWriter(writer) && !IsOnlyWhitespaceOnPenultimateLine(true))
            {
                WriteNewLine();
            }

            EndBlock();
            WriteSpace();

            elseCount = Emitter.AsyncBlock.Steps.Count;

            WriteSpace();
            WriteElse();
            BeginBlock();

            Write($"{JS.Vars.ASYNC_STEP} = {Emitter.AsyncBlock.Step};");
            WriteNewLine();
            Write("continue;");
            writer = SaveWriter();
            Emitter.AsyncBlock.AddAsyncStep();
            WriteAwaiters(ConditionalExpression.FalseExpression);

            oldValue = Emitter.ReplaceAwaiterByVar;
            oldAsyncExpressionHandling      = Emitter.AsyncExpressionHandling;
            Emitter.ReplaceAwaiterByVar     = true;
            Emitter.AsyncExpressionHandling = true;
            Write(taskResultVar + " = ");
            ConditionalExpression.FalseExpression.AcceptVisitor(Emitter);
            WriteSemiColon();
            Emitter.ReplaceAwaiterByVar     = oldValue;
            Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

            if (Emitter.AsyncBlock.Steps.Count > elseCount)
            {
                elseStep = Emitter.AsyncBlock.Steps.Last();
            }

            if (RestoreWriter(writer) && !IsOnlyWhitespaceOnPenultimateLine(true))
            {
                WriteNewLine();
            }

            EndBlock();
            WriteSpace();

            if (Emitter.IsAsync && Emitter.AsyncBlock.Steps.Count > startCount)
            {
                if (Emitter.AsyncBlock.Steps.Count <= elseCount && !IsJumpStatementLast(Emitter.Output.ToString()))
                {
                    WriteNewLine();
                    Write($"{JS.Vars.ASYNC_STEP} = {Emitter.AsyncBlock.Step};");
                    WriteNewLine();
                    Write("continue;");
                }

                var nextStep = Emitter.AsyncBlock.AddAsyncStep();

                if (trueStep != null)
                {
                    trueStep.JumpToStep = nextStep.Step;
                }

                if (elseStep != null)
                {
                    elseStep.JumpToStep = nextStep.Step;
                }
            }
            else if (Emitter.IsAsync)
            {
                WriteNewLine();
            }

            if (Emitter.IsAsync)
            {
                Emitter.AsyncBlock.EmittedAsyncSteps = EmittedAsyncSteps;
            }
        }
예제 #14
0
        protected void VisitIfElseStatement()
        {
            IfElseStatement ifElseStatement = IfElseStatement;

            var awaiters = GetAwaiters(ifElseStatement);

            if (awaiters == null || awaiters.Length == 0)
            {
                WriteIf();
                WriteOpenParentheses();
                ifElseStatement.Condition.AcceptVisitor(Emitter);
                WriteCloseParentheses();
                EmitBlockOrIndentedLine(ifElseStatement.TrueStatement);
                if (ifElseStatement.FalseStatement != null && !ifElseStatement.FalseStatement.IsNull)
                {
                    Write(" else");
                    EmitBlockOrIndentedLine(ifElseStatement.FalseStatement);
                }
                return;
            }

            WriteAwaiters(ifElseStatement.Condition);

            WriteIf();
            WriteOpenParentheses();

            var oldValue = Emitter.ReplaceAwaiterByVar;

            Emitter.ReplaceAwaiterByVar = true;
            ifElseStatement.Condition.AcceptVisitor(Emitter);
            Emitter.ReplaceAwaiterByVar = oldValue;

            WriteCloseParentheses();

            int        startCount = 0;
            int        elseCount  = 0;
            IAsyncStep trueStep   = null;
            IAsyncStep elseStep   = null;

            if (Emitter.IsAsync)
            {
                startCount = Emitter.AsyncBlock.Steps.Count;

                EmittedAsyncSteps = Emitter.AsyncBlock.EmittedAsyncSteps;
                Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>();

                Emitter.IgnoreBlock = ifElseStatement.TrueStatement;
                WriteSpace();
                BeginBlock();
                Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";");
                WriteNewLine();
                Write("continue;");
                var writer = SaveWriter();
                Emitter.AsyncBlock.AddAsyncStep();
                ifElseStatement.TrueStatement.AcceptVisitor(Emitter);

                if (Emitter.AsyncBlock.Steps.Count > startCount)
                {
                    trueStep = Emitter.AsyncBlock.Steps.Last();
                }

                if (RestoreWriter(writer) && !IsOnlyWhitespaceOnPenultimateLine(true))
                {
                    WriteNewLine();
                }

                EndBlock();
                WriteSpace();

                elseCount = Emitter.AsyncBlock.Steps.Count;
            }
            else
            {
                EmitBlockOrIndentedLine(ifElseStatement.TrueStatement);
            }

            if (ifElseStatement.FalseStatement != null && !ifElseStatement.FalseStatement.IsNull)
            {
                WriteElse();
                if (Emitter.IsAsync)
                {
                    Emitter.IgnoreBlock = ifElseStatement.FalseStatement;
                    WriteSpace();
                    BeginBlock();
                    Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";");
                    WriteNewLine();
                    Write("continue;");
                    var writer = SaveWriter();
                    Emitter.AsyncBlock.AddAsyncStep();
                    ifElseStatement.FalseStatement.AcceptVisitor(Emitter);

                    if (Emitter.AsyncBlock.Steps.Count > elseCount)
                    {
                        elseStep = Emitter.AsyncBlock.Steps.Last();
                    }

                    if (RestoreWriter(writer) && !IsOnlyWhitespaceOnPenultimateLine(true))
                    {
                        WriteNewLine();
                    }

                    EndBlock();
                    WriteSpace();
                }
                else
                {
                    EmitBlockOrIndentedLine(ifElseStatement.FalseStatement);
                }
            }

            if (Emitter.IsAsync && Emitter.AsyncBlock.Steps.Count > startCount)
            {
                if (Emitter.AsyncBlock.Steps.Count <= elseCount && !IsJumpStatementLast(Emitter.Output.ToString()))
                {
                    WriteNewLine();
                    Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";");
                    WriteNewLine();
                    Write("continue;");
                }

                var nextStep = Emitter.AsyncBlock.AddAsyncStep();

                if (trueStep != null)
                {
                    trueStep.JumpToStep = nextStep.Step;
                }

                if (elseStep != null)
                {
                    elseStep.JumpToStep = nextStep.Step;
                }
            }
            else if (Emitter.IsAsync)
            {
                WriteNewLine();
            }

            if (Emitter.IsAsync)
            {
                Emitter.AsyncBlock.EmittedAsyncSteps = EmittedAsyncSteps;
            }
        }
예제 #15
0
        protected void VisitIfElseStatement()
        {
            IfElseStatement ifElseStatement = this.IfElseStatement;

            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;
            }
        }
예제 #16
0
파일: ForBlock.cs 프로젝트: zwmyint/Bridge
        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(JS.Vars.ASYNC_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);

            if (!forStatement.Condition.IsNull)
            {
                forStatement.Condition.AcceptVisitor(this.Emitter);
            }
            else
            {
                this.Write("true");
            }

            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;");

            this.EmittedAsyncSteps = this.Emitter.AsyncBlock.EmittedAsyncSteps;
            this.Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>();
            var writer = this.SaveWriter();

            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(JS.Vars.ASYNC_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;
        }
예제 #17
0
        internal void WriteAsyncBinaryExpression(int index)
        {
            if (this.Emitter.AsyncBlock.WrittenAwaitExpressions.Contains(this.BinaryOperatorExpression))
            {
                return;
            }

            this.Emitter.AsyncBlock.WrittenAwaitExpressions.Add(this.BinaryOperatorExpression);

            this.WriteAwaiters(this.BinaryOperatorExpression.Left);

            this.WriteIf();
            this.WriteOpenParentheses();

            var oldValue = this.Emitter.ReplaceAwaiterByVar;
            var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling;

            this.Emitter.ReplaceAwaiterByVar     = true;
            this.Emitter.AsyncExpressionHandling = true;

            var isOr = this.BinaryOperatorExpression.Operator == BinaryOperatorType.BitwiseOr ||
                       this.BinaryOperatorExpression.Operator == BinaryOperatorType.ConditionalOr;

            if (isOr)
            {
                this.Write("!");
            }

            this.BinaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
            this.WriteCloseParentheses();
            this.Emitter.ReplaceAwaiterByVar     = oldValue;
            this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling;

            int        startCount = 0;
            IAsyncStep trueStep   = 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.BinaryOperatorExpression.Right);

            oldValue = this.Emitter.ReplaceAwaiterByVar;
            oldAsyncExpressionHandling           = this.Emitter.AsyncExpressionHandling;
            this.Emitter.ReplaceAwaiterByVar     = true;
            this.Emitter.AsyncExpressionHandling = true;
            this.Write(taskResultVar + " = ");
            this.BinaryOperatorExpression.Right.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.WriteNewLine();
            this.Write($"{taskResultVar} = {(isOr ? "true" : "false")};");
            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;
            }

            this.Emitter.AsyncBlock.EmittedAsyncSteps = this.EmittedAsyncSteps;
        }
예제 #18
0
        protected void VisitAsyncWhileStatement()
        {
            var oldValue       = Emitter.ReplaceAwaiterByVar;
            var jumpStatements = Emitter.JumpStatements;

            Emitter.JumpStatements = new List <IJumpInfo>();

            IAsyncStep conditionStep = null;
            var        lastStep      = Emitter.AsyncBlock.Steps.Last();

            if (string.IsNullOrWhiteSpace(lastStep.Output.ToString()))
            {
                conditionStep = lastStep;
            }
            else
            {
                lastStep.JumpToStep = Emitter.AsyncBlock.Step;
                conditionStep       = Emitter.AsyncBlock.AddAsyncStep();
            }

            WriteAwaiters(WhileStatement.Condition);
            Emitter.ReplaceAwaiterByVar = true;

            WriteIf();
            WriteOpenParentheses(true);
            WhileStatement.Condition.AcceptVisitor(Emitter);
            WriteCloseParentheses(true);
            Emitter.ReplaceAwaiterByVar = oldValue;

            WriteSpace();
            BeginBlock();

            Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";");
            WriteNewLine();
            Write("continue;");

            var writer = SaveWriter();

            Emitter.AsyncBlock.AddAsyncStep();
            Emitter.IgnoreBlock = WhileStatement.EmbeddedStatement;

            var startCount = Emitter.AsyncBlock.Steps.Count;

            WhileStatement.EmbeddedStatement.AcceptVisitor(Emitter);

            if (!IsJumpStatementLast(Emitter.Output.ToString()))
            {
                WriteNewLine();
                Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";");
                WriteNewLine();
                Write("continue;");
            }

            RestoreWriter(writer);

            WriteNewLine();
            EndBlock();
            WriteSpace();

            if (!IsJumpStatementLast(Emitter.Output.ToString()))
            {
                WriteNewLine();
                Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";");
                WriteNewLine();
                Write("continue;");
            }

            var nextStep = Emitter.AsyncBlock.AddAsyncStep();

            conditionStep.JumpToStep = nextStep.Step;

            if (Emitter.JumpStatements.Count > 0)
            {
                Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position));
                foreach (var jump in Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step);
                }
            }

            Emitter.JumpStatements = jumpStatements;
        }