PY-8132 Fixed: Completion shows function instead of variable if function contains a variable with name equal to function name

Update CompletionVariantsProcessor to ignore same name elements from outer scope
This commit is contained in:
Semyon Proshev
2017-08-18 16:03:22 +03:00
parent 98d1343e4c
commit 8a5f550986
5 changed files with 18 additions and 10 deletions
@@ -161,6 +161,7 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
if (PyUtil.isClassPrivateName(name) && !PyUtil.inSameFile(element, myContext)) {
return;
}
markAsProcessed(name);
myVariants.put(name, setupItem(LookupElementBuilder.createWithSmartPointer(name, element).withIcon(element.getIcon(0))));
}
@@ -169,6 +170,7 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
Icon icon = element.getIcon(0);
// things like PyTargetExpression cannot have a general icon, but here we only have variables
if (icon == null) icon = PlatformIcons.VARIABLE_ICON;
markAsProcessed(name);
myVariants.put(name, setupItem(LookupElementBuilder.createWithSmartPointer(name, element).withIcon(icon)));
}
}
@@ -121,14 +121,16 @@ public abstract class VariantsProcessor implements PsiScopeProcessor {
return false;
}
protected void addElement(@NotNull String name, @NotNull PsiElement element) {
mySeenNames.add(name);
}
protected abstract void addElement(@NotNull String name, @NotNull PsiElement element);
protected void addImportedElement(@NotNull String name, @NotNull PyElement element) {
addElement(name, element);
}
protected void markAsProcessed(@NotNull String name) {
mySeenNames.add(name);
}
@Contract("null -> false")
private boolean nameIsAcceptable(@Nullable String name) {
if (name == null) {
@@ -0,0 +1,3 @@
def abracadabra():
abracadabra = "str"
print(abracadabra)
@@ -0,0 +1,3 @@
def abracadabra():
abracadabra = "str"
print(abracadab<caret>)
@@ -1138,8 +1138,6 @@ public class PythonCompletionTest extends PyTestCase {
// PY-18246
public void testTypingNamedTupleCreatedViaCallInstance() {
myFixture.copyDirectoryToProject("../typing", "");
final List<String> suggested = doTestByText(
"from typing import NamedTuple\n" +
"EmployeeRecord = NamedTuple('EmployeeRecord', [\n" +
@@ -1157,8 +1155,6 @@ public class PythonCompletionTest extends PyTestCase {
// PY-18246
public void testTypingNamedTupleCreatedViaKwargsCallInstance() {
myFixture.copyDirectoryToProject("../typing", "");
final List<String> suggested = doTestByText(
"from typing import NamedTuple\n" +
"EmployeeRecord = NamedTuple('EmployeeRecord', name=str, age=int, title=str, department=str)\n" +
@@ -1174,8 +1170,6 @@ public class PythonCompletionTest extends PyTestCase {
runWithLanguageLevel(
LanguageLevel.PYTHON36,
() -> {
myFixture.copyDirectoryToProject("../typing", "");
final List<String> suggested = doTestByText(
"from typing import NamedTuple\n" +
"class EmployeeRecord(NamedTuple):\n" +
@@ -1194,7 +1188,6 @@ public class PythonCompletionTest extends PyTestCase {
// PY-21519
public void testTypeComment() {
myFixture.copyDirectoryToProject("../typing", "");
final List<String> variants = doTestByFile();
assertContainsElements(variants, "List", "Union", "Optional");
}
@@ -1205,6 +1198,11 @@ public class PythonCompletionTest extends PyTestCase {
assertDoesntContain(variants, "illegal");
}
// PY-8132
public void testOuterCompletionVariantDoesNotOverwriteClosestOne() {
doTest();
}
@Override
protected String getTestDataPath() {
return super.getTestDataPath() + "/completion";