KT-1672 Don't complete import java.lang.reflect.Array when Array is typed at the beginning of a line

#KT-1672 fixed
This commit is contained in:
Nikolay Krasko
2012-06-01 00:11:14 +04:00
parent 22fe0d80a7
commit f18372cfdc
8 changed files with 151 additions and 18 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin.completion.weigher;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.CompletionSorter;
import org.jetbrains.jet.lang.psi.JetFile;
/**
* @author Nikolay Krasko
@@ -29,7 +30,9 @@ public final class JetCompletionSorting {
public static CompletionResultSet addJetSorting(CompletionParameters parameters, CompletionResultSet result) {
CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher());
sorter = sorter.weighAfter("negativeStats", new JetLocalPreferableWeigher());
sorter = sorter.weighAfter("negativeStats",
new JetLocalPreferableWeigher(),
new JetExplicitlyImportedWeigher((JetFile)parameters.getOriginalFile()));
return result.withRelevanceSorter(sorter);
}
}
@@ -0,0 +1,78 @@
/*
* Copyright 2010-2012 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 org.jetbrains.jet.plugin.completion.weigher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.plugin.completion.JetLookupObject;
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
/**
* @author Nikolay Krasko
*/
// class ExplicitlyImportedWeigher extends ProximityWeigher {
public class JetExplicitlyImportedWeigher extends LookupElementWeigher {
private final JetFile file;
protected JetExplicitlyImportedWeigher(JetFile file) {
super("JetExplicitlyWeigher");
this.file = file;
}
private enum MyResult {
kotlinDefaultImport,
imported,
notImported,
normal
}
@NotNull
@Override
public Comparable weigh(@NotNull LookupElement element) {
Object object = element.getObject();
if (object instanceof JetLookupObject) {
JetLookupObject lookupObject = (JetLookupObject) object;
DeclarationDescriptor descriptor = lookupObject.getDescriptor();
if (descriptor != null) {
FqNameUnsafe fqName = DescriptorUtils.getFQName(descriptor);
// Invalid name can be met for class object descriptor: Test.MyTest.A.<no name provided>.testOther
if (FqName.isValid(fqName.toString())) {
ImportPath importPath = new ImportPath(fqName.toString());
if (ImportInsertHelper.doNeedImport(importPath, null, file)) {
return MyResult.notImported;
}
else {
if (ImportInsertHelper.isImportedWithKotlinDefault(importPath)) {
return MyResult.kotlinDefaultImport;
}
return MyResult.imported;
}
}
}
}
return MyResult.normal;
}
}
@@ -31,7 +31,10 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -140,18 +143,28 @@ public class ImportInsertHelper {
return true;
}
for (ImportPath defaultJetImport : DefaultModuleConfiguration.DEFAULT_JET_IMPORTS) {
if (QualifiedNamesUtil.isImported(defaultJetImport, importPath)) {
return true;
}
}
if (isImportedWithKotlinDefault(importPath)) return true;
if (isImportedWithJavaDefault(importPath)) return true;
return false;
}
public static boolean isImportedWithJavaDefault(ImportPath importPath) {
for (ImportPath defaultJavaImport : JavaBridgeConfiguration.DEFAULT_JAVA_IMPORTS) {
if (QualifiedNamesUtil.isImported(defaultJavaImport, importPath)) {
return true;
}
}
return false;
}
public static boolean isImportedWithKotlinDefault(ImportPath importPath) {
for (ImportPath defaultJetImport : DefaultModuleConfiguration.DEFAULT_JET_IMPORTS) {
if (QualifiedNamesUtil.isImported(defaultJetImport, importPath)) {
return true;
}
}
return false;
}
@@ -0,0 +1,15 @@
fun main(args: Array<String>) {
Array<caret>
}
// COMPLETE: 2
// WITH_ORDER: 1
// EXIST: Array~(jet)
// EXIST: Array~(java.sql)
// Developer! Every ancient failure of this test is important!
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.testing.InTextDirectivesUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -94,21 +95,25 @@ public class ExpectedCompletionUtils {
public static final String ABSENT_LINE_PREFIX = "// ABSENT:";
public static final String NUMBER_LINE_PREFIX = "// NUMBER:";
public static final String EXECUTION_TIME_PREFIX = "// TIME:";
public static final String WITH_ORDER_PREFIX = "// WITH_ORDER:";
private final String existLinePrefix;
private final String absentLinePrefix;
private final String numberLinePrefix;
private final String executionTimePrefix;
private final String withOrderPrefix;
public ExpectedCompletionUtils() {
this(EXIST_LINE_PREFIX, ABSENT_LINE_PREFIX, NUMBER_LINE_PREFIX, EXECUTION_TIME_PREFIX);
this(EXIST_LINE_PREFIX, ABSENT_LINE_PREFIX, NUMBER_LINE_PREFIX, EXECUTION_TIME_PREFIX, WITH_ORDER_PREFIX);
}
public ExpectedCompletionUtils(String existLinePrefix, String absentLinePrefix, String numberLinePrefix, String execitionTimePrefix) {
public ExpectedCompletionUtils(String existLinePrefix, String absentLinePrefix,
String numberLinePrefix, String executionTimePrefix, String withOrderPrefix) {
this.existLinePrefix = existLinePrefix;
this.absentLinePrefix = absentLinePrefix;
this.numberLinePrefix = numberLinePrefix;
this.executionTimePrefix = execitionTimePrefix;
this.executionTimePrefix = executionTimePrefix;
this.withOrderPrefix = withOrderPrefix;
}
@NotNull
@@ -122,7 +127,7 @@ public class ExpectedCompletionUtils {
}
public static CompletionProposal[] processProposalAssertions(String prefix, String fileText) {
List<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
Collection<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
for (String proposalStr : InTextDirectivesUtils.findListWithPrefix(prefix, fileText)) {
Matcher matcher = CompletionProposal.PATTERN.matcher(proposalStr);
matcher.find();
@@ -144,15 +149,28 @@ public class ExpectedCompletionUtils {
return InTextDirectivesUtils.getPrefixedInt(fileText, executionTimePrefix);
}
protected static void assertContainsRenderedItems(CompletionProposal[] expected, LookupElement[] items) {
public boolean isWithOrder(String fileText) {
return InTextDirectivesUtils.getPrefixedInt(fileText, withOrderPrefix) != null;
}
protected static void assertContainsRenderedItems(CompletionProposal[] expected, LookupElement[] items, boolean checkOrder) {
List<CompletionProposal> itemsInformation = getItemsInformation(items);
int indexOfPrevious = Integer.MIN_VALUE;
for (CompletionProposal expectedProposal : expected) {
boolean isFound = false;
for (CompletionProposal proposal : itemsInformation) {
for (int index = 0; index < itemsInformation.size(); index++) {
CompletionProposal proposal = itemsInformation.get(index);
if (proposal.isSuitable(expectedProposal)) {
isFound = true;
Assert.assertTrue("Invalid order of existent elements in " + listToString(itemsInformation),
!checkOrder || index > indexOfPrevious);
indexOfPrevious = index;
break;
}
}
@@ -186,7 +204,7 @@ public class ExpectedCompletionUtils {
return result;
}
protected static String listToString(List<ExpectedCompletionUtils.CompletionProposal> items) {
protected static String listToString(Collection<CompletionProposal> items) {
return StringUtil.join(
Collections2.transform(items, new Function<CompletionProposal, String>() {
@Override
@@ -145,6 +145,10 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest();
}
public void testStandardJetArrayFirst() {
doTest();
}
public void testSubpackageInFun() {
doTest();
}
@@ -38,7 +38,9 @@ public abstract class JetCompletionMultiTestBase extends CompletionTestCase {
final String fileText = getFile().getText();
final ExpectedCompletionUtils completionUtils = new ExpectedCompletionUtils();
ExpectedCompletionUtils.assertContainsRenderedItems(completionUtils.itemsShouldExist(fileText), myItems);
ExpectedCompletionUtils.assertContainsRenderedItems(
completionUtils.itemsShouldExist(fileText), myItems, completionUtils.isWithOrder(fileText));
ExpectedCompletionUtils.assertNotContainsRenderedItems(completionUtils.itemsShouldAbsent(fileText), myItems);
Integer itemsNumber = completionUtils.getExpectedNumber(fileText);
@@ -19,9 +19,9 @@ package org.jetbrains.jet.completion;
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.completion.LightCompletionTestCase;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
import org.apache.commons.lang.SystemUtils;
@@ -71,7 +71,7 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
myItems = new LookupElement[0];
}
ExpectedCompletionUtils.assertContainsRenderedItems(expected, myItems);
ExpectedCompletionUtils.assertContainsRenderedItems(expected, myItems, completionUtils.isWithOrder(fileText));
ExpectedCompletionUtils.assertNotContainsRenderedItems(unexpected, myItems);
if (itemsNumber != null) {
@@ -110,7 +110,7 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
protected void complete(final int time) {
new CodeCompletionHandlerBase(type, false, false, true).invokeCompletion(getProject(), getEditor(), time, false);
LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
Lookup lookup = LookupManager.getActiveLookup(myEditor);
myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
}