-
Notifications
You must be signed in to change notification settings - Fork 4.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
A code fix for a set of Documentation Comment diagnostics returned by the compiler #12902
Conversation
Thanks for the submission - tagging @dotnet/roslyn-ide for review |
test vsi please |
<Document> | ||
class Program1 | ||
{ | ||
/// <summary> |
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.
Minor note: if you wrap the body in <![CDATA[
and ]]>
tags you don't need <
and >
which might make this easier to read. E.g.,
var initial = @"
<Workspace>
<Project ...>
<Document>
<![CDATA[
class Program 1
{
/// <summary>
...
]]>
...
";
Aside from my minor comments, looks good to me. |
public void Fizz(int value) {} | ||
} | ||
"; | ||
var parseOptions = Options.Regular.WithDocumentationMode(DocumentationMode.Diagnose); |
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.
so the pattern i prefer in cases like this is that you have your own TestAsync function in this class which creates theese parse options and calls the original TestAsync. Then all the functions in this class call that Test function. Test code follows hte same rules as normal code and we shoudl apply DRY.
(yes, i know there are TONS of cases where we violate this. but no reason to continue bad habits when we can avoid them). Thanks!
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.
Also, the core test method you call must pass in:
, compareTokens: false
The reason for this is that if you don't pass this in, then our test code will explicitly ignore trivia. That's obviously bad because this entire feature is precisely about changing trivia. :)
This is also the benefit of having a single test method. You change one and everything else picks it up.
As usual @Hosch250 your commitment to testing is phenomenal. Your contributions are very appreciated by the entire team. |
Looks like test failure is due to: #11032 retest windows_vsi_p1_open_prtest please |
@@ -14,351 +14,373 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.DocumentationComme | |||
Nothing, | |||
New VisualBasicRemoveDocCommentNodeCodeFixProvider()) | |||
End Function | |||
|
|||
Private Overloads Async Function TestAsync(ByVal initial As String, ByVal expected As String) As Task | |||
|
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.
remove newline.
LGTM. @Pilchie Any concerns here? |
If you hold off a bit on merging this, I'll add the fix for CS1572 also. The others all involve removing the entire block, or adding elements (I think). |
@Hosch250 alright, thanks, I'll hold off on merging until I hear from you. |
Just running my tests right now, so it shouldn't be long :) |
…nding the correct node slightly.
{ | ||
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
var commentParent = root.FindNode(span); | ||
var triviaNode = commentParent.GetLeadingTrivia().Single(s => s.GetLocation().SourceSpan.Contains(span)); |
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.
s => s.Span.Contains(span)
I will fix these and add fixes for BC42313 and BC42315 as well (I just need to add them to the list of fixable diagnostics and add tests). |
|
||
var triviaNodeStructure = triviaNode.GetStructure(); | ||
|
||
var paramNode = triviaNodeStructure.ChildNodes().Single(s => s.Span.Contains(span)); |
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.
single is dangerous here. What if you had something like:
/// <summary>
/// <param ... >
/// </summary>
Couldn't both the summary node and the param node contain the span in question?
I'd far prefer something like SingleOrDefault just to be resilient to strange parse tree structures. (same applies to the higher use of Single).
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 will change this, but, IIRC, SingleOrDefault
still throws if there is more than one matching node. I'll have to add tests for this possibility.
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 are correct. 'FirstOrDefault' then. :)
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.
Or, somethgin that actually tries to get the right node but won't crash :)
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.
Yes, I will have to redesign this.
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.
Actually, no, that situation you show will not cause a crash. I only retrieve the child nodes, which is the first level under the given element. This would crash if I had retrieved the descendant nodes, but the only way it could crash under the child nodes would be if the span covered two elements. I will change it to SingleOrDefault
and return an unchanged document if I can't find a matching node, however, unless you think this isn't safe enough.
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.
Ah good point. Can you still do FirstOrDefault then, and just bail in the default case. I don't want us to introduce a crash with Single late in the process that only happens in rare cases, but we don't run into until some customer hits it :)
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.
Yes, that would be good--I wouldn't want to cause a crash either.
A few more comments. If @Pilchie is cool with this, and the comments are addressed, then 👍 Thanks! |
I may not be able to get this in tonight. Working on addressing the comments and adding tests right now. |
I just caught a bug:
That fires the diagnostic off, and running my quick fix will kill the whole |
@CyrusNajmabadi Bug fixed and ready for review again. |
I won't have a chance to review until Saturday, but this can be merged before then if @CyrusNajmabadi and @jmarolf are happy with it. |
test vsi please |
Is the reason for failure #11032 again? |
|
||
// There *should* always be one node here if the diagnostic fires, | ||
// but we will use `FirstOrDefault` just to safeguard against a sly bug | ||
var triviaNode = commentParent.GetLeadingTrivia().FirstOrDefault(s => s.Span.Contains(span)); |
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 can use the flag to search in trivia as well as non-trivia nodes here to simplify this.
test vsi please |
@CyrusNajmabadi I'm ready for this to be reviewed again whenever you are ready. I made a few slight changes to use the pre-written node-finding API, and fixed the bug I mentioned on Wednesday night. |
Thank you for the information. |
paramNode = paramNode.Parent; | ||
} | ||
|
||
if (paramNode == 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.
This whole check should happen prior to calling "RegisterCodeFix". Because if we can't transform the document then we shouldn't offer a fix.
@Hosch250 If you extract that code into a helper you can then call it both before and after the 'RegisterXXX' call. Make that change and i'll happily merge this. If you want, i'm also ok making that change myself. Your call! |
I will do it. |
Done, sorry it took so long. I will be back in about an hour in case you have more questions. |
Merged in. Thanks a ton! |
Thanks for merging @CyrusNajmabadi. and thanks for the awesome contribution @Hosch250! |
Reference #7070