Skip to content

Conversation

@vitek-karas
Copy link
Member

After the basic annotation of Type.GetInterface and Type.GetInterfaces this propagates this annotation to all places which require it. It also resolves warnings in all the places where this shows up.

For the most part this is just blindly propagating the annotations.

Most of the suppressions rely on the fact that is IFoo is referenced (and thus the Type instance of it exists at runtime), trimmer guarantees that it will keep it on all types which implement that interface. And also on additional fact that if IFoo<> is preserved, then all instantiations of it are also preserved. This is true for linker, but not necessarily true for AOT - that is we can do better if we don't have to make that assumption. For now I rely on that assumption.

After the basic annotation of Type.GetInterface and Type.GetInterfaces this propagates this annotation to all places which require it. It also resolves warnings in all the places where this shows up.
@vitek-karas vitek-karas added the linkable-framework Issues associated with delivering a linker friendly framework label May 7, 2021
@vitek-karas vitek-karas added this to the 6.0.0 milestone May 7, 2021
@vitek-karas vitek-karas self-assigned this May 7, 2021
@ghost
Copy link

ghost commented May 7, 2021

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented May 7, 2021

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer
See info in area-owners.md if you want to be subscribed.

Issue Details

After the basic annotation of Type.GetInterface and Type.GetInterfaces this propagates this annotation to all places which require it. It also resolves warnings in all the places where this shows up.

For the most part this is just blindly propagating the annotations.

Most of the suppressions rely on the fact that is IFoo is referenced (and thus the Type instance of it exists at runtime), trimmer guarantees that it will keep it on all types which implement that interface. And also on additional fact that if IFoo<> is preserved, then all instantiations of it are also preserved. This is true for linker, but not necessarily true for AOT - that is we can do better if we don't have to make that assumption. For now I rely on that assumption.

Author: vitek-karas
Assignees: vitek-karas
Labels:

linkable-framework

Milestone: 6.0.0

return list.ToArray();
}

[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've submitted #52535 to see whether we can just delete the problematic code instead.

I think this would only do something if we allowed instance fields on interfaces, but that smells a lot like multiple-inheritance problems, so I don't think we're ever going to allow that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for testing this.

"The trimmer will keep the interface and thus all of its implementations in that case. " +
"The call to GetInterfaces may return less results in trimmed apps, but it will " +
"include the interfaces this method looks for if they should be there.")]
static Type[] GetInterfacesOnType (Type t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static Type[] GetInterfacesOnType (Type t)
static Type[] GetInterfacesOnType(Type t)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been officially tainted by the linker repo coding style 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make this part of the process after working in the linker repo:

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
public sealed override Type[] FindInterfaces(TypeFilter filter, object? filterCriteria) => throw new NotSupportedException(SR.NotSupported_SignatureType);

public sealed override InterfaceMapping GetInterfaceMap(Type interfaceType) => throw new NotSupportedException(SR.NotSupported_SignatureType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about GetInterfaceMap? Does this need any annotations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to. The GetInterfaceMap returns the per-method details for the specified interface type - so the interface type is guaranteed to exist. Maybe we need to annotate it with PublicMethods? @MichalStrehovsky would you know?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need to annotate it with PublicMethods

Does PublicMethods include explicitly implemented methods?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or do you mean PublicMethods on the interface type?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might have to be all the methods on the interface: #46912 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - we will need to make it all methods... although I will have to play with it - if it has different semantics than GetMethod regarding inheritance... oh well.

@eerhardt
Copy link
Member

eerhardt commented May 11, 2021

    public virtual System.Collections.Generic.IEnumerable<System.Type> ImplementedInterfaces { get { throw null; } }

What about TypeInfo.ImplementedInterfaces? Shouldn't that be annotated?

Looks like it was just missed in the ref file. The src file has it annotated.


Refers to: src/libraries/System.Runtime/ref/System.Runtime.cs:9079 in 702bed0. [](commit_id = 702bed0, deletion_comment = False)

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I had just one more comment on TypeInfo.ImplementedInterfaces ref file. Other than that, looks good.

The Interfaces annotation is transitive (by definition), so once it applies to a Type it also applies to all the interfaces implemented by that type.
@vitek-karas
Copy link
Member Author

With the last change I annotated the return value of GetInterface with Interfaces as well.
The Interfaces annotation is transitive - it guarantees that on a type A all of the interfaces that type implements (as in, can be casted to) will be preserved. That means it's recursively marking all interfaces - and thus if I pick IA which is implemented by A, all of the interfaces on IA are already marked as well.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@vitek-karas vitek-karas merged commit e43bd13 into dotnet:main May 12, 2021
@vitek-karas vitek-karas deleted the GetInterfacesAnnotation branch May 12, 2021 21:20
@ghost ghost locked as resolved and limited conversation to collaborators Jun 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Reflection linkable-framework Issues associated with delivering a linker friendly framework new-api-needs-documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants