Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Michael Golubev
2013-11-04 17:56:04 +01:00
11 changed files with 256 additions and 229 deletions
@@ -113,6 +113,21 @@ class Foo {
'''
}
public void "test complete variable name in string literal"() {
myFixture.configureByText "a.java", '''
class Xoo {
String foobar = "foo<caret>";
}
'''
complete()
myFixture.checkResult '''
class Xoo {
String foobar = "foobar<caret>";
}
'''
}
private void complete() {
myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_COMPLETION)
}
@@ -44,7 +44,6 @@ import java.util.*;
*/
public class HippieWordCompletionHandler implements CodeInsightActionHandler {
private static final Key<CompletionState> KEY_STATE = new Key<CompletionState>("HIPPIE_COMPLETION_STATE");
private static final String WHITESPACE_CHARS = " \t\n";
private final boolean myForward;
public HippieWordCompletionHandler(boolean forward) {
@@ -188,7 +187,7 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
}
}
private static boolean isWordLike(CharSequence seq, int start, int end) {
private static boolean containsLetters(CharSequence seq, int start, int end) {
for (int i = start; i < end; i++) {
if (Character.isLetter(seq.charAt(i))) {
return true;
@@ -256,7 +255,7 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
@Override
public boolean processToken(int start, int end) {
if ((start > caretOffset || end < caretOffset) && //skip prefix itself
end - start > matcher.getPrefix().length() && isWordLike(chars, start, end)) {
end - start > matcher.getPrefix().length()) {
final String word = chars.subSequence(start, end).toString();
if (matcher.isStartMatch(word)) {
CompletionVariant v = new CompletionVariant(editor, word, start);
@@ -280,25 +279,15 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
while (!iterator.atEnd()) {
int start = iterator.getStart();
int end = iterator.getEnd();
if (StringUtil.indexOfAny(chars, WHITESPACE_CHARS, start, end) < 0) {
//a single token without whitespace, consider it one word, even if it's an identifier with '-' inside
if (isWordLike(chars, start, end) && !processor.processToken(start, end)) {
return;
}
iterator.advance();
continue;
}
// a token with whitespace inside (a string literal or comment)
// use the default java-identifier notion of word
while (start < end) {
int wordStart = start;
while (wordStart < end && !Character.isJavaIdentifierPart(chars.charAt(wordStart))) wordStart++;
while (wordStart < end && !isWordPart(chars.charAt(wordStart))) wordStart++;
int wordEnd = wordStart;
while (wordEnd < end && Character.isJavaIdentifierPart(chars.charAt(wordEnd))) wordEnd++;
while (wordEnd < end && isWordPart(chars.charAt(wordEnd))) wordEnd++;
if (!processor.processToken(wordStart, wordEnd)) {
if (wordEnd > wordStart && containsLetters(chars, wordStart, wordEnd) && !processor.processToken(wordStart, wordEnd)) {
return;
}
start = wordEnd + 1;
@@ -307,6 +296,10 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
}
}
private static boolean isWordPart(final char c) {
return Character.isJavaIdentifierPart(c) || c == '-' || c == '*' ;
}
private static CompletionData computeData(final Editor editor, final CharSequence charsSequence) {
final int offset = editor.getCaretModel().getOffset();
@@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.Collections;
@@ -86,7 +87,7 @@ public class GotoActionAction extends GotoActionBase implements DumbAware {
final String enteredText,
final Project project,
final Component component,
@NotNull final AnActionEvent e) {
@Nullable final AnActionEvent e) {
if (element instanceof OptionDescription) {
final String configurableId = ((OptionDescription)element).getConfigurableId();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -108,10 +109,12 @@ public class GotoActionAction extends GotoActionBase implements DumbAware {
}
final Presentation presentation = action.getTemplatePresentation().clone();
final DataContext context = DataManager.getInstance().getDataContext(component);
final AnActionEvent event = new AnActionEvent(e.getInputEvent(), context,
e.getPlace(), presentation,
final AnActionEvent event = new AnActionEvent(e == null ? null : e.getInputEvent(),
context,
e == null ? ActionPlaces.UNKNOWN : e.getPlace(),
presentation,
ActionManager.getInstance(),
e.getModifiers());
e == null ? 0 : e.getModifiers());
if (ActionUtil.lastUpdateAndCheckDumb(action, event, true)) {
if (action instanceof ActionGroup) {
@@ -336,7 +336,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private void initSearchField(final MySearchTextField search) {
final JTextField editor = search.getTextEditor();
onFocusLost();
// onFocusLost();
editor.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
@@ -379,7 +379,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
public void focusLost(FocusEvent e) {
if ( myPopup instanceof AbstractPopup && myPopup.isVisible() && ((AbstractPopup)myPopup).getPopupWindow() == e.getOppositeComponent()) {
if ( myPopup instanceof AbstractPopup && myPopup.isVisible()
&& ((myList == e.getOppositeComponent()) || ((AbstractPopup)myPopup).getPopupWindow() == e.getOppositeComponent())) {
return;
}
onFocusLost();
@@ -491,7 +492,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
option.setOptionState(!option.isOptionEnabled());
}
else {
GotoActionAction.openOptionOrPerformAction(value, pattern, project, comp, event);
Component c = comp;
if (c == null) {
c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
}
GotoActionAction.openOptionOrPerformAction(value, pattern, project, c, event);
}
}
});
@@ -36,8 +36,9 @@ import java.awt.datatransfer.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
/**
* <p>This class is used to workaround the problem with getting clipboard contents (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4818143).
@@ -125,6 +126,7 @@ public class ClipboardSynchronizer implements ApplicationComponent {
myClipboardHandler.resetContent();
}
private static class ClipboardHandler {
public void init() {
}
@@ -178,6 +180,7 @@ public class ClipboardSynchronizer implements ApplicationComponent {
}
}
private static class MacClipboardHandler extends ClipboardHandler {
private Pair<String,Transferable> myFullTransferable;
@@ -216,7 +219,7 @@ public class ClipboardSynchronizer implements ApplicationComponent {
LOG.info(e);
}
}
myFullTransferable = null;
return transferable;
}
@@ -246,11 +249,11 @@ public class ClipboardSynchronizer implements ApplicationComponent {
super.setContent(content, owner);
}
}
@Nullable
public static Transferable getContentsSafe() {
final Ref<Transferable> result = new Ref<Transferable>();
Foundation.executeOnMainThread(new Runnable() {
@Override
public void run() {
@@ -263,46 +266,47 @@ public class ClipboardSynchronizer implements ApplicationComponent {
return result.get();
}
}
@Nullable
private static Transferable getClipboardContentNatively() {
String plainText = "public.utf8-plain-text";
ID pasteboard = Foundation.invoke("NSPasteboard", "generalPasteboard");
ID types = Foundation.invoke(pasteboard, "types");
IntegerType count = Foundation.invoke(types, "count");
@Nullable
private static Transferable getClipboardContentNatively() {
String plainText = "public.utf8-plain-text";
ID plainTextType = null;
ID pasteboard = Foundation.invoke("NSPasteboard", "generalPasteboard");
ID types = Foundation.invoke(pasteboard, "types");
IntegerType count = Foundation.invoke(types, "count");
for (int i = 0; i < count.intValue(); i++) {
ID each = Foundation.invoke(types, "objectAtIndex:", i);
String eachType = Foundation.toStringViaUTF8(each);
if (plainText.equals(eachType)) {
plainTextType = each;
break;
ID plainTextType = null;
for (int i = 0; i < count.intValue(); i++) {
ID each = Foundation.invoke(types, "objectAtIndex:", i);
String eachType = Foundation.toStringViaUTF8(each);
if (plainText.equals(eachType)) {
plainTextType = each;
break;
}
}
// will put string value even if we doesn't found java object. this is needed because java caches clipboard value internally and
// will reset it ONLY IF we'll put jvm-object into clipboard (see our setContent optimizations which avoids putting jvm-objects
// into clipboard)
Transferable result = null;
if (plainTextType != null) {
ID text = Foundation.invoke(pasteboard, "stringForType:", plainTextType);
String value = Foundation.toStringViaUTF8(text);
if (value == null) {
LOG.info(String.format("[Clipboard] Strange string value (null?) for type: %s", plainTextType));
}
else {
result = new StringSelection(value);
}
}
return result;
}
// will put string value even if we doesn't found java object. this is needed because java caches clipboard value internally and
// will reset it ONLY IF we'll put jvm-object into clipboard (see our setContent optimizations which avoids putting jvm-objects
// into clipboard)
Transferable result = null;
if (plainTextType != null) {
ID text = Foundation.invoke(pasteboard, "stringForType:", plainTextType);
String value = Foundation.toStringViaUTF8(text);
if (value == null) {
LOG.info(String.format("[Clipboard] Strange string value (null?) for type: %s", plainTextType));
}
else {
result = new StringSelection(value);
}
}
return result;
}
private static class XWinClipboardHandler extends ClipboardHandler {
private static final FlavorTable FLAVOR_MAP = (FlavorTable)SystemFlavorMap.getDefaultFlavorMap();
@@ -328,15 +332,19 @@ public class ClipboardSynchronizer implements ApplicationComponent {
}
try {
final Pair<long[], ? extends Collection<DataFlavor>> contents = checkContentsQuick();
final Collection<DataFlavor> contents = checkContentsQuick();
if (contents != null) {
return contents.second.contains(dataFlavor);
return contents.contains(dataFlavor);
}
return super.isDataFlavorAvailable(dataFlavor);
}
catch (NullPointerException e) {
LOG.warn("Sun bug #6322854", e);
LOG.warn("Java bug #6322854", e);
return false;
}
catch (IllegalArgumentException e) {
LOG.warn("Java bug #7173464", e);
return false;
}
}
@@ -349,49 +357,20 @@ public class ClipboardSynchronizer implements ApplicationComponent {
}
try {
final Pair<long[], ? extends Collection<DataFlavor>> contents = checkContentsQuick();
if (contents != null && contents.second.isEmpty()) {
final Collection<DataFlavor> contents = checkContentsQuick();
if (contents != null && contents.isEmpty()) {
return null;
}
try {
return super.getContents();
}
catch (IllegalArgumentException e) {
// todo[r.sh] to remove in IDEA 12.1
if (contents != null && "Comparison method violates its general contract!".equals(e.getMessage())) {
LOG.error("Cannot sort: " + contents.second + ", atoms: " + atomNames(contents.first), e);
return null;
}
throw e;
}
return super.getContents();
}
catch (NullPointerException e) {
LOG.warn("Sun bug #6322854", e);
LOG.warn("Java bug #6322854", e);
return null;
}
}
private static List<String> atomNames(long[] formats) {
try {
Class<?> toolkit = Class.forName("sun.awt.X11.XToolkit");
Method getDisplay = toolkit.getDeclaredMethod("getDisplay");
getDisplay.setAccessible(true);
long display = (Long)getDisplay.invoke(null);
Class<?> wrapper = Class.forName("sun.awt.X11.XlibWrapper");
Method getAtomName = wrapper.getDeclaredMethod("XGetAtomName", long.class, long.class);
getAtomName.setAccessible(true);
List<String> atoms = new ArrayList<String>();
for (long format : formats) {
String name = (String)getAtomName.invoke(null, display, format);
atoms.add(format + ":" + name);
}
return atoms;
}
catch (Throwable t) {
return Collections.emptyList();
catch (IllegalArgumentException e) {
LOG.warn("Java bug #7173464", e);
return null;
}
}
@@ -413,7 +392,7 @@ public class ClipboardSynchronizer implements ApplicationComponent {
* collection of available data flavors otherwise.
*/
@Nullable
private static Pair<long[], ? extends Collection<DataFlavor>> checkContentsQuick() {
private static Collection<DataFlavor> checkContentsQuick() {
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
final Class<? extends Clipboard> aClass = clipboard.getClass();
if (!"sun.awt.X11.XClipboard".equals(aClass.getName())) return null;
@@ -433,10 +412,10 @@ public class ClipboardSynchronizer implements ApplicationComponent {
try {
final long[] formats = (long[])getClipboardFormats.invoke(clipboard);
if (formats == null || formats.length == 0) {
return Pair.create(formats, Collections.<DataFlavor>emptySet());
return Collections.emptySet();
}
@SuppressWarnings({"unchecked"}) final Set<DataFlavor> set = DataTransferer.getInstance().getFlavorsForFormats(formats, FLAVOR_MAP).keySet();
return Pair.create(formats, set);
return set;
}
catch (IllegalAccessException ignore) { }
catch (IllegalArgumentException ignore) { }
@@ -454,6 +433,7 @@ public class ClipboardSynchronizer implements ApplicationComponent {
}
}
private static class HeadlessClipboardHandler extends ClipboardHandler {
private volatile Transferable myContent = null;
@@ -5009,6 +5009,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myDropHandler = dropHandler;
}
private static class MyInputMethodHandleSwingThreadWrapper implements InputMethodRequests {
private final InputMethodRequests myDelegate;
@@ -5018,114 +5019,53 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Override
public Rectangle getTextLocation(final TextHitInfo offset) {
if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getTextLocation(offset);
final Rectangle[] r = new Rectangle[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getTextLocation(offset);
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
return execute(new Computable<Rectangle>() {
@Override
public Rectangle compute() {
return myDelegate.getTextLocation(offset);
}
});
}
@Override
public TextHitInfo getLocationOffset(final int x, final int y) {
if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getLocationOffset(x, y);
final TextHitInfo[] r = new TextHitInfo[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getLocationOffset(x, y);
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
return execute(new Computable<TextHitInfo>() {
@Override
public TextHitInfo compute() {
return myDelegate.getLocationOffset(x, y);
}
});
}
@Override
public int getInsertPositionOffset() {
if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getInsertPositionOffset();
final int[] r = new int[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getInsertPositionOffset();
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
return execute(new Computable<Integer>() {
@Override
public Integer compute() {
return myDelegate.getInsertPositionOffset();
}
});
}
@Override
public AttributedCharacterIterator getCommittedText(final int beginIndex,
final int endIndex,
public AttributedCharacterIterator getCommittedText(final int beginIndex, final int endIndex,
final AttributedCharacterIterator.Attribute[] attributes) {
if (ApplicationManager.getApplication().isDispatchThread()) {
return myDelegate.getCommittedText(beginIndex, endIndex, attributes);
}
final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getCommittedText(beginIndex, endIndex, attributes);
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
return execute(new Computable<AttributedCharacterIterator>() {
@Override
public AttributedCharacterIterator compute() {
return myDelegate.getCommittedText(beginIndex, endIndex, attributes);
}
});
}
@Override
public int getCommittedTextLength() {
if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getCommittedTextLength();
final int[] r = new int[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getCommittedTextLength();
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
return execute(new Computable<Integer>() {
@Override
public Integer compute() {
return myDelegate.getCommittedTextLength();
}
});
}
@Override
@@ -5136,27 +5076,40 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Override
public AttributedCharacterIterator getSelectedText(final AttributedCharacterIterator.Attribute[] attributes) {
if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getSelectedText(attributes);
return execute(new Computable<AttributedCharacterIterator>() {
@Override
public AttributedCharacterIterator compute() {
return myDelegate.getSelectedText(attributes);
}
});
}
final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1];
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
r[0] = myDelegate.getSelectedText(attributes);
}
});
private static <T> T execute(final Computable<T> computable) {
if (ApplicationManager.getApplication().isDispatchThread()) {
return computable.compute();
}
catch (InterruptedException e) {
LOG.error(e);
else {
final Ref<T> ref = Ref.create();
try {
GuiUtils.invokeAndWait(new Runnable() {
@Override
public void run() {
ref.set(computable.compute());
}
});
}
catch (InterruptedException e) {
LOG.error(e);
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return ref.get();
}
catch (InvocationTargetException e) {
LOG.error(e);
}
return r[0];
}
}
private class MyInputMethodHandler implements InputMethodRequests {
private String composedText;
private ProperTextRange composedTextRange;
@@ -5357,8 +5310,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
private class MyMouseAdapter extends MouseAdapter {
private class MyMouseAdapter extends MouseAdapter {
private boolean mySelectionTweaked;
@Override
@@ -6160,14 +6113,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Override
public void updateStarted(@NotNull Document doc) {
if (doc != getDocument()) return;
bulkUpdateStarted();
}
@Override
public void updateFinished(@NotNull Document doc) {
if (doc != getDocument()) return;
bulkUpdateFinished();
}
}
@@ -7,6 +7,7 @@ import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsCommit;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
@@ -26,7 +27,7 @@ public class VcsCommitImpl implements VcsCommit {
public VcsCommitImpl(@NotNull Hash hash, @NotNull List<Hash> parents) {
myHash = hash;
myParents = parents;
myParents = new ArrayList<Hash>(parents);
}
@Override
@@ -39,7 +39,7 @@ import java.util.Set;
/**
* @author Kirill Likhodedov
*/
public class VcsLogManager {
public class VcsLogManager implements Disposable {
public static final ExtensionPointName<VcsLogProvider> LOG_PROVIDER_EP = ExtensionPointName.create("com.intellij.logProvider");
@@ -61,6 +61,7 @@ public class VcsLogManager {
myLogObjectsFactory = logObjectsFactory;
mySettings = settings;
myUiProperties = uiProperties;
Disposer.register(myProject, this);
}
@NotNull
@@ -71,6 +72,7 @@ public class VcsLogManager {
VcsLogDataHolder.init(myProject, myLogObjectsFactory, logProviders, mySettings, new Consumer<VcsLogDataHolder>() {
@Override
public void consume(VcsLogDataHolder vcsLogDataHolder) {
Disposer.register(VcsLogManager.this, vcsLogDataHolder);
VcsLogUI logUI = new VcsLogUI(vcsLogDataHolder, myProject, mySettings,
new VcsLogColorManagerImpl(logProviders.keySet()), myUiProperties);
myLogDataHolder = vcsLogDataHolder;
@@ -119,6 +121,10 @@ public class VcsLogManager {
return myUi;
}
@Override
public void dispose() {
}
private static class VcsLogContainer extends JPanel {
private final JBLoadingPanel myLoadingPanel;
@@ -165,8 +165,14 @@ class DetailsPanel extends JPanel implements ListSelectionListener {
String authorText = commit.getAuthorName() + " at " + DateFormatUtil.formatDateTime(commit.getAuthorTime());
if (!commit.getAuthorName().equals(commit.getCommitterName()) || !commit.getAuthorEmail().equals(commit.getCommitterEmail())) {
authorText += " (committed by " + commit.getCommitterName() +
" at " + DateFormatUtil.formatDateTime(commit.getCommitTime()) + ")";
String commitTime;
if (commit.getCommitTime() != commit.getAuthorTime()) {
commitTime = " at " + DateFormatUtil.formatDateTime(commit.getCommitTime());
}
else {
commitTime = "";
}
authorText += " (committed by " + commit.getCommitterName() + commitTime + ")";
}
myAuthor.setText(authorText);
}
@@ -64,6 +64,7 @@ import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static git4idea.history.GitLogParser.GitLogOption.*;
@@ -535,8 +536,10 @@ public class GitHistoryUtils {
@NotNull
public static List<TimedVcsCommit> readAllHashes(@NotNull Project project, @NotNull VirtualFile root) throws VcsException {
GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG);
GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_TIME);
final int COMMIT_BUFFER = 1000;
GitLineHandler h = new GitLineHandler(project, root, GitCommand.LOG);
final GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, AUTHOR_TIME);
h.setStdoutSuppressed(true);
h.addParameters(parser.getPretty(), "--encoding=UTF-8");
h.addParameters("HEAD", "--branches", "--remotes", "--tags");
@@ -544,21 +547,82 @@ public class GitHistoryUtils {
h.addParameters("--date-order");
h.endOptions();
String output = h.run();
final List<TimedVcsCommit> commits = ContainerUtil.newArrayList();
List<GitLogRecord> records = parser.parse(output);
return ContainerUtil.map(records, new Function<GitLogRecord, TimedVcsCommit>() {
final StringBuilder record = new StringBuilder();
final AtomicInteger records = new AtomicInteger();
final Ref<VcsException> ex = new Ref<VcsException>();
h.addLineListener(new GitLineHandlerListener() {
@Override
public TimedVcsCommit fun(GitLogRecord record) {
List<Hash> parents = new SmartList<Hash>();
for (String parent : record.getParentsHashes()) {
parents.add(HashImpl.build(parent));
public void onLineAvailable(String line, Key outputType) {
try {
int recordEnd = line.indexOf(GitLogParser.RECORD_END);
String afterParseRemainder;
if (recordEnd == line.length() - 1) { // ends with
record.append(line);
afterParseRemainder = "";
}
else if (recordEnd == -1) { // record doesn't end on this line => just appending, no parsing
record.append(line);
afterParseRemainder = null;
}
else { // record ends in the middle of this line
record.append(line.substring(0, recordEnd + 1));
afterParseRemainder = line.substring(recordEnd + 1);
}
if (afterParseRemainder != null && records.incrementAndGet() > COMMIT_BUFFER) { // null means can't parse now
commits.addAll(parseCommit(parser, record));
record.setLength(0);
record.append(afterParseRemainder);
}
}
return ServiceManager.getService(VcsLogObjectsFactory.class).createTimedCommit(HashImpl.build(record.getHash()),
parents, record.getAuthorTimeStamp());
catch (Exception e) {
ex.set(new VcsException(e));
}
}
@Override
public void processTerminated(int exitCode) {
try {
commits.addAll(parseCommit(parser, record));
}
catch (Exception e) {
ex.set(new VcsException(e));
}
}
@Override
public void startFailed(Throwable exception) {
ex.set(new VcsException(exception));
}
});
h.runInCurrentThread(null);
if (!ex.isNull()) {
throw ex.get();
}
return commits;
}
private static List<TimedVcsCommit> parseCommit(GitLogParser parser, StringBuilder record) {
List<GitLogRecord> rec = parser.parse(record.toString());
return ContainerUtil.mapNotNull(rec, new Function<GitLogRecord, TimedVcsCommit>() {
@Override
public TimedVcsCommit fun(GitLogRecord record) {
return record == null ? null : convert(record);
}
});
}
@NotNull
private static TimedVcsCommit convert(GitLogRecord rec) {
VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
List<Hash> parents = ContainerUtil.map(rec.getParentsHashes(), new Function<String, Hash>() {
@Override
public Hash fun(String s) {
return HashImpl.build(s);
}
});
return factory.createTimedCommit(HashImpl.build(rec.getHash()), parents, rec.getAuthorTimeStamp());
}
private static class MyTokenAccumulator {
@@ -361,6 +361,7 @@ prepended
prepends
preprocessor
preprocessors
println
processlist
profiler
progressbar