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:
Nikolay Krasko
2012-12-06 13:52:14 +04:00
parent 1092164684
commit c224b6441d
26 changed files with 206 additions and 12 deletions
@@ -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()
}
@@ -0,0 +1,8 @@
// "Import" "true"
// ERROR: Unresolved reference: Some
package testing
fun testing() {
<caret>Some.test()
}
@@ -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()
}
@@ -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()
@@ -0,0 +1,6 @@
// "Import" "false"
// ERROR: Unresolved reference: SomeTest
package testing
val x = testing.<caret>SomeTest()
@@ -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
@@ -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()
@@ -0,0 +1,6 @@
// "Import" "false"
// ERROR: Unresolved reference: SomeTest
package testing
val x = testing?.<caret>SomeTest()
@@ -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();