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 reference types by default #7130

Merged
merged 6 commits into from
Jan 7, 2022

Conversation

drewnoakes
Copy link
Member

Context

In #7093 (comment) we observed that adding #nullable enable would better document the intended nullness of values.

It would be good if new code was #nullable enable by default.

Changes Made

This turns C# 9's nullable reference types on by default for all projects in the solution, and opts out unannotated files by adding #nullable disable to them.

This has two nice properties:

  1. New code will be written with nullability in mind as the feature will be on by default.
  2. It's easy to find unannotated code by searching for #nullable disable.

Testing

CI. The nullable reference types feature does not impact code at runtime, other than the addition of metadata.

Notes

We have taken this approach in the .NET Project System and in CPS, and it's worked very well for us.

Code under Deprecated is unchanged.

This is the kind of change a team should discuss first. I was curious if it'd be an easy change for MSBuild and by the time I had an answer, I also had a PR. I will not be offended if this is not a change you wish to make at this time.

@rainersigwald
Copy link
Member

I think I'm on board with this? I wasn't willing to do it myself and I still find the approach kinda ugly, but it does encourage modernization and make the old-and-busted unannotated files stand out. And I don't have a better approach--without a mechanism to enforce "new files get nullable enabled by default/if you do major surgery in a file enable it" we were just kinda sitting still.

@drewnoakes drewnoakes force-pushed the dev/drnoakes/nullable-by-default branch from a141513 to 9f75c90 Compare December 7, 2021 02:14
This turns C# 9's nullable reference types on by default for all projects in the solution, and opts out unannotated files by adding `#nullable disable` to them.

This has two nice properties:

1. New code will be written with nullability in mind as the feature will be on by default.
2. It's easy to find unannotated code by searching for `#nullable disable`.

We have taken this approach in the .NET Project System and in CPS, and it's worked very well for us.

Code under `Deprecated` is unchanged.
@drewnoakes drewnoakes force-pushed the dev/drnoakes/nullable-by-default branch from 9f75c90 to d7724dd Compare December 7, 2021 02:23
@drewnoakes
Copy link
Member Author

drewnoakes commented Dec 7, 2021

I made this change with a regex, matching on ^namespace .

There are a lot of file changes here and reviewing is a pain. The strategy I used to validate this approach was review all files that had more or less than two line changes (the addition of #nullable disable\n\n). To do this:

$ git show cc006b994e5ef15c9c392502b88c2a3ee62972af --stat | grep -v " 2 "
 src/Build.UnitTests/BackEnd/IntegrationTests.cs                      | 4 +++-
 src/Build.UnitTests/BackEnd/TaskBuilder_Tests.cs                     | 3 +++
 src/Build.UnitTests/ConsoleOutputAlignerTests.cs                     | 1 -
 src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs                | 1 -
 src/Build/BackEnd/Components/ProjectCache/CacheContext.cs            | 1 -
 src/Build/BackEnd/Components/ProjectCache/CacheResult.cs             | 1 -
 src/Build/BackEnd/Components/ProjectCache/PluginLoggerBase.cs        | 1 -
 src/Build/BackEnd/Components/ProjectCache/PluginTargetResult.cs      | 1 -
 src/Build/BackEnd/Components/ProjectCache/ProjectCacheDescriptor.cs  | 1 -
 src/Build/BackEnd/Components/ProjectCache/ProjectCacheItem.cs        | 1 -
 src/Build/BackEnd/Components/ProjectCache/ProjectCachePluginBase.cs  | 1 -
 src/Build/BackEnd/Components/ProjectCache/ProjectCacheService.cs     | 1 -
 src/Build/BackEnd/Components/ProjectCache/ProxyTargets.cs            | 1 -
 src/Build/Logging/BinaryLogger/BinaryLogRecordKind.cs                | 4 +++-
 src/Build/Logging/ParallelLogger/ConsoleOutputAligner.cs             | 1 -
 src/Deprecated/Conversion/Microsoft.Build.Conversion.csproj          | 3 ++-
 src/Deprecated/Engine/Microsoft.Build.Engine.csproj                  | 3 ++-
 src/Directory.Build.props                                            | 1 +
 src/Framework/FileClassifier.cs                                      | 1 -
 src/Framework/ImmutableFilesTimestampCache.cs                        | 1 -
 src/Framework/TestInfo.cs                                            | 4 +++-
 src/Shared/ExceptionHandling.cs                                      | 4 ++++
 src/Shared/RegisteredTaskObjectCacheBase.cs                          | 3 ++-
 src/Shared/UnitTests/TestAssemblyInfo.cs                             | 5 +++--
 src/StringTools/StringTools.csproj                                   | 3 +--
 src/Tasks/GetCompatiblePlatform.cs                                   | 1 -

The one-line changes are all removals of #nullable enable that previously existed.

I reviewed all the others. There were some incorrect substitutions in code blocks. I've fixed those.

The other changes here look good to me.

@rainersigwald
Copy link
Member

I made this change with a regex, matching on ^namespace .

I learned this morning that there's a VS refactoring to do this!

We discussed this with the team and we're planning to go ahead with this approach--thanks for piloting it out for us!

Comment on lines +5 to +6
#nullable disable

Copy link
Member

Choose a reason for hiding this comment

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

Just move this above the #ifs?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. Merged latest main and resolved conflict.

@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Jan 5, 2022
@Forgind Forgind merged commit 518c041 into dotnet:main Jan 7, 2022
@drewnoakes drewnoakes deleted the dev/drnoakes/nullable-by-default branch January 7, 2022 22:05
rainersigwald added a commit to rainersigwald/msbuild that referenced this pull request Mar 1, 2022
Per the comment, this was removable once we turned on nullable. Which was done in dotnet#7130.
rokonec pushed a commit that referenced this pull request Mar 2, 2022
Per the comment, this was removable once we turned on nullable. Which was done in #7130.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants