Add support for returning pseudo-custom attributes based on missing types.

This commit is contained in:
jfrijters 2011-03-06 08:16:41 +00:00
Родитель f20cd45070
Коммит 68816bf709
6 изменённых файлов: 76 добавлений и 20 удалений

Просмотреть файл

@ -46,7 +46,7 @@ namespace IKVM.Reflection
this.index = index;
}
// this is for pseudo-custom attributes
// this is for pseudo-custom attributes and CustomAttributeBuilder.ToData()
internal CustomAttributeData(Module module, ConstructorInfo constructor, object[] args, List<CustomAttributeNamedArgument> namedArguments)
{
this.module = module;
@ -148,11 +148,11 @@ namespace IKVM.Reflection
ConstructorInfo constructor;
if (type == u.System_Security_Permissions_HostProtectionAttribute && action == (int)System.Security.Permissions.SecurityAction.LinkDemand)
{
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
constructor = type.GetPseudoCustomAttributeConstructor();
}
else
{
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { u.System_Security_Permissions_SecurityAction }, null);
constructor = type.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction);
}
// LAMESPEC there is an additional length here (probably of the named argument list)
ByteReader slice = br.Slice(br.ReadCompressedInt());

Просмотреть файл

@ -1,5 +1,5 @@
/*
Copyright (C) 2008, 2010 Jeroen Frijters
Copyright (C) 2008-2011 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -112,7 +112,31 @@ namespace IKVM.Reflection
blob.ReadCompressedInt();
marshalType = ReadString(blob);
marshalCookie = ReadString(blob);
marshalTypeRef = module.Assembly.GetType(marshalType) ?? module.universe.GetType(marshalType);
// we have to use a custom type lookup scheme here, because we want to use FindType to avoid a MissingAssemblyException
TypeNameParser parser = TypeNameParser.Parse(marshalType, false);
if (!parser.Error)
{
TypeName n = TypeName.Split(parser.FirstNamePart);
Type type = null;
if (parser.AssemblyName != null)
{
Assembly asm = module.Assembly.universe.Load(parser.AssemblyName, module.Assembly, false);
if (asm != null)
{
type = asm.FindType(n);
}
}
else
{
type = module.Assembly.FindType(n)
?? module.universe.Mscorlib.FindType(n);
}
if (type != null)
{
marshalTypeRef = parser.Expand(type, module.Assembly, false, marshalType);
}
}
}
Type typeofMarshalAs = module.universe.System_Runtime_InteropServices_MarshalAsAttribute;
@ -122,47 +146,57 @@ namespace IKVM.Reflection
List<CustomAttributeNamedArgument> named = new List<CustomAttributeNamedArgument>();
if (arraySubType != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("ArraySubType"), new CustomAttributeTypedArgument(typeofUnmanagedType, arraySubType.Value)));
AddNamedArgument(named, typeofMarshalAs, "ArraySubType", typeofUnmanagedType, arraySubType.Value);
}
if (sizeParamIndex != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SizeParamIndex"), new CustomAttributeTypedArgument(module.universe.System_Int16, sizeParamIndex.Value)));
AddNamedArgument(named, typeofMarshalAs, "SizeParamIndex", module.universe.System_Int16, sizeParamIndex.Value);
}
if (sizeConst != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SizeConst"), new CustomAttributeTypedArgument(module.universe.System_Int32, sizeConst.Value)));
AddNamedArgument(named, typeofMarshalAs, "SizeConst", module.universe.System_Int32, sizeConst.Value);
}
if (safeArraySubType != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SafeArraySubType"), new CustomAttributeTypedArgument(typeofVarEnum, safeArraySubType.Value)));
AddNamedArgument(named, typeofMarshalAs, "SafeArraySubType", typeofVarEnum, safeArraySubType.Value);
}
if (safeArrayUserDefinedSubType != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("SafeArrayUserDefinedSubType"), new CustomAttributeTypedArgument(typeofType, safeArrayUserDefinedSubType)));
AddNamedArgument(named, typeofMarshalAs, "SafeArrayUserDefinedSubType", typeofType, safeArrayUserDefinedSubType);
}
if (iidParameterIndex != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("IidParameterIndex"), new CustomAttributeTypedArgument(module.universe.System_Int32, iidParameterIndex.Value)));
AddNamedArgument(named, typeofMarshalAs, "IidParameterIndex", module.universe.System_Int32, iidParameterIndex.Value);
}
if (marshalType != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalType"), new CustomAttributeTypedArgument(module.universe.System_String, marshalType)));
AddNamedArgument(named, typeofMarshalAs, "MarshalType", module.universe.System_String, marshalType);
}
if (marshalTypeRef != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalTypeRef"), new CustomAttributeTypedArgument(module.universe.System_Type, marshalTypeRef)));
AddNamedArgument(named, typeofMarshalAs, "MarshalTypeRef", module.universe.System_Type, marshalTypeRef);
}
if (marshalCookie != null)
{
named.Add(new CustomAttributeNamedArgument(typeofMarshalAs.GetField("MarshalCookie"), new CustomAttributeTypedArgument(module.universe.System_String, marshalCookie)));
AddNamedArgument(named, typeofMarshalAs, "MarshalCookie", module.universe.System_String, marshalCookie);
}
ConstructorInfo constructor = typeofMarshalAs.GetConstructor(new Type[] { typeofUnmanagedType });
ConstructorInfo constructor = typeofMarshalAs.GetPseudoCustomAttributeConstructor(typeofUnmanagedType);
return new CustomAttributeData(module, constructor, new object[] { unmanagedType }, named);
}
}
throw new BadImageFormatException();
}
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type attributeType, string fieldName, Type valueType, object value)
{
// some fields are not available on the .NET Compact Framework version of MarshalAsAttribute
FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, null, null));
if (field != null)
{
list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value)));
}
}
internal static void SetMarshalAsAttribute(ModuleBuilder module, int token, CustomAttributeBuilder attribute)
{
attribute = attribute.DecodeBlob(module.Assembly);

Просмотреть файл

@ -128,7 +128,7 @@ namespace IKVM.Reflection.Reader
{
if (module.FieldLayout.records[i].Field == rid)
{
ConstructorInfo constructor = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute.GetConstructor(new Type[] { module.universe.System_Int32 });
ConstructorInfo constructor = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute.GetPseudoCustomAttributeConstructor(module.universe.System_Int32);
list.Add(new CustomAttributeData(module, constructor,
new object[] { module.FieldLayout.records[i].Offset },
null));

Просмотреть файл

@ -266,7 +266,7 @@ namespace IKVM.Reflection.Reader
const short CharMapErrorOff = 0x2000;
Type type = module.universe.System_Runtime_InteropServices_DllImportAttribute;
ConstructorInfo constructor = type.GetConstructor(new Type[] { module.universe.System_String });
ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_String);
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>();
int flags = module.ImplMap.records[i].MappingFlags;
string entryPoint = module.GetString(module.ImplMap.records[i].ImportName);
@ -312,10 +312,10 @@ namespace IKVM.Reflection.Reader
AddNamedArgument(list, type, "ExactSpelling", flags, NoMangle);
AddNamedArgument(list, type, "SetLastError", flags, SupportsLastError);
AddNamedArgument(list, type, "PreserveSig", (int)GetMethodImplementationFlags(), (int)MethodImplAttributes.PreserveSig);
AddNamedArgument(list, type, "CallingConvention", (int)callingConvention);
AddNamedArgument(list, type, "CallingConvention", module.universe.System_Runtime_InteropServices_CallingConvention, (int)callingConvention);
if (charSet.HasValue)
{
AddNamedArgument(list, type, "CharSet", (int)charSet.Value);
AddNamedArgument(list, type, "CharSet", module.universe.System_Runtime_InteropServices_CharSet, (int)charSet.Value);
}
if ((flags & (BestFitOn | BestFitOff)) != 0)
{
@ -349,7 +349,7 @@ namespace IKVM.Reflection.Reader
private static void AddNamedArgument(List<CustomAttributeNamedArgument> list, Type attributeType, string fieldName, Type valueType, object value)
{
// some fields are not available on the .NET Compact Framework version of DllImportAttribute
FieldInfo field = attributeType.GetField(fieldName);
FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, null, null));
if (field != null)
{
list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value)));

Просмотреть файл

@ -1636,6 +1636,16 @@ namespace IKVM.Reflection
typeFlags |= TypeFlags.ValueType;
return this;
}
internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
{
Universe u = this.Module.universe;
MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, null, CallingConventions.Standard | CallingConventions.HasThis, 0);
MethodBase mb =
FindMethod(".ctor", methodSig) ??
u.GetMissingMethodOrThrow(this, ".ctor", methodSig);
return (ConstructorInfo)mb;
}
}
abstract class ElementHolderType : Type

Просмотреть файл

@ -125,6 +125,8 @@ namespace IKVM.Reflection
private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
private Type typeof_System_Runtime_InteropServices_CallingConvention;
private Type typeof_System_Runtime_InteropServices_CharSet;
private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
@ -371,6 +373,16 @@ namespace IKVM.Reflection
get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
}
internal Type System_Runtime_InteropServices_CallingConvention
{
get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
}
internal Type System_Runtime_InteropServices_CharSet
{
get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
}
internal Type System_Runtime_InteropServices_ComImportAttribute
{
get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }