From 59a39ec2b9092aa9dc99e2cee4bf76b53134ea24 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 2 Jul 2013 14:57:33 +0200 Subject: [PATCH] IDEA-109359 Goto file doesn't work with parent directory pattern and middle-matching --- .../navigation/ChooseByNameTest.groovy | 8 ++++ .../DefaultChooseByNameItemProvider.java | 39 ++++++++++++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy index 826fe16461e1..d056b8dd1cc4 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy @@ -98,6 +98,14 @@ class Intf { assert elements == files } + public void "test middle matching for directories"() { + def fooIndex = myFixture.addFileToProject("foo/index.html", "foo") + def ooIndex = myFixture.addFileToProject("oo/index.html", "oo") + def fooBarIndex = myFixture.addFileToProject("foo/bar/index.html", "foo bar") + def elements = getPopupElements(new GotoFileModel(project), "oo/index") + assert elements == [ooIndex, fooIndex, fooBarIndex] + } + private List getPopupElements(ChooseByNameModel model, String text) { return getPopupElements(createPopup(model), text) } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java index 9b1a67ef8855..7d30b0203090 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java @@ -28,7 +28,7 @@ import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.util.proximity.PsiProximityComparator; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import gnu.trove.TObjectIntHashMap; +import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,14 +63,16 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider indicator.checkCanceled(); List sameNameElements = new SmartList(); - final TObjectIntHashMap sameNameWeights = new TObjectIntHashMap(); + final Map sameNameWeights = new THashMap(); Comparator weightComparator = new Comparator() { @Override public int compare(Object o1, Object o2) { - return sameNameWeights.get(o2) - sameNameWeights.get(o1); + return sameNameWeights.get(o1).compareTo(sameNameWeights.get(o2)); } }; + List qualifierMiddleMatched = new ArrayList(); + List> patternsAndMatchers = getPatternsAndMatchers(qualifierPattern, base); boolean sortedByMatchingDegree = !(base.getModel() instanceof CustomMatcherModel); @@ -91,27 +93,39 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider sameNameWeights.clear(); for (final Object element : elements) { indicator.checkCanceled(); - Integer degree = matchQualifier(element, base, patternsAndMatchers); - if (degree != null) { + MatchResult qualifierResult = matchQualifier(element, base, patternsAndMatchers); + if (qualifierResult != null) { sameNameElements.add(element); - sameNameWeights.put(element, degree); + sameNameWeights.put(element, qualifierResult); } } sortByProximity(base, sameNameElements); Collections.sort(sameNameElements, weightComparator); for (Object element : sameNameElements) { - if (needSeparator && !consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false; + if (!sameNameWeights.get(element).startMatch) { + qualifierMiddleMatched.add(element); + continue; + } + + if (needSeparator && !startMiddleMatchVariants(consumer, qualifierMiddleMatched)) return false; if (!consumer.process(element)) return false; needSeparator = false; afterStartMatch = result.startMatch; } } else if (elements.length == 1 && matchQualifier(elements[0], base, patternsAndMatchers) != null) { - if (needSeparator && !consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false; + if (needSeparator && !startMiddleMatchVariants(consumer, qualifierMiddleMatched)) return false; if (!consumer.process(elements[0])) return false; afterStartMatch = result.startMatch; } } + return ContainerUtil.process(qualifierMiddleMatched, consumer); + } + + private static boolean startMiddleMatchVariants(Processor consumer, List qualifierMiddleMatched) { + if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false; + if (!ContainerUtil.process(qualifierMiddleMatched, consumer)) return false; + qualifierMiddleMatched.clear(); return true; } @@ -167,7 +181,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider return answer.isEmpty() ? Collections.singletonList(s) : answer; } - private static Integer matchQualifier(@NotNull Object element, + private static MatchResult matchQualifier(@NotNull Object element, @NotNull final ChooseByNameBase base, @NotNull List> patternsAndMatchers) { final String name = base.getModel().getFullName(element); @@ -177,6 +191,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider int matchingDegree = 0; int matchPosition = 0; + boolean startMatch = true; patterns: for (Pair patternAndMatcher : patternsAndMatchers) { final String pattern = patternAndMatcher.first; @@ -187,6 +202,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider MatchResult suspectMatch = matches(base, pattern, matcher, suspect); if (suspectMatch != null) { matchingDegree += suspectMatch.matchingDegree; + startMatch &= suspectMatch.startMatch; matchPosition = j + 1; continue patterns; } @@ -205,7 +221,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider } - return matchingDegree; + return new MatchResult(name, matchingDegree, startMatch); } @NotNull @@ -215,6 +231,9 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider @Override public Pair fun(String s) { String namePattern = getNamePattern(base, s); + if (base.isSearchInAnyPlace() && !namePattern.trim().isEmpty()) { + namePattern = "*" + namePattern; + } return Pair.create(namePattern, buildPatternMatcher(namePattern, NameUtil.MatchingCaseSensitivity.NONE)); } });