Inheritance: Statement, IResourceUseStatement
Example #1
0
 /// <summary>
 /// Visits the specified resource use statement.
 /// </summary>
 /// <param name="resourceUseStatement">The resource use statement.</param>
 public override void Visit(IResourceUseStatement resourceUseStatement)
 {
     ResourceUseStatement mutableResourceUseStatement = new ResourceUseStatement(resourceUseStatement);
     this.resultStatement = this.myCodeCopier.DeepCopy(mutableResourceUseStatement);
 }
Example #2
0
 /// <summary>
 /// Visits the specified resource use statement.
 /// </summary>
 /// <param name="resourceUseStatement">The resource use statement.</param>
 /// <returns></returns>
 protected virtual IStatement DeepCopy(ResourceUseStatement resourceUseStatement)
 {
     resourceUseStatement.ResourceAcquisitions = this.Substitute(resourceUseStatement.ResourceAcquisitions);
       resourceUseStatement.Body = this.Substitute(resourceUseStatement.Body);
       return resourceUseStatement;
 }
Example #3
0
        /// <summary>
        /// Looking for the pattern:
        /// IDisposable&lt;T&gt; variable = e;
        /// try {
        ///   using_body
        /// } finally {
        ///   if (variable != null) {
        ///     variable.Dispose();
        ///   }
        /// }
        /// The type of the variable is *not* actually IDisposable, but some
        /// type that implements IDisposable.
        /// The assignment might be a local-declaration statement or else it
        /// might be an assignment statement.
        /// </summary>
		public override void TraverseChildren(IBlockStatement block)
		{
			Contract.Assume(block is BlockStatement);
			var decompiledBlock = (BlockStatement)block;
			var statements = decompiledBlock.Statements;

			for (int i = 2; i < statements.Count; ++i)
			{
				var tryFinally = statements[i] as TryCatchFinallyStatement;
				if (tryFinally == null) continue;

                var finallyBody = tryFinally.FinallyBody;
                if (finallyBody == null) continue;
                var finallyStatements = finallyBody.Statements;
                if (tryFinally.CatchClauses.Any()) continue;

                ILocalDefinition variable;
                IStatement resourceAcquisition;
				var variableDeclaration = statements[i - 2] as ILocalDeclarationStatement;
                if (variableDeclaration == null) {
                    var es = statements[i - 2] 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;
                    variable = loc;
                    resourceAcquisition = es;
                } else {
                    variable = variableDeclaration.LocalVariable;
                    resourceAcquisition = variableDeclaration;
                }

                // finally block either looks like:
                //    variable.Dispose();
                // or
                //    if (variable != null) variable.Dispose();
                // or
                //    iDisposableLocalVar := variable as IDisposable;
                //    if (iDisposableLocalVar != null) iDisposableLocalVar.Dispose();
                var c = finallyStatements.Count();
                if (c == 1)
                {
                    var expression = finallyStatements.Single() as IExpressionStatement;
                    var isDispose = this.MatchMethodCall(expression.Expression, variable, "Dispose");
                    if (!isDispose) continue;
                } else if (c == 3 || c == 4)
                {
                    IBoundExpression be;
                    ILocalDefinition iDisposableVariable = variable;
                    var index = 0;
                    if (c == 4)
                    {
                        var es = finallyStatements.ElementAt(index++) as IExpressionStatement;
                        if (es == null) continue;
                        var assignment = es.Expression as IAssignment;
                        if (assignment == null) continue;
                        var castIfPossible = assignment.Source as ICastIfPossible;
                        if (castIfPossible == null) continue;
                        if (!TypeHelper.TypesAreEquivalent(castIfPossible.TargetType, this.IDisposable)) continue;
                        be = castIfPossible.ValueToCast as IBoundExpression;
                        if (be == null) continue;
                        if (be.Instance != null) continue;
                        if (be.Definition != variable) continue;
                        if (assignment.Target.Instance != null) continue;
                        iDisposableVariable = assignment.Target.Definition as ILocalDefinition;
                        if (iDisposableVariable == null) continue;
                    }
                    var conditional = finallyStatements.ElementAt(index++) as IConditionalStatement;
                    if (conditional == null) continue;
                    var expressionStatement = finallyStatements.ElementAt(index++) as IExpressionStatement;
                    if (expressionStatement == null) continue;
                    var lableledStatement = finallyStatements.ElementAt(index++) as ILabeledStatement;
                    if (lableledStatement == null) continue;

                    var equality = conditional.Condition as IEquality;
                    if (equality == null) continue;
                    be = equality.LeftOperand as IBoundExpression;
                    if (be == null) continue;
                    if (be.Instance != null) continue;
                    if (be.Definition != iDisposableVariable) continue;
                    if (!(conditional.FalseBranch is IEmptyStatement)) continue;
                    var gotoStatement = conditional.TrueBranch as IGotoStatement;
                    if (gotoStatement == null) continue;
                    if (gotoStatement.TargetStatement != lableledStatement) continue;
                    var methodCall = expressionStatement.Expression as IMethodCall;
                    if (methodCall == null) continue;
                    var ct = methodCall.MethodToCall.ContainingType;
                    if (!TypeHelper.TypesAreEquivalent(ct, this.IDisposable)) continue;
                }
                else
                {
                    continue;
                }

				var resourceUse = new ResourceUseStatement()
				{
					Locations = tryFinally.Locations,
                    ResourceAcquisitions = resourceAcquisition,
					Body = tryFinally.TryBody
				};

				statements[i] = resourceUse;
				statements.RemoveAt(i - 2);
				i--;
			}

			base.TraverseChildren(block);
		}
Example #4
0
 /// <summary>
 /// Visits the specified resource use statement.
 /// </summary>
 /// <param name="resourceUseStatement">The resource use statement.</param>
 /// <returns></returns>
 public virtual IStatement Visit(ResourceUseStatement resourceUseStatement)
 {
     resourceUseStatement.ResourceAcquisitions = Visit(resourceUseStatement.ResourceAcquisitions);
       resourceUseStatement.Body = Visit(resourceUseStatement.Body);
       return resourceUseStatement;
 }
Example #5
0
 /// <summary>
 /// Rewrites the children of the given resource usage statement.
 /// </summary>
 public virtual void RewriteChildren(ResourceUseStatement resourceUseStatement)
 {
     this.RewriteChildren((Statement)resourceUseStatement);
       resourceUseStatement.ResourceAcquisitions = this.Rewrite(resourceUseStatement.ResourceAcquisitions);
       resourceUseStatement.Body = this.Rewrite(resourceUseStatement.Body);
 }
Example #6
0
 /// <summary>
 /// Visits the specified resource use statement.
 /// </summary>
 /// <param name="resourceUseStatement">The resource use statement.</param>
 public override void Visit(IResourceUseStatement resourceUseStatement)
 {
     ResourceUseStatement mutableResourceUseStatement = resourceUseStatement as ResourceUseStatement;
     if (alwaysMakeACopy || mutableResourceUseStatement == null) mutableResourceUseStatement = new ResourceUseStatement(resourceUseStatement);
     this.resultStatement = this.myCodeMutator.Visit(mutableResourceUseStatement);
 }