prefer class own methods to the inherited ones in completion, when the class is defined in the library

This commit is contained in:
peter
2013-02-12 14:53:31 +01:00
parent e5c4630655
commit ab7a35690b
5 changed files with 113 additions and 49 deletions
@@ -517,7 +517,7 @@ public class JavaCompletionUtil {
}
private static LookupElement highlight(LookupElement decorator) {
return PrioritizedLookupElement.withGrouping(
return PrioritizedLookupElement.withExplicitProximity(
LookupElementDecorator.withRenderer(decorator, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
@Override
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
@@ -2,24 +2,24 @@
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package com.intellij.codeInsight.completion;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
package com.intellij.codeInsight.completion
import com.intellij.JavaTestUtil
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ex.PathManagerEx
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.roots.ContentEntry
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.SourceFolder
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
/**
* @author peter
*/
@@ -32,14 +32,11 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
public void testPackagePrefix() throws Throwable {
myFixture.configureByFile("/codeInsight/completion/normal/" + getTestName(false) + ".java");
new WriteCommandAction.Simple(getProject()) {
@Override
protected void run() throws Throwable {
final ModifiableRootModel model = ModuleRootManager.getInstance(myFixture.getModule()).getModifiableModel();
model.getContentEntries()[0].getSourceFolders()[0].setPackagePrefix("foo.bar.goo");
model.commit();
}
}.execute().throwException();
ApplicationManager.application.runWriteAction {
final ModifiableRootModel model = ModuleRootManager.getInstance(myFixture.getModule()).getModifiableModel();
model.getContentEntries()[0].getSourceFolders()[0].setPackagePrefix("foo.bar.goo");
model.commit();
}
myFixture.completeBasic();
myFixture.checkResultByFile("/codeInsight/completion/normal/" + getTestName(false) + "_after.java");
@@ -50,18 +47,15 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
public void testPreferTestCases() throws Throwable {
myFixture.configureByFile("/codeInsight/completion/normal/" + getTestName(false) + ".java");
new WriteCommandAction.Simple(getProject()) {
@Override
protected void run() throws Throwable {
final ModifiableRootModel model = ModuleRootManager.getInstance(myFixture.getModule()).getModifiableModel();
ContentEntry contentEntry = model.getContentEntries()[0];
SourceFolder sourceFolder = contentEntry.getSourceFolders()[0];
VirtualFile file = sourceFolder.getFile();
contentEntry.removeSourceFolder(sourceFolder);
contentEntry.addSourceFolder(file, true);
model.commit();
}
}.execute().throwException();
ApplicationManager.application.runWriteAction {
final ModifiableRootModel model = ModuleRootManager.getInstance(myFixture.getModule()).getModifiableModel();
ContentEntry contentEntry = model.getContentEntries()[0];
SourceFolder sourceFolder = contentEntry.getSourceFolders()[0];
VirtualFile file = sourceFolder.getFile();
contentEntry.removeSourceFolder(sourceFolder);
contentEntry.addSourceFolder(file, true);
model.commit();
}
myFixture.addClass("package foo; public class SomeTestCase {}");
myFixture.addClass("package bar; public class SomeTestec {}");
@@ -110,4 +104,24 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
myFixture.checkResult("class Main { foo.bar.AxBxCxDxEx<caret> }");
}
public void testPreferOwnMethods() {
def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/../../../lib")
def nanoJar = lib.children.find { it.name.startsWith("nanoxml") }
PsiTestUtil.addLibrary(myModule, 'nano1', lib.path, ["/$nanoJar.name!/"] as String[], [] as String[])
assert JavaPsiFacade.getInstance(project).findClass('net.n3.nanoxml.StdXMLParser', GlobalSearchScope.allScope(project))
myFixture.configureByText "a.java", """
public class Test {
void method(net.n3.nanoxml.StdXMLParser f) {
f.<caret>
}
}
"""
myFixture.completeBasic()
myFixture.assertPreferredCompletionItems 0, 'getBuilder'
}
}
@@ -31,11 +31,17 @@ public class PrioritizedLookupElement<T extends LookupElement> extends LookupEle
public static final ClassConditionKey<PrioritizedLookupElement> CLASS_CONDITION_KEY = ClassConditionKey.create(PrioritizedLookupElement.class);
private final double myPriority;
private final int myGrouping;
private final int myExplicitProximity;
public PrioritizedLookupElement(T delegate, double priority, int grouping) {
private PrioritizedLookupElement(T delegate, double priority, int grouping) {
this(delegate, priority, grouping, 0);
}
private PrioritizedLookupElement(T delegate, double priority, int grouping, int explicitProximity) {
super(delegate);
myPriority = priority;
myGrouping = grouping;
myExplicitProximity = explicitProximity;
}
public double getPriority() {
@@ -46,6 +52,10 @@ public class PrioritizedLookupElement<T extends LookupElement> extends LookupEle
return myGrouping;
}
public int getExplicitProximity() {
return myExplicitProximity;
}
public static LookupElement withPriority(LookupElement element, double priority) {
final PrioritizedLookupElement prioritized = element.as(CLASS_CONDITION_KEY);
return new PrioritizedLookupElement<LookupElement>(element, priority, prioritized == null ? 0 : prioritized.getGrouping());
@@ -55,4 +65,11 @@ public class PrioritizedLookupElement<T extends LookupElement> extends LookupEle
final PrioritizedLookupElement prioritized = element.as(CLASS_CONDITION_KEY);
return new PrioritizedLookupElement<LookupElement>(element, prioritized == null ? 0 : prioritized.getPriority(), grouping);
}
public static LookupElement withExplicitProximity(LookupElement element, int explicitProximity) {
final PrioritizedLookupElement prioritized = element.as(CLASS_CONDITION_KEY);
double priority = prioritized == null ? 0 : prioritized.getPriority();
int grouping = prioritized == null ? 0 : prioritized.getGrouping();
return new PrioritizedLookupElement<LookupElement>(element, priority, grouping, explicitProximity);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElement;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class ExplicitProximityWeigher extends CompletionWeigher {
@Override
public Integer weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
PrioritizedLookupElement prioritized = item.as(PrioritizedLookupElement.CLASS_CONDITION_KEY);
return prioritized != null ? prioritized.getExplicitProximity() : 0;
}
}
@@ -469,15 +469,17 @@
<weigher key="proximity" implementationClass="com.intellij.psi.util.proximity.SdkOrLibraryWeigher" id="sdkOrLibrary"
order="after sameModule"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PriorityWeigher" id="priority" order="first"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.StatisticsWeigher" id="stats"
order="after priority"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PrefixMatchingWeigher" id="prefix"
order="after stats"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.LookupElementProximityWeigher" id="proximity"
order="after prefix"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.GroupingWeigher" id="grouping"
order="last"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PriorityWeigher" id="priority" order="first"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.StatisticsWeigher" id="stats"
order="after priority"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.PrefixMatchingWeigher" id="prefix"
order="after stats"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.ExplicitProximityWeigher" id="explicitProximity"
order="after prefix"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.LookupElementProximityWeigher" id="proximity"
order="after explicitProximity"/>
<weigher key="completion" implementationClass="com.intellij.codeInsight.completion.GroupingWeigher" id="grouping"
order="last"/>
<completion.contributor language="any" implementationClass="com.intellij.codeInsight.completion.DefaultCompletionContributor"
id="default"