Skip to content

Implement 'Enable nullable reference types' refactoring#57200

Merged
sharwell merged 12 commits intodotnet:mainfrom
sharwell:enable-nullable
Oct 22, 2021
Merged

Implement 'Enable nullable reference types' refactoring#57200
sharwell merged 12 commits intodotnet:mainfrom
sharwell:enable-nullable

Conversation

@sharwell
Copy link
Copy Markdown
Contributor

@sharwell sharwell commented Oct 18, 2021

Fixes #52893

  • Figure out the scope of the two remaining TODO comments as they relate to this pull request
  • Add tests for remaining forms of #nullable directive
  • Add tests for handling of generated code

Screenshots

image

image

image

@ghost ghost added the Area-IDE label Oct 18, 2021
var nullableDisableTrivia = SyntaxFactory.Trivia(SyntaxFactory.NullableDirectiveTrivia(SyntaxFactory.Token(SyntaxKind.DisableKeyword).WithPrependedLeadingTrivia(SyntaxFactory.ElasticSpace), isActive: true));
var updatedRoot = root.ReplaceToken(firstToken, firstToken.WithLeadingTrivia(firstToken.LeadingTrivia.Add(nullableDisableTrivia).Add(newLine).Add(newLine)));

// TODO: remove all '#nullable disable' directives in code with no nullable types
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

💡 It may be sufficient to move this to a separate diagnostic analyzer/code fix, where it would be applicable both as a follow-up for this refactoring and as a helper for code that enabled nullable reference types through other strategies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what are the odds of this happening in practice? i'd guess either:

  1. very low
  2. only for very common/obvious syntactic forms (like enums)

Given this, i would instead only look for really obvious cases to remove. Beyond that, just leave in.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

➡️ For now, opting to not implement this. We can create a separate diagnostic analyzer in the future to point out redundant directives, and at that point leverage it in this refactoring to improve the results.


// TODO: remove all '#nullable disable' directives in code with no nullable types

// TODO: remove all redundant directives
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

💡 It may be sufficient to move this to a separate diagnostic analyzer/code fix, where it would be applicable both as a follow-up for this refactoring and as a helper for code that enabled nullable reference types through other strategies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i would only look for the most basic case. Specifically, if the file now starts with #nullable enable and nothing else, then remove that. If there's any sort of multi-directive stuff going on, then leave it alone.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

➡️ This simplification is now implemented. Further identification of redundant #nullable directives can be implemented as a separate diagnostic analyzer.

if (originalNode.SettingToken.IsKind(SyntaxKind.EnableKeyword))
{
return rewrittenNode.WithSettingToken(SyntaxFactory.Token(SyntaxKind.RestoreKeyword).WithTriviaFrom(rewrittenNode.SettingToken));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

something feels fishy here, though i can't quite put my finger on it. i think it's that disable doesn't change, while the other two rotate. i trust that this logic is correct? my feeble brain keeps getting confused by it :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

💭 It's strange, but it seems to be correct. With Nullable Reference Types disabled, #nullable disable and #nullable restore have the same meaning.

if (nextToken.IsKind(SyntaxKind.HashToken) && nextToken.Parent.IsKind(SyntaxKind.EndRegionDirectiveTrivia))
{
firstToken = nextToken.Parent.GetLastToken(includeDirectives: true).GetNextToken(includeDirectives: true);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this seems fine. though perhaps it should be a loop? though i guess the change of having multiple empty regions in a row is so low as to be pointless :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

💭 Yeah, the main goal here was to not mess up a known file header pattern.

@jinujoseph jinujoseph added this to the 17.1.P1 milestone Oct 19, 2021
@sharwell sharwell marked this pull request as ready for review October 19, 2021 22:25
@sharwell sharwell requested a review from a team as a code owner October 19, 2021 22:25
Copy link
Copy Markdown
Contributor

@jmarolf jmarolf left a comment

Choose a reason for hiding this comment

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

:shipit:

@sharwell sharwell enabled auto-merge October 19, 2021 23:59
@sharwell sharwell disabled auto-merge October 19, 2021 23:59
@sharwell sharwell enabled auto-merge October 20, 2021 18:24
@sharwell sharwell merged commit d204c5b into dotnet:main Oct 22, 2021
@ghost ghost modified the milestones: 17.1.P1, Next Oct 22, 2021
@jcouv
Copy link
Copy Markdown
Member

jcouv commented Oct 22, 2021

Nice. Thanks!

@RikkiGibson RikkiGibson modified the milestones: Next, 17.1.P1 Oct 25, 2021
@sharwell sharwell deleted the enable-nullable branch October 27, 2021 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fixer to add project-level nullable enable option

6 participants