/// <summary> /// Visits the specified for each statement. /// </summary> /// <param name="forEachStatement">For each statement.</param> /// <returns></returns> protected virtual IStatement DeepCopy(ForEachStatement forEachStatement) { forEachStatement.Collection = Substitute(forEachStatement.Collection); forEachStatement.Body = Substitute(forEachStatement.Body); return forEachStatement; }
/// <summary> /// Rewrites the children of the given foreach statement. /// </summary> public override void RewriteChildren(ForEachStatement forEachStatement) { if (this.scopesWithCapturedLocals.ContainsKey(forEachStatement)) { var statements = new List<IStatement>(); forEachStatement.Collection = this.Rewrite(forEachStatement.Collection); this.AllocateClosureFor(forEachStatement, statements, delegate() { this.isInsideAnonymousMethod = true; var local = forEachStatement.Variable; var fieldType = this.Rewrite(this.copier.Copy(local.Type)); //get the type as the anon delegate will see it this.isInsideAnonymousMethod = false; this.CreateClosureField(local, fieldType, local.Type, local.Name.Value); var field = this.fieldReferencesForUseInsideThisMethod[local]; statements.Add(new ExpressionStatement() { Expression = new Assignment() { Target = new TargetExpression() { Instance = this.currentClosureObject, Definition = field, Type = field.Type }, Source = new BoundExpression() { Definition = local, Type = local.Type }, Type = fieldType, } }); statements.Add(this.Rewrite(forEachStatement.Body)); forEachStatement.Body = new BlockStatement() { Statements = statements }; }); } else base.RewriteChildren(forEachStatement); }
/// <summary> /// Visits the specified for each statement. /// </summary> /// <param name="forEachStatement">For each statement.</param> public override void Visit(IForEachStatement forEachStatement) { ForEachStatement mutableForEachStatement = new ForEachStatement(forEachStatement); this.resultStatement = this.myCodeCopier.DeepCopy(mutableForEachStatement); }
public override void TraverseChildren(IBlockStatement block) { Contract.Assume(block is BlockStatement); var decompiledBlock = (BlockStatement)block; var statements = decompiledBlock.Statements; for (int i = 0; i < statements.Count; ++i) { var resourceUse = statements[i] as ResourceUseStatement; if (resourceUse == null) continue; var resourceUseBody = resourceUse.Body as BlockStatement; if (resourceUseBody == null) continue; var resourceUseStatements = resourceUseBody.Statements; if (resourceUseStatements.Count != 1) continue; ILocalDefinition resourceVar; IExpression initialValue; var enumeratorDeclaration = resourceUse.ResourceAcquisitions as ILocalDeclarationStatement; if (enumeratorDeclaration == null) { var es = resourceUse.ResourceAcquisitions as IExpressionStatement; if (es == null) continue; var assign = es.Expression as IAssignment; if (assign == null) continue; if (assign.Target.Instance != null) continue; resourceVar = assign.Target.Definition as ILocalDefinition; if (resourceVar == null) continue; initialValue = assign.Source; } else { resourceVar = enumeratorDeclaration.LocalVariable; initialValue = enumeratorDeclaration.InitialValue; } var collection = this.MatchMethodCall(initialValue, "GetEnumerator"); if (collection == null) continue; var isEnumerator = TypeHelper.TypesAreEquivalent(resourceVar.Type, this.host.PlatformType.SystemCollectionsIEnumerator) || this.MatchInterface(resourceVar, "System.Collections.IEnumerator"); if (!isEnumerator) continue; var loop = resourceUseStatements.Last() as IWhileDoStatement; if (loop == null) continue; var methodCall = loop.Condition as IMethodCall; if (methodCall == null) continue; var be = methodCall.ThisArgument as IBoundExpression; if (be != null) { if (be.Instance != null) continue; if (be.Definition != resourceVar) continue; } else { var addrOf = methodCall.ThisArgument as IAddressOf; if (addrOf == null) continue; var ae = addrOf.Expression as IAddressableExpression; if (ae == null) continue; if (ae.Instance != null) continue; if (ae.Definition != resourceVar) continue; } var ct = methodCall.MethodToCall.ContainingType.ResolvedType; if (!SupportsIEnumerator(ct)) continue; if (methodCall.MethodToCall.Name.Value != "MoveNext") continue; var loopBody = loop.Body as BlockStatement; if (loopBody == null || loopBody.Statements.Count < 2) continue; var c = loopBody.Statements.Count; var j = 0; while (j < c && !(loopBody.Statements[j] is ILocalDeclarationStatement)) j++; if (j == c) continue; var lds = loopBody.Statements[j] as ILocalDeclarationStatement; methodCall = lds.InitialValue as IMethodCall; if (methodCall == null) { // it might be "LDS x, null; x := get_Current();" if (lds.InitialValue != null) continue; var k = j+1; if (loopBody.Statements[k] is ILabeledStatement) k++; var es = loopBody.Statements[k] as IExpressionStatement; if (es == null) continue; var assign = es.Expression as IAssignment; if (assign == null) continue; if (assign.Target.Instance != null) continue; var loc = assign.Target.Definition as ILocalDefinition; if (loc == null) continue; methodCall = assign.Source as IMethodCall; if (methodCall == null) continue; loopBody.Statements.RemoveAt(k); } be = methodCall.ThisArgument as IBoundExpression; if (be != null) { if (be.Instance != null) continue; if (be.Definition != resourceVar) continue; } else { var addrOf = methodCall.ThisArgument as IAddressOf; if (addrOf == null) continue; var ae = addrOf.Expression as IAddressableExpression; if (ae == null) continue; if (ae.Instance != null) continue; if (ae.Definition != resourceVar) continue; } var enumerator = lds.LocalVariable; ct = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType).ResolvedType; if (!SupportsIEnumerator(ct)) continue; if (methodCall.MethodToCall.Name.Value != "get_Current") continue; var body = loopBody; body.Statements.RemoveAt(j); var forEachStatement = new ForEachStatement() { Locations = resourceUse.Locations, Variable = enumerator, Collection = collection, Body = body }; statements[i] = forEachStatement; } base.TraverseChildren(block); }
/// <summary> /// Rewrites the children of the given foreach statement. /// </summary> public virtual void RewriteChildren(ForEachStatement forEachStatement) { this.RewriteChildren((Statement)forEachStatement); forEachStatement.Variable = this.Rewrite((LocalDefinition)forEachStatement.Variable); forEachStatement.Collection = this.Rewrite(forEachStatement.Collection); forEachStatement.Body = this.Rewrite(forEachStatement.Body); }
/// <summary> /// Visits the specified for each statement. /// </summary> /// <param name="forEachStatement">For each statement.</param> /// <returns></returns> public virtual IStatement Visit(ForEachStatement forEachStatement) { forEachStatement.Collection = Visit(forEachStatement.Collection); forEachStatement.Body = Visit(forEachStatement.Body); return forEachStatement; }
/// <summary> /// Visits the specified for each statement. /// </summary> /// <param name="forEachStatement">For each statement.</param> public override void Visit(IForEachStatement forEachStatement) { ForEachStatement mutableForEachStatement = forEachStatement as ForEachStatement; if (alwaysMakeACopy || mutableForEachStatement == null) mutableForEachStatement = new ForEachStatement(forEachStatement); this.resultStatement = this.myCodeMutator.Visit(mutableForEachStatement); }