KT-8716 Exception on attempt to implement function

#KT-8716 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-08-07 20:11:21 +03:00
parent c943ec104d
commit 377201bbcd
8 changed files with 66 additions and 17 deletions
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.OverrideResolver
public class ImplementMethodsHandler : OverrideImplementMethodsHandler(), IntentionAction {
override fun collectMethodsToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
return OverrideResolver.getMissingImplementations(descriptor)
.map { OverrideMemberChooserObject(project, it, it) }
.map { OverrideMemberChooserObject.create(project, it, it) }
}
override fun getChooserTitle() = "Implement Members"
@@ -16,13 +16,50 @@
package org.jetbrains.kotlin.idea.core.overrideImplement
import com.intellij.codeInsight.generation.ClassMember
import com.intellij.codeInsight.generation.MemberChooserObject
import com.intellij.codeInsight.generation.MemberChooserObjectBase
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject
class OverrideMemberChooserObject(
project: Project,
val member: CallableMemberDescriptor,
val immediateSuper: CallableMemberDescriptor
) : DescriptorMemberChooserObject(DescriptorToSourceUtilsIde.getAnyDeclaration(project, member)!!, member)
interface OverrideMemberChooserObject : ClassMember {
val descriptor: CallableMemberDescriptor
val immediateSuper: CallableMemberDescriptor
companion object {
fun create(project: Project, descriptor: CallableMemberDescriptor, immediateSuper: CallableMemberDescriptor): OverrideMemberChooserObject {
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor)
if (declaration != null) {
return WithDeclaration(descriptor, declaration, immediateSuper)
}
else {
return WithoutDeclaration(descriptor, immediateSuper)
}
}
private class WithDeclaration(
descriptor: CallableMemberDescriptor,
declaration: PsiElement,
override val immediateSuper: CallableMemberDescriptor
) : DescriptorMemberChooserObject(declaration, descriptor), OverrideMemberChooserObject {
override val descriptor: CallableMemberDescriptor
get() = super<DescriptorMemberChooserObject>.descriptor as CallableMemberDescriptor
}
private class WithoutDeclaration(
override val descriptor: CallableMemberDescriptor,
override val immediateSuper: CallableMemberDescriptor
) : MemberChooserObjectBase(DescriptorMemberChooserObject.getText(descriptor), DescriptorMemberChooserObject.getIcon(null, descriptor)), OverrideMemberChooserObject {
override fun getParentNodeDelegate(): MemberChooserObject? {
val parentClassifier = descriptor.containingDeclaration as? ClassifierDescriptor ?: return null
return MemberChooserObjectBase(DescriptorMemberChooserObject.getText(parentClassifier), DescriptorMemberChooserObject.getIcon(null, parentClassifier))
}
}
}
}
@@ -59,7 +59,7 @@ public class OverrideMethodsHandler : OverrideImplementMethodsHandler() {
else {
immediateSupers.singleOrNull { (it.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.CLASS } ?: immediateSupers.first()
}
result.add(OverrideMemberChooserObject(project, realSuper, immediateSuperToUse))
result.add(OverrideMemberChooserObject.create(project, realSuper, immediateSuperToUse))
}
}
}
@@ -40,7 +40,7 @@ import javax.swing.Icon
public open class DescriptorMemberChooserObject(
psiElement: PsiElement,
public val descriptor: DeclarationDescriptor
public open val descriptor: DeclarationDescriptor
) : PsiElementMemberChooserObject(psiElement, DescriptorMemberChooserObject.getText(descriptor), DescriptorMemberChooserObject.getIcon(psiElement, descriptor)), ClassMemberWithElement {
override fun getParentNodeDelegate(): MemberChooserObject {
@@ -74,29 +74,29 @@ public open class DescriptorMemberChooserObject(
nameShortness = NameShortness.SHORT
}
private fun getText(descriptor: DeclarationDescriptor): String {
public fun getText(descriptor: DeclarationDescriptor): String {
return if (descriptor is ClassDescriptor)
descriptor.fqNameSafe.render()
else
MEMBER_RENDERER.render(descriptor)
}
private fun getIcon(element: PsiElement, descriptor: DeclarationDescriptor): Icon {
if (element.isValid) {
val isClass = element is PsiClass || element is JetClass
public fun getIcon(declaration: PsiElement?, descriptor: DeclarationDescriptor): Icon {
if (declaration != null && declaration.isValid) {
val isClass = declaration is PsiClass || declaration is JetClass
val flags = if (isClass) 0 else Iconable.ICON_FLAG_VISIBILITY
if (element is JetDeclaration) {
if (declaration is JetDeclaration) {
// kotlin declaration
// visibility and abstraction better detect by a descriptor
return JetDescriptorIconProvider.getIcon(descriptor, element, flags)
return JetDescriptorIconProvider.getIcon(descriptor, declaration, flags)
}
else {
// it is better to show java icons for java code
return element.getIcon(flags)
return declaration.getIcon(flags)
}
}
else {
return JetDescriptorIconProvider.getIcon(descriptor, element, 0)
return JetDescriptorIconProvider.getIcon(descriptor, declaration, 0)
}
}
}
@@ -0,0 +1,3 @@
class C : (String) -> Boolean {
<caret>
}
@@ -0,0 +1,5 @@
class C : (String) -> Boolean {
override fun invoke(p1: String): Boolean {
<selection><caret>throw UnsupportedOperationException()</selection>
}
}
@@ -146,7 +146,7 @@ public abstract class AbstractOverrideImplementTest : JetLightCodeInsightFixture
val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, javaClass<JetClassOrObject>())
?: error("Caret should be inside class or object")
val chooserObjects = handler.collectMethodsToGenerate(classOrObject).sortBy { it.member.name.asString() + " in " + it.immediateSuper.containingDeclaration.name.asString() }
val chooserObjects = handler.collectMethodsToGenerate(classOrObject).sortBy { it.descriptor.name.asString() + " in " + it.immediateSuper.containingDeclaration.name.asString() }
performGenerateCommand(classOrObject, chooserObjects)
}
@@ -214,4 +214,8 @@ public final class OverrideImplementTest extends AbstractOverrideImplementTest {
public void testAmbiguousSuper() {
doMultiOverrideFileTest();
}
public void testImplementFunctionType() {
doMultiImplementFileTest();
}
}