KT-8716 Exception on attempt to implement function
#KT-8716 Fixed
This commit is contained in:
+1
-1
@@ -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"
|
||||
|
||||
+42
-5
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user