public override Statement Clone() { BlockStatement clonnedTry = @try != null ? @try.Clone() as BlockStatement : null; BlockStatement clonnedfault = fault != null ? fault.Clone() as BlockStatement : null; FinallyClause clonnedFinally = @finally != null ? @finally.Clone() as FinallyClause : null; TryStatement result = new TryStatement(clonnedTry, clonnedfault, clonnedFinally); foreach (CatchClause @catch in this.catchClauses) { result.AddToCatchClauses((CatchClause)@catch.Clone()); } CopyParentAndLabel(result); return result; }
public override void VisitTryStatement(TryStatement node) { if (!foundEnumeratorAssignment) { insideTry = false; base.VisitTryStatement(node); return; } if (CanContainForeach(node)) { insideTry = true; theTry = node; base.VisitTryStatement(node); } insideTry = false; }
public override Statement CloneStatementOnly() { BlockStatement clonnedTry = @try != null? @try.CloneStatementOnly() as BlockStatement : null; BlockStatement clonnedfault = fault != null?fault.CloneStatementOnly() as BlockStatement : null; FinallyClause clonnedFinally = @finally != null? @finally.CloneStatementOnly() as FinallyClause : null; TryStatement result = new TryStatement(clonnedTry, clonnedfault, clonnedFinally); foreach (CatchClause @catch in this.catchClauses) { result.AddToCatchClauses((CatchClause)@catch.CloneStatementOnly()); } CopyParentAndLabel(result); return(result); }
public override void VisitTryStatement(TryStatement node) { WriteKeyword(KeyWordWriter.Try); WriteLine(); Visit(node.Try); //if (node.CatchClauses.Count != 0) //{ // Visit(node.CatchClauses); //} foreach (ICodeNode @catch in node.CatchClauses) { Visit(@catch); } if (node.Finally != null) { WriteKeyword(KeyWordWriter.Finally); WriteLine(); Visit(node.Finally); } WriteSpecialEndBlock(KeyWordWriter.Try); }
private bool CanContainForeach(TryStatement tryStatement) { if ((tryStatement.CatchClauses.Count == 0) && (tryStatement.Try.Statements.Count == 1) && (tryStatement.Finally != null) && ((tryStatement.Finally.Body.Statements.Count == 1) || (tryStatement.Finally.Body.Statements.Count == 2))) { return IsValidFinally(tryStatement.Finally.Body); } return false; }
public override void VisitTryStatement(TryStatement node) { WriteKeyword(KeyWordWriter.Try); WriteLine(); Visit(node.Try); if (node.CatchClauses.Count != 0) { WriteLine(); Visit(node.CatchClauses); } if (node.Finally != null) { WriteLine(); WriteKeyword(KeyWordWriter.Finally); WriteLine(); Visit(node.Finally); } WriteSpecialEndBlock(KeyWordWriter.Try); }
private bool Match(StatementCollection statements, int statementIndex) { PrepareMatcher(statements, statementIndex); Statement currentStatement = statements[statementIndex]; if (currentStatement.CodeNodeType == CodeNodeType.TryStatement) { @try = currentStatement as TryStatement; if (!DetermineWithFlagLockTypeVersion(@try)) { return false; } if (this.lockType == LockType.WithFlagV2) { if (statementIndex - 2 < 0 || !CheckLockVariableAssignmentExpression(statements[statementIndex - 2])) { return false; } } } else if (currentStatement.CodeNodeType == CodeNodeType.ExpressionStatement && CheckTheMethodInvocation((currentStatement as ExpressionStatement).Expression as MethodInvocationExpression, "Enter")) { MethodReference methodReference = ((currentStatement as ExpressionStatement).Expression as MethodInvocationExpression).MethodExpression.Method; if(methodReference.Parameters.Count != 1) { return false; } if (statementIndex + 1 >= statements.Count || statementIndex - 2 < 0) { return false; } @try = statements[statementIndex + 1] as TryStatement; lockType = LockType.Simple; if(!CheckTheAssignExpressions(statements[statementIndex - 2], statements[statementIndex - 1])) { return false; } lockingInstructions.AddRange(currentStatement.UnderlyingSameMethodInstructions); } if (@try == null) return false; if (!IsLockStatement(@try)) return false; this.body = @try.Try; return true; }
private void PrepareMatcher(StatementCollection statements, int statementIndex) { this.statements = statements; this.statementIndex = statementIndex; @try = null; this.body = null; this.@lock = null; this.lockObjectExpression = null; this.theLocalVariable = null; this.thePhiVariable = null; this.lockingInstructions.Clear(); }
public override ICodeNode VisitTryStatement(TryStatement node) { if (node.Finally != null && node.Finally.Body.Statements.Count == 1 && node.Finally.Body.Statements[0].CodeNodeType == CodeNodeType.ExpressionStatement) { ExpressionStatement theExpressionStatement = node.Finally.Body.Statements[0] as ExpressionStatement; if (theExpressionStatement.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression) { MethodReferenceExpression theMethodReferenceExpression = (theExpressionStatement.Expression as MethodInvocationExpression).MethodExpression; if (theMethodReferenceExpression != null && theMethodReferenceExpression.Method != null && theMethodReferenceExpression.Method.DeclaringType != null) { TypeDefinition theDeclaringTypeDef = theMethodReferenceExpression.Method.DeclaringType.Resolve(); if (theDeclaringTypeDef == yieldDeclaringType) { node.Finally = new FinallyClause(theMethodReferenceExpression.Method.Resolve().Body.Decompile(Language), node.Finally.UnderlyingSameMethodInstructions); } } } } return base.VisitTryStatement(node); }
private bool DetermineWithFlagLockTypeVersion(TryStatement @try) { if (@try == null || @try.Try == null || @try.Try.Statements.Count == 0) { return false; } if (@try.Try.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } ExpressionStatement firstStatement = @try.Try.Statements[0] as ExpressionStatement; if (firstStatement.Expression.CodeNodeType == CodeNodeType.BinaryExpression) { lockType = LockType.WithFlagV1; } else if (firstStatement.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression) { lockType = LockType.WithFlagV2; } else { return false; } return true; }
private bool IsTryFinallyStatement(TryStatement @try) { return (@try.CatchClauses.Count == 0) && (@try.Finally != null); }
private void PrepareUsingBlock(BinaryExpression binaryExpression, TryStatement @try, ExpressionStatement expressionStatement) { this.expression = binaryExpression.Left; for (int i = 0; i < @try.Try.Statements.Count; i++) { this.blockStatement.AddStatement(@try.Try.Statements[i]); } if (expressionStatement != null) { VisitAssignExpression(expressionStatement); } }
private bool CheckStandardUsingBlock(IfStatement ifStatement, TryStatement @try, ExpressionStatement expressionStatement) { if (ifStatement.Condition.CodeNodeType != CodeNodeType.BinaryExpression) return false; var binaryExpression = (BinaryExpression) ifStatement.Condition; var methodReference = GetDisposeMethodReference(ifStatement, binaryExpression); if (methodReference == null) { return false; } Expression methodTarget = methodReference.Target; if (methodTarget != null && methodTarget.CodeNodeType == CodeNodeType.CastExpression && (methodTarget as CastExpression).TargetType.FullName == "System.IDisposable") { methodTarget = (methodTarget as CastExpression).Expression; } if (binaryExpression.Left.CheckInnerReferenceExpressions(methodTarget)) { PrepareUsingBlock(binaryExpression, @try, expressionStatement); return true; } return false; }
internal bool Match() { ExpressionStatement expressionStatement = null; theTry = null; if (statement.CodeNodeType == CodeNodeType.TryStatement) { theTry = statement as TryStatement; } else if (nextStatement.CodeNodeType == CodeNodeType.TryStatement) { theTry = nextStatement as TryStatement; expressionStatement = statement as ExpressionStatement; hasExpression = true; } if (theTry == null) return false; if (!IsTryFinallyStatement(theTry)) return false; if (theTry.Finally.Body.Statements.Count != 1) return false; var firstFinallyStatement = theTry.Finally.Body.Statements[0]; if (firstFinallyStatement.CodeNodeType != CodeNodeType.IfStatement) return false; var ifStatement = (IfStatement)firstFinallyStatement; if (!CheckStandardUsingBlock(ifStatement, theTry, expressionStatement)) { return false; } FixExpression(); return true; }
public virtual void VisitTryStatement(TryStatement node) { Visit(node.Try); Visit(node.CatchClauses); Visit(node.Fault); Visit(node.Finally); }
private void ClearState() { insideTry = false; foundEnumeratorAssignment = false; foundWhile = false; foreachCollection = null; foreachVariable = null; foreachVariableInstructions.Clear(); foreachCollectionInstructions.Clear(); foreachBody = new BlockStatement(); theEnumerator = null; theTry = null; @foreach = null; enumeratorAssignmentStatement = null; foreachVariableType = null; isEnumeratorUsedInsideForEach = false; foreachConditionInstructions = null; }
public override void VisitTryStatement(TryStatement node) { }
bool IsLockStatement(TryStatement @try) { if(@try == null) { return false; } //If the lock is with a flag and it's V1 then the statements in the try should be at least 3: 2 assignments and the method invocation // If the lock is with a flag and it's V2 the statement in the try should be at least 1: the method invocation. bool result = (this.lockType == LockType.WithFlagV1 && @try.Try.Statements.Count > 2) || this.lockType == LockType.Simple || (this.lockType == LockType.WithFlagV2 && @try.Try.Statements.Count > 0); result &= @try.CatchClauses.Count == 0 && @try.Finally != null; if (result) { if(lockType == LockType.WithFlagV1 || lockType == LockType.WithFlagV2) { int enterMethodInvocationIndex; if (lockType == LockType.WithFlagV1) { result &= CheckTheAssignExpressions(@try.Try.Statements[0], @try.Try.Statements[1]); enterMethodInvocationIndex = 2; } else // lockType == LockType.WithFlagV2 { enterMethodInvocationIndex = 0; } //The index 3 is because of the generated PhiVariable, if this variable is cleand before this step the matching will fail result &= @try.Try.Statements[enterMethodInvocationIndex].CodeNodeType == CodeNodeType.ExpressionStatement; if (result) { ExpressionStatement expressionStmt = @try.Try.Statements[enterMethodInvocationIndex] as ExpressionStatement; result &= expressionStmt.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression; MethodInvocationExpression methodInvocation = expressionStmt.Expression as MethodInvocationExpression; result &= CheckTheMethodInvocation(methodInvocation, "Enter") && methodInvocation.MethodExpression.Method.Parameters.Count == 2; if (result) { lockingInstructions.AddRange(methodInvocation.UnderlyingSameMethodInstructions); this.theFlagVariable = GetTheFlagVariable(methodInvocation); } } } result &= CheckTheFinallyClause(@try.Finally.Body); } return result; }