Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamicallyAccessedMemberTypes.Interfaces does not cover GetInterfaces on base type #2473

Closed
roji opened this issue Jan 2, 2022 · 7 comments

Comments

@roji
Copy link
Member

roji commented Jan 2, 2022

The following method causes what seems to be a false positive trim analysis warning:

static IEnumerable<Type> GetDeclaredInterfaces(
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type type)
{
    var interfaces = type.GetInterfaces();

    if (type.BaseType == typeof(object)
        || type.BaseType == null)
    {
        return interfaces;
    }

    return interfaces.Except(type.BaseType.GetInterfaces());
}

The call of GetInterfaces() on type.BaseType triggers:

/home/roji/projects/test/Program.cs(22,5): Trim analysis warning IL2075: Program.<<Main>$>g__GetDeclaredInterfaces|0_0(Type): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The return value of method 'System.Type System.Type::get_BaseType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/roji/projects/test/Test.csproj]

If all interfaces on type are preserved, all interfaces on its base type should be preserved as well. There may be a similar issue with other DynamicallyAccessedMemberTypes members as well.

@marek-safar
Copy link
Contributor

/cc @vitek-karas @MichalStrehovsky

@vitek-karas
Copy link
Member

Good catch - #2476 has the fix, we'll try to take it for 6.0.2xx.

@vitek-karas
Copy link
Member

Fixed by #2476 for 6.0.2xx.

@roji
Copy link
Member Author

roji commented Jan 7, 2022

@vitek-karas I'm running into this for DynamicallyAccessedMemberTypes.PublicFields - can you confirm that this (and other relevant annotations) are also propagated via BaseType?

@vitek-karas
Copy link
Member

Almost all public members should be propagated. The code for this is here:

DynamicallyAccessedMemberTypes propagatedMemberTypes = DynamicallyAccessedMemberTypes.None;
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.All)
propagatedMemberTypes = DynamicallyAccessedMemberTypes.All;
else {
// PublicConstructors are not propagated to base type
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicEvents))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicEvents;
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicFields))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicFields;
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicMethods))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicMethods;
// PublicNestedTypes are not propagated to base type
// PublicParameterlessConstructor is not propagated to base type
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicProperties))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicProperties;
if (dynamicallyAccessedMemberNode.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.Interfaces))
propagatedMemberTypes |= DynamicallyAccessedMemberTypes.Interfaces;

Private member annotations are not propagated, because that's how reflection works. Meaning calling Type.GetMethods() (with any combination of binding flags) will never return private members on the base type. The annotations were designed to follow the same semantics as reflection binding.

@roji
Copy link
Member Author

roji commented Jan 7, 2022

Perfect, thanks @vitek-karas!

@vitek-karas
Copy link
Member

Note: Everything but the Interfaces should already work in 6.0... so if you see anything different, please let us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants