Inheritance: Statement, IForEachStatement
Beispiel #1
0
 /// <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);
 }
Beispiel #3
0
 /// <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);
 }
Beispiel #4
0
		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);
		}
Beispiel #5
0
 /// <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);
 }
Beispiel #6
0
 /// <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;
 }
Beispiel #7
0
 /// <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);
 }