Skip to content

Fixing parsing of diffs with empty neutral lines and diffs without co… #32

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ public List<Diff> parse(InputStream in) {
case INITIAL:
// nothing to do
break;
case END_HEADER:
parsedDiffs.add(currentDiff);
currentDiff = new Diff();
case HEADER:
parseHeader(currentDiff, currentLine);
break;
Expand Down Expand Up @@ -101,7 +104,7 @@ public List<Diff> parse(InputStream in) {
}

private void parseNeutralLine(Diff currentDiff, String currentLine) {
Line line = new Line(Line.LineType.NEUTRAL, currentLine);
Line line = new Line(Line.LineType.NEUTRAL, currentLine.startsWith(" ") ? currentLine.substring(1) : currentLine);
currentDiff.getLatestHunk().getLines().add(line);
}

Expand Down
57 changes: 46 additions & 11 deletions src/main/java/io/reflectoring/diffparser/unified/ParserState.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ public ParserState nextState(ParseWindow window) {
}
},

/**
* The parser is in this state if it is currently parsing a header line,
* which immediately followed another diff, with the "end" diff delimiter.
*/
END_HEADER {
@Override
public ParserState nextState(ParseWindow window) {
String line = window.getFocusLine();
if (matchesFromFilePattern(line)) {
logTransition(line, HEADER, FROM_FILE);
return FROM_FILE;
} else {
logTransition(line, HEADER, HEADER);
return HEADER;
}
}
},

/**
* The parser is in this state if it is currently parsing the line containing the "from" file.
* <p/>
Expand Down Expand Up @@ -142,6 +160,9 @@ public ParserState nextState(ParseWindow window) {
} else if (matchesEndPattern(line, window)) {
logTransition(line, FROM_LINE, END);
return END;
} else if (matchesHeaderPattern(line, window)) {
logTransition(line, FROM_LINE, END_HEADER);
return END_HEADER;
} else if (matchesHunkStartPattern(line)) {
logTransition(line, FROM_LINE, HUNK_START);
return HUNK_START;
Expand Down Expand Up @@ -172,6 +193,9 @@ public ParserState nextState(ParseWindow window) {
} else if (matchesEndPattern(line, window)) {
logTransition(line, TO_LINE, END);
return END;
} else if (matchesHeaderPattern(line, window)) {
logTransition(line, TO_LINE, END_HEADER);
return END_HEADER;
} else if (matchesHunkStartPattern(line)) {
logTransition(line, TO_LINE, HUNK_START);
return HUNK_START;
Expand Down Expand Up @@ -199,6 +223,9 @@ public ParserState nextState(ParseWindow window) {
} else if (matchesEndPattern(line, window)) {
logTransition(line, NEUTRAL_LINE, END);
return END;
} else if (matchesHeaderPattern(line, window)) {
logTransition(line, NEUTRAL_LINE, END_HEADER);
return END_HEADER;
} else if (matchesHunkStartPattern(line)) {
logTransition(line, NEUTRAL_LINE, HUNK_START);
return HUNK_START;
Expand All @@ -217,8 +244,8 @@ public ParserState nextState(ParseWindow window) {
@Override
public ParserState nextState(ParseWindow window) {
String line = window.getFocusLine();
logTransition(line, END, INITIAL);
return INITIAL;
logTransition(line, END, HEADER);
return HEADER;
}
};

Expand Down Expand Up @@ -272,24 +299,32 @@ protected boolean matchesEndPattern(String line, ParseWindow window) {
// We found another newline after the current newline without a start of a new diff in between. That makes the
// current line just a newline within the current diff.
return false;
} else if (matchesHunkStartPattern(futureLine) ||
matchesFromLinePattern(futureLine) ||
matchesToLinePattern(futureLine)) {
// We found an added/removed line, or another hunk start - this
// was just a neutral line in the middle of a hunk.
return false;
} else {
i++;
}
}
// We reached the end of the stream.
return true;
} else {
// some diff tools like "svn diff" do not put an empty line between two diffs
// we add that empty line and call the method again
String nextFromFileLine = window.getFutureLine(3);
if(nextFromFileLine != null && matchesFromFilePattern(nextFromFileLine)){
window.addLine(1, "");
return matchesEndPattern(line, window);
}else{
return false;
}
return false;
}
}

protected boolean matchesHeaderPattern(String line, ParseWindow window) {
// some diff tools like "svn diff" do not put an empty line between two diffs
// we add that empty line and call the method again
String nextFromFileLine = window.getFutureLine(2);
if(nextFromFileLine != null && matchesFromFilePattern(nextFromFileLine)){
return matchesEndPattern("", window);
}else{
return false;
}
}

}
Loading