From eb22a991a463291dc2b8c1deca61f631da78c006 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 20 Sep 2013 15:52:53 +0200 Subject: [PATCH] fix todo duplication when several pattern match -> prefer finding match with last pattern (in settings list), thus default TODO pattern is matched last --- .../psi/impl/cache/impl/BaseFilterLexer.java | 48 +++++++++++-------- .../impl/id/PlatformIdTableBuilding.java | 6 +-- .../psi/impl/cache/impl/todo/TodoIndex.java | 2 +- .../psi/impl/search/IndexPatternSearcher.java | 16 +++++-- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java index d297a9a0c4c5..d2e98c25c64b 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/BaseFilterLexer.java @@ -22,6 +22,7 @@ import com.intellij.psi.impl.cache.impl.id.IdTableBuilding; import com.intellij.psi.search.IndexPattern; import com.intellij.psi.search.UsageSearchContext; import com.intellij.util.text.CharArrayUtil; +import gnu.trove.TIntArrayList; import org.jetbrains.annotations.Nullable; import java.util.regex.Matcher; @@ -32,7 +33,7 @@ public abstract class BaseFilterLexer extends DelegateLexer implements IdTableBu private int myTodoScannedBound = 0; private int myOccurenceMask; - private TodoScanningData[] myTodoScanningData; + private TodoScanningState myTodoScanningState; private CharSequence myCachedBufferSequence; private char[] myCachedArraySequence; @@ -49,49 +50,56 @@ public abstract class BaseFilterLexer extends DelegateLexer implements IdTableBu if (start >= end) return; // this prevents scanning of the same comment twice CharSequence input = myCachedBufferSequence.subSequence(start, end); - myTodoScanningData = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningData); + myTodoScanningState = advanceTodoItemsCount(input, myOccurrenceConsumer, myTodoScanningState); myTodoScannedBound = end; } - public static class TodoScanningData { - final IndexPattern pattern; - final Matcher matcher; + public static class TodoScanningState { + final IndexPattern[] myPatterns; + final Matcher[] myMatchers; + TIntArrayList myOccurences; - public TodoScanningData(IndexPattern pattern, Matcher matcher) { - this.matcher = matcher; - this.pattern = pattern; + public TodoScanningState(IndexPattern[] patterns, Matcher[] matchers) { + myPatterns = patterns; + myMatchers = matchers; + myOccurences = new TIntArrayList(1); } } - public static TodoScanningData[] advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningData[] todoScanningData) { - if (todoScanningData == null) { + public static TodoScanningState advanceTodoItemsCount(final CharSequence input, final OccurrenceConsumer consumer, TodoScanningState todoScanningState) { + if (todoScanningState == null) { IndexPattern[] patterns = IndexPatternUtil.getIndexPatterns(); - todoScanningData = new TodoScanningData[patterns.length]; + + Matcher[] matchers = new Matcher[patterns.length]; + todoScanningState = new TodoScanningState(patterns, matchers); for (int i = 0; i < patterns.length; ++i) { - IndexPattern indexPattern = patterns[i]; - Pattern pattern = indexPattern.getPattern(); + Pattern pattern = patterns[i].getPattern(); if (pattern != null) { - todoScanningData [i] = new TodoScanningData(indexPattern, pattern.matcher("")); + matchers[i] = pattern.matcher(""); } } + } else { + todoScanningState.myOccurences.resetQuick(); } - for (TodoScanningData data:todoScanningData) { - if (data == null) continue; - Matcher matcher = data.matcher; + for (int i = todoScanningState.myMatchers.length - 1; i >= 0; --i) { + Matcher matcher = todoScanningState.myMatchers[i]; + if (matcher == null) continue; matcher.reset(input); while (matcher.find()) { - if (matcher.start() != matcher.end()) { - consumer.incTodoOccurrence(data.pattern); + int start = matcher.start(); + if (start != matcher.end() && todoScanningState.myOccurences.indexOf(start) == -1) { + consumer.incTodoOccurrence(todoScanningState.myPatterns[i]); + todoScanningState.myOccurences.add(start); } } } - return todoScanningData; + return todoScanningState; } @Override diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java index 15224f5a975f..14da4f8231e9 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/id/PlatformIdTableBuilding.java @@ -173,7 +173,7 @@ public abstract class PlatformIdTableBuilding { } final int documentLength = chars.length(); - BaseFilterLexer.TodoScanningData[] todoScanningDatas = null; + BaseFilterLexer.TodoScanningState todoScanningState = null; final HighlighterIterator iterator = highlighter.createIterator(0); while (!iterator.atEnd()) { @@ -184,10 +184,10 @@ public abstract class PlatformIdTableBuilding { if (start >= documentLength) break; int end = iterator.getEnd(); - todoScanningDatas = BaseFilterLexer.advanceTodoItemsCount( + todoScanningState = BaseFilterLexer.advanceTodoItemsCount( chars.subSequence(start, Math.min(end, documentLength)), occurrenceConsumer, - todoScanningDatas + todoScanningState ); if (end > documentLength) break; } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java index 7ddbf024b3bf..5139707e75e5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/todo/TodoIndex.java @@ -133,7 +133,7 @@ public class TodoIndex extends FileBasedIndexExtension @Override public int getVersion() { - return 4; + return 5; } @Override diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java index 26004caf6e12..d108c6030e6c 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/IndexPatternSearcher.java @@ -77,21 +77,24 @@ public class IndexPatternSearcher implements QueryExecutor=0; --j) { + if (!collectPatternMatches(patterns[j], chars, commentStart, commentEnd, file, queryParameters.getRange(), consumer, occurrences)) { return false; } } } else { if (!collectPatternMatches(queryParameters.getPattern(), chars, commentStart, commentEnd, file, queryParameters.getRange(), - consumer)) { + consumer, occurrences)) { return false; } } @@ -236,7 +239,9 @@ public class IndexPatternSearcher implements QueryExecutor consumer) { + Processor consumer, + TIntArrayList matches + ) { Pattern pattern = indexPattern.getPattern(); if (pattern != null) { ProgressManager.checkCanceled(); @@ -253,7 +258,8 @@ public class IndexPatternSearcher implements QueryExecutor