internal static void GetConstructors(Type type, out ConstructorInfo defCtor, out ConstructorInfo singleOneArgCtor)
{
defCtor = null;
int oneArgCtorCount = 0;
ConstructorInfo oneArgCtor = null;
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
// HACK we have a special rule to make some additional custom attributes from mscorlib usable:
// Attributes that have two constructors, one an enum and another one taking a byte, short or int,
// we only expose the enum constructor.
if (constructors.Length == 2 && type.Assembly == Types.Object.Assembly)
{
ParameterInfo[] p0 = constructors[0].GetParameters();
ParameterInfo[] p1 = constructors[1].GetParameters();
if (p0.Length == 1 && p1.Length == 1)
{
Type t0 = p0[0].ParameterType;
Type t1 = p1[0].ParameterType;
bool swapped = false;
if (t1.IsEnum)
{
Type tmp = t0;
t0 = t1;
t1 = tmp;
swapped = true;
}
if (t0.IsEnum && (t1 == Types.Byte || t1 == Types.Int16 || t1 == Types.Int32))
{
if (swapped)
{
singleOneArgCtor = constructors[1];
}
else
{
singleOneArgCtor = constructors[0];
}
return;
}
}
}
if (type.Assembly == Types.Object.Assembly)
{
if (type.FullName == "System.Runtime.CompilerServices.MethodImplAttribute")
{
foreach (ConstructorInfo ci in constructors)
{
ParameterInfo[] p = ci.GetParameters();
if (p.Length == 1 && p[0].ParameterType.IsEnum)
{
singleOneArgCtor = ci;
return;
}
}
}
}
foreach (ConstructorInfo ci in constructors)
{
ParameterInfo[] args = ci.GetParameters();
if (args.Length == 0)
{
defCtor = ci;
}
else if (args.Length == 1)
{
if (IsSupportedType(args[0].ParameterType))
{
oneArgCtor = ci;
oneArgCtorCount++;
}
else
{
// set to two to make sure we don't see the oneArgCtor as viable
oneArgCtorCount = 2;
}
}
}
singleOneArgCtor = oneArgCtorCount == 1 ? oneArgCtor : null;
}