My question is really the same as this one \"Finding out what exceptions a method might throw in C#\". However, I would really like to know if anyone knows of a way to deter
This should not be extremely hard. You can get list of exceptions created by a method like this:
IEnumerable GetCreatedExceptions(MethodDefinition method)
{
return method.GetInstructions()
.Where(i => i.OpCode == OpCodes.Newobj)
.Select(i => ((MemberReference) i.Operand).DeclaringType)
.Where(tr => tr.Name.EndsWith("Exception"))
.Distinct();
}
Snippets use Lokad.Quality.dll from the Open Source Lokad Shared Libraries (which uses Mono.Cecil to do the heavy-lifting around code reflection). I actually put this code into one of the test cases in trunk.
Say, we have a class like this:
class ExceptionClass
{
public void Run()
{
InnerCall();
throw new NotSupportedException();
}
void InnerCall()
{
throw new NotImplementedException();
}
}
then in order to get all exceptions from just the Run method:
var codebase = new Codebase("Lokad.Quality.Test.dll");
var type = codebase.Find();
var method = type.GetMethods().First(md => md.Name == "Run");
var exceptions = GetCreatedExceptions(method)
.ToArray();
Assert.AreEqual(1, exceptions.Length);
Assert.AreEqual("NotSupportedException", exceptions[0].Name);
Now all that remains is to walk down the method call stack down to a certain depth. You can get a list of methods referenced by a method like this:
var references = method.GetReferencedMethods();
Now before being able to call GetCreatedExceptions upon any method down the stack we just need to actually look up into the codebase and resolve all MethodReference instances to MethodDefinition instances actually containing the byte code (with some caching to avoid scanning existing branches). That's the most time-consuming part of the code (since Codebase object does not implement any method lookups on top of Cecil), but that should be doable.