Skip to content

Conversation

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Jun 23, 2020

Yet another batch of trimming annotations.

Resolves #32921.

Yet another batch of trimming annotations.

// GetDefaultMembers
// This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Why All? The doc says it can be only constructor, method, property, or field and I think they have to be public

Copy link
Member Author

Choose a reason for hiding this comment

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

The doc says it can be only constructor, method, property, or field and I think they have to be public

Couldn't find that mention in the doc - the impl also works for events and nested types. It's a janky API.

It was forced by the annotation on GetMember. I've fixed that up.


// GetDefaultMembers
// This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the attribute have any effect here when the type is sealed?

Copy link
Member

Choose a reason for hiding this comment

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

The attribute is on the "this" - which is a special case - it annotates the type this RuntimeType represents. So for example calling typeof<MyType>.GetDefaultMembers() would end up (due to this attribute) marking the entire MyType.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure but as this is C# code there won't be any call (IL reference) to this method

Copy link
Member

Choose a reason for hiding this comment

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

Note that the same annotation is on Type.GetDefaultMembers() - the current data flow implementation in the linker assumes that the entire inheritance hierarchy for a given method has the same annotations (We're missing the validation in the linker for now dotnet/linker#1028).

Other than the above rule, this also means that when analyzing the method body of this method the linker can make assumptions about the this and won't generate warnings...

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Why All (that includes NestedTypes as well) ? The doc says it can be only constructor, method, property, or field and I think they have to be public

Copy link
Member

@vitek-karas vitek-karas left a comment

Choose a reason for hiding this comment

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

Other than the comment about All it looks good.

/// <summary>Gets a description of the state of the state machine object, suitable for debug purposes.</summary>
/// <param name="stateMachine">The state machine object.</param>
/// <returns>A description of the state machine.</returns>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

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

Can we close #32921 with this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup


[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Justification = "Implementation detail of Activator that linker intrinsically recognizes")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

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

Why are IL2006 and IL2026 both UnrecognizedReflectionPattern ? Shouldn't different warning numbers have different titles/names?

Copy link
Member

Choose a reason for hiding this comment

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

@mateoatr to comment on the second parameter values...

Copy link
Contributor

Choose a reason for hiding this comment

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

Anything that is put after the colon in the CheckId parameter is used only for documentation purposes (this is, the warning suppression mechanism completely ignores what the user puts after the colon, it only cares for the four numbers of the warning id).
We sometimes put a subcategory on the warnings to further categorize them, although this specific warning does not have the UnrecognizedReflectionPattern subcategory, I don't know if we should add it.

Copy link
Member

Choose a reason for hiding this comment

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

It is super confusing as a reader to see 2 warning numbers with the same string. What is the title of IL2026? RequiresUnreferencedCode? We should update it here so this doesn't look like duplicated attributes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed to RequiresUnreferencedCode.

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.

Just a couple clarifying questions. LGTM

| DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.PublicNestedTypes)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Justification = "Linker doesn't recongnize GetMember(BindingFlags.Public) but this is what the body is doing")]
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: typo in recongnize

| DynamicallyAccessedMemberTypes.PublicEvents
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.PublicFields
Copy link
Member

Choose a reason for hiding this comment

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

PublicFields is there twice

| DynamicallyAccessedMemberTypes.PublicEvents
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.PublicFields
Copy link
Member

Choose a reason for hiding this comment

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

Same as above - duplicate PublicFields

Copy link
Member

Choose a reason for hiding this comment

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

And also below some more...

Copy link
Member Author

Choose a reason for hiding this comment

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

Sigh. Fixed.

I hope the one user of this useless API is going to appreciate the size savings from the restriction on .All because we just spent quite a bit of Microsoft money on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this is an indicator we are missing DynamicallyAccessedMemberTypes.AllPublic enum value

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe this is an indicator we are missing DynamicallyAccessedMemberTypes.AllPublic enum value

We can consider that - would that annotation be useful outside these two rarely used APIs?

@MichalStrehovsky MichalStrehovsky merged commit 188a3a8 into dotnet:master Jun 24, 2020
@MichalStrehovsky MichalStrehovsky deleted the annotmore branch June 24, 2020 11:13
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetAsyncStateMachineDescription may change behavior on app processed by ILLink

6 participants