Skip to content

Add code fix to help choose which piece to take when there is a merge conflict#15853

Merged
CyrusNajmabadi merged 8 commits intodotnet:masterfrom
CyrusNajmabadi:mergeMarkerAnalyzer
Mar 2, 2017
Merged

Add code fix to help choose which piece to take when there is a merge conflict#15853
CyrusNajmabadi merged 8 commits intodotnet:masterfrom
CyrusNajmabadi:mergeMarkerAnalyzer

Conversation

@CyrusNajmabadi
Copy link
Contributor

Looks like this:

image

image

image

@CyrusNajmabadi CyrusNajmabadi changed the title Add code fix to help choose which piece to take when there is a merge conflict." [mergeMarkerAnalyzer ae14e1d] Add code Add code fix to help choose which piece to take when there is a merge conflict Dec 13, 2016
@dpoeschl
Copy link
Contributor

@CyrusNajmabadi The title of this PR is misleading. There's a non-trivial amount of compiler changes too.

@CyrusNajmabadi
Copy link
Contributor Author

This is a branch off of #15850 . That PR contains the compiler changes, and i'm working through getting that reviewed.

This PR was around the CodeFixProvider. It would not go in without the other PR being reviewed and going in first.

<data name="ERR_OpenEndedComment" xml:space="preserve">
<value>End-of-file found, '*/' expected</value>
</data>
<data name="ERR_Merge_conflict_marker_encountered" xml:space="preserve">
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you push the resource down and reuse it instead of duplicating it between C# and VB?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. The compilers don't work that way wrt resources.

ERR_PPDefFollowsToken = 1032,
//ERR_TooManyLines = 1033, unused in Roslyn.
//ERR_LineTooLong = 1034, unused in Roslyn.
ERR_Merge_conflict_marker_encountered = 1034,
Copy link
Contributor

Choose a reason for hiding this comment

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

CS1034 already has meaning, so I wouldn't re-use it like this. https://msdn.microsoft.com/en-us/library/7bb77w7x(v=vs.90).aspx

return triviaList;
}

private void LexConflictMarkerEndOfLine(ref SyntaxListBuilder triviaList)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe name this LexConflictMarkerEndLines?
But I don't understand why more than one newline after <<<<<<< would be trailing trivia on it. Any subsequent newlines feel like they belong to the first token in that half of the diff (so that a codefix taking everything in the "mine" side wouldn't also need to worry about extra newlines attached to the <<<<<<< line -- they could just take everything in that half of the diff and know that it's correct.

Copy link
Member

Choose a reason for hiding this comment

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

Agree, and that is the general heuristic for newline trivia - it is generally attached to the next token, except the first newline which ends a line.

ch <> "_"c AndAlso
ch <> "R"c AndAlso
ch <> "r"c AndAlso
ch <> "<"c AndAlso
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment above is now incorrect.

ShouldBeGoodQuickToken("ab$=")
ShouldBeGoodQuickToken(" a =")
ShouldBeGoodQuickToken(" =a")
ShouldBeGoodQuickToken("a,")
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand these changes.

while (true)
{
token = token.GetNextToken(includeZeroWidth: true);
if (token.RawKind == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

A comment explaining the magic number would be nice

}

var index = GetEqualsConflictMarkerIndex(text, token);
if (index >= 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Verifying my understanding of the compiler side: the <<<<<<< is only treated as a conflict marker if there exists a ======= and a >>>>>>> to match, right? Otherwise this index would always be -1 and you'd be stuck in a loop either forever or until GetNextToken fails, I'm not sure which.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and you'd be stuck in a loop either forever or until GetNextToken fails, I'm not sure which.

You're in the loop until there are no more tokens in the file, in which case the above 'if' check breaks out.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep. Thanks.

if (index + 3 < token.LeadingTrivia.Count)
{
var equalsTrivia = leadingTrivia[index];
var endOfLineTrivia = leadingTrivia[index + 1];
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is actually all of the endlines, then pluralizing here would be better.

return -1;
}

private SyntaxTrivia GetEqualsConflictMarker(SyntaxToken token)
Copy link
Contributor

Choose a reason for hiding this comment

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

What's going on here? I don't see any callers.


private void ClassifyConflictMarker(SyntaxTrivia trivia)
{
AddClassification(trivia, ClassificationTypeNames.Comment);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we introduce a new color here? I might want to make my conflict markers bright red. 😄

@dpoeschl
Copy link
Contributor

In general, it would be nice to see more tests of "broken" scenarios. Almost conflict resolution code, but without the =======, or without the >>>>>>>, or whatever.

ERR_PPDefFollowsToken = 1032,
//ERR_TooManyLines = 1033, unused in Roslyn.
//ERR_LineTooLong = 1034, unused in Roslyn.
ERR_Merge_conflict_marker_encountered = 1034,
Copy link
Member

Choose a reason for hiding this comment

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

New error codes should please be moved near then end. They are currently approximately segregated by the version of the compiler in which they were introduced.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@CyrusNajmabadi
Copy link
Contributor Author

retest windows_release_unit64_prtest please

@DustinCampbell
Copy link
Member

This is very cool! Should we get the right folks to review the API additions, or wait on that until it's closer to being ready?


var startTrivia = root.FindTrivia(context.Span.Start);

if (!IsConflictMarker(text, startTrivia, '<'))
Copy link
Contributor

Choose a reason for hiding this comment

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

So this only provides a fix on the <<<<<<<, but not the other markers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently yes.

@Pilchie Pilchie added this to the 2.1 milestone Jan 9, 2017
@agocke agocke changed the base branch from post-dev15 to master February 14, 2017 23:28
}

return start < TextWindow.Position;
return start < TextWindow.Position;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Extra space.

return triviaList;
}

private void LexConflictMarkerEndOfLine(ref SyntaxListBuilder triviaList)
Copy link
Member

Choose a reason for hiding this comment

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

Agree, and that is the general heuristic for newline trivia - it is generally attached to the next token, except the first newline which ends a line.

@CyrusNajmabadi CyrusNajmabadi merged commit ef7e35e into dotnet:master Mar 2, 2017
@CyrusNajmabadi CyrusNajmabadi deleted the mergeMarkerAnalyzer branch March 2, 2017 03:06
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.

8 participants