Skip to content

Commit

Permalink
[release/6.0.2xx] Propagate Interfaces annotation through Type.BaseTy…
Browse files Browse the repository at this point in the history
…pe (#2476)

The Interfaces annotation makes sure the type has all interfaces, meaning `GetInterfaces` reflection call will work on it. That means that all interfaces of the base type are also preserved, so the `Interfaces` annotation should be propagated to the base type as well.
  • Loading branch information
vitek-karas authored Jan 7, 2022
1 parent e28b7f3 commit 5b33e3a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,9 @@ public override bool HandleCall (MethodBody callingMethodBody, MethodReference c

if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicProperties))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicProperties;

if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.Interfaces))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.Interfaces;
}

methodReturnValue = MergePointValue.MergeValues (methodReturnValue, CreateMethodReturnValue (calledMethod, propagatedMemberTypes));
Expand Down
8 changes: 8 additions & 0 deletions test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public static void Main ()
TestNonPublicNestedTypesAreNotPropagated (typeof (TestType));
TestNonPublicPropertiesAreNotPropagated (typeof (TestType));

TestInterfacesPropagated (typeof (TestType));

TestCombinationOfPublicsIsPropagated (typeof (TestType));
TestCombinationOfNonPublicsIsNotPropagated (typeof (TestType));
TestCombinationOfPublicAndNonPublicsPropagatesPublicOnly (typeof (TestType));
Expand Down Expand Up @@ -164,6 +166,12 @@ static void TestNonPublicPropertiesAreNotPropagated ([DynamicallyAccessedMembers
derivedType.BaseType.RequiresNonPublicProperties ();
}

[RecognizedReflectionAccessPattern]
static void TestInterfacesPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type derivedType)
{
derivedType.BaseType.RequiresInterfaces ();
}

[RecognizedReflectionAccessPattern]
static void TestCombinationOfPublicsIsPropagated (
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicProperties)] Type derivedType)
Expand Down
38 changes: 38 additions & 0 deletions test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public static void Main ()
TestUnkownIgnoreCase3Params (1);
TestUnkownIgnoreCase5Params (1);
TestGenericTypeWithAnnotations ();

BaseTypeInterfaces.Test ();
}

[Kept]
Expand Down Expand Up @@ -409,5 +411,41 @@ static void TestGenericTypeWithAnnotations ()
" test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
Type.GetType (reflectionTypeKeptString);
}

[Kept]
class BaseTypeInterfaces
{
[Kept]
interface ITest
{
[Kept]
void Method ();
}

[Kept]
[KeptInterface (typeof (ITest))]
class BaseType : ITest
{
[Kept]
public void Method () { }
}

[Kept]
[KeptBaseType (typeof (BaseType))]
[KeptInterface (typeof (ITest))]
class DerivedType : BaseType, ITest
{
[Kept]
public void Method () { }
}

[Kept]
public static void Test ()
{
ITest t = null;
t.Method ();
typeof (DerivedType).GetInterfaces ();
}
}
}
}

0 comments on commit 5b33e3a

Please sign in to comment.