Skip to content

Commit

Permalink
merge hyperlink merging changes by meo (#185); cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
donnerpeter committed May 23, 2014
1 parent 68f7fad commit b37122b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("ForLoopReplaceableByForEach")
public class CompositeFilter implements Filter, FilterMixin {
private static final Logger LOG = Logger.getInstance(CompositeFilter.class);

private final List<Filter> myFilters = new ArrayList<Filter>();
private boolean myIsAnyHeavy;
private boolean forceUseAllFilters = true;
private final DumbService myDumbService;

public CompositeFilter(@NotNull Project project) {
Expand All @@ -47,53 +50,78 @@ public Result applyFilter(final String line, final int entireLength) {
final boolean dumb = myDumbService.isDumb();
List<Filter> filters = myFilters;
int count = filters.size();
//noinspection ForLoopReplaceableByForEach
Result finalResult = null;

List<ResultItem> resultItems = null;
for (int i = 0; i < count; i++) {
Filter filter = filters.get(i);
if (!dumb || DumbService.isDumbAware(filter)) {
long t0 = System.currentTimeMillis();
Result result = null;

Result result;
try {
result = filter.applyFilter(line, entireLength);
}
catch (Throwable t) {
throw new RuntimeException("Error while applying " + filter + " to '"+line+"'", t);
throw new RuntimeException("Error while applying " + filter + " to '" + line + "'", t);
}
finalResult = merge(finalResult, result);
resultItems = merge(resultItems, result);

t0 = System.currentTimeMillis() - t0;
if (t0 > 1000) {
LOG.warn(filter.getClass().getSimpleName() + ".applyFilter() took " + t0 + " ms on '''" + line + "'''");
}
if (finalResult != null && finalResult.getNextAction() == NextAction.EXIT) {
return finalResult;
if (shouldStopFiltering(result)) {
break;
}
}
}
return finalResult;
return createFinalResult(resultItems);
}

protected Result merge(@Nullable Result finalResult, @Nullable Result result) {
if (result != null) {
if (finalResult == null) {
finalResult = result;
@Nullable
private static Result createFinalResult(@Nullable List<ResultItem> resultItems) {
if (resultItems == null) {
return null;
}
return new Result(resultItems);
}

private boolean shouldStopFiltering(@Nullable Result result) {
return result != null && result.getNextAction() == NextAction.EXIT && !forceUseAllFilters;
}

@Nullable
protected List<ResultItem> merge(@Nullable List<ResultItem> resultItems, @Nullable Result newResult) {
if (newResult != null) {
if (resultItems == null) {
resultItems = new ArrayList<ResultItem>();
}
else {
finalResult = new Result(mergeResultItems(finalResult, result));
finalResult.setNextAction(result.getNextAction());
List<ResultItem> newItems = newResult.getResultItems();
for (int i = 0; i < newItems.size(); i++) {
ResultItem item = newItems.get(i);
if (item.hyperlinkInfo == null || !intersects(resultItems, item)) {
resultItems.add(item);
}
}
}
return finalResult;
return resultItems;
}

private List<ResultItem> mergeResultItems(Result finalResult, Result result) {
List<ResultItem> finalResultResultItems = finalResult.getResultItems();
List<ResultItem> resultItems = result.getResultItems();
protected boolean intersects(List<ResultItem> items, ResultItem newItem) {
TextRange newItemTextRange = null;

List<ResultItem> mergedList = new ArrayList<ResultItem>(finalResultResultItems.size() + resultItems.size());
mergedList.addAll(finalResultResultItems);
mergedList.addAll(resultItems);
return mergedList;
for (int i = 0; i < items.size(); i++) {
ResultItem item = items.get(i);
if (item.hyperlinkInfo != null) {
if (newItemTextRange == null) {
newItemTextRange = new TextRange(newItem.highlightStartOffset, newItem.highlightEndOffset);
}
if (newItemTextRange.intersectsStrict(item.highlightStartOffset, item.highlightEndOffset)) {
return true;
}
}
}
return false;
}

@Override
Expand All @@ -109,12 +137,12 @@ public void applyHeavyFilter(Document copiedFragment, int startOffset, int start
final boolean dumb = myDumbService.isDumb();
List<Filter> filters = myFilters;
int count = filters.size();
//noinspection ForLoopReplaceableByForEach

for (int i = 0; i < count; i++) {
Filter filter = filters.get(i);
if (! (filter instanceof FilterMixin) || !((FilterMixin)filter).shouldRunHeavy()) continue;
if (!(filter instanceof FilterMixin) || !((FilterMixin)filter).shouldRunHeavy()) continue;
if (!dumb || DumbService.isDumbAware(filter)) {
((FilterMixin) filter).applyHeavyFilter(copiedFragment, startOffset, startLineNumber, consumer);
((FilterMixin)filter).applyHeavyFilter(copiedFragment, startOffset, startLineNumber, consumer);
}
}
}
Expand All @@ -125,7 +153,7 @@ public String getUpdateMessage() {
List<Filter> filters = myFilters;
final List<String> updateMessage = new ArrayList<String>();
int count = filters.size();
//noinspection ForLoopReplaceableByForEach

for (int i = 0; i < count; i++) {
Filter filter = filters.get(i);

Expand All @@ -149,4 +177,9 @@ public void addFilter(final Filter filter) {
myFilters.add(filter);
myIsAnyHeavy |= filter instanceof FilterMixin;
}

public void setForceUseAllFilters(boolean forceUseAllFilters) {
this.forceUseAllFilters = forceUseAllFilters;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ public interface Filter {

class Result extends ResultItem {
protected NextAction myNextAction = NextAction.EXIT;
protected List<ResultItem> myResultItems;
protected final List<ResultItem> myResultItems;

public Result(final int highlightStartOffset, final int highlightEndOffset, final HyperlinkInfo hyperlinkInfo) {
this(highlightStartOffset, highlightEndOffset, hyperlinkInfo, null);
}

public Result(final int highlightStartOffset, final int highlightEndOffset, final HyperlinkInfo hyperlinkInfo, final TextAttributes highlightAttributes) {
super(highlightStartOffset, highlightEndOffset, hyperlinkInfo, highlightAttributes);
myResultItems = null;
}

public Result(@NotNull List<ResultItem> resultItems) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ public HyperlinkInfo getHyperlinkInfo() {

private final Set<MyFlushRunnable> myCurrentRequests = new HashSet<MyFlushRunnable>();

protected final CompositeFilter myPredefinedMessageFilter;
protected final CompositeFilter myCustomFilter;
protected final CompositeFilter myFilters;

@Nullable private final InputFilter myInputMessageFilter;

Expand Down Expand Up @@ -287,20 +286,19 @@ protected ConsoleViewImpl(@NotNull final Project project,
myPsiDisposedCheck = new DisposedPsiManagerCheck(project);
myProject = project;

myCustomFilter = new CompositeFilter(project);
myPredefinedMessageFilter = new CompositeFilter(project);
myFilters = new CompositeFilter(project);
if (usePredefinedMessageFilter) {
for (ConsoleFilterProvider eachProvider : Extensions.getExtensions(ConsoleFilterProvider.FILTER_PROVIDERS)) {
Filter[] filters = eachProvider instanceof ConsoleFilterProviderEx
? ((ConsoleFilterProviderEx)eachProvider).getDefaultFilters(project, searchScope)
: eachProvider.getDefaultFilters(project);
for (Filter filter : filters) {
myPredefinedMessageFilter.addFilter(filter);
myFilters.addFilter(filter);
}
}
}
myHeavyUpdateTicket = 0;
myHeavyAlarm = myPredefinedMessageFilter.isAnyHeavy() ? new Alarm(Alarm.ThreadToUse.SHARED_THREAD, this) : null;
myHeavyAlarm = myFilters.isAnyHeavy() ? new Alarm(Alarm.ThreadToUse.SHARED_THREAD, this) : null;


ConsoleInputFilterProvider[] inputFilters = Extensions.getExtensions(ConsoleInputFilterProvider.INPUT_FILTER_PROVIDERS);
Expand Down Expand Up @@ -475,7 +473,7 @@ public void run() {
public JComponent getComponent() {
if (myMainPanel == null) {
myMainPanel = new JPanel(new BorderLayout());
myJLayeredPane = new MyDiffContainer(myMainPanel, myPredefinedMessageFilter.getUpdateMessage());
myJLayeredPane = new MyDiffContainer(myMainPanel, myFilters.getUpdateMessage());
Disposer.register(this, myJLayeredPane);
add(myJLayeredPane, BorderLayout.CENTER);
}
Expand Down Expand Up @@ -846,7 +844,7 @@ public void setUpdateFoldingsEnabled(boolean updateFoldingsEnabled) {

@Override
public void addMessageFilter(final Filter filter) {
myCustomFilter.addFilter(filter);
myFilters.addFilter(filter);
}

@Override
Expand Down Expand Up @@ -965,7 +963,7 @@ private void popupInvoked(MouseEvent mouseEvent) {
}

private void highlightHyperlinksAndFoldings(RangeMarker lastProcessedOutput) {
boolean canHighlightHyperlinks = !myCustomFilter.isEmpty() || !myPredefinedMessageFilter.isEmpty();
boolean canHighlightHyperlinks = !myFilters.isEmpty() || !myFilters.isEmpty();

if (!canHighlightHyperlinks && myUpdateFoldingsEnabled) {
return;
Expand All @@ -976,10 +974,10 @@ private void highlightHyperlinksAndFoldings(RangeMarker lastProcessedOutput) {
ApplicationManager.getApplication().assertIsDispatchThread();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
if (canHighlightHyperlinks) {
myHyperlinks.highlightHyperlinks(myCustomFilter, myPredefinedMessageFilter, line1, endLine);
myHyperlinks.highlightHyperlinks(myFilters, line1, endLine);
}

if (myAllowHeavyFilters && myPredefinedMessageFilter.isAnyHeavy() && myPredefinedMessageFilter.shouldRunHeavy()) {
if (myAllowHeavyFilters && myFilters.isAnyHeavy() && myFilters.shouldRunHeavy()) {
runHeavyFilters(line1, endLine);
}
if (myUpdateFoldingsEnabled) {
Expand All @@ -1002,9 +1000,9 @@ private void runHeavyFilters(int line1, int endLine) {
myHeavyAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (! myPredefinedMessageFilter.shouldRunHeavy()) return;
if (!myFilters.shouldRunHeavy()) return;
try {
myPredefinedMessageFilter.applyHeavyFilter(documentCopy, startOffset, startLine, new Consumer<FilterMixin.AdditionalHighlight>() {
myFilters.applyHeavyFilter(documentCopy, startOffset, startLine, new Consumer<FilterMixin.AdditionalHighlight>() {
@Override
public void consume(final FilterMixin.AdditionalHighlight additionalHighlight) {
if (myFlushAlarm.isDisposed()) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,19 @@ public HyperlinkInfo getHyperlinkInfoByPoint(final Point p) {
return getHyperlinkInfoByLineAndCol(pos.line, pos.column);
}

@Deprecated
public void highlightHyperlinks(final Filter customFilter, final Filter predefinedMessageFilter, final int line1, final int endLine) {
highlightHyperlinks(new Filter() {
@Nullable
@Override
public Result applyFilter(String line, int entireLength) {
Result result = customFilter.applyFilter(line, entireLength);
return result != null ? result : predefinedMessageFilter.applyFilter(line, entireLength);
}
}, line1, endLine);
}

public void highlightHyperlinks(final Filter customFilter, final int line1, final int endLine) {
final Document document = myEditor.getDocument();

final int startLine = Math.max(0, line1);
Expand All @@ -251,9 +263,6 @@ public void highlightHyperlinks(final Filter customFilter, final Filter predefin
}
final String text = getLineText(document, line, true);
Filter.Result result = customFilter.applyFilter(text, endOffset);
if (result == null) {
result = predefinedMessageFilter.applyFilter(text, endOffset);
}
if (result != null) {
for (Filter.ResultItem resultItem : result.getResultItems()) {
if (resultItem.hyperlinkInfo != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.intellij.execution.filters;

import com.intellij.mock.MockDumbService;
import junit.framework.Assert;
import org.junit.Assert;
import org.jetbrains.annotations.Nullable;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -30,6 +30,7 @@ public class CompositeFilterTest {
@Before
public void setUp() throws Exception {
myCompositeFilter = new CompositeFilter(new MockDumbService(null));
myCompositeFilter.setForceUseAllFilters(false);
}

@Test
Expand All @@ -55,6 +56,9 @@ public void testApplyNextFilter() throws Exception {
myCompositeFilter.addFilter(returnResultFilter());
notNullResultOfSize(applyFilter(), 3);

myCompositeFilter.setForceUseAllFilters(true);
notNullResultOfSize(applyFilter(), 4);

}

@Test
Expand All @@ -73,7 +77,7 @@ private Filter.Result applyFilter() {
return myCompositeFilter.applyFilter("foo\n", 10);
}

private void notNullResultOfSize(Filter.Result object, int expected) {
private static void notNullResultOfSize(Filter.Result object, int expected) {
Assert.assertNotNull(object);
List<Filter.ResultItem> resultItems = object.getResultItems();
Assert.assertEquals(expected, resultItems.size());
Expand All @@ -83,7 +87,8 @@ private void notNullResultOfSize(Filter.Result object, int expected) {
}
}

private Filter throwSOEFilter() {
private static Filter throwSOEFilter() {
//noinspection InfiniteRecursion
return new Filter() {
@Nullable
@Override
Expand All @@ -93,7 +98,7 @@ public Result applyFilter(String line, int entireLength) {
};
}

private Filter returnNullFilter() {
private static Filter returnNullFilter() {
return new Filter() {
@Nullable
@Override
Expand All @@ -103,7 +108,7 @@ public Result applyFilter(String line, int entireLength) {
};
}

private Filter returnResultFilter() {
private static Filter returnResultFilter() {
return new Filter() {
@Nullable
@Override
Expand All @@ -113,7 +118,7 @@ public Result applyFilter(String line, int entireLength) {
};
}

private Filter returnContinuingResultFilter() {
private static Filter returnContinuingResultFilter() {
return new Filter() {
@Nullable
@Override
Expand All @@ -125,7 +130,7 @@ public Result applyFilter(String line, int entireLength) {
};
}

private Filter.Result createResult() {
private static Filter.Result createResult() {
return new Filter.Result(1, 1, null, null);
}
}
}

0 comments on commit b37122b

Please sign in to comment.