-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Initial attempt at removing explicit #nullable enable in source #44936
base: main
Are you sure you want to change the base?
Conversation
…xing projects previously using these statements to now use <Nullable>enable</Nullable>. Got the Microsoft.DotNet.Cli.Utils.csproj building. More to come.
… nullable enable. Added WorkloadRootPath.cs since the tuples were problematic with nullability logic.
…m/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md#nullable-reference-type-support Converted Microsoft.DotNet.Configurer.csproj to nullable. Realized the other projects that need nullable are massive, so putting this on the backburner.
# Conflicts: # src/Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj # src/Cli/Microsoft.DotNet.Cli.Utils/UILanguageOverride.cs # src/Cli/dotnet/dotnet.csproj # src/Common/WorkloadFileBasedInstall.cs # src/Containers/Microsoft.NET.Build.Containers/LocalDaemons/DockerCli.cs # src/Resolvers/Microsoft.DotNet.NativeWrapper/Microsoft.DotNet.NativeWrapper.csproj # src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs # src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadInstallType.cs # src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs # src/Tasks/Common/NuGetUtils.cs # src/WebSdk/Publish/Tasks/Microsoft.NET.Sdk.Publish.Tasks.csproj # src/WebSdk/Publish/Tasks/MsDeploy/CommonUtility.cs # src/WebSdk/Publish/Tasks/Tasks/MsDeploy/MSDeploy.cs # src/WebSdk/Publish/Tasks/Tasks/MsDeploy/VsMsdeploy.cs # src/WebSdk/Publish/Tasks/Tasks/WebJobs/GenerateRunCommandFile.cs # src/WebSdk/Publish/Tasks/Tasks/ZipDeploy/HttpClientHelpers.cs # src/WebSdk/Publish/Tasks/Tasks/ZipDeploy/HttpResponseMessageWrapper.cs # src/WebSdk/Publish/Tasks/WebJobsCommandGenerator.cs
…ccidental removal of nullable on the WorkloadManifestReader.
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
|
||
namespace Microsoft.NET.Sdk.WorkloadManifestReader | ||
{ | ||
public record WorkloadRootPath(string? Path, bool Installable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this record as there was a tuple being passed around previously. Made more sense to use an actual defined type.
//Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind validationKind = Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind.None; | ||
//Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind currentvalidationKind; | ||
//Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind currentValidationKind; | ||
//string[] validationKinds = item.Kind.Split(new char[] { ',' }); | ||
|
||
//foreach (string strValidationKind in validationKinds) | ||
//{ | ||
// if (System.Enum.TryParse<Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind>(strValidationKind, out currentvalidationKind)) | ||
// if (System.Enum.TryParse<Microsoft.Web.Deployment.DeploymentSyncParameterValidationKind>(strValidationKind, out currentValidationKind)) | ||
// { | ||
// validationKind |= currentvalidationKind; | ||
// validationKind |= currentValidationKind; | ||
// } | ||
//} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea why this is here. A relic of the past? 🗿
@@ -1,4 +1,4 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<Project Sdk="Microsoft.NET.Sdk"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BOM change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd assume so. I had changed more in this file initially but removed those changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider reverting all changes in this file then.
@@ -9,6 +9,7 @@ | |||
<RepositoryType>git</RepositoryType> | |||
<DefineConstants Condition="'$(IncludeAspNetCoreRuntime)' == 'false'">$(DefineConstants);EXCLUDE_ASPNETCORE</DefineConstants> | |||
<IsPackable>true</IsPackable> | |||
<Nullable>enable</Nullable> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be in a directory.build.props
perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not possible without doing the entire repo first or figuring out some way of untangling the mess of shared code files. Or, you manually check nested project directories to see if all the projects in that directory already use nullability and then added a new Directory.Build.props
for that sub-directory. Doesn't seem worthwhile, though. This is way too initial to do that kind of change.
@@ -317,7 +317,7 @@ static ICommand CreateCommandFromRunProperties(ProjectInstance project, RunPrope | |||
CommandSpec commandSpec = new(runProperties.RunCommand, runProperties.RunArguments); | |||
|
|||
var command = CommandFactoryUsingResolver.Create(commandSpec) | |||
.WorkingDirectory(runProperties.RunWorkingDirectory); | |||
.WorkingDirectory(runProperties.RunWorkingDirectory ?? string.Empty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this previously be null and any concerns about being empty now. Assuming we didn't have explicit null vs. nullorwhitespace checks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was already defined as string? RunWorkingDirectory
at the top of this file. What changed was WorkingDirectory
now became part of a nullable-enabled assembly, and its parameter is defined as string projectDirectory
. That means, previously, if this was passed null
, it would assign it to process.StartInfo.WorkingDirectory
. If the decompiled code is to be believed, the default for that property is ""
, so I just left it as that in this situation. The code for it does handle null, and it'll just return string.Empty
anyway.
|
||
//only Microsoft.DotNet.MSBuildSdkResolver (net7.0) has nullables enabled | ||
#pragma warning disable IDE0240 // Remove redundant nullable directive | ||
#pragma warning disable IDE0240 | ||
#nullable enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this just remove the #nullable enable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cannot. It is a shared file. You'd have to do the entire Microsoft.NET.Build.Tasks and (likely) the dotnet CLI project, which are thousands of changes.
@@ -1,10 +1,9 @@ | |||
// Licensed to the .NET Foundation under one or more agreements. | |||
// The .NET Foundation licenses this file to you under the MIT license. | |||
|
|||
#pragma warning disable IDE0240 // Nullable directive is redundant (when file is included to a project that already enables nullable | |||
|
|||
#pragma warning disable IDE0240 | |||
#nullable enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, should we remove the #nullable enable
an
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you see changes like this, it is because I initially tried to remove it, but then added it back again because it is a shared source file and cannot be removed.
|
||
if (line.Length == 0 || line[0] == '#') | ||
if (line is null || line.Length == 0 || line[0] == '#') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this instead be string.IsNullOrWhitespace(line)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I did that at first but changed it to this because string.IsNullOrWhitespace
is not recognized by the analyzer as a null-check. Therefore, the call to the indexer in the rest of the or-statement would need to be line![0] == '#'
which is a little jankier. This seemed like a simpler change since it is more explicit to the analyzer.
{ | ||
if (sourcePath == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are empty paths valid here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -57,7 +57,7 @@ public CommandResult Execute() | |||
|
|||
if (!string.IsNullOrEmpty(_workingDirectory)) | |||
{ | |||
_environment.SetWorkingDirectory(_workingDirectory); | |||
_environment.SetWorkingDirectory(_workingDirectory!); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
! Justification: string.IsNullOrEmpty
check
{ | ||
correctedPath = string.Empty; | ||
if (string.IsNullOrWhiteSpace(existingPath)) | ||
{ | ||
return false; | ||
} | ||
|
||
IEnumerable<string> paths = existingPath.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); | ||
IEnumerable<string> paths = existingPath!.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
! Justification: string.IsNullOrEmpty
check
Related: #25920
Summary
I started working on this in March and aborted the idea because I hit a point where thousands of changes needed to occur. There has been a resurgence in trying to get the repo to be Nullable enable everywhere.
I started by removing
#nullable enable
in any source files. Then, I attempted to make those projects use<Nullable>enable</Nullable>
. There were many issues with this, but in the end, to make the build work, any shared source files I had to add:This is because those files are now shared between both nullable and non-nullable projects. So, this is a stopgap to getting to a point where nullable is enabled everywhere and no source files contain
#nullable enable
.Problems
When making projects
<Nullable>enable</Nullable>
, there are several chain reactions that can occur.#nullable enable
in the file, or<Nullable>enable</Nullable>
null
or you need to add custom logic to handle thenull
situationnull
should be handled?
to everything is really detrimental as you can cause more work for yourself than just handlingnull
in a strategic location!
should be used sparingly and intentionally. For example,string.IsNullOrEmpty
is not recognized as a null check, so you might need to help the analyzers by putting!
on uses of the variable after that point.string
used as a property where you don't know ifstring.Empty
is an acceptable value?
but this can cause a chain reaction of null checking necessary throughout the class and callers of that class and its properties.Projects now using
<Nullable>enable</Nullable>
Other changes
record
to replace passing around a tuple