Merge pull request #16135 from katemihalikova/diff3

Add support for diff3-style merge
This commit is contained in:
Nathan Shively-Sanders 2017-05-30 11:27:22 -07:00 committed by GitHub
commit 2c3c4dd465
12 changed files with 258 additions and 10 deletions

View file

@ -429,6 +429,7 @@ namespace ts {
case CharacterCodes.slash:
// starts of normal trivia
case CharacterCodes.lessThan:
case CharacterCodes.bar:
case CharacterCodes.equals:
case CharacterCodes.greaterThan:
// Starts of conflict marker trivia
@ -496,6 +497,7 @@ namespace ts {
break;
case CharacterCodes.lessThan:
case CharacterCodes.bar:
case CharacterCodes.equals:
case CharacterCodes.greaterThan:
if (isConflictMarkerTrivia(text, pos)) {
@ -562,12 +564,12 @@ namespace ts {
}
}
else {
Debug.assert(ch === CharacterCodes.equals);
// Consume everything from the start of the mid-conflict marker to the start of the next
// end-conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
// Consume everything from the start of a ||||||| or ======= marker to the start
// of the next ======= or >>>>>>> marker.
while (pos < len) {
const ch = text.charCodeAt(pos);
if (ch === CharacterCodes.greaterThan && isConflictMarkerTrivia(text, pos)) {
const currentChar = text.charCodeAt(pos);
if ((currentChar === CharacterCodes.equals || currentChar === CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
break;
}
@ -1562,6 +1564,16 @@ namespace ts {
pos++;
return token = SyntaxKind.OpenBraceToken;
case CharacterCodes.bar:
if (isConflictMarkerTrivia(text, pos)) {
pos = scanConflictMarkerTrivia(text, pos, error);
if (skipTrivia) {
continue;
}
else {
return token = SyntaxKind.ConflictMarkerTrivia;
}
}
if (text.charCodeAt(pos + 1) === CharacterCodes.bar) {
return pos += 2, token = SyntaxKind.BarBarToken;
}

View file

@ -424,6 +424,50 @@ class D { }\r\n\
comment("=======\r\nclass D { }\r\n"),
comment(">>>>>>> Branch - a"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification(
"class C {\r\n\
<<<<<<< HEAD\r\n\
v = 1;\r\n\
||||||| merged common ancestors\r\n\
v = 3;\r\n\
=======\r\n\
v = 2;\r\n\
>>>>>>> Branch - a\r\n\
}",
ts.EndOfLineState.None,
keyword("class"),
identifier("C"),
punctuation("{"),
comment("<<<<<<< HEAD"),
identifier("v"),
operator("="),
numberLiteral("1"),
punctuation(";"),
comment("||||||| merged common ancestors\r\n v = 3;\r\n"),
comment("=======\r\n v = 2;\r\n"),
comment(">>>>>>> Branch - a"),
punctuation("}"),
finalEndOfLineState(ts.EndOfLineState.None));
testLexicalClassification(
"<<<<<<< HEAD\r\n\
class C { }\r\n\
||||||| merged common ancestors\r\n\
class E { }\r\n\
=======\r\n\
class D { }\r\n\
>>>>>>> Branch - a\r\n",
ts.EndOfLineState.None,
comment("<<<<<<< HEAD"),
keyword("class"),
identifier("C"),
punctuation("{"),
punctuation("}"),
comment("||||||| merged common ancestors\r\nclass E { }\r\n"),
comment("=======\r\nclass D { }\r\n"),
comment(">>>>>>> Branch - a"),
finalEndOfLineState(ts.EndOfLineState.None));
});
it("'of' keyword", function () {

View file

@ -685,9 +685,9 @@ namespace ts {
continue;
}
// for the ======== add a comment for the first line, and then lex all
// subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.equals);
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
}
}
@ -782,8 +782,8 @@ namespace ts {
}
function classifyDisabledMergeCode(text: string, start: number, end: number) {
// Classify the line that the ======= marker is on as a comment. Then just lex
// all further tokens and add them to the result.
// Classify the line that the ||||||| or ======= marker is on as a comment.
// Then just lex all further tokens and add them to the result.
let i: number;
for (i = start; i < end; i++) {
if (isLineBreak(text.charCodeAt(i))) {

View file

@ -0,0 +1,24 @@
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(2,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(4,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(6,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia1.ts(8,1): error TS1185: Merge conflict marker encountered.
==== tests/cases/compiler/conflictMarkerDiff3Trivia1.ts (4 errors) ====
class C {
<<<<<<< HEAD
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 1;
||||||| merged common ancestors
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 3;
=======
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
v = 2;
>>>>>>> Branch-a
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
}

View file

@ -0,0 +1,18 @@
//// [conflictMarkerDiff3Trivia1.ts]
class C {
<<<<<<< HEAD
v = 1;
||||||| merged common ancestors
v = 3;
=======
v = 2;
>>>>>>> Branch-a
}
//// [conflictMarkerDiff3Trivia1.js]
var C = (function () {
function C() {
this.v = 1;
}
return C;
}());

View file

@ -0,0 +1,34 @@
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(3,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(4,6): error TS2304: Cannot find name 'a'.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(6,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(9,1): error TS1185: Merge conflict marker encountered.
tests/cases/compiler/conflictMarkerDiff3Trivia2.ts(12,1): error TS1185: Merge conflict marker encountered.
==== tests/cases/compiler/conflictMarkerDiff3Trivia2.ts (5 errors) ====
class C {
foo() {
<<<<<<< B
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
a();
~
!!! error TS2304: Cannot find name 'a'.
}
||||||| merged common ancestors
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
c();
}
=======
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
b();
}
>>>>>>> A
~~~~~~~
!!! error TS1185: Merge conflict marker encountered.
public bar() { }
}

View file

@ -0,0 +1,28 @@
//// [conflictMarkerDiff3Trivia2.ts]
class C {
foo() {
<<<<<<< B
a();
}
||||||| merged common ancestors
c();
}
=======
b();
}
>>>>>>> A
public bar() { }
}
//// [conflictMarkerDiff3Trivia2.js]
var C = (function () {
function C() {
}
C.prototype.foo = function () {
a();
};
C.prototype.bar = function () { };
return C;
}());

View file

@ -0,0 +1,9 @@
class C {
<<<<<<< HEAD
v = 1;
||||||| merged common ancestors
v = 3;
=======
v = 2;
>>>>>>> Branch-a
}

View file

@ -0,0 +1,15 @@
class C {
foo() {
<<<<<<< B
a();
}
||||||| merged common ancestors
c();
}
=======
b();
}
>>>>>>> A
public bar() { }
}

View file

@ -0,0 +1,22 @@
/// <reference path='fourslash.ts' />
////class C {
////<<<<<<< HEAD
////v = 1;
////||||||| merged common ancestors
////v = 3;
////=======
////v = 2;
////>>>>>>> Branch - a
////}
format.document();
verify.currentFileContentIs("class C {\r\n\
<<<<<<< HEAD\r\n\
v = 1;\r\n\
||||||| merged common ancestors\r\n\
v = 3;\r\n\
=======\r\n\
v = 2;\r\n\
>>>>>>> Branch - a\r\n\
}");

View file

@ -0,0 +1,23 @@
/// <reference path="fourslash.ts"/>
////class C {
////<<<<<<< HEAD
//// v = 1;
////||||||| merged common ancestors
//// v = 3;
////=======
//// v = 2;
////>>>>>>> Branch - a
////}
const c = classification;
verify.syntacticClassificationsAre(
c.keyword("class"), c.className("C"), c.punctuation("{"),
c.comment("<<<<<<< HEAD"),
c.identifier("v"), c.operator("="), c.numericLiteral("1"), c.punctuation(";"),
c.comment("||||||| merged common ancestors"),
c.identifier("v"), c.punctuation("="), c.numericLiteral("3"), c.punctuation(";"),
c.comment("======="),
c.identifier("v"), c.punctuation("="), c.numericLiteral("2"), c.punctuation(";"),
c.comment(">>>>>>> Branch - a"),
c.punctuation("}"));

View file

@ -0,0 +1,19 @@
/// <reference path="fourslash.ts"/>
////<<<<<<< HEAD
////class C { }
////||||||| merged common ancestors
////class E { }
////=======
////class D { }
////>>>>>>> Branch - a
const c = classification;
verify.syntacticClassificationsAre(
c.comment("<<<<<<< HEAD"),
c.keyword("class"), c.className("C"), c.punctuation("{"), c.punctuation("}"),
c.comment("||||||| merged common ancestors"),
c.keyword("class"), c.identifier("E"), c.punctuation("{"), c.punctuation("}"),
c.comment("======="),
c.keyword("class"), c.identifier("D"), c.punctuation("{"), c.punctuation("}"),
c.comment(">>>>>>> Branch - a"));