public override Statement VisitForEach(ForEach forEach) { WriteStart("foreach ("); this.VisitTypeReference(forEach.TargetVariableType); Write(" "); this.VisitExpression(forEach.TargetVariable); Write(" in "); this.VisitExpression(forEach.SourceEnumerable); Write(")"); this.VisitBlock(forEach.Body); return forEach; }
void AddWriteStream(TypeNode type, StatementList statements, TypeNode referringType, Expression src, Identifier writer) { // Generate the following code: // XxxxSerializer s = new XxxxSerializer(); // foreach (Xxxx x in src) { // s.Serialize(x,writer); // } // Where Xxxx is the element type for the given stream type. if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) { type = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type); } else { statements = AddCheckForNull(statements, Duplicate(src, referringType), type); } TypeNode ceType = Checker.GetCollectionElementType(type); //todo: should check that type has an IEnumerator. Identifier loopVariable = Identifier.For("e"); loopVariable.Type = ceType; Block body = new Block(); body.Statements = new StatementList(); Expression name, ns; GetNameAndNamespace(ceType, out name, out ns); // call the Serialize method on it, passing the member we're serializing. if (!AddWriteSimpleType(ceType, body.Statements, referringType, writer, loopVariable, name, ns)) { AddCallSerializer(ceType, body.Statements, loopVariable, writer, name, ns); } ForEach fe = new ForEach(ceType, loopVariable, src, body); statements.Add(fe); }
public override Statement VisitForEach(ForEach forEach) { Statement rVal = base.VisitForEach(forEach); // // Create a temporary variable to hold our enumerator position // forEach.ScopeForTemporaryVariables.Members.Add( new Field(forEach.ScopeForTemporaryVariables, null, FieldFlags.Public, new Identifier("____" + forEach.UniqueKey.ToString(CultureInfo.InvariantCulture)), SystemTypes.Int32, new Literal(0, SystemTypes.Int32))); // Add the local variables we've added here to the method's "locals" list. Class scope; for (scope = forEach.ScopeForTemporaryVariables; scope is BlockScope; scope = scope.BaseClass) ; MethodScope mScope = scope as MethodScope; Debug.Assert(mScope != null); for (int i = 0, n = forEach.ScopeForTemporaryVariables.Members.Count; i < n; i++) { Member m = forEach.ScopeForTemporaryVariables.Members[i]; ZMethod zMethod = mScope.DeclaringMethod as ZMethod; Debug.Assert(zMethod != null); zMethod.LocalVars.Add((Field)m); } return rVal; }
public override Statement VisitForEach(ForEach forEach) { if (forEach == null) return null; return base.VisitForEach((ForEach)forEach.Clone()); }
public virtual Statement VisitForEach(ForEach forEach) { if (forEach == null) return null; forEach.TargetVariableType = this.VisitTypeReference(forEach.TargetVariableType); forEach.TargetVariable = this.VisitTargetExpression(forEach.TargetVariable); forEach.SourceEnumerable = this.VisitExpression(forEach.SourceEnumerable); forEach.InductionVariable = this.VisitTargetExpression(forEach.InductionVariable); forEach.Invariants = this.VisitLoopInvariantList(forEach.Invariants); forEach.Body = this.VisitBlock(forEach.Body); return forEach; }
private ForEach ParseForEach(TokenSet followers){ ForEach forEach = new ForEach(); forEach.StatementTerminatesNormallyIfEnumerableIsNull = false; forEach.StatementTerminatesNormallyIfEnumeratorIsNull = false; forEach.SourceContext = this.scanner.CurrentSourceContext; Debug.Assert(this.currentToken == Token.Foreach); this.GetNextToken(); SourceContext sctx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); forEach.TargetVariableType = forEach.TargetVariableTypeExpression = this.ParseTypeExpression(null, followers|Parser.IdentifierOrNonReservedKeyword|Token.In|Token.RightParenthesis); forEach.TargetVariable = this.scanner.GetIdentifier(); if (this.currentToken == Token.In) this.HandleError(Error.BadForeachDecl); else this.SkipIdentifierOrNonReservedKeyword(); this.Skip(Token.In); forEach.SourceEnumerable = this.ParseExpression(followers|Token.RightParenthesis); this.ParseBracket(sctx, Token.RightParenthesis, followers|Token.ElementsSeen|Token.Invariant|Parser.StatementStart, Error.ExpectedRightParenthesis); if (this.currentToken == Token.ElementsSeen){ this.GetNextToken(); forEach.InductionVariable = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); this.SkipSemiColon(followers); } forEach.Invariants = this.ParseLoopInvariants(followers); SourceContext savedCompoundStatementOpeningContext = this.compoundStatementOpeningContext; forEach.SourceContext.EndPos = this.scanner.endPos; this.compoundStatementOpeningContext = forEach.SourceContext; Block b = this.ParseStatementAsBlock(followers); forEach.Body = b; if (b != null) forEach.SourceContext.EndPos = b.SourceContext.EndPos; this.compoundStatementOpeningContext = savedCompoundStatementOpeningContext; return forEach; }
/// <summary> /// To be C# compliant, we should not allow anything to be the source of a foreach loop (which includes /// comprehensions) unless it either has a GetEnumerator() method or if it is an array. /// (It used to be that we would happily use something that was already an Enumerator, but that leads /// to a problem: once the enumerator is exhausted, there is not necessarily a good, automatic, way to /// reset it. And there isn't necessarily a good way to clone it beforehand.) /// </summary> /// <param name="forEach">The AST that represents the foreach loop</param> /// <returns>Either whatever the base visitor returns or else null (if there is an error)</returns> public override Statement VisitForEach(ForEach forEach) { Statement s = base.VisitForEach(forEach); ForEach f = s as ForEach; if (f != null) { // don't allow a source enumerable that is just an enumerator CollectionEnumerator cEnumerator = f.SourceEnumerable as CollectionEnumerator; if (cEnumerator != null && cEnumerator.GetEnumerator == null) { // Then it is not a type that supports GetEnumerator(), but if it is an array, then we'll let it slide. TypeNode possiblyArrayType = this.typeSystem.GetUnderlyingType(cEnumerator.Collection.Type) as ArrayType; if (possiblyArrayType == null) { this.HandleError(forEach, Error.ForEachMissingMember, this.GetTypeName(cEnumerator.Collection.Type), this.GetTypeName(cEnumerator.Collection.Type), "GetEnumerator"); return null; } } } return s; }
public override Statement VisitForEach(ForEach forEach) { Normalizer normalizer = new Normalizer(false); Identifier incrVar = new Identifier("____" + forEach.UniqueKey.ToString(CultureInfo.InvariantCulture)); Expression sourceEnumerable = normalizer.VisitExpression(forEach.SourceEnumerable); Statement incrStmt = Templates.GetStatementTemplate("foreachIncrementer"); Replacer.Replace(incrStmt, "_iterator", incrVar); BasicBlock incrBlock = new BasicBlock(incrStmt); AddBlock(incrBlock); incrBlock.MiddleOfTransition = true; incrBlock.SkipNormalizer = true; incrBlock.SourceContext = forEach.SourceContext; PushContinuationStack(incrBlock); this.Visit(forEach.Body); BasicBlock bodyBlock = PopContinuationStack(); Statement derefStmt = Templates.GetStatementTemplate("foreachDeref"); Replacer.Replace(derefStmt, "_tmpVar", normalizer.VisitExpression(forEach.TargetVariable)); Replacer.Replace(derefStmt, "_collectionExpr", sourceEnumerable); Replacer.Replace(derefStmt, "_collectionType", new Identifier(forEach.SourceEnumerable.Type.FullName)); Replacer.Replace(derefStmt, "_iterator", incrVar); BasicBlock derefBlock = new BasicBlock(derefStmt, bodyBlock); AddBlock(derefBlock); derefBlock.MiddleOfTransition = true; derefBlock.SkipNormalizer = true; Expression testExpr = Templates.GetExpressionTemplate("foreachTest"); Replacer.Replace(testExpr, "_iterator", incrVar); Replacer.Replace(testExpr, "_sourceEnumerable", sourceEnumerable); BasicBlock testBlock = new BasicBlock(null, testExpr, derefBlock, CurrentContinuation); AddBlock(testBlock); testBlock.SkipNormalizer = true; incrBlock.UnconditionalTarget = testBlock; Statement initStmt = Templates.GetStatementTemplate("foreachInit"); Replacer.Replace(initStmt, "_iterator", incrVar); BasicBlock initBlock = new BasicBlock(initStmt, testBlock); AddBlock(initBlock); initBlock.MiddleOfTransition = true; initBlock.SkipNormalizer = true; initBlock.SourceContext = forEach.SourceContext; CurrentContinuation = initBlock; return forEach; }
// // We support iteration over arrays and sets // public override Statement VisitForEach(ForEach forEach) { if (forEach == null) return null; forEach.TargetVariableType = this.VisitTypeReference(forEach.TargetVariableType); forEach.TargetVariable = this.VisitTargetExpression(forEach.TargetVariable); forEach.SourceEnumerable = this.VisitExpression(forEach.SourceEnumerable); if (forEach.TargetVariableType == null || forEach.TargetVariable == null || forEach.SourceEnumerable == null) return null; TypeNode collectionType = forEach.SourceEnumerable.Type; Set setCollection = collectionType as Set; ZArray arrayCollection = collectionType as ZArray; TypeNode memberType = null; if (setCollection != null) memberType = setCollection.SetType; if (arrayCollection != null) memberType = arrayCollection.ElementType; if (memberType == null) { this.HandleError(forEach.SourceEnumerable, Error.InvalidForeachSource); return null; } if (memberType != forEach.TargetVariableType) { this.HandleError(forEach.TargetVariable, Error.InvalidForeachTargetType); return null; } forEach.Body = this.VisitBlock(forEach.Body); return forEach; }
public EventingVisitor(Action<ForEach> visitForEach) { VisitedForEach += visitForEach; } public event Action<ForEach> VisitedForEach; public override Statement VisitForEach(ForEach forEach) { if (VisitedForEach != null) VisitedForEach(forEach); return base.VisitForEach(forEach); }