From d9b886f191e2ed5064149ee30adf335361c022fc Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 24 Dec 2014 16:09:47 +0300 Subject: [PATCH] [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. --- .../openapi/diff/impl/patch/PatchReader.java | 24 ++++++++++++++----- .../changes/shelf/ShelveChangesManager.java | 22 ++++++++++++++--- .../vcs/changes/shelf/ShelvedChangeList.java | 3 +-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java index 9a78602ac8de..236816854c8e 100644 --- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java +++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/PatchReader.java @@ -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 readAllPatches() throws PatchSyntaxException { @@ -169,10 +173,12 @@ public class PatchReader { private static class AdditionalInfoParser implements Parser { // first is path! private final Map> myResultMap; + private final boolean myIgnoreMode; private Map myAddMap; private PatchSyntaxException mySyntaxException; - private AdditionalInfoParser() { + private AdditionalInfoParser(boolean ignore) { + myIgnoreMode = ignore; myAddMap = new HashMap(); myResultMap = new HashMap>(); } @@ -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 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 myPatches; private boolean myDiffCommandLike; private boolean myIndexLike; - private PatchContentParser() { + private PatchContentParser(boolean parseHunks) { + myParseHunks = parseHunks; myPatches = new SmartList(); } @@ -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); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java index 96bb835bc086..461d58d52d48 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java @@ -665,10 +665,26 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD notifyStateChanged(); } - // todo problem: control usage - public static List loadPatches(Project project, final String patchPath, CommitContext commitContext) throws IOException, PatchSyntaxException { + @NotNull + public static List loadPatches(Project project, + final String patchPath, + CommitContext commitContext) throws IOException, PatchSyntaxException { + return loadPatches(project, patchPath, commitContext, true); + } + + @NotNull + static List loadPatchesWithoutContent(Project project, + final String patchPath, + CommitContext commitContext) throws IOException, PatchSyntaxException { + return loadPatches(project, patchPath, commitContext, false); + } + + private static List 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 textFilePatches = reader.readAllPatches(); final TransparentlyFailedValueI>, PatchSyntaxException> additionalInfo = reader.getAdditionalInfo( null); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java index af3bb540d65e..e88ce0885733 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java @@ -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 getChanges(Project project) { if (myChanges == null) { try { - final List list = ShelveChangesManager.loadPatches(project, PATH, null); + final List list = ShelveChangesManager.loadPatchesWithoutContent(project, PATH, null); myChanges = new ArrayList(); for (FilePatch patch : list) { FileStatus status;