From 422c6aa643236df506bcc1d2888addaf6afd3455 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 26 Jun 2019 15:53:51 +0300 Subject: [PATCH] PY-15603 Clean up in PyQualifiedNameProvider, add tests on class members GitOrigin-RevId: 8082da991199b19830ff565065ef4d2d9124b37d --- .../actions/PyQualifiedNameProvider.java | 11 ++++----- .../methodReference/pkg/__init__.py | 0 .../methodReference/pkg/subpkg/__init__.py | 0 .../methodReference/pkg/subpkg/mod.py | 3 +++ .../nestedClassReference/pkg/__init__.py | 0 .../pkg/subpkg/__init__.py | 0 .../nestedClassReference/pkg/subpkg/mod.py | 3 +++ .../python/PyQualifiedNameProviderTest.java | 23 +++++++++++++++++-- 8 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 python/testData/qualifiedName/methodReference/pkg/__init__.py create mode 100644 python/testData/qualifiedName/methodReference/pkg/subpkg/__init__.py create mode 100644 python/testData/qualifiedName/methodReference/pkg/subpkg/mod.py create mode 100644 python/testData/qualifiedName/nestedClassReference/pkg/__init__.py create mode 100644 python/testData/qualifiedName/nestedClassReference/pkg/subpkg/__init__.py create mode 100644 python/testData/qualifiedName/nestedClassReference/pkg/subpkg/mod.py diff --git a/python/src/com/jetbrains/python/actions/PyQualifiedNameProvider.java b/python/src/com/jetbrains/python/actions/PyQualifiedNameProvider.java index b6f8f89f8a6c..67bb8fb108a7 100644 --- a/python/src/com/jetbrains/python/actions/PyQualifiedNameProvider.java +++ b/python/src/com/jetbrains/python/actions/PyQualifiedNameProvider.java @@ -31,7 +31,7 @@ import java.util.Collection; public class PyQualifiedNameProvider implements QualifiedNameProvider { - public static final char SEPARATOR = '.'; + private static final char CLASS_MEMBER_SEPARATOR = '.'; @Override public PsiElement adjustElementToCopy(PsiElement element) { @@ -47,7 +47,7 @@ public class PyQualifiedNameProvider implements QualifiedNameProvider { if (element instanceof PyFunction) { final PyClass containingClass = ((PyFunction)element).getContainingClass(); if (containingClass != null) { - return containingClass.getQualifiedName() + SEPARATOR + ((PyFunction)element).getName(); + return containingClass.getQualifiedName() + CLASS_MEMBER_SEPARATOR + ((PyFunction)element).getName(); } else { return ((PyFunction)element).getQualifiedName(); @@ -67,13 +67,12 @@ public class PyQualifiedNameProvider implements QualifiedNameProvider { if (!functions.isEmpty()) { return ContainerUtil.getFirstItem(functions); } - final int sharpIdx = fqn.lastIndexOf(SEPARATOR); - if (sharpIdx > -1) { - final String className = StringUtil.getPackageName(fqn, SEPARATOR); + if (StringUtil.containsChar(fqn, CLASS_MEMBER_SEPARATOR)) { + final String className = StringUtil.getPackageName(fqn, CLASS_MEMBER_SEPARATOR); aClass = PyClassNameIndex.findClass(className, project); if (aClass != null) { - final String memberName = StringUtil.getShortName(fqn, SEPARATOR); + final String memberName = StringUtil.getShortName(fqn, CLASS_MEMBER_SEPARATOR); final PyClass nestedClass = aClass.findNestedClass(memberName, false); if (nestedClass != null) return nestedClass; final PyFunction methodByName = aClass.findMethodByName(memberName, false, null); diff --git a/python/testData/qualifiedName/methodReference/pkg/__init__.py b/python/testData/qualifiedName/methodReference/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/qualifiedName/methodReference/pkg/subpkg/__init__.py b/python/testData/qualifiedName/methodReference/pkg/subpkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/qualifiedName/methodReference/pkg/subpkg/mod.py b/python/testData/qualifiedName/methodReference/pkg/subpkg/mod.py new file mode 100644 index 000000000000..ead6c1e3aacf --- /dev/null +++ b/python/testData/qualifiedName/methodReference/pkg/subpkg/mod.py @@ -0,0 +1,3 @@ +class MyClass: + def method(self): + pass \ No newline at end of file diff --git a/python/testData/qualifiedName/nestedClassReference/pkg/__init__.py b/python/testData/qualifiedName/nestedClassReference/pkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/qualifiedName/nestedClassReference/pkg/subpkg/__init__.py b/python/testData/qualifiedName/nestedClassReference/pkg/subpkg/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/qualifiedName/nestedClassReference/pkg/subpkg/mod.py b/python/testData/qualifiedName/nestedClassReference/pkg/subpkg/mod.py new file mode 100644 index 000000000000..c08b62808bf4 --- /dev/null +++ b/python/testData/qualifiedName/nestedClassReference/pkg/subpkg/mod.py @@ -0,0 +1,3 @@ +class MyClass: + class Nested: + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyQualifiedNameProviderTest.java b/python/testSrc/com/jetbrains/python/PyQualifiedNameProviderTest.java index c57e3bcb542f..a70bd8cbaa7b 100644 --- a/python/testSrc/com/jetbrains/python/PyQualifiedNameProviderTest.java +++ b/python/testSrc/com/jetbrains/python/PyQualifiedNameProviderTest.java @@ -15,16 +15,16 @@ */ package com.jetbrains.python; +import com.intellij.psi.PsiElement; import com.jetbrains.python.actions.PyQualifiedNameProvider; import com.jetbrains.python.fixtures.PyTestCase; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.junit.Test; /** * @author Mikhail Golubev */ public class PyQualifiedNameProviderTest extends PyTestCase { - @Test public void testTopLevelFunctionReference() { myFixture.copyDirectoryToProject(getTestName(true) + "/a", "a"); myFixture.configureByFile("a/b/c/module.py"); @@ -36,6 +36,25 @@ public class PyQualifiedNameProviderTest extends PyTestCase { return new PyQualifiedNameProvider().getQualifiedName(myFixture.getElementAtCaret()); } + public void testNestedClassReference() { + doDirectoryTest("pkg/subpkg/mod.py", "pkg.subpkg.mod.MyClass.Nested"); + } + + public void testMethodReference() { + doDirectoryTest("pkg/subpkg/mod.py", "pkg.subpkg.mod.MyClass.method"); + } + + private void doDirectoryTest(@NotNull String targetFile, @NotNull String expectedQualifiedName) { + myFixture.copyDirectoryToProject(getTestName(true), ""); + myFixture.configureByFile(targetFile); + final PsiElement target = myFixture.getElementAtCaret(); + final PyQualifiedNameProvider provider = new PyQualifiedNameProvider(); + final String actualQualifiedName = provider.getQualifiedName(myFixture.getElementAtCaret()); + assertEquals(expectedQualifiedName, actualQualifiedName); + final PsiElement element = provider.qualifiedNameToElement(expectedQualifiedName, myFixture.getProject()); + assertEquals(target, element); + } + @Override protected String getTestDataPath() { return super.getTestDataPath() + "/qualifiedName";