[vcs] IDEA-117448 Don't read & store patch text until really needed

ShelvedChangeList doesn't need patch text itself to provide the changes,
this texts are loaded and parsed in ShelvedChange#getChanges when needed

=> let read patch files in "ignore content" mode & use this mode
when ShelveChangeLists are loaded.
This commit is contained in:
Kirill Likhodedov
2014-12-24 16:11:21 +03:00
parent 02e6f70615
commit d9b886f191
3 changed files with 38 additions and 11 deletions
@@ -52,9 +52,13 @@ public class PatchReader {
@NonNls private static final Pattern ourContextAfterHunkStartPattern = Pattern.compile("--- (\\d+),(\\d+) ----");
public PatchReader(CharSequence patchContent) {
this(patchContent, false);
}
public PatchReader(CharSequence patchContent, boolean parseHunks) {
myLines = LineTokenizer.tokenizeIntoList(patchContent, false);
myAdditionalInfoParser = new AdditionalInfoParser();
myPatchContentParser = new PatchContentParser();
myAdditionalInfoParser = new AdditionalInfoParser(!parseHunks);
myPatchContentParser = new PatchContentParser(parseHunks);
}
public List<TextFilePatch> readAllPatches() throws PatchSyntaxException {
@@ -169,10 +173,12 @@ public class PatchReader {
private static class AdditionalInfoParser implements Parser {
// first is path!
private final Map<String,Map<String, CharSequence>> myResultMap;
private final boolean myIgnoreMode;
private Map<String, CharSequence> myAddMap;
private PatchSyntaxException mySyntaxException;
private AdditionalInfoParser() {
private AdditionalInfoParser(boolean ignore) {
myIgnoreMode = ignore;
myAddMap = new HashMap<String, CharSequence>();
myResultMap = new HashMap<String, Map<String, CharSequence>>();
}
@@ -194,12 +200,16 @@ public class PatchReader {
@Override
public boolean testIsStart(String start) {
if (mySyntaxException != null) return false; // stop on first error
if (myIgnoreMode || mySyntaxException != null) return false; // stop on first error
return start != null && start.contains(UnifiedDiffWriter.ADDITIONAL_PREFIX);
}
@Override
public void parse(String start, ListIterator<String> iterator) {
if (myIgnoreMode) {
return;
}
if (! iterator.hasNext()) {
mySyntaxException = new PatchSyntaxException(iterator.previousIndex(), "Empty additional info header");
return;
@@ -244,13 +254,15 @@ public class PatchReader {
private static class PatchContentParser implements Parser {
private final boolean myParseHunks;
private DiffFormat myDiffFormat = null;
private final List<TextFilePatch> myPatches;
private boolean myDiffCommandLike;
private boolean myIndexLike;
private PatchContentParser() {
private PatchContentParser(boolean parseHunks) {
myParseHunks = parseHunks;
myPatches = new SmartList<TextFilePatch>();
}
@@ -302,7 +314,7 @@ public class PatchReader {
}
extractFileName(curLine, curPatch, false, myDiffCommandLike && myIndexLike);
while (iterator.hasNext()) {
while (myParseHunks && iterator.hasNext()) {
PatchHunk hunk;
if (myDiffFormat == DiffFormat.UNIFIED) {
hunk = readNextHunkUnified(iterator);
@@ -665,10 +665,26 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
notifyStateChanged();
}
// todo problem: control usage
public static List<TextFilePatch> loadPatches(Project project, final String patchPath, CommitContext commitContext) throws IOException, PatchSyntaxException {
@NotNull
public static List<TextFilePatch> loadPatches(Project project,
final String patchPath,
CommitContext commitContext) throws IOException, PatchSyntaxException {
return loadPatches(project, patchPath, commitContext, true);
}
@NotNull
static List<? extends FilePatch> loadPatchesWithoutContent(Project project,
final String patchPath,
CommitContext commitContext) throws IOException, PatchSyntaxException {
return loadPatches(project, patchPath, commitContext, false);
}
private static List<TextFilePatch> loadPatches(Project project,
final String patchPath,
CommitContext commitContext,
boolean loadContent) throws IOException, PatchSyntaxException {
char[] text = FileUtil.loadFileText(new File(patchPath), CharsetToolkit.UTF8);
PatchReader reader = new PatchReader(new CharArrayCharSequence(text));
PatchReader reader = new PatchReader(new CharArrayCharSequence(text), loadContent);
final List<TextFilePatch> textFilePatches = reader.readAllPatches();
final TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo = reader.getAdditionalInfo(
null);
@@ -24,7 +24,6 @@ package com.intellij.openapi.vcs.changes.shelf;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.impl.patch.FilePatch;
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
@@ -109,7 +108,7 @@ public class ShelvedChangeList implements JDOMExternalizable {
public List<ShelvedChange> getChanges(Project project) {
if (myChanges == null) {
try {
final List<TextFilePatch> list = ShelveChangesManager.loadPatches(project, PATH, null);
final List<? extends FilePatch> list = ShelveChangesManager.loadPatchesWithoutContent(project, PATH, null);
myChanges = new ArrayList<ShelvedChange>();
for (FilePatch patch : list) {
FileStatus status;