public override void TraverseChildren(IBlockStatement block) { base.TraverseChildren(block); Contract.Assume(block is BlockStatement); var decompiledBlock = (BlockStatement)block; var statements = decompiledBlock.Statements; for (int i = 0; i < statements.Count-1; i++) { //TODO: need to deal with patterns where the decl and the assignment are separated. var loclDecl = statements[i] as LocalDeclarationStatement; if (loclDecl == null) continue; var local = loclDecl.LocalVariable; if (local.Type.TypeCode != PrimitiveTypeCode.Boolean) continue; //if (this.sourceLocationProvider != null) { // bool isCompilerGenerated; // var sourceName = this.sourceLocationProvider.GetSourceNameFor(local, out isCompilerGenerated); // if (!isCompilerGenerated) continue; //} var tryFinallyStatement = statements[i+1] as TryCatchFinallyStatement; if (tryFinallyStatement == null) continue; if (tryFinallyStatement.FinallyBody == null || tryFinallyStatement.CatchClauses.Count > 0 || tryFinallyStatement.FaultBody != null) continue; ILocalDefinition monitorVar; var monitorObject = this.GetMonitor(tryFinallyStatement.TryBody, local, out monitorVar); if (monitorObject == null) continue; if (!this.FinallyBodyCallsMonitorExit(tryFinallyStatement.FinallyBody, local, monitorVar)) continue; this.numberOfAssignmentsToLocal[local]-=2; this.numberOfReferencesToLocal[local]-=2; this.numberOfAssignmentsToLocal[monitorVar]--; this.numberOfReferencesToLocal[monitorVar]--; var tryStatements = ((BlockStatement)tryFinallyStatement.TryBody).Statements; tryStatements.RemoveRange(0, 3); var body = new BlockStatement() { Statements = tryStatements }; var lockStatement = new LockStatement() { Guard = monitorObject, Body = body, Locations = tryFinallyStatement.Locations }; statements[i] = lockStatement; statements.RemoveAt(i+1); if (this.numberOfAssignmentsToLocal[monitorVar] == 0) { for (int j = 0; j < statements.Count; j++) { var ldecl = statements[j] as LocalDeclarationStatement; if (ldecl == null) continue; if (ldecl.LocalVariable != monitorVar) continue; statements.RemoveAt(j); break; } } } }
/// <summary> /// Visits the specified lock statement. /// </summary> /// <param name="lockStatement">The lock statement.</param> /// <returns></returns> protected virtual IStatement DeepCopy(LockStatement lockStatement) { lockStatement.Guard = Substitute(lockStatement.Guard); lockStatement.Body = Substitute(lockStatement.Body); return lockStatement; }
/// <summary> /// Visits the specified lock statement. /// </summary> /// <param name="lockStatement">The lock statement.</param> public override void Visit(ILockStatement lockStatement) { LockStatement mutableLockStatement = new LockStatement(lockStatement); this.resultStatement = this.myCodeCopier.DeepCopy(mutableLockStatement); }
/// <summary> /// Visits the specified lock statement. /// </summary> /// <param name="lockStatement">The lock statement.</param> /// <returns></returns> public virtual IStatement Visit(LockStatement lockStatement) { lockStatement.Guard = Visit(lockStatement.Guard); lockStatement.Body = Visit(lockStatement.Body); return lockStatement; }
/// <summary> /// Rewrites the children of the given lock statement. /// </summary> public virtual void RewriteChildren(LockStatement lockStatement) { this.RewriteChildren((Statement)lockStatement); lockStatement.Guard = this.Rewrite(lockStatement.Guard); lockStatement.Body = this.Rewrite(lockStatement.Body); }
/// <summary> /// Visits the specified lock statement. /// </summary> /// <param name="lockStatement">The lock statement.</param> public override void Visit(ILockStatement lockStatement) { LockStatement mutableLockStatement = lockStatement as LockStatement; if (alwaysMakeACopy || mutableLockStatement == null) mutableLockStatement = new LockStatement(lockStatement); this.resultStatement = this.myCodeMutator.Visit(mutableLockStatement); }