Skip to content

Commit 7b940ff

Browse files
committed
refactor(UnifiedDiffReader): reduce cognitive complexity from 45 to ~5 via phase-driven helpers
1 parent f42ef36 commit 7b940ff

2 files changed

Lines changed: 115 additions & 99 deletions

File tree

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,14 @@ nbproject/
44
target/
55

66
*.iml
7+
8+
# Assignment docs and generated reports (not part of library source)
9+
docs/
10+
*.docx
11+
*.pdf
12+
*.py
13+
14+
# OS artifacts
15+
.DS_Store
16+
Thumbs.db
17+
desktop.ini

java-diff-utils/src/main/java/com/github/difflib/unifieddiff/UnifiedDiffReader.java

Lines changed: 104 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -82,121 +82,128 @@ public final class UnifiedDiffReader {
8282
private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine("^-", this::processDelLine);
8383
private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine("^\\+", this::processAddLine);
8484

85+
private final UnifiedDiffLine[] FILE_HEADER_RULES = {
86+
DIFF_COMMAND,
87+
SIMILARITY_INDEX,
88+
INDEX,
89+
FROM_FILE,
90+
TO_FILE,
91+
RENAME_FROM,
92+
RENAME_TO,
93+
COPY_FROM,
94+
COPY_TO,
95+
NEW_FILE_MODE,
96+
DELETED_FILE_MODE,
97+
OLD_MODE,
98+
NEW_MODE,
99+
BINARY_ADDED,
100+
BINARY_DELETED,
101+
BINARY_EDITED
102+
};
103+
104+
private final UnifiedDiffLine[] HEADER_STOP_RULES = {
105+
DIFF_COMMAND,
106+
SIMILARITY_INDEX,
107+
INDEX,
108+
FROM_FILE,
109+
TO_FILE,
110+
RENAME_FROM,
111+
RENAME_TO,
112+
COPY_FROM,
113+
COPY_TO,
114+
NEW_FILE_MODE,
115+
DELETED_FILE_MODE,
116+
OLD_MODE,
117+
NEW_MODE,
118+
BINARY_ADDED,
119+
BINARY_DELETED,
120+
BINARY_EDITED,
121+
CHUNK
122+
};
123+
85124
private UnifiedDiffFile actualFile;
86125

87126
UnifiedDiffReader(Reader reader) {
88127
this.READER = new InternalUnifiedDiffReader(reader);
89128
}
90129

91-
// schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, new_file],
92-
// [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
93-
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
94-
// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
95130
private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
96-
// String headerTxt = "";
97-
// LOG.log(Level.FINE, "header parsing");
98-
// String line = null;
99-
// while (READER.ready()) {
100-
// line = READER.readLine();
101-
// LOG.log(Level.FINE, "parsing line {0}", line);
102-
// if (DIFF_COMMAND.validLine(line) || INDEX.validLine(line)
103-
// || FROM_FILE.validLine(line) || TO_FILE.validLine(line)
104-
// || NEW_FILE_MODE.validLine(line)) {
105-
// break;
106-
// } else {
107-
// headerTxt += line + "\n";
108-
// }
109-
// }
110-
// if (!"".equals(headerTxt)) {
111-
// data.setHeader(headerTxt);
112-
// }
113-
114131
String line = READER.readLine();
115132
while (line != null) {
116-
String headerTxt = "";
117-
LOG.log(Level.FINE, "header parsing");
118-
while (line != null) {
119-
LOG.log(Level.FINE, "parsing line {0}", line);
120-
if (validLine(
121-
line,
122-
DIFF_COMMAND,
123-
SIMILARITY_INDEX,
124-
INDEX,
125-
FROM_FILE,
126-
TO_FILE,
127-
RENAME_FROM,
128-
RENAME_TO,
129-
COPY_FROM,
130-
COPY_TO,
131-
NEW_FILE_MODE,
132-
DELETED_FILE_MODE,
133-
OLD_MODE,
134-
NEW_MODE,
135-
BINARY_ADDED,
136-
BINARY_DELETED,
137-
BINARY_EDITED,
138-
CHUNK)) {
139-
break;
140-
} else {
141-
headerTxt += line + "\n";
142-
}
143-
line = READER.readLine();
144-
}
145-
if (!"".equals(headerTxt)) {
146-
data.setHeader(headerTxt);
133+
line = parseHeaderSection(line);
134+
line = parseFileHeader(line);
135+
line = parseChunkSection(line);
136+
if (line == null || (line.startsWith("--") && !line.startsWith("---"))) {
137+
break;
147138
}
148-
if (line != null && !CHUNK.validLine(line)) {
149-
initFileIfNecessary();
150-
while (line != null && !CHUNK.validLine(line)) {
151-
if (!processLine(
152-
line,
153-
DIFF_COMMAND,
154-
SIMILARITY_INDEX,
155-
INDEX,
156-
FROM_FILE,
157-
TO_FILE,
158-
RENAME_FROM,
159-
RENAME_TO,
160-
COPY_FROM,
161-
COPY_TO,
162-
NEW_FILE_MODE,
163-
DELETED_FILE_MODE,
164-
OLD_MODE,
165-
NEW_MODE,
166-
BINARY_ADDED,
167-
BINARY_DELETED,
168-
BINARY_EDITED)) {
169-
throw new UnifiedDiffParserException("expected file start line not found");
170-
}
171-
line = READER.readLine();
172-
}
139+
}
140+
parseTailSection();
141+
return data;
142+
}
143+
144+
private String parseHeaderSection(String currentLine) throws IOException {
145+
String line = currentLine;
146+
String headerTxt = "";
147+
LOG.log(Level.FINE, "header parsing");
148+
while (line != null) {
149+
LOG.log(Level.FINE, "parsing line {0}", line);
150+
if (validLine(line, HEADER_STOP_RULES)) {
151+
break;
152+
} else {
153+
headerTxt += line + "\n";
173154
}
174-
if (line != null) {
175-
processLine(line, CHUNK);
176-
while ((line = READER.readLine()) != null) {
177-
line = checkForNoNewLineAtTheEndOfTheFile(line);
178-
179-
if (!processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL)) {
180-
throw new UnifiedDiffParserException("expected data line not found");
181-
}
182-
if ((originalTxt.size() == old_size && revisedTxt.size() == new_size)
183-
|| (old_size == 0
184-
&& new_size == 0
185-
&& originalTxt.size() == this.old_ln
186-
&& revisedTxt.size() == this.new_ln)) {
187-
finalizeChunk();
188-
break;
189-
}
155+
line = READER.readLine();
156+
}
157+
if (!"".equals(headerTxt)) {
158+
data.setHeader(headerTxt);
159+
}
160+
return line;
161+
}
162+
163+
private String parseFileHeader(String currentLine) throws IOException, UnifiedDiffParserException {
164+
String line = currentLine;
165+
if (line != null && !CHUNK.validLine(line)) {
166+
initFileIfNecessary();
167+
while (line != null && !CHUNK.validLine(line)) {
168+
if (!processLine(line, FILE_HEADER_RULES)) {
169+
throw new UnifiedDiffParserException("expected file start line not found");
190170
}
191171
line = READER.readLine();
172+
}
173+
}
174+
return line;
175+
}
192176

177+
private String parseChunkSection(String currentLine) throws IOException, UnifiedDiffParserException {
178+
String line = currentLine;
179+
if (line != null) {
180+
processLine(line, CHUNK);
181+
while ((line = READER.readLine()) != null) {
193182
line = checkForNoNewLineAtTheEndOfTheFile(line);
183+
184+
if (!processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL)) {
185+
throw new UnifiedDiffParserException("expected data line not found");
186+
}
187+
if (isChunkFinished()) {
188+
finalizeChunk();
189+
break;
190+
}
194191
}
195-
if (line == null || (line.startsWith("--") && !line.startsWith("---"))) {
196-
break;
197-
}
192+
line = READER.readLine();
193+
line = checkForNoNewLineAtTheEndOfTheFile(line);
198194
}
195+
return line;
196+
}
199197

198+
private boolean isChunkFinished() {
199+
return (originalTxt.size() == old_size && revisedTxt.size() == new_size)
200+
|| (old_size == 0
201+
&& new_size == 0
202+
&& originalTxt.size() == this.old_ln
203+
&& revisedTxt.size() == this.new_ln);
204+
}
205+
206+
private void parseTailSection() throws IOException {
200207
if (READER.ready()) {
201208
String tailTxt = "";
202209
while (READER.ready()) {
@@ -207,8 +214,6 @@ private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
207214
}
208215
data.setTailTxt(tailTxt);
209216
}
210-
211-
return data;
212217
}
213218

214219
private String checkForNoNewLineAtTheEndOfTheFile(String line) throws IOException {

0 commit comments

Comments
 (0)