private bool HandleWhileStatement(JsWhileStatement stmt, StackEntry location, ImmutableStack <StackEntry> stack, ImmutableStack <Tuple <string, State> > breakStack, ImmutableStack <Tuple <string, State> > continueStack, State currentState, State returnState, IList <JsStatement> currentBlock, bool isFirstStatement)
        {
            if (!isFirstStatement)
            {
                // We have to create a new block for the statement.
                var topOfLoopState = CreateNewStateValue(currentState.FinallyStack);
                Enqueue(stack.Push(location), breakStack, continueStack, topOfLoopState, returnState);
                currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState));
                return(false);
            }
            else
            {
                var afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState);

                currentBlock.Add(JsStatement.If(JsExpression.LogicalNot(stmt.Condition), new JsGotoStateStatement(afterLoopState.Item1, currentState), null));
                var currentName = GetLabelForState(currentState);
                currentBlock.AddRange(Handle(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(stmt.Body, 0)), breakStack.Push(Tuple.Create(currentName, afterLoopState.Item1)), continueStack.Push(Tuple.Create(currentName, currentState)), currentState, currentState, false, false));

                if (!stack.IsEmpty || location.Index < location.Block.Statements.Count - 1)
                {
                    Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.Item1, returnState);
                }

                return(false);
            }
        }
Esempio n. 2
0
 public override void VisitWhileStatement(JsWhileStatement node)
 {
     output.Append("while (");
     node.Condition.Accept(this);
     output.Append(")");
     WriteMaybeBlock(node.Body, true);
 }
        public virtual JsStatement VisitWhileStatement(JsWhileStatement statement, TData data)
        {
            var condition = VisitExpression(statement.Condition, data);
            var body      = VisitStatement(statement.Body, data);

            return(ReferenceEquals(condition, statement.Condition) && ReferenceEquals(body, statement.Body) ? statement : new JsWhileStatement(condition, body));
        }
Esempio n. 4
0
 public object VisitWhileStatement(JsWhileStatement statement, bool addNewline)
 {
     _cb.Append("while").Append(_space + "(");
     VisitExpression(statement.Condition, false);
     _cb.Append(")" + _space);
     VisitStatement(statement.Body, addNewline);
     return(null);
 }
Esempio n. 5
0
 public virtual JsNode Visit(JsWhileStatement node)
 {
     return(DefaultVisit(node, x =>
     {
         x.Condition = (JsExpression)x.Condition.Accept(this);
         x.Body = (JsStatement)x.Body.Accept(this);
         return x;
     }));
 }
        public override JsStatement VisitWhileStatement(JsWhileStatement statement, object data)
        {
            bool old = _unnamedIsMatch;

            _unnamedIsMatch = false;
            VisitStatement(statement.Body, null);
            _unnamedIsMatch = old;
            return(statement);
        }
Esempio n. 7
0
        public override JsNode Visit(JsWhileStatement node)
        {
            if (loop != null)
            {
                return(node);
            }
            loop = node;

            node.Body = TransformBody((JsStatement)node.Body.Accept(this));
            return(node);
        }
Esempio n. 8
0
 public virtual void Visit(JsWhileStatement node)
 {
     DefaultVisit(node);
     node.Condition.Accept(this);
     node.Body.Accept(this);
 }
        public override void VisitForeachStatement(ForeachStatement foreachStatement)
        {
            var ferr = (ForEachResolveResult)_resolver.Resolve(foreachStatement);
            var iterator = (LocalResolveResult)_resolver.Resolve(foreachStatement.VariableNameToken);

            var systemArray = _compilation.FindType(KnownTypeCode.Array);
            var inExpression = ResolveWithConversion(foreachStatement.InExpression);
            if (Equals(inExpression.Type, systemArray) || inExpression.Type.DirectBaseTypes.Contains(systemArray)) {
                var arrayResult = CompileExpression(foreachStatement.InExpression, true);
                _result.AddRange(arrayResult.AdditionalStatements);
                var array = arrayResult.Expression;
                if (ExpressionCompiler.IsJsExpressionComplexEnoughToGetATemporaryVariable.Process(array)) {
                    var tmpArray = CreateTemporaryVariable(ferr.CollectionType, foreachStatement.GetRegion());
                    _result.Add(new JsVariableDeclarationStatement(_variables[tmpArray].Name, array));
                    array = JsExpression.Identifier(_variables[tmpArray].Name);
                }

                var length = systemArray.GetProperties().SingleOrDefault(p => p.Name == "Length");
                if (length == null) {
                    _errorReporter.InternalError("Property Array.Length not found.");
                    return;
                }
                var lengthSem = _metadataImporter.GetPropertySemantics(length);
                if (lengthSem.Type != PropertyScriptSemantics.ImplType.Field) {
                    _errorReporter.InternalError("Property Array.Length is not implemented as a field.");
                    return;
                }

                var index = CreateTemporaryVariable(_compilation.FindType(KnownTypeCode.Int32), foreachStatement.GetRegion());
                var jsIndex = JsExpression.Identifier(_variables[index].Name);
                var body = new[] { new JsVariableDeclarationStatement(_variables[iterator.Variable].Name, JsExpression.Index(array, jsIndex)) }
                          .Concat(CreateInnerCompiler().Compile(foreachStatement.EmbeddedStatement).Statements);

                _result.Add(new JsForStatement(new JsVariableDeclarationStatement(_variables[index].Name, JsExpression.Number(0)),
                                               JsExpression.Lesser(jsIndex, JsExpression.MemberAccess(array, lengthSem.FieldName)),
                                               JsExpression.PostfixPlusPlus(jsIndex),
                                               new JsBlockStatement(body)));
            }
            else {
                var getEnumeratorCall = _expressionCompiler.Compile(ferr.GetEnumeratorCall, true);
                _result.AddRange(getEnumeratorCall.AdditionalStatements);
                var enumerator = CreateTemporaryVariable(ferr.EnumeratorType, foreachStatement.GetRegion());
                _result.Add(new JsVariableDeclarationStatement(new JsVariableDeclaration(_variables[enumerator].Name, getEnumeratorCall.Expression)));

                var moveNextInvocation = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new LocalResolveResult(enumerator), ferr.MoveNextMethod, new ResolveResult[0]), true);
                if (moveNextInvocation.AdditionalStatements.Count > 0)
                    _errorReporter.InternalError("MoveNext() invocation is not allowed to require additional statements.");

                var getCurrent = _expressionCompiler.Compile(new MemberResolveResult(new LocalResolveResult(enumerator), ferr.CurrentProperty), true);
                var preBody = getCurrent.AdditionalStatements.Concat(new[] { new JsVariableDeclarationStatement(new JsVariableDeclaration(_variables[iterator.Variable].Name, getCurrent.Expression)) }).ToList();
                var body = CreateInnerCompiler().Compile(foreachStatement.EmbeddedStatement);

                body = new JsBlockStatement(preBody.Concat(body.Statements));

                JsStatement disposer;

                var systemIDisposable = _compilation.FindType(KnownTypeCode.IDisposable);
                var disposeMethod = systemIDisposable.GetMethods().Single(m => m.Name == "Dispose");
                var conversions = CSharpConversions.Get(_compilation);
                var disposableConversion = conversions.ImplicitConversion(enumerator.Type, systemIDisposable);
                if (disposableConversion.IsValid) {
                    // If the enumerator is implicitly convertible to IDisposable, we should dispose it.
                    var compileResult = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new ConversionResolveResult(systemIDisposable, new LocalResolveResult(enumerator), disposableConversion), disposeMethod, new ResolveResult[0]), false);
                    if (compileResult.AdditionalStatements.Count != 0)
                        _errorReporter.InternalError("Call to IDisposable.Dispose must not return additional statements.");
                    disposer = new JsExpressionStatement(compileResult.Expression);
                }
                else if (enumerator.Type.GetDefinition().IsSealed) {
                    // If the enumerator is sealed and not implicitly convertible to IDisposable, we need not dispose it.
                    disposer = null;
                }
                else {
                    // We don't know whether the enumerator is convertible to IDisposable, so we need to conditionally dispose it.
                    var test = _expressionCompiler.Compile(new TypeIsResolveResult(new LocalResolveResult(enumerator), systemIDisposable, _compilation.FindType(KnownTypeCode.Boolean)), true);
                    if (test.AdditionalStatements.Count > 0)
                        _errorReporter.InternalError("\"is\" test must not return additional statements.");
                    var innerStatements = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new ConversionResolveResult(systemIDisposable, new LocalResolveResult(enumerator), conversions.ExplicitConversion(enumerator.Type, systemIDisposable)), disposeMethod, new ResolveResult[0]), false);
                    disposer = new JsIfStatement(test.Expression, new JsBlockStatement(innerStatements.AdditionalStatements.Concat(new[] { new JsExpressionStatement(innerStatements.Expression) })), null);
                }
                JsStatement stmt = new JsWhileStatement(moveNextInvocation.Expression, body);
                if (disposer != null)
                    stmt = new JsTryStatement(stmt, null, disposer);
                _result.Add(stmt);
            }
        }
        private bool HandleWhileStatement(JsWhileStatement stmt, StackEntry location, ImmutableStack<StackEntry> stack, ImmutableStack<Tuple<string, State>> breakStack, ImmutableStack<Tuple<string, State>> continueStack, State currentState, State returnState, IList<JsStatement> currentBlock)
        {
            if (currentBlock.Count > 0) {
                // We have to create a new block for the statement.
                var topOfLoopState = CreateNewStateValue(currentState.FinallyStack);
                Enqueue(stack.Push(location), breakStack, continueStack, topOfLoopState, returnState);
                currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState));
                return false;
            }
            else {
                var afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState);

                currentBlock.Add(new JsIfStatement(JsExpression.LogicalNot(stmt.Condition), new JsGotoStateStatement(afterLoopState.Item1, currentState), null));
                var currentName = GetLabelForState(currentState);
                currentBlock.AddRange(Handle(ImmutableStack<StackEntry>.Empty.Push(new StackEntry(stmt.Body, 0)), breakStack.Push(Tuple.Create(currentName, afterLoopState.Item1)), continueStack.Push(Tuple.Create(currentName, currentState)), currentState, currentState));

                if (!stack.IsEmpty || location.Index < location.Block.Statements.Count - 1) {
                    Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.Item1, returnState);
                }

                return false;
            }
        }
        public override JsStatement VisitWhileStatement(JsWhileStatement statement, object data)
        {
            var body = VisitLoopBody(statement.Body, data);

            return(ReferenceEquals(body, statement.Body) ? statement : new JsWhileStatement(statement.Condition, body));
        }
Esempio n. 12
0
 public void Visit(JsWhileStatement node)
 {
     BeforeVisit(node);
     DefaultVisit(node, VisitWhileStatement);
     AfterVisit(node);
 }
Esempio n. 13
0
 public virtual void VisitWhileStatement(JsWhileStatement node)
 {
 }