Create AddNonNullTypes code fixer#30098
Create AddNonNullTypes code fixer#30098jcouv wants to merge 7 commits intodotnet:features/NullableReferenceTypesfrom
Conversation
ef2dcad to
0d8d37e
Compare
There was a problem hiding this comment.
Typo'ed NonNull #Resolved
There was a problem hiding this comment.
I don't think that's very useful. Most likely you should use a module-level attribute instead for such cases.
Also, I suspect it's not trivial to implement properly.
The cost/benefit combination makes it low priority at the moment (we're trying to address blockers before preview 1). #Closed
There was a problem hiding this comment.
I'll leave it to you to decide the right design. However:
Also, I suspect it's not trivial to implement properly.
This should be very trivial. Basically, you derive from SyntaxEditorBasedCodeFixProvider, and implement FixAll. Your fixall will wlak all your diagnostics and get the unique set of TypeDecls to fix. Then it will just walk all of those and add attributes like you do today.
#Closed
There was a problem hiding this comment.
Yes, that'd be the core, but what about FixAll across documents (partial type scenarios)?
SyntaxEditorBasedCodeFixProvider seems to work on a document basis. #Closed
There was a problem hiding this comment.
Hrmm... i'm a bit skeptical that that's an important enough scenario to care about. It seems fine to just place the attribute on the differnet parts :)
That said, if this is important enogh for you, an easy fix is to simply pass along the FixAllState object (or the FixAllScope) with SyntaxEditorBasedFixAllProvider.FixAllAsync. Then, if it's not 'document' you simply only fix the TypeDecl if it is considered the 'first part' of the partial type. #Closed
There was a problem hiding this comment.
If we went with the brute force approach, the fixer would produce errors in cases involving partial types (the attribute can't be specified multiple times).
If we try a more tricky approach, I'm concerned that we would produce fewer attributes than required to fix the warnings: the scenario is that you have a partial class where the 'first part' doesn't involve any nullable notations (thus no warnings), and some other part does.
Maybe there is a way to share state across documents when doing such a FixAll? That would solve the problem.
Just to give options labels:
- no FixAll
- brute-force FixAll (per document, handle type nesting)
- partial-aware FixAll (prefer 'first part', per document, handle type nesting)
- cross-document FixAll #Closed
There was a problem hiding this comment.
Or just fix this part:
(the attribute can't be specified multiple times).
I personally get super frustrated with these types of attributes because now i have to deal with that :) #Closed
There was a problem hiding this comment.
the scenario is that you have a partial class where the 'first part' doesn't involve any nullable notations (thus no warnings), and some other part does.
Gotcha. An interesting case to be sure. It does feel like we could expose a more flexibly entrypoint in SyntaxEditorBasedCodeFixProvider. One where you got to handle all the diagnostics at once, instead of us handling each document one at a time, having you only fixup that document. #Closed
src/Features/CSharp/Portable/AddNonNullTypes/CSharpAddNonNullTypesCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
this keeps syntax trees alive. preferable to not do that. #Closed
There was a problem hiding this comment.
Fixed. Also fixed HideBase which I had modeled after. #Closed
|
@dotnet/roslyn-ide for review. Thanks #Resolved |
1 similar comment
|
@dotnet/roslyn-ide for review. Thanks #Resolved |
|
@dotnet/roslyn-ide for review (simple fixer). Thanks #Resolved |
jasonmalinowski
left a comment
There was a problem hiding this comment.
Looks like there's some missing tests and one possible functional bug. Great start though.
There was a problem hiding this comment.
So this is a bug then? It seems we should have this assert the correct behavior and then skip the test with a Skip attribute, rather than assert "wrong" behavior? #Resolved
There was a problem hiding this comment.
Skipping tests risks that we forget unskipping.
The comment is there to clarify that the expectation is "wrong". #Resolved
There was a problem hiding this comment.
Skipped tests that aren't unskipped we can tool to catch automatically, this we can't. Please just use a skip and have it assert the right thing. #Resolved
There was a problem hiding this comment.
The "right thing" is not yet decided, as explained in the comment and the linked issue. Two options:
- not trigger
- toggle to
true
I don't think this PR should depend on figuring out the design for some future work.
There was a problem hiding this comment.
"NonNullTYpes" has a typo. #Resolved
src/Features/CSharp/Portable/AddNonNullTypes/CSharpAddNonNullTypesCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/AddNonNullTypes/CSharpAddNonNullTypesCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
src/Features/CSharp/Portable/AddNonNullTypes/CSharpAddNonNullTypesCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Should be indented a bit farther. #Resolved
|
@jasonmalinowski All feedback addressed, except the request to skip a test (because the "right" behavior is pending some design). #Resolved |
| = ImmutableArray.Create(CS8632, CS8629); | ||
|
|
||
| public CSharpAddNonNullTypesCodeFixProvider() | ||
| : base(supportsFixAll: false) |
| <value>Hide base member</value> | ||
| </data> | ||
| <data name="Add_NonNullTypes_attribute" xml:space="preserve"> | ||
| <value>Add NonNullTypes attribute</value> |
There was a problem hiding this comment.
Nit: would probably look better as Add [NonNullTypes] attribute #Pending
| using System.Threading; | ||
| using System; | ||
| using Microsoft.CodeAnalysis.CodeActions; | ||
| using Microsoft.CodeAnalysis.Editing; |
There was a problem hiding this comment.
ordering. #Pending
| private class MyCodeAction : CodeAction.DocumentChangeAction | ||
| { | ||
| public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument) | ||
| : base(CSharpFeaturesResources.Hide_base_member, createChangedDocument) |
There was a problem hiding this comment.
dumb question... why was this rolled into this PR? #Resolved
There was a problem hiding this comment.
Earlier in this PR, you pointed out bad pattern (holding onto objects) which I had picked up from that fixer. #Resolved
| if (containingType == null) | ||
| { | ||
| return; | ||
| } |
There was a problem hiding this comment.
this is somewhat busted in that we have already registered the fix, but now it doesn't do anything in this case. Unless we're guaranteeing that this diagnostic will always be reported inside a type-decl, then we need to change tings slightly. specifically, the RegisterCodeFixesAsync method needs to check if we're in a containing-type first, before registering teh fix.
| @@ -42,7 +51,25 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) | |||
| return; | |||
There was a problem hiding this comment.
same issue here. but this seems to be a different feature. so it's buggy that feature was written that way.
|
I'm going to hold-off this PR, as we're going to switch to a directive method to turn the feature on. |
|
Directive approach seems far saner. does this mean no concerns about attribute circularity? |
|
@CyrusNajmabadi Yes. Cycles are a key motivation for switching to directive. |
|
Loveit! |
|
Closing because we don't use the |
This is a first take. The goal is to give users a convenient path into nullable feature (start using nullable-related syntax, we offer to turn the feature on).
Some things that are not handled yet:
[NonNullTypes(false)]then we should flip it totrueinstead[module: NonNullTypes](but we'll need to decide which file to put it in, or whether to inject it via msbuild/GenerateAssemblyInfoinstead)using System.Runtime.CompilerServices;instead?(Filed follow-up issue #30099)