public override void OnExceptionHandler(ExceptionHandler node)
{
bool untypedException = (node.Flags & ExceptionHandlerFlags.Untyped) == ExceptionHandlerFlags.Untyped;
bool anonymousException = (node.Flags & ExceptionHandlerFlags.Anonymous) == ExceptionHandlerFlags.Anonymous;
bool filterHandler = (node.Flags & ExceptionHandlerFlags.Filter) == ExceptionHandlerFlags.Filter;
if (untypedException)
{
// If untyped, set the handler to except System.Exception
node.Declaration.Type = CodeBuilder.CreateTypeReference(TypeSystemServices.ExceptionType);
}
else
{
Visit(node.Declaration.Type);
// Require typed exception handlers to except only
// exceptions at least as derived as System.Exception
if(!TypeSystemServices.IsValidException(GetType(node.Declaration.Type)))
{
Errors.Add(CompilerErrorFactory.InvalidExceptArgument(node.Declaration.Type, GetType(node.Declaration.Type)));
}
}
if(!anonymousException)
{
// If the exception is not anonymous, place it into a
// local variable and enter a new namespace
DeclareLocal(node.Declaration, true);
EnterNamespace(new DeclarationsNamespace(CurrentNamespace, node.Declaration));
}
try
{
// The filter handler has access to the exception if it
// is not anonymous, so it is protected to ensure
// any exception in the filter condition (a big no-no)
// will still clean up the namespace if necessary
if (filterHandler)
{
Visit(node.FilterCondition);
}
Visit(node.Block);
}
finally
{
// Clean up the namespace if necessary
if(!anonymousException)
{
LeaveNamespace();
}
}
}