You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.142
Former-commit-id: 7467d4b717762eeaf652d77f1486dd11ffb1ff1f
This commit is contained in:
parent
e52655b4dc
commit
0abdbe5a7d
@@ -295,13 +295,219 @@ namespace System
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
static extern CustomAttributeData [] GetCustomAttributesDataInternal (ICustomAttributeProvider obj);
|
||||
|
||||
internal static IList<CustomAttributeData> GetCustomAttributesData (ICustomAttributeProvider obj)
|
||||
internal static IList<CustomAttributeData> GetCustomAttributesData (ICustomAttributeProvider obj, bool inherit = false)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException ("obj");
|
||||
throw new ArgumentNullException (nameof (obj));
|
||||
|
||||
CustomAttributeData [] attrs = GetCustomAttributesDataInternal (obj);
|
||||
return Array.AsReadOnly<CustomAttributeData> (attrs);
|
||||
if (!inherit)
|
||||
return GetCustomAttributesDataBase (obj, null, false);
|
||||
|
||||
return GetCustomAttributesData (obj, typeof (MonoCustomAttrs), inherit);
|
||||
}
|
||||
|
||||
internal static IList<CustomAttributeData> GetCustomAttributesData (ICustomAttributeProvider obj, Type attributeType, bool inherit)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException (nameof (obj));
|
||||
if (attributeType == null)
|
||||
throw new ArgumentNullException (nameof (attributeType));
|
||||
|
||||
if (attributeType == typeof (MonoCustomAttrs))
|
||||
attributeType = null;
|
||||
|
||||
const string Message = "Invalid custom attribute data format";
|
||||
IList<CustomAttributeData> r;
|
||||
IList<CustomAttributeData> res = GetCustomAttributesDataBase (obj, attributeType, false);
|
||||
// shortcut
|
||||
if (!inherit && res.Count == 1) {
|
||||
if (res [0] == null)
|
||||
throw new CustomAttributeFormatException (Message);
|
||||
if (attributeType != null) {
|
||||
if (attributeType.IsAssignableFrom (res [0].AttributeType))
|
||||
r = new CustomAttributeData[] { res [0] };
|
||||
else
|
||||
r = Array.Empty<CustomAttributeData> ();
|
||||
} else {
|
||||
r = new CustomAttributeData[] { res [0] };
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
if (inherit && GetBase (obj) == null)
|
||||
inherit = false;
|
||||
|
||||
// if AttributeType is sealed, and Inherited is set to false, then
|
||||
// there's no use in scanning base types
|
||||
if ((attributeType != null && attributeType.IsSealed) && inherit) {
|
||||
var usageAttribute = RetrieveAttributeUsage (attributeType);
|
||||
if (!usageAttribute.Inherited)
|
||||
inherit = false;
|
||||
}
|
||||
|
||||
var initialSize = Math.Max (res.Count, 16);
|
||||
List<CustomAttributeData> a = null;
|
||||
ICustomAttributeProvider btype = obj;
|
||||
|
||||
/* Non-inherit case */
|
||||
if (!inherit) {
|
||||
if (attributeType == null) {
|
||||
foreach (CustomAttributeData attrData in res) {
|
||||
if (attrData == null)
|
||||
throw new CustomAttributeFormatException (Message);
|
||||
}
|
||||
|
||||
var result = new CustomAttributeData [res.Count];
|
||||
res.CopyTo (result, 0);
|
||||
return result;
|
||||
} else {
|
||||
a = new List<CustomAttributeData> (initialSize);
|
||||
foreach (CustomAttributeData attrData in res) {
|
||||
if (attrData == null)
|
||||
throw new CustomAttributeFormatException (Message);
|
||||
if (!attributeType.IsAssignableFrom (attrData.AttributeType))
|
||||
continue;
|
||||
a.Add (attrData);
|
||||
}
|
||||
|
||||
return a.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Inherit case */
|
||||
var attributeInfos = new Dictionary<Type, AttributeInfo> (initialSize);
|
||||
int inheritanceLevel = 0;
|
||||
a = new List<CustomAttributeData> (initialSize);
|
||||
|
||||
do {
|
||||
foreach (CustomAttributeData attrData in res) {
|
||||
AttributeUsageAttribute usage;
|
||||
if (attrData == null)
|
||||
throw new CustomAttributeFormatException (Message);
|
||||
|
||||
Type attrType = attrData.AttributeType;
|
||||
if (attributeType != null) {
|
||||
if (!attributeType.IsAssignableFrom (attrType))
|
||||
continue;
|
||||
}
|
||||
|
||||
AttributeInfo firstAttribute;
|
||||
if (attributeInfos.TryGetValue (attrType, out firstAttribute))
|
||||
usage = firstAttribute.Usage;
|
||||
else
|
||||
usage = RetrieveAttributeUsage (attrType);
|
||||
|
||||
// The same as for CustomAttributes.
|
||||
//
|
||||
// Only add attribute to the list of attributes if
|
||||
// - we are on the first inheritance level, or the attribute can be inherited anyway
|
||||
// and (
|
||||
// - multiple attributes of the type are allowed
|
||||
// or (
|
||||
// - this is the first attribute we've discovered
|
||||
// or
|
||||
// - the attribute is on same inheritance level than the first
|
||||
// attribute that was discovered for this attribute type ))
|
||||
if ((inheritanceLevel == 0 || usage.Inherited) && (usage.AllowMultiple ||
|
||||
(firstAttribute == null || (firstAttribute != null
|
||||
&& firstAttribute.InheritanceLevel == inheritanceLevel))))
|
||||
a.Add(attrData);
|
||||
|
||||
if (firstAttribute == null)
|
||||
attributeInfos.Add (attrType, new AttributeInfo (usage, inheritanceLevel));
|
||||
}
|
||||
|
||||
if ((btype = GetBase (btype)) != null) {
|
||||
inheritanceLevel++;
|
||||
res = GetCustomAttributesDataBase (btype, attributeType, true);
|
||||
}
|
||||
} while (inherit && btype != null);
|
||||
|
||||
return a.ToArray ();
|
||||
}
|
||||
|
||||
internal static IList<CustomAttributeData> GetCustomAttributesDataBase (ICustomAttributeProvider obj, Type attributeType, bool inheritedOnly)
|
||||
{
|
||||
CustomAttributeData[] attrsData;
|
||||
if (IsUserCattrProvider (obj)) {
|
||||
//FIXME resolve this case if it makes sense. Assign empty array for now.
|
||||
//attrsData = obj.GetCustomAttributesData(attributeType, true);
|
||||
attrsData = Array.Empty<CustomAttributeData> ();
|
||||
} else
|
||||
attrsData = GetCustomAttributesDataInternal (obj);
|
||||
|
||||
//
|
||||
// All pseudo custom attributes are Inherited = false hence we can avoid
|
||||
// building attributes data array which would be discarded by inherited checks
|
||||
//
|
||||
if (!inheritedOnly) {
|
||||
CustomAttributeData[] pseudoAttrsData = GetPseudoCustomAttributesData (obj, attributeType);
|
||||
if (pseudoAttrsData != null) {
|
||||
if (attrsData.Length == 0)
|
||||
return Array.AsReadOnly (pseudoAttrsData);
|
||||
CustomAttributeData[] res = new CustomAttributeData [attrsData.Length + pseudoAttrsData.Length];
|
||||
Array.Copy (attrsData, res, attrsData.Length);
|
||||
Array.Copy (pseudoAttrsData, 0, res, attrsData.Length, pseudoAttrsData.Length);
|
||||
return Array.AsReadOnly (res);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.AsReadOnly (attrsData);
|
||||
}
|
||||
|
||||
internal static CustomAttributeData[] GetPseudoCustomAttributesData (ICustomAttributeProvider obj, Type attributeType)
|
||||
{
|
||||
CustomAttributeData[] pseudoAttrsData = null;
|
||||
|
||||
/* FIXME: Add other types */
|
||||
if (obj is MonoMethod)
|
||||
pseudoAttrsData = ((MonoMethod)obj).GetPseudoCustomAttributesData ();
|
||||
else if (obj is FieldInfo)
|
||||
pseudoAttrsData = ((FieldInfo)obj).GetPseudoCustomAttributesData ();
|
||||
else if (obj is ParameterInfo)
|
||||
pseudoAttrsData = ((ParameterInfo)obj).GetPseudoCustomAttributesData ();
|
||||
else if (obj is Type)
|
||||
pseudoAttrsData = GetPseudoCustomAttributesData (((Type)obj));
|
||||
|
||||
if ((attributeType != null) && (pseudoAttrsData != null)) {
|
||||
for (int i = 0; i < pseudoAttrsData.Length; ++i) {
|
||||
if (attributeType.IsAssignableFrom (pseudoAttrsData [i].AttributeType)) {
|
||||
if (pseudoAttrsData.Length == 1)
|
||||
return pseudoAttrsData;
|
||||
else
|
||||
return new CustomAttributeData[] { pseudoAttrsData[i] };
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<CustomAttributeData> ();
|
||||
}
|
||||
|
||||
return pseudoAttrsData;
|
||||
}
|
||||
|
||||
static CustomAttributeData[] GetPseudoCustomAttributesData (Type type)
|
||||
{
|
||||
int count = 0;
|
||||
var Attributes = type.Attributes;
|
||||
|
||||
/* IsSerializable returns true for delegates/enums as well */
|
||||
if ((Attributes & TypeAttributes.Serializable) != 0)
|
||||
count++;
|
||||
if ((Attributes & TypeAttributes.Import) != 0)
|
||||
count++;
|
||||
|
||||
if (count == 0)
|
||||
return null;
|
||||
CustomAttributeData[] attrsData = new CustomAttributeData [count];
|
||||
count = 0;
|
||||
|
||||
if ((Attributes & TypeAttributes.Serializable) != 0)
|
||||
attrsData [count++] = new CustomAttributeData ((typeof (SerializableAttribute)).GetConstructor (Type.EmptyTypes));
|
||||
if ((Attributes & TypeAttributes.Import) != 0)
|
||||
attrsData [count++] = new CustomAttributeData ((typeof (ComImportAttribute)).GetConstructor (Type.EmptyTypes));
|
||||
|
||||
return attrsData;
|
||||
}
|
||||
|
||||
internal static bool IsDefined (ICustomAttributeProvider obj, Type attributeType, bool inherit)
|
||||
|
||||
Reference in New Issue
Block a user