Fixed small inconsistency in presentation for nested classes

This commit is contained in:
Valentin Kipyatkov
2015-06-19 22:58:15 +03:00
parent 01e56dc571
commit 73fd4ad57f
6 changed files with 68 additions and 12 deletions
@@ -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('.', "<root>")
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 -> {
@@ -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)) {
@@ -0,0 +1,5 @@
class JavaOuter {
class Nested {
class NestedNested {}
}
}
@@ -0,0 +1,7 @@
class Outer {
class Nested {
class NestedNested
}
}
// ALLOW_AST_ACCESS
@@ -0,0 +1,11 @@
fun f(nested: Outer.Nested?){}
fun f(nested: Outer.Nested.NestedNested?){}
fun foo(nest<caret>)
// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested?", tailText: " (<root>)" }
// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested", tailText: " (<root>)" }
// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested.NestedNested?", tailText: " (<root>)" }
// EXIST: { lookupString: "nested", itemText: "nested: Outer.Nested.NestedNested", tailText: " (<root>)" }
// EXIST: { lookupString: "nested", itemText: "nested: JavaOuter.Nested", tailText: " (<root>)" }
// EXIST: { lookupString: "nested", itemText: "nested: JavaOuter.Nested.NestedNested", tailText: " (<root>)" }
@@ -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/");