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

Add [MemberNotNull] and [MemberNotNullWhen] support #85

Closed

Conversation

kevinchalet
Copy link

Fixes #84.

@@ -94,7 +94,7 @@ Namespace Global.System.Diagnostics.CodeAnalysis

''' <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
<AttributeUsage(AttributeTargets.Parameter, Inherited:=False)>
Friend NotInheritable Class DoesNotReturnAttribute
Friend NotInheritable Class DoesNotReturnIfAttribute
Copy link
Author

@kevinchalet kevinchalet Oct 6, 2020

Choose a reason for hiding this comment

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

I believe it's an actual bug, as DoesNotReturnAttribute already appears earlier in the file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice find. We have a test hole. @sharwell

@@ -110,4 +110,65 @@ Namespace Global.System.Diagnostics.CodeAnalysis
Public ReadOnly Property ParameterValue As Boolean
End Class

''' <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
<AttributeUsage(AttributeTargets.Method Or AttributeTargets.Property, Inherited:=False, AllowMultiple:=True)>
Friend NotInheritable Class MemberNotNullAttribute
Copy link
Author

Choose a reason for hiding this comment

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

I'm by no means a VB.NET expert, so please double check (and forgive any rookie mistake 😅)


protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory)
{
var constructor1 = MethodFactory.Constructor(wellKnownTypes.TypeSystem);
Copy link
Author

Choose a reason for hiding this comment

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

It's the first time I play with Cecil, so you'll likely want to triple-check I'm not doing anything stupid 😄

@kevinchalet
Copy link
Author

@jnm2 @sharwell PTAL 😄

jnm2
jnm2 previously approved these changes Oct 6, 2020
Copy link
Contributor

@jnm2 jnm2 left a comment

Choose a reason for hiding this comment

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

Thanks so much for this, we really appreciate it!

@sharwell I'm less familiar with the ProvidedAttributeType part. Does it need custom attributes to be added on the string array like NotNullIfNotNullAttributeProvidedType does, and could we follow up after this PR with a test that would fail if this is needed and missing?

protected override void ImplementAttribute(ModuleDefinition module, TypeDefinition attribute, WellKnownTypes wellKnownTypes, CustomAttributeFactory attributeFactory)
{
attribute.CustomAttributes.Add(attributeFactory.NullableContext(1));
attribute.CustomAttributes.Add(attributeFactory.Nullable(0));
attribute.CustomAttributes.Add(attributeFactory.AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, allowMultiple: true, inherited: false));
var constructor = MethodFactory.Constructor(wellKnownTypes.TypeSystem);
constructor.Parameters.Add(new ParameterDefinition("parameterName", ParameterAttributes.None, wellKnownTypes.TypeSystem.String));
attribute.Methods.Add(constructor);
}


/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
internal class MemberNotNullAttribute : Attribute
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these should be declared as sealed. Could you update the URL at the top to https://github.com/dotnet/runtime/blob/v5.0.0-rc.1.20451.14/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs and then compare against it?

Copy link
Author

Choose a reason for hiding this comment

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

Nice catch! Looks like I accidentally removed it when copying the definition 😅

Fixed.

@kevinchalet
Copy link
Author

Wooops, looks like I broke something. I'll take a look 😅

@kevinchalet
Copy link
Author

I tried to add [ParamArray] to the members parameters to see if it could help, but it didn't.

I'm out of ideas. I'll wait for @sharwell to magically find the root cause in 3 seconds 🤣

@jnm2
Copy link
Contributor

jnm2 commented Oct 7, 2020

Hmm, I can confirm that this repros locally for me on member_not_null but not on master:

msbuild /restore /verbosity:minimal
git clean -xdf tests
dotnet msbuild -restore tests/MultiTFM -warnaserror -nr:false -v:m

…ibute/MemberNotNullWhenAttribute's definition
@kevinchalet
Copy link
Author

kevinchalet commented Oct 7, 2020

What's super weird is that the error ("Mono.Cecil.ResolutionException: Failed to resolve System.AttributeTargets") is about a type reference I haven't changed in this PR 😕

I added the nullable/nullable context attributes as you suggested. Dunno if it will fix it tho 😄

image

image

@jnm2
Copy link
Contributor

jnm2 commented Oct 7, 2020

Waiting for @sharwell seems like a good plan. The only idea I have is to do a binary search of deleting half your changes repeatedly until we find the line that seems to perturb the behavior into failing. Bit slow of a process.

@kevinchalet
Copy link
Author

@jnm2 I'll wait for @sharwell's feedback.

Anyway, thanks a lot for your assistance and your review. Much appreciated 😃


/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
internal sealed class MemberNotNullAttribute : Attribute
Copy link
Member

Choose a reason for hiding this comment

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

📝 These need to be conditionally included for .NET Standard 2.1 and .NET Core 3.x builds when GenerateNullableAttributes is set. See here for an example:

https://github.com/dotnet/roslyn/blob/bc85a40ac042f9cf799f5e43deb0fee2d595247b/src/Compilers/Core/Portable/InternalUtilities/NullableAttributes.cs#L90-L94

This will require conditional directives in the source file, and modifications to the handling of GenerateNullableAttributes in the build targets.

Copy link
Author

Choose a reason for hiding this comment

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

Hum yeah, great point. I'll give it a try when I have a moment.

Copy link
Author

Choose a reason for hiding this comment

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

Updated. Let me know if I got it right.

@kevinchalet
Copy link
Author

Alright, I'm now out of ideas and this is way a more painful process than I had anticipated.

@jnm2 @sharwell this is now failing in the WPF tests. If you guys have an idea, let me know. Otherwise, I'll close this PR as I don't think I'll be able to fix that.

@kevinchalet
Copy link
Author

Latest commits improved things, but we're back to the Failed to resolve System.AttributeTargets error that makes no sense to me...

@sharwell
Copy link
Member

sharwell commented Oct 15, 2020

@kevinchalet Been busy but hoping to get to this 😄

@kevinchalet
Copy link
Author

Haha, no worries. I closed this PR as I wasn't able to fix it on my own, but I'd be happy to revive it if we can find the root cause of the issue 😄

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

Successfully merging this pull request may close these issues.

Consider adding MemberNotNullAttribute and MemberNotNullWhenAttribute
3 participants