private static bool FilterForBox(ParsedMethodBody methodBody) { for (int i = 0; i < methodBody.Instructions.Count; ++i) { var instruction = methodBody.Instructions[i]; if (instruction.OpCode == OpCodes.Box) { if (instruction.Operand.OfType <Type>().Match(t => t.IsGenericParameter, () => false) && i < methodBody.Instructions.Count - 1) { var nextOpCode = methodBody.Instructions[i + 1].OpCode; if (nextOpCode == OpCodes.Brtrue || nextOpCode == OpCodes.Brtrue_S || nextOpCode == OpCodes.Brfalse || nextOpCode == OpCodes.Brfalse_S) { continue; } if (i >= 2 && nextOpCode == OpCodes.Ceq && methodBody.Instructions[i - 2].OpCode == OpCodes.Ldnull) { continue; } if (i < methodBody.Instructions.Count - 2 && nextOpCode == OpCodes.Ldnull && methodBody.Instructions[i + 2].OpCode == OpCodes.Ceq) { continue; } } return(true); } } return(false); }
private static bool FilterForNewObject(ParsedMethodBody methodBody) { var isAsyncMethod = methodBody.Parent.Value().Match(c => false, m => m.GetCustomAttribute <AsyncStateMachineAttribute>() != null); foreach (var instruction in methodBody.Instructions.Skip(isAsyncMethod ? 1 : 0).Where(i => i.OpCode == OpCodes.Newobj)) { if (instruction.Operand.OfType <ConstructorInfo>().Match(constructor => !constructor.ReflectedType.IsValueType && !typeof(Exception).IsAssignableFrom(constructor.ReflectedType), () => false)) { return(true); } } return(false); }