Skip to content

Commit

Permalink
Implement DAMT.*WithInherited (#109608)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky authored Nov 11, 2024
1 parent 4087cc8 commit f7334fa
Show file tree
Hide file tree
Showing 15 changed files with 1,037 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors))
{
foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited);
foreach (var c in typeDefinition.ApplyIncludeInherited(t => t.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic), withInherited))
yield return c;
}

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors))
{
foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited);
foreach (var c in typeDefinition.ApplyIncludeInherited(t => t.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public), withInherited))
yield return c;
}

Expand All @@ -52,7 +54,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods))
{
foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited);
foreach (var m in typeDefinition.ApplyIncludeInherited(t => t.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return m;
}

Expand All @@ -64,7 +67,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields))
{
foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited);
foreach (var f in typeDefinition.ApplyIncludeInherited(t => t.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return f;
}

Expand All @@ -76,7 +80,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes))
{
foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited);
foreach (var t in typeDefinition.ApplyIncludeInherited(t => t.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic), withInherited))
{
yield return t;
var members = new List<TypeSystemEntity>();
Expand All @@ -88,7 +93,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes))
{
foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited);
foreach (var t in typeDefinition.ApplyIncludeInherited(t => t.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public), withInherited))
{
yield return t;
var members = new List<TypeSystemEntity>();
Expand All @@ -100,7 +106,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties))
{
foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited);
foreach (var p in typeDefinition.ApplyIncludeInherited(t => t.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return p;
}

Expand All @@ -112,7 +119,8 @@ public static IEnumerable<TypeSystemEntity> GetDynamicallyAccessedMembers(this T

if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents))
{
foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited);
foreach (var e in typeDefinition.ApplyIncludeInherited(t => t.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return e;
}

Expand Down Expand Up @@ -504,6 +512,20 @@ private static DefType TryGetBaseType(this TypeDesc type)
}
}

private static IEnumerable<T> ApplyIncludeInherited<T>(this TypeDesc type, Func<TypeDesc, IEnumerable<T>> selector, bool includeBases)
{
do
{
foreach (var m in selector(type))
yield return m;

if (!includeBases)
yield break;

type = type.TryGetBaseType();
} while (type != null);
}

private static DefType[] TryGetExplicitlyImplementedInterfaces(this TypeDesc type)
{
if (type is MetadataType mdType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<Compile Include="..\..\Common\TypeSystem\Interop\UnmanagedCallingConventions.cs" Link="Interop\UnmanagedCallingConventions.cs" />
<Compile Include="..\ILCompiler.Reflection.ReadyToRun\PEReaderExtensions.cs" Link="Reflection\PEReaderExtensions.cs" />
<Compile Include="$(ToolsProjectRoot)illink\src\ILLink.Shared\ClosedAttribute.cs" Link="ILLink.Shared\ClosedAttribute.cs" />
<Compile Include="$(ToolsProjectRoot)illink\src\ILLink.Shared\DynamicallyAccessedMemberTypesEx.cs" Link="ILLink.Shared\DynamicallyAccessedMemberTypesEx.cs" />
<Compile Include="$(ToolsProjectRoot)illink\src\ILLink.Shared\ParameterIndex.cs" Link="ILLink.Shared\ParameterIndex.cs" />
<Compile Include="$(ToolsProjectRoot)illink\src\ILLink.Shared\TrimAnalysis\ReferenceKind.cs" Link="ILLink.Shared\TrimAnalysis\ReferenceKind.cs" />
<Compile Include="$(ToolsProjectRoot)illink\src\ILLink.Shared\TypeSystemProxy\GenericParameterProxy.cs" Link="ILLink.Shared\TypeSystemProxy\GenericParameterProxy.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,76 @@ enum DynamicallyAccessedMemberTypes
/// </summary>
Interfaces = 0x2000,

/// <summary>
/// Specifies all non-public constructors, including those inherited from base classes.
/// </summary>
NonPublicConstructorsWithInherited = NonPublicConstructors | 0x4000,

/// <summary>
/// Specifies all non-public methods, including those inherited from base classes.
/// </summary>
NonPublicMethodsWithInherited = NonPublicMethods | 0x8000,

/// <summary>
/// Specifies all non-public fields, including those inherited from base classes.
/// </summary>
NonPublicFieldsWithInherited = NonPublicFields | 0x10000,

/// <summary>
/// Specifies all non-public nested types, including those inherited from base classes.
/// </summary>
NonPublicNestedTypesWithInherited = NonPublicNestedTypes | 0x20000,

/// <summary>
/// Specifies all non-public properties, including those inherited from base classes.
/// </summary>
NonPublicPropertiesWithInherited = NonPublicProperties | 0x40000,

/// <summary>
/// Specifies all non-public events, including those inherited from base classes.
/// </summary>
NonPublicEventsWithInherited = NonPublicEvents | 0x80000,

/// <summary>
/// Specifies all public constructors, including those inherited from base classes.
/// </summary>
PublicConstructorsWithInherited = PublicConstructors | 0x100000,

/// <summary>
/// Specifies all public nested types, including those inherited from base classes.
/// </summary>
PublicNestedTypesWithInherited = PublicNestedTypes | 0x200000,

/// <summary>
/// Specifies all constructors, including those inherited from base classes.
/// </summary>
AllConstructors = PublicConstructorsWithInherited | NonPublicConstructorsWithInherited,

/// <summary>
/// Specifies all methods, including those inherited from base classes.
/// </summary>
AllMethods = PublicMethods | NonPublicMethodsWithInherited,

/// <summary>
/// Specifies all fields, including those inherited from base classes.
/// </summary>
AllFields = PublicFields | NonPublicFieldsWithInherited,

/// <summary>
/// Specifies all nested types, including those inherited from base classes.
/// </summary>
AllNestedTypes = PublicNestedTypesWithInherited | NonPublicNestedTypesWithInherited,

/// <summary>
/// Specifies all properties, including those inherited from base classes.
/// </summary>
AllProperties = PublicProperties | NonPublicPropertiesWithInherited,

/// <summary>
/// Specifies all events, including those inherited from base classes.
/// </summary>
AllEvents = PublicEvents | NonPublicEventsWithInherited,

/// <summary>
/// Specifies all members.
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8846,6 +8846,20 @@ public enum DynamicallyAccessedMemberTypes
PublicEvents = 2048,
NonPublicEvents = 4096,
Interfaces = 8192,
NonPublicConstructorsWithInherited = 16388,
NonPublicMethodsWithInherited = 32784,
AllMethods = 32792,
NonPublicFieldsWithInherited = 65600,
AllFields = 65632,
NonPublicNestedTypesWithInherited = 131328,
NonPublicPropertiesWithInherited = 263168,
AllProperties = 263680,
NonPublicEventsWithInherited = 528384,
AllEvents = 530432,
PublicConstructorsWithInherited = 1048579,
AllConstructors = 1064967,
PublicNestedTypesWithInherited = 2097280,
AllNestedTypes = 2228608,
}
[System.AttributeUsageAttribute(System.AttributeTargets.Constructor | System.AttributeTargets.Field | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
public sealed partial class DynamicDependencyAttribute : System.Attribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default;

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicConstructors)) {
foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited);
foreach (var c in typeDefinition.ApplyIncludeInherited (t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic), withInherited))
yield return c;
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicConstructors)) {
foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited);
foreach (var c in typeDefinition.ApplyIncludeInherited (t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public), withInherited))
yield return c;
}

Expand All @@ -45,7 +47,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicMethods)) {
foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited);
foreach (var m in typeDefinition.ApplyIncludeInherited (t => t.GetMethodsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return m;
}

Expand All @@ -55,7 +58,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicFields)) {
foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited);
foreach (var f in typeDefinition.ApplyIncludeInherited (t => t.GetFieldsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return f;
}

Expand All @@ -65,7 +69,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) {
foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) {
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited);
foreach (var nested in typeDefinition.ApplyIncludeInherited (t => t.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) {
yield return nested;
var members = new List<ISymbol> ();
nested.GetAllOnType (declaredOnly: false, members);
Expand All @@ -75,7 +80,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicNestedTypes)) {
foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public)) {
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited);
foreach (var nested in typeDefinition.ApplyIncludeInherited (t => t.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public), withInherited)) {
yield return nested;
var members = new List<ISymbol> ();
nested.GetAllOnType (declaredOnly: false, members);
Expand All @@ -85,7 +91,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicProperties)) {
foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited);
foreach (var p in typeDefinition.ApplyIncludeInherited (t => t.GetPropertiesOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return p;
}

Expand All @@ -95,7 +102,8 @@ public static IEnumerable<ISymbol> GetDynamicallyAccessedMembers (this ITypeSymb
}

if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicEvents)) {
foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags))
bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited);
foreach (var e in typeDefinition.ApplyIncludeInherited (t => t.GetEventsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited))
yield return e;
}

Expand Down Expand Up @@ -410,5 +418,18 @@ static void GetAllOnType (ITypeSymbol type, bool declaredOnly, List<ISymbol> mem
}
}
}
private static IEnumerable<T> ApplyIncludeInherited<T> (this ITypeSymbol thisType, Func<ITypeSymbol, IEnumerable<T>> selector, bool includeBases)
{
ITypeSymbol? type = thisType;
do {
foreach (var m in selector (type))
yield return m;

if (!includeBases)
yield break;

type = type.BaseType;
} while (type != null);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

namespace System.Diagnostics.CodeAnalysis
{
public static class DynamicallyAccessedMemberTypesEx
{
/// <summary>
/// Specifies all non-public constructors, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicConstructorsWithInherited = DynamicallyAccessedMemberTypes.NonPublicConstructors | (DynamicallyAccessedMemberTypes) 0x4000;

/// <summary>
/// Specifies all non-public methods, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicMethodsWithInherited = DynamicallyAccessedMemberTypes.NonPublicMethods | (DynamicallyAccessedMemberTypes) 0x8000;

/// <summary>
/// Specifies all non-public fields, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicFieldsWithInherited = DynamicallyAccessedMemberTypes.NonPublicFields | (DynamicallyAccessedMemberTypes) 0x10000;

/// <summary>
/// Specifies all non-public nested types, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicNestedTypesWithInherited = DynamicallyAccessedMemberTypes.NonPublicNestedTypes | (DynamicallyAccessedMemberTypes) 0x20000;

/// <summary>
/// Specifies all non-public properties, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicPropertiesWithInherited = DynamicallyAccessedMemberTypes.NonPublicProperties | (DynamicallyAccessedMemberTypes) 0x40000;

/// <summary>
/// Specifies all non-public events, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes NonPublicEventsWithInherited = DynamicallyAccessedMemberTypes.NonPublicEvents | (DynamicallyAccessedMemberTypes) 0x80000;

/// <summary>
/// Specifies all public constructors, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes PublicConstructorsWithInherited = DynamicallyAccessedMemberTypes.PublicConstructors | (DynamicallyAccessedMemberTypes) 0x100000;

/// <summary>
/// Specifies all public nested types, including those inherited from base classes.
/// </summary>
public const DynamicallyAccessedMemberTypes PublicNestedTypesWithInherited = DynamicallyAccessedMemberTypes.PublicNestedTypes | (DynamicallyAccessedMemberTypes) 0x200000;
}
}
Loading

0 comments on commit f7334fa

Please sign in to comment.