internal unsafe static bool FilterCustomAttributeRecord(
CustomAttributeRecord caRecord, MetadataImport scope, ref Assembly lastAptcaOkAssembly,
Module decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, bool mustBeInheritable,
object[] attributes, IList derivedAttributes,
out RuntimeType attributeType, out RuntimeMethodHandle ctor, out bool ctorHasParameters, out bool isVarArg)
{
ctor = new RuntimeMethodHandle();
attributeType = null;
ctorHasParameters = false;
isVarArg = false;
IntPtr blobStart = caRecord.blob.Signature;
IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
// Resolve attribute type from ctor parent token found in decorated decoratedModule scope
attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType;
// Test attribute type against user provided attribute type filter
if (!(attributeFilterType.IsAssignableFrom(attributeType)))
return false;
if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes))
return false;
// APTCA checks
if (attributeType.Assembly != lastAptcaOkAssembly &&
!attributeType.Assembly.AptcaCheck(decoratedModule.Assembly))
return false;
// Cache last successful APTCA check (optimization)
lastAptcaOkAssembly = decoratedModule.Assembly;
// Resolve the attribute ctor
ConstArray ctorSig = scope.GetMethodSignature(caRecord.tkCtor);
isVarArg = (ctorSig[0] & 0x05) != 0;
ctorHasParameters = ctorSig[1] != 0;
if (ctorHasParameters)
{
// Resolve method ctor token found in decorated decoratedModule scope
ctor = decoratedModule.ModuleHandle.ResolveMethodHandle(caRecord.tkCtor);
}
else
{
// Resolve method ctor token from decorated decoratedModule scope
ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor();
if (ctor.IsNullHandle() && !attributeType.IsValueType)
throw new MissingMethodException(".ctor");
}
// Visibility checks
if (ctor.IsNullHandle())
{
if (!attributeType.IsVisible && !attributeType.TypeHandle.IsVisibleFromModule(decoratedModule.ModuleHandle))
return false;
return true;
}
if (ctor.IsVisibleFromModule(decoratedModule))
return true;
MetadataToken tkParent = new MetadataToken();
if (decoratedToken.IsParamDef)
{
tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
tkParent = new MetadataToken(scope.GetParentToken(tkParent));
}
else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef)
{
tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
}
else if (decoratedToken.IsTypeDef)
{
tkParent = decoratedToken;
}
if (tkParent.IsTypeDef)
return ctor.IsVisibleFromType(decoratedModule.ModuleHandle.ResolveTypeHandle(tkParent));
return false;
}
#endregion