From db8e5c2e2e40ed57a434f3e65785524da1cca3c2 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Tue, 15 Feb 2022 17:09:19 +0200 Subject: [PATCH] PY-47962 Start-match non-imported module names in completion This way we further reduce the number of irrelevant completion items suggested effectively in every expression context, e.g. not suggesting "parser" and "calendar" modules for the "ar" prefix, only something like "argparse" or "array". The same applies to the completion of attributes with unresolved qualifiers. GitOrigin-RevId: 7a58053c4744c3d0066c379a4f190ffd09bfabd1 --- .../PyModuleNameCompletionContributor.kt | 1 + .../stubs/PyQualifiedNameCompletionMatcher.java | 2 +- .../fb.py | 1 + .../fb_util.py | 1 + .../foo_bar.py | 1 + .../foobar.py | 1 + .../main.py | 1 + .../mod_fb.py | 1 + .../mod_foo_bar.py | 1 + .../{fileinput => nt_parser}/__init__.py | 0 .../fb.py | 0 .../fb_util.py | 0 .../foo_bar.py | 0 .../foobar.py | 0 .../main.py | 1 + .../mod_fb.py | 0 .../mod_foo_bar.py | 0 ...yNotImportedQualifiedNameCompletionTest.java | 17 ++++++++++++++++- 18 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb_util.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foo_bar.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foobar.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/main.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_fb.py create mode 100644 python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_foo_bar.py rename python/testData/completion/notImportedQualifiedName/FuzzyResultsShouldBeAddedToAliasAttributesCompletion/{fileinput => nt_parser}/__init__.py (100%) create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb_util.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foo_bar.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foobar.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/main.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_fb.py create mode 100644 python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_foo_bar.py diff --git a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyModuleNameCompletionContributor.kt b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyModuleNameCompletionContributor.kt index 5c9ee03e599f..90a9ef3b7f95 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyModuleNameCompletionContributor.kt +++ b/python/python-psi-impl/src/com/jetbrains/python/codeInsight/completion/PyModuleNameCompletionContributor.kt @@ -56,6 +56,7 @@ class PyModuleNameCompletionContributor : CompletionContributor(), DumbAware { getCompletionVariants(parameters.position.parent, parameters.originalFile, otherVariants).asSequence() .filterIsInstance() .filterNot { it.lookupString.startsWith('_') } + .filter { result.prefixMatcher.isStartMatch(it) } .forEach { result.addElement(PrioritizedLookupElement.withPriority(it, NOT_IMPORTED_MODULE_WEIGHT.toDouble())) } } diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/stubs/PyQualifiedNameCompletionMatcher.java b/python/python-psi-impl/src/com/jetbrains/python/psi/stubs/PyQualifiedNameCompletionMatcher.java index 0352475b62fb..7d9e6c86b021 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/stubs/PyQualifiedNameCompletionMatcher.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/stubs/PyQualifiedNameCompletionMatcher.java @@ -172,7 +172,7 @@ public class PyQualifiedNameCompletionMatcher { private boolean qualifierMatches(@NotNull QualifiedName qualifier) { String firstComponent = Objects.requireNonNullElse(qualifier.getFirstComponent(), ""); - if (!myQualifierFirstComponentMatcher.prefixMatches(firstComponent)) return false; + if (!myQualifierFirstComponentMatcher.isStartMatch(firstComponent)) return false; String remainder = qualifier.getComponentCount() == 0 ? "" : qualifier.removeHead(1).toString(); if (!myQualifierRemainderMatcher.prefixMatches(remainder)) return false; return true; diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb_util.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb_util.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/fb_util.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foo_bar.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foo_bar.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foo_bar.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foobar.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foobar.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/foobar.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/main.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/main.py new file mode 100644 index 000000000000..52d49b877f4a --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/main.py @@ -0,0 +1 @@ +fb.va \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_fb.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_fb.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_fb.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_foo_bar.py b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_foo_bar.py new file mode 100644 index 000000000000..6fbcff414a68 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/AttributesOfModulesWithMiddleMatchNotSuggested/mod_foo_bar.py @@ -0,0 +1 @@ +var = 42 \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/FuzzyResultsShouldBeAddedToAliasAttributesCompletion/fileinput/__init__.py b/python/testData/completion/notImportedQualifiedName/FuzzyResultsShouldBeAddedToAliasAttributesCompletion/nt_parser/__init__.py similarity index 100% rename from python/testData/completion/notImportedQualifiedName/FuzzyResultsShouldBeAddedToAliasAttributesCompletion/fileinput/__init__.py rename to python/testData/completion/notImportedQualifiedName/FuzzyResultsShouldBeAddedToAliasAttributesCompletion/nt_parser/__init__.py diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb_util.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/fb_util.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foo_bar.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foo_bar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foobar.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/foobar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/main.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/main.py new file mode 100644 index 000000000000..710667b603b0 --- /dev/null +++ b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/main.py @@ -0,0 +1 @@ +fb \ No newline at end of file diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_fb.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_fb.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_foo_bar.py b/python/testData/completion/notImportedQualifiedName/ModuleNamesWithMiddleMatchNotSuggested/mod_foo_bar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java b/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java index 3346b4ab5ced..ad818b22edf2 100644 --- a/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PyNotImportedQualifiedNameCompletionTest.java @@ -74,6 +74,7 @@ public class PyNotImportedQualifiedNameCompletionTest extends PyTestCase { assertTrue(matcher.prefixMatches("foo.bar.xxx.baz")); assertFalse(matcher.prefixMatches("foo.bar.baz.xxx")); assertFalse(matcher.prefixMatches("xxx.foo.bar.baz")); + assertFalse(matcher.prefixMatches("nonfoo.foo.bar.baz")); } public void testImportForModuleFunction() { @@ -129,7 +130,7 @@ public class PyNotImportedQualifiedNameCompletionTest extends PyTestCase { myFixture.completeBasic(); List variants = myFixture.getLookupElementStrings(); assertEquals(2, variants.size()); - assertContainsElements(variants, "np.invert", "fileinput.input"); + assertContainsElements(variants, "np.invert", "nt_parser.input"); } //PY-47253 @@ -180,6 +181,20 @@ public class PyNotImportedQualifiedNameCompletionTest extends PyTestCase { assertContainsElements(myFixture.getLookupElementStrings(), "config", "contrib"); } + // PY-47962 + public void testModuleNamesWithMiddleMatchNotSuggested() { + List variants = doBasicCompletion(); + assertDoesntContain(variants, "mod_foo_bar", "mod_fb", "foobar"); + assertContainsElements(variants, "fb", "fb_util", "foo_bar"); + } + + // PY-47962 + public void testAttributesOfModulesWithMiddleMatchNotSuggested() { + List variants = doBasicCompletion(); + assertDoesntContain(variants, "mod_foo_bar.var", "mod_fb.var", "foobar.var"); + assertContainsElements(variants, "fb.var", "fb_util.var", "foo_bar.var"); + } + @Nullable private List doBasicCompletion() { myFixture.copyDirectoryToProject(getTestName(false), "");