KT-3133 Editor suggest to specify the package when it already has specified
Do not suggest imports in imports and in qualified names #KT-3133 Fixed
This commit is contained in:
@@ -347,6 +347,20 @@ public class JetPsiUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isFirstPartInQualified(@NotNull JetSimpleNameExpression nameExpression) {
|
||||
@SuppressWarnings("unchecked") JetUserType userType = PsiTreeUtil.getParentOfType(nameExpression, JetUserType.class, true, JetDeclaration.class);
|
||||
if (userType != null) {
|
||||
return PsiTreeUtil.isAncestor(userType.getFirstChild(), nameExpression, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") JetQualifiedExpression qualifiedExpression = PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class, true, JetDeclaration.class);
|
||||
if (qualifiedExpression != null) {
|
||||
return PsiTreeUtil.isAncestor(qualifiedExpression.getFirstChild(), nameExpression, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isVoidType(@Nullable JetTypeReference typeReference) {
|
||||
if (typeReference == null) {
|
||||
return false;
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
@@ -96,8 +97,11 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
|
||||
ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) element.getContainingFile());
|
||||
|
||||
List<FqName> result = Lists.newArrayList();
|
||||
result.addAll(getClassNames(referenceName, (JetFile) file, resolveSession));
|
||||
result.addAll(getJetTopLevelFunctions(referenceName, element, resolveSession, file.getProject()));
|
||||
if (!isSuppressedTopLevelImportInPosition(element)) {
|
||||
result.addAll(getClassNames(referenceName, (JetFile) file, resolveSession));
|
||||
result.addAll(getJetTopLevelFunctions(referenceName, element, resolveSession, file.getProject()));
|
||||
}
|
||||
|
||||
result.addAll(getJetExtensionFunctions(referenceName, element, resolveSession, file.getProject()));
|
||||
|
||||
return Collections2.filter(result, new Predicate<FqName>() {
|
||||
@@ -109,6 +113,10 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isSuppressedTopLevelImportInPosition(@NotNull JetSimpleNameExpression element) {
|
||||
return element.isImportDirectiveExpression() || !JetPsiUtil.isFirstPartInQualified(element);
|
||||
}
|
||||
|
||||
private static Collection<FqName> getJetTopLevelFunctions(
|
||||
@NotNull String referenceName,
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Import" "true"
|
||||
// ERROR: Unresolved reference: Some
|
||||
|
||||
package testing
|
||||
|
||||
import some.Some
|
||||
|
||||
fun testing() {
|
||||
<caret>Some.test()
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Import" "true"
|
||||
// ERROR: Unresolved reference: Some
|
||||
|
||||
package testing
|
||||
|
||||
fun testing() {
|
||||
<caret>Some.test()
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package some
|
||||
|
||||
public class Some {
|
||||
class object {
|
||||
public fun test() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Import" "true"
|
||||
// ERROR: Unresolved reference: Some
|
||||
package testing
|
||||
|
||||
import some.Some
|
||||
|
||||
class TestClass: <caret>Some.InnerInSome()
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Import" "true"
|
||||
// ERROR: Unresolved reference: Some
|
||||
package testing
|
||||
|
||||
class TestClass: <caret>Some.InnerInSome()
|
||||
@@ -0,0 +1,7 @@
|
||||
package some
|
||||
|
||||
public class Some {
|
||||
public open class InnerInSome {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: externalFun
|
||||
|
||||
package testing
|
||||
|
||||
fun some() {
|
||||
testing.<caret>externalFun()
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: externalFun
|
||||
|
||||
package testing
|
||||
|
||||
fun some() {
|
||||
testing.<caret>externalFun()
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package some
|
||||
|
||||
fun externalFun() {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
import testing.<caret>SomeTest
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
import testing.<caret>SomeTest
|
||||
@@ -0,0 +1,4 @@
|
||||
package some
|
||||
|
||||
public class SomeTest
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
val x = some.<caret>SomeTest()
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
val x = testing.<caret>SomeTest()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package some
|
||||
|
||||
public class SomeTest
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Import" "false"
|
||||
// ACTION: Change to constructor invocation
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
class Some: testing.<caret>SomeTest
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Import" "false"
|
||||
// ACTION: Change to constructor invocation
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
class Some: testing.<caret>SomeTest
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package some
|
||||
|
||||
public class SomeTest
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
val x = testing?.<caret>SomeTest()
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Import" "false"
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
package testing
|
||||
|
||||
val x = testing?.<caret>SomeTest()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package some
|
||||
|
||||
public class SomeTest
|
||||
@@ -38,10 +38,38 @@ public class AutoImportFixTest extends JetQuickFixMultiFileTest {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testImportInFirstPartInQualifiedExpression() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testImportInFirstPartInUserType() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportForFunInQualifiedNotFirst() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportForPrivateClass() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportInImports() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportInQualifiedExpressionNotFirst() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportInQualifiedUserTypeNotFirst() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoImportInSafeQualifiedExpressionNotFirst() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCheckFileName() {
|
||||
return getTestName(true) + ".after.kt";
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
@@ -26,11 +27,13 @@ import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import junit.framework.ComparisonFailure;
|
||||
import org.jetbrains.jet.InTextDirectivesUtils;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
@@ -41,6 +44,14 @@ public abstract class JetQuickFixMultiFileTest extends DaemonAnalyzerTestCase {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<String> getActionsTexts(List<IntentionAction> availableActions) {
|
||||
List<String> texts = new ArrayList<String>();
|
||||
for (IntentionAction intentionAction : availableActions) {
|
||||
texts.add(intentionAction.getText());
|
||||
}
|
||||
return texts;
|
||||
}
|
||||
|
||||
public void doTest() throws Exception {
|
||||
configureByFiles(null, getTestFileNames().toArray(new String[1]));
|
||||
|
||||
@@ -69,20 +80,27 @@ public abstract class JetQuickFixMultiFileTest extends DaemonAnalyzerTestCase {
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath)
|
||||
throws Exception {
|
||||
IntentionAction action = LightQuickFixTestCase.findActionWithText(getAvailableActions(), text);
|
||||
List<IntentionAction> availableActions = getAvailableActions();
|
||||
IntentionAction action = LightQuickFixTestCase.findActionWithText(availableActions, text);
|
||||
|
||||
if (action == null) {
|
||||
if (actionShouldBeAvailable) {
|
||||
List<IntentionAction> actions = getAvailableActions();
|
||||
List<String> texts = new ArrayList<String>();
|
||||
for (IntentionAction intentionAction : actions) {
|
||||
texts.add(intentionAction.getText());
|
||||
}
|
||||
List<String> texts = getActionsTexts(availableActions);
|
||||
Collection<HighlightInfo> infos = doHighlighting();
|
||||
fail("Action with text '" + text + "' is not available in test " + testFullPath + "\n" +
|
||||
"Available actions (" + texts.size() + "): " + texts + "\n" +
|
||||
actions + "\n" +
|
||||
availableActions + "\n" +
|
||||
"Infos:" + infos);
|
||||
}
|
||||
else {
|
||||
Set<String> validActions = Sets.newHashSet(InTextDirectivesUtils.findLinesWithPrefixRemoved("// ACTION:", getFile().getText()));
|
||||
for (IntentionAction availableAction : availableActions) {
|
||||
if (!validActions.contains(availableAction.getText())) {
|
||||
fail(String.format("Unexpected action available at current position: %s. Use // ACTION: directive",
|
||||
availableAction.getText()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!actionShouldBeAvailable) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
import org.apache.commons.lang.SystemUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.InTextDirectivesUtils;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
@@ -34,7 +35,6 @@ import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
import org.jetbrains.jet.plugin.highlighter.IdeErrorMessages;
|
||||
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
||||
import org.jetbrains.jet.testing.ConfigRuntimeUtil;
|
||||
import org.jetbrains.jet.InTextDirectivesUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
@@ -132,8 +132,6 @@ public class JetQuickFixTest extends LightQuickFixTestCase {
|
||||
if (diagnostics.size() != 0) {
|
||||
List<String> expectedErrorStrings = InTextDirectivesUtils.findLinesWithPrefixRemoved("// ERROR:", getFile().getText());
|
||||
|
||||
System.out.println(getFile().getText());
|
||||
|
||||
Collection<String> expectedErrors = new HashSet<String>(expectedErrorStrings);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
Reference in New Issue
Block a user