From 73fd4ad57fbfa249890609bc6a76fe98fdad4017 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 19 Jun 2015 22:58:15 +0300 Subject: [PATCH] Fixed small inconsistency in presentation for nested classes --- .../idea/completion/LookupElementFactory.kt | 47 +++++++++++++++---- .../ParameterNameAndTypeCompletion.kt | 4 +- ...erNameAndTypeNestedClasses.dependency.java | 5 ++ ...eterNameAndTypeNestedClasses.dependency.kt | 7 +++ .../ParameterNameAndTypeNestedClasses.kt | 11 +++++ ...tiFileJvmBasicCompletionTestGenerated.java | 6 +++ 6 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.java create mode 100644 idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.kt create mode 100644 idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt index 2a3a4dabb17..5046fbebbdc 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea.completion import com.intellij.codeInsight.completion.InsertHandler import com.intellij.codeInsight.lookup.* import com.intellij.codeInsight.lookup.impl.LookupCellRenderer -import com.intellij.openapi.util.Iconable import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import org.jetbrains.kotlin.asJava.KotlinLightClass @@ -30,12 +29,13 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.completion.handlers.* import org.jetbrains.kotlin.idea.util.TypeNullability import org.jetbrains.kotlin.idea.util.nullability +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils -import javax.swing.Icon public class LookupElementFactory( private val resolutionFacade: ResolutionFacade, @@ -43,13 +43,14 @@ public class LookupElementFactory( ) { public fun createLookupElement( descriptor: DeclarationDescriptor, - boldImmediateMembers: Boolean + boldImmediateMembers: Boolean, + qualifyNestedClasses: Boolean = false ): LookupElement { val _descriptor = if (descriptor is CallableMemberDescriptor) DescriptorUtils.unwrapFakeOverride(descriptor) else descriptor - var element = createLookupElement(_descriptor, DescriptorToSourceUtils.descriptorToDeclaration(_descriptor)) + var element = createLookupElement(_descriptor, DescriptorToSourceUtils.descriptorToDeclaration(_descriptor), qualifyNestedClasses) val weight = callableWeight(descriptor) if (weight != null) { @@ -98,7 +99,7 @@ public class LookupElementFactory( GRAYED } - public fun createLookupElementForJavaClass(psiClass: PsiClass): LookupElement { + public fun createLookupElementForJavaClass(psiClass: PsiClass, qualifyNestedClasses: Boolean = false): LookupElement { val lookupObject = object : DeclarationLookupObjectImpl(null, psiClass, resolutionFacade) { override fun getIcon(flags: Int) = psiClass.getIcon(flags) } @@ -111,8 +112,21 @@ public class LookupElementFactory( } val qualifiedName = psiClass.getQualifiedName()!! - val packageName = qualifiedName.substringBeforeLast('.', "") - element = element.appendTailText(" ($packageName)", true) + var containerName = qualifiedName.substringBeforeLast('.', FqName.ROOT.toString()) + + if (qualifyNestedClasses) { + val nestLevel = psiClass.parents.takeWhile { it is PsiClass }.count() + if (nestLevel > 0) { + var itemText = psiClass.getName() + for (i in 1..nestLevel) { + itemText = containerName.substringAfterLast('.') + "." + itemText + containerName = containerName.substringBeforeLast('.', FqName.ROOT.toString()) + } + element = element.withPresentableText(itemText) + } + } + + element = element.appendTailText(" ($containerName)", true) if (lookupObject.isDeprecated) { element = element.setStrikeout(true) @@ -123,7 +137,8 @@ public class LookupElementFactory( private fun createLookupElement( descriptor: DeclarationDescriptor, - declaration: PsiElement? + declaration: PsiElement?, + qualifyNestedClasses: Boolean = false ): LookupElement { if (descriptor is ClassifierDescriptor && declaration is PsiClass && @@ -131,7 +146,7 @@ public class LookupElementFactory( // for java classes we create special lookup elements // because they must be equal to ones created in TypesCompletion // otherwise we may have duplicates - return createLookupElementForJavaClass(declaration) + return createLookupElementForJavaClass(declaration, qualifyNestedClasses) } // for constructor use name and icon of containing class @@ -169,7 +184,19 @@ public class LookupElementFactory( element = element.appendTailText(typeParams.map { it.getName().asString() }.joinToString(", ", "<", ">"), true) } - element = element.appendTailText(" (" + DescriptorUtils.getFqName(descriptor.getContainingDeclaration()) + ")", true) + var container = descriptor.getContainingDeclaration() + + if (qualifyNestedClasses) { + element = element.withPresentableText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderClassifierName(descriptor)) + + while (container is ClassDescriptor) { + container = container.getContainingDeclaration() + } + } + + if (container is PackageFragmentDescriptor || container is ClassDescriptor) { + element = element.appendTailText(" (" + DescriptorUtils.getFqName(container) + ")", true) + } } else -> { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt index 4f82de7702d..1dc6b705d51 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt @@ -169,12 +169,12 @@ class ParameterNameAndTypeCompletion( private class DescriptorType(private val classifier: ClassifierDescriptor) : Type(DescriptorUtils.getFqName(classifier).render()) { override fun createTypeLookupElement(lookupElementFactory: LookupElementFactory) - = lookupElementFactory.createLookupElement(classifier, false) + = lookupElementFactory.createLookupElement(classifier, false, qualifyNestedClasses = true) } private class JavaClassType(private val psiClass: PsiClass) : Type(psiClass.getQualifiedName()!!) { override fun createTypeLookupElement(lookupElementFactory: LookupElementFactory) - = lookupElementFactory.createLookupElementForJavaClass(psiClass) + = lookupElementFactory.createLookupElementForJavaClass(psiClass, qualifyNestedClasses = true) } private class ArbitraryType(private val type: JetType) : Type(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) { diff --git a/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.java b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.java new file mode 100644 index 00000000000..95fd3d35007 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.java @@ -0,0 +1,5 @@ +class JavaOuter { + class Nested { + class NestedNested {} + } +} diff --git a/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.kt b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.kt new file mode 100644 index 00000000000..b5785934499 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.dependency.kt @@ -0,0 +1,7 @@ +class Outer { + class Nested { + class NestedNested + } +} + +// ALLOW_AST_ACCESS \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.kt b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.kt new file mode 100644 index 00000000000..2f2f8f20d21 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/ParameterNameAndTypeNestedClasses.kt @@ -0,0 +1,11 @@ +fun f(nested: Outer.Nested?){} +fun f(nested: Outer.Nested.NestedNested?){} + +fun foo(nest) + +// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested?", tailText: " ()" } +// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested", tailText: " ()" } +// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested.NestedNested?", tailText: " ()" } +// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested.NestedNested", tailText: " ()" } +// EXIST: { lookupString: "nested", itemText: "nested: JavaOuter.Nested", tailText: " ()" } +// EXIST: { lookupString: "nested", itemText: "nested: JavaOuter.Nested.NestedNested", tailText: " ()" } diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index 315021d19bf..a4427324377 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -221,6 +221,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("ParameterNameAndTypeNestedClasses") + public void testParameterNameAndTypeNestedClasses() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/ParameterNameAndTypeNestedClasses/"); + doTest(fileName); + } + @TestMetadata("PreferMemberToExtension") public void testPreferMemberToExtension() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/PreferMemberToExtension/");