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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+78
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user