diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java index 3788852a8f2a..8e5974caa8e2 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java +++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java @@ -23,7 +23,6 @@ import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.Matcher; import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.Iterator; import static com.intellij.psi.codeStyle.NameUtil.MatchingCaseSensitivity.*; @@ -40,115 +39,6 @@ public class MinusculeMatcher implements Matcher { myPattern = StringUtil.trimEnd(pattern, "* ").toCharArray(); } - @Nullable - private FList matchName(String name, int patternIndex, int nameIndex) { - if (patternIndex == myPattern.length) { - return FList.emptyList(); - } - if ('*' == myPattern[patternIndex]) { - return skipChars(name, patternIndex, nameIndex, true); - } - if (nameIndex == name.length()) { - return null; - } - - if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') { - return skipChars(name, patternIndex, nameIndex, false); - } - - if (' ' == myPattern[patternIndex] && patternIndex != myPattern.length - 1) { - return skipWords(name, patternIndex, nameIndex); - } - - if ((patternIndex == 0 || patternIndex == 1 && myPattern[0] == ' ' && nameIndex == 0) && - myOptions != NameUtil.MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[patternIndex]) { - return null; - } - - if (NameUtil.isWordSeparator(name.charAt(nameIndex))) { - return skipSeparators(name, patternIndex, nameIndex); - } - - if (StringUtil.toLowerCase(name.charAt(nameIndex)) != StringUtil.toLowerCase(myPattern[patternIndex])) { - if (Character.isDigit(name.charAt(nameIndex)) && nameIndex > 0 || (name.charAt(nameIndex) == '.' && name.indexOf('.', nameIndex + 1) > 0)) { - return matchName(name, patternIndex, nameIndex + 1); - } - return null; - } - - if (myOptions == ALL && name.charAt(nameIndex) != myPattern[patternIndex]) { - return null; - } - - int nextStart = NameUtil.nextWord(name, nameIndex); - - int lastUpper = NameUtil.isWordStart(myPattern[patternIndex]) ? 0 : -1; - - int i = 1; - while (true) { - if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) { - break; - } - char p = myPattern[patternIndex + i]; - char w = name.charAt(i + nameIndex); - if (lastUpper == i - 1 && NameUtil.isWordStart(p) && myOptions != ALL) { - if (p == w) { - lastUpper = i; - } - p = StringUtil.toLowerCase(p); - } - - if (myOptions != ALL) { - w = StringUtil.toLowerCase(w); - } - if (w != p) { - break; - } - i++; - } - - if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) { - return FList.emptyList().prepend(TextRange.from(nameIndex, i)); - } - - return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i); - } - - private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) { - return nextStart == name.length() && - patternIndex + i == myPattern.length - 1 && - ' ' == myPattern[patternIndex + i] && - (i == 1 && NameUtil.isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()); - } - - @Nullable - private FList matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) { - boolean star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*'; - if (lastUpper >= 1) { - int nextNameIndex = star && matchLen == lastUpper ? nameIndex + lastUpper : nextStart; - int nextPatternIndex = patternIndex + lastUpper + 1; - FList ranges = star ? matchName(name, nextPatternIndex, nextNameIndex) : skipWords(name, nextPatternIndex, nextNameIndex); - if (ranges != null) { - return prependRange(ranges, nameIndex, lastUpper + 1); - } - } - - int trial = matchLen; - while (trial > 0) { - FList ranges = skipWords(name, patternIndex + trial, nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, trial); - } - trial--; - } - - FList ranges = matchName(name, patternIndex + matchLen, nameIndex + matchLen); - if (ranges != null) { - return prependRange(ranges, nameIndex, matchLen); - } - return null; - } - private static FList prependRange(FList ranges, int from, int length) { TextRange head = ranges.getHead(); if (head != null && head.getStartOffset() == from + length) { @@ -157,123 +47,6 @@ public class MinusculeMatcher implements Matcher { return ranges.prepend(TextRange.from(from, length)); } - @Nullable - private FList skipSeparators(String name, int patternIndex, int nameIndex) { - int nextStart = NameUtil.nextWord(name, nameIndex); - assert nextStart - nameIndex == 1 : "'" + name + "'" + nameIndex + " " + nextStart; - char p = myPattern[patternIndex]; - if (NameUtil.isWordSeparator(p)) { - if (myOptions != NameUtil.MatchingCaseSensitivity.NONE && - nameIndex == 0 && name.length() > 1 && patternIndex + 1 < myPattern.length && - NameUtil.isWordSeparator(name.charAt(1)) && !NameUtil.isWordSeparator(myPattern[patternIndex + 1])) { - return null; - } - - final FList ranges = matchName(name, patternIndex + 1, nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, 1); - } - - return null; - } - - return matchName(name, patternIndex, nextStart); - } - - @Nullable - private FList skipChars(String name, int patternIndex, int nameIndex, boolean maySkipNextChar) { - boolean veryStart = patternIndex == 0; - while ('*' == myPattern[patternIndex]) { - patternIndex++; - if (patternIndex == myPattern.length) { - return FList.emptyList(); - } - } - - char nextChar = myPattern[patternIndex]; - boolean upper = Character.isUpperCase(myPattern[patternIndex]); - - int fromIndex = nameIndex; - while (true) { - int next = StringUtil.indexOfIgnoreCase(name, nextChar, fromIndex); - if (next < 0) { - break; - } - if (next == 0 && myOptions != NameUtil.MatchingCaseSensitivity.NONE && name.charAt(next) != nextChar) { - fromIndex = next + 1; - continue; - } - if (upper && next > 0 && !Character.isUpperCase(name.charAt(next))) { - fromIndex = next + 1; - continue; - } - - if (veryStart && next > 0 && !NameUtil.isWordStart(name, next) && !NameUtil.isWordSeparator(nextChar)) { - if (next == name.length() - 1) { - return null; - } - if (patternIndex == myPattern.length - 1 || - Character.isLetter(myPattern[patternIndex + 1]) && (myPattern[patternIndex + 1] != name.charAt(next + 1) || - NameUtil.isWordStart(name, next + 1))) { - fromIndex = next + 1; - continue; - } - } - - FList ranges = matchName(name, patternIndex, next); - if (ranges != null) { - return ranges; - } - if (!maySkipNextChar) { - return null; - } - fromIndex = next + 1; - } - return null; - } - - @Nullable - private FList skipWords(String name, int patternIndex, int nameIndex) { - while (patternIndex < myPattern.length && ' ' == myPattern[patternIndex]) { - patternIndex++; - } - if (patternIndex == myPattern.length) { - return FList.emptyList(); - } - if (nameIndex == name.length()) { - return null; - } - if (myPattern[patternIndex] == '*') { - return skipChars(name, patternIndex, nameIndex, true); - } - - if (nameIndex == 0 || NameUtil.isWordStart(name, nameIndex)) { - FList ranges = matchName(name, patternIndex, nameIndex); - if (ranges != null) { - return ranges; - } - } - - boolean separatorInPattern = !Character.isLetterOrDigit(myPattern[patternIndex]); - int fromIndex = nameIndex; - while (fromIndex < name.length()) { - int next = separatorInPattern ? name.indexOf(myPattern[patternIndex], fromIndex) : NameUtil.nextWord(name, fromIndex); - if (next < 0) { - break; - } - - FList ranges = matchName(name, patternIndex, next); - if (ranges != null) { - return ranges; - } - fromIndex = next; - if (separatorInPattern) { - fromIndex++; - } - } - return null; - } - public int matchingDegree(String name) { Iterable iterable = matchingFragments(name); if (iterable == null) return Integer.MIN_VALUE; @@ -351,22 +124,21 @@ public class MinusculeMatcher implements Matcher { @Nullable public Iterable matchingFragments(String name) { - if (name.isEmpty()) { - return myPattern.length == 0 ? Collections.emptyList() : null; - } - - if (true) { - return matchWildcards(name, 0, 0); - } - - return matchName(name, 0, 0); + return matchWildcards(name, 0, 0); } @Nullable private FList matchWildcards(String name, int patternIndex, int nameIndex) { - while (isWildcard(patternIndex)) { - patternIndex++; + if (nameIndex < 0) { + return null; } + if (!isWildcard(patternIndex)) { + return matchFragment(name, patternIndex, nameIndex); + } + + do { + patternIndex++; + } while (isWildcard(patternIndex)); boolean space = isPatternChar(patternIndex - 1, ' '); if (patternIndex == myPattern.length) { if (space && nameIndex != name.length() && (patternIndex < 2 || !NameUtil.isWordStart(myPattern[patternIndex - 2]))) { @@ -375,26 +147,26 @@ public class MinusculeMatcher implements Matcher { return FList.emptyList(); } + { + FList ranges = matchFragment(name, patternIndex, nameIndex); + if (ranges != null) { + return ranges; + } + } + char p = myPattern[patternIndex]; - if (isWildcard(patternIndex - 1)) { - { + while (true) { + nameIndex = space ? indexOfWordStart(name, p, nameIndex) : StringUtil.indexOfIgnoreCase(name, p, nameIndex + 1); + if (nameIndex < 0) { + return null; + } + if (!Character.isUpperCase(p) || NameUtil.isWordStart(name, nameIndex)) { FList ranges = matchFragment(name, patternIndex, nameIndex); if (ranges != null) { return ranges; } } - while (true) { - nameIndex = space ? indexOfWordStart(name, p, nameIndex) : StringUtil.indexOfIgnoreCase(name, p, nameIndex + 1); - if (nameIndex < 0) return null; - if (!Character.isUpperCase(p) || NameUtil.isWordStart(name, nameIndex)) { - FList ranges = matchFragment(name, patternIndex, nameIndex); - if (ranges != null) { - return ranges; - } - } - } } - return matchFragment(name, patternIndex, nameIndex); } @Nullable @@ -414,11 +186,9 @@ public class MinusculeMatcher implements Matcher { } if (myPattern[patternIndex + i] != name.charAt(nameIndex + i)) { int nextWordStart = indexOfWordStart(name, myPattern[patternIndex + i], nameIndex + i); - if (nextWordStart >= 0) { - FList ranges = matchWildcards(name, patternIndex + i, nextWordStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, i); - } + FList ranges = matchWildcards(name, patternIndex + i, nextWordStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, i); } } } @@ -430,11 +200,9 @@ public class MinusculeMatcher implements Matcher { } while (i >= minFragment) { int nextWordStart = isWildcard(patternIndex + i) ? nameIndex + i : indexOfWordStart(name, myPattern[patternIndex + i], nameIndex + i); - if (nextWordStart >= 0) { - FList ranges = matchWildcards(name, patternIndex + i, nextWordStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, i); - } + FList ranges = matchWildcards(name, patternIndex + i, nextWordStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, i); } i--; }