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

Enable nullable everywhere #954

Merged
merged 3 commits into from
Aug 7, 2024
Merged

Enable nullable everywhere #954

merged 3 commits into from
Aug 7, 2024

Conversation

j3parker
Copy link
Member

@j3parker j3parker commented Aug 7, 2024

I'd like to add more csproj's soon, and to have nullable enabled in those places, so for simplicity I'm enabling it globally first.

I'd like to add more csproj's soon, and to have nullable enabled in
those places, so for simplicity I'm enabling it globally first.
@j3parker j3parker requested a review from mthjones August 7, 2024 15:08
@j3parker j3parker marked this pull request as ready for review August 7, 2024 15:08
@j3parker j3parker requested a review from omsmith as a code owner August 7, 2024 15:08
}
}

#endif
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 other project brings in a package for this but I'm pretty meh on that.

In the future I'm going to make a folder for common source for analyzers and some Directory.Build.targets magic to <Compile Include="..." LinkBase="Common" />-in some shared analyzer code and this can go in there.

var syntaxReference = attribute.ApplicationSyntaxReference;

if( syntaxReference == null ) {
// ??
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 know if this is possible but also don't care much. I changed the behaviour to just silently continue if it happens

SourceText? allowedListText = bannedListFile.GetText();

if( allowedListText == null ) {
throw new Exception( "Couldn't read config" );
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'm not sure how this would happen so I didn't try hard on this exception; I figure its better than the NullReferenceException we'd otherwise have. The IDE/CLI will tell you which analyzer threw an exception so I figure this is enough hint for now.

@@ -53,7 +54,7 @@ internal sealed class CategoryAnalyzer : DiagnosticAnalyzer {
context: ctx,
bannedCategories: bannedCategories,
types: types,
syntax: ctx.Node as MethodDeclarationSyntax
syntax: (ctx.Node as MethodDeclarationSyntax)!
Copy link
Member

Choose a reason for hiding this comment

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

nit: SyntaxNodeAnalysisContext.Node is already non-nullable. If this were a hard-cast would we be able to avoid needing to force non-null?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yeah sure. Technically a hard cast throws a different exception/earlier but the reason I used ! is that in the context the cast will always succeed, so yeah I'll switch to hard cast

src/D2L.CodeStyle.TestAnalyzers/NUnit/CategoryAnalyzer.cs Outdated Show resolved Hide resolved
src/D2L.CodeStyle.TestAnalyzers/NUnit/CategoryAnalyzer.cs Outdated Show resolved Hide resolved
src/D2L.CodeStyle.TestAnalyzers/NUnit/CategoryAnalyzer.cs Outdated Show resolved Hide resolved
compilation.GetTypeByMetadataName( "NUnit.Framework.TestCaseAttribute" ),
compilation.GetTypeByMetadataName( "NUnit.Framework.TestCaseSourceAttribute" ),
compilation.GetTypeByMetadataName( "NUnit.Framework.TheoryAttribute" )
}.Where( x => x != null )!
Copy link
Member

Choose a reason for hiding this comment

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

Is the null-forgiving op necessary on the result of Where?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, well known problem.

They've talked about extending nullable analysis more to handle LINQ stuff but nothing very concrete. Also related to covariance headaches (e.g. Task<T> vs Task<T?>)

The Where( x => x is not null )! thing is pretty common from what I've seen. Sometimes people make their own extensions. I've also seen .OfType<T>() but that feels even worse to me (not obvious what kind of "casting" is happening there)

Comment on lines +73 to +74
// TODO: can this actually be null?
var syntaxReference = attribute.ApplicationSyntaxReference!;
Copy link
Member Author

Choose a reason for hiding this comment

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

comment is just there as a hint that this ! is a guess.
Clearly it hasn't caused troubles yet 🤷

@@ -189,11 +193,16 @@ ISymbol symbol

TypedConstant arg = args[0];

if( arg.Type == null ) {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Behaviour change that I think is reasonable (ditto below)?

if( arg.Type.SpecialType != SpecialType.System_String ) {
return;
}

string category = arg.Value as string;
string category = (string?)arg.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.

We know that arg.Type is System.String. I'm not sure if null can actually be returned here, I somewhat doubt it -- but this is equivalent behaviour fwiw

Copy link
Member

Choose a reason for hiding this comment

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

Does [TestCategory( null )] bail out on an earlier check? I guess it's treated as object because the constant is evaluated independently of the context it's used in?

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'm not sure

if( testFixtureAttribute == null ) {
types = null;
return false;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

(reasonable imo) behaviour change

Copy link
Member Author

Choose a reason for hiding this comment

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

(clearly its not crashing today, so maybe in practice not, but I suppose NUnit could rename / move these types in the future.)

if( arg.Type.SpecialType != SpecialType.System_String ) {
return;
}

string category = arg.Value as string;
string category = (string?)arg.Value!;
Copy link
Member

Choose a reason for hiding this comment

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

Does [TestCategory( null )] bail out on an earlier check? I guess it's treated as object because the constant is evaluated independently of the context it's used in?

@j3parker j3parker merged commit 63fed57 into main Aug 7, 2024
1 check passed
@j3parker j3parker deleted the nullable branch August 7, 2024 16:59
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.

2 participants