KT-13953 Import member popup should not suggest methods when only property or variable is valid

#KT-13953 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-09-21 21:54:27 +03:00
parent e30c211b3e
commit 038068aa44
5 changed files with 85 additions and 12 deletions
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Errors
@@ -122,7 +123,7 @@ internal abstract class ImportFixBase<T : KtExpression>(expression: T) :
}
}
fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>):
private fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>):
Collection<DeclarationDescriptor> {
val nameStr = name.asString()
if (nameStr.isEmpty()) return emptyList()
@@ -149,7 +150,15 @@ internal abstract class ImportFixBase<T : KtExpression>(expression: T) :
val indicesHelper = KotlinIndicesHelper(resolutionFacade, searchScope, ::isVisible)
val result = fillCandidates(nameStr, callTypeAndReceiver, bindingContext, indicesHelper)
var result = fillCandidates(nameStr, callTypeAndReceiver, bindingContext, indicesHelper)
// for CallType.DEFAULT do not include functions if there is no parenthesis
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
val isCall = element.parent is KtCallExpression
if (!isCall) {
result = result.filter { it !is FunctionDescriptor }
}
}
return if (result.size > 1)
reduceCandidatesBasedOnDependencyRuleViolation(result, file)
@@ -0,0 +1,23 @@
// FILE: main.before.kt
// "Import" "false"
// ACTION: Create local variable 'foobar'
// ACTION: Create object 'foobar'
// ACTION: Create parameter 'foobar'
// ACTION: Create property 'foobar'
// ACTION: Rename reference
// ERROR: Unresolved reference: foobar
//KT-9009
package foo
fun f() {
foobar<caret>
}
// FILE: dependency.before.kt
package bar
fun foobar() {
}
@@ -0,0 +1,25 @@
// FILE: main.before.kt
// "Import member" "false"
// ACTION: Create local variable 'foobar'
// ACTION: Create object 'foobar'
// ACTION: Create parameter 'foobar'
// ACTION: Create property 'foobar'
// ACTION: Rename reference
// ERROR: Unresolved reference: foobar
//KT-9009
package foo
fun f() {
foobar<caret>
}
// FILE: dependency.before.kt
package bar
object Foo {
fun foobar() {
}
}
@@ -261,10 +261,11 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
});
assert beforeFile != null;
assert afterFile != null;
subFiles.remove(afterFile);
subFiles.remove(beforeFile);
if (afterFile != null) {
subFiles.remove(afterFile);
}
configureMultiFileTest(subFiles, beforeFile);
@@ -288,15 +289,18 @@ public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzer
String actualText = getFile().getText();
String afterText = new StringBuilder(actualText).insert(getEditor().getCaretModel().getOffset(), "<caret>").toString();
if (pair.second && !afterText.equals(afterFile.content)) {
StringBuilder actualTestFile = new StringBuilder();
actualTestFile.append("// FILE: ").append(beforeFile.path).append("\n").append(beforeFile.content);
for (TestFile file : subFiles) {
actualTestFile.append("// FILE: ").append(file.path).append("\n").append(file.content);
}
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText);
if (pair.second) {
assertNotNull(".after file should exist", afterFile);
if (!afterText.equals(afterFile.content)) {
StringBuilder actualTestFile = new StringBuilder();
actualTestFile.append("// FILE: ").append(beforeFile.path).append("\n").append(beforeFile.content);
for (TestFile file : subFiles) {
actualTestFile.append("// FILE: ").append(file.path).append("\n").append(file.content);
}
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText);
KotlinTestUtils.assertEqualsToFile(new File(beforeFileName), actualTestFile.toString());
KotlinTestUtils.assertEqualsToFile(new File(beforeFileName), actualTestFile.toString());
}
}
}
catch (ComparisonFailure e) {
@@ -347,6 +347,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
doTestWithExtraFile(fileName);
}
@TestMetadata("noFunctionImportOnSimpleName.test")
public void testNoFunctionImportOnSimpleName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/noFunctionImportOnSimpleName.test");
doTestWithExtraFile(fileName);
}
@TestMetadata("noImportForFunInQualifiedNotFirst.before.Main.kt")
public void testNoImportForFunInQualifiedNotFirst() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/noImportForFunInQualifiedNotFirst.before.Main.kt");
@@ -407,6 +413,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
doTestWithExtraFile(fileName);
}
@TestMetadata("noMemberFunctionImportOnSimpleName.test")
public void testNoMemberFunctionImportOnSimpleName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/noMemberFunctionImportOnSimpleName.test");
doTestWithExtraFile(fileName);
}
@TestMetadata("notExcludedClass.before.Main.kt")
public void testNotExcludedClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/notExcludedClass.before.Main.kt");