Skip to content

Commit

Permalink
Support inherit parameter in TypeDef.GetCustomAttributes
Browse files Browse the repository at this point in the history
Issue: #121
  • Loading branch information
MSDN-WhiteKnight committed Jul 2, 2023
1 parent fdec3f6 commit 1ae0854
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CilTools.Metadata/Internal/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,5 +562,10 @@ public static bool IsCoreAssembly(Assembly ass)
return StrEquals(name, "mscorlib") || StrEquals(name, "netstandard") || StrEquals(name, "System.Runtime")
|| StrEquals(name, "System.Private.CoreLib");
}

public static bool IsCoreType(Type t, string fullName)
{
return StrEquals(t.FullName, fullName) && IsCoreAssembly(t.Assembly);
}
}
}
26 changes: 25 additions & 1 deletion CilTools.Metadata/TypeDef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,32 @@ public override object[] GetCustomAttributes(bool inherit)
//this is needed to emulate GetCustomAttributesData for .NET Framework 3.5

CustomAttributeHandleCollection coll = this.type.GetCustomAttributes();
object[] declared = Utils.ReadCustomAttributes(coll, this, this.assembly);

if (!inherit) return declared;

//merge inherited and declared
List<object> ret = new List<object>(coll.Count);

for (int i = 0; i < declared.Length; i++)
{
ret.Add(declared[i]);
}

Type bt = this.BaseType;

if (bt != null && !Utils.IsCoreType(bt, "System.Object"))
{
object[] inherited = this.BaseType.GetCustomAttributes(inherit);
ret.Capacity += inherited.Length;

for (int i = 0; i < inherited.Length; i++)
{
ret.Add(inherited[i]);
}
}

return Utils.ReadCustomAttributes(coll, this, this.assembly);
return ret.ToArray();
}

public override bool IsDefined(Type attributeType, bool inherit)
Expand Down
36 changes: 35 additions & 1 deletion tests/CilTools.Metadata.Tests/TypeDefTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CilTools.Reflection;
using CilTools.Syntax;
using CilTools.Tests.Common;
using CilTools.Tests.Common.Attributes;
using CilTools.Tests.Common.TestData;
using CilTools.Tests.Common.TextUtils;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CilTools.Metadata.Tests
{
Expand Down Expand Up @@ -53,6 +55,12 @@ public class TypeWithStaticCtor
static TypeWithStaticCtor() { }
}

[My(444)]
public class CustomAttrsTestType { }

[Category("Unicorns")]
public class AttrInheritanceTestType : CustomAttrsTestType { }

[TestClass]
public class TypeDefTests
{
Expand Down Expand Up @@ -988,5 +996,31 @@ public void Test_IsEnum_Negative(Type t)
Assert.IsFalse(t.IsEnum);
Assert.IsTrue(t.IsClass);
}

[TestMethod]
[TypeTestData(typeof(SampleType), BytecodeProviders.Metadata)]
public void Test_GetCustomAttributes_Empty(Type t)
{
object[] attrs = t.GetCustomAttributes(false);
Assert.AreEqual(0, attrs.Length);
attrs = t.GetCustomAttributes(true);
Assert.AreEqual(0, attrs.Length);
}

static void VerifyCustomAtrribute(object attr, string expectedType)
{
Assert.AreEqual(expectedType, ((ICustomAttribute)attr).Constructor.DeclaringType.FullName);
}

[TestMethod]
[TypeTestData(typeof(AttrInheritanceTestType), BytecodeProviders.Metadata)]
public void Test_GetCustomAttributes_Inherit(Type t)
{
object[] attrs = t.GetCustomAttributes(true);

Assert.AreEqual(2, attrs.Length);
VerifyCustomAtrribute(attrs[0], "System.ComponentModel.CategoryAttribute");
VerifyCustomAtrribute(attrs[1], "CilTools.Tests.Common.MyAttribute");
}
}
}

0 comments on commit 1ae0854

Please sign in to comment.