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); } }
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)); }
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); }
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); }
public override JsNode Visit(JsWhileStatement node) { if (loop != null) { return(node); } loop = node; node.Body = TransformBody((JsStatement)node.Body.Accept(this)); return(node); }
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)); }
public void Visit(JsWhileStatement node) { BeforeVisit(node); DefaultVisit(node, VisitWhileStatement); AfterVisit(node); }
public virtual void VisitWhileStatement(JsWhileStatement node) { }