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 {
|
public class ImplementMethodsHandler : OverrideImplementMethodsHandler(), IntentionAction {
|
||||||
override fun collectMethodsToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
|
override fun collectMethodsToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
|
||||||
return OverrideResolver.getMissingImplementations(descriptor)
|
return OverrideResolver.getMissingImplementations(descriptor)
|
||||||
.map { OverrideMemberChooserObject(project, it, it) }
|
.map { OverrideMemberChooserObject.create(project, it, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChooserTitle() = "Implement Members"
|
override fun getChooserTitle() = "Implement Members"
|
||||||
|
|||||||
+42
-5
@@ -16,13 +16,50 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.core.overrideImplement
|
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.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject
|
import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject
|
||||||
|
|
||||||
class OverrideMemberChooserObject(
|
interface OverrideMemberChooserObject : ClassMember {
|
||||||
project: Project,
|
val descriptor: CallableMemberDescriptor
|
||||||
val member: CallableMemberDescriptor,
|
val immediateSuper: CallableMemberDescriptor
|
||||||
val immediateSuper: CallableMemberDescriptor
|
|
||||||
) : DescriptorMemberChooserObject(DescriptorToSourceUtilsIde.getAnyDeclaration(project, member)!!, member)
|
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 {
|
else {
|
||||||
immediateSupers.singleOrNull { (it.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.CLASS } ?: immediateSupers.first()
|
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(
|
public open class DescriptorMemberChooserObject(
|
||||||
psiElement: PsiElement,
|
psiElement: PsiElement,
|
||||||
public val descriptor: DeclarationDescriptor
|
public open val descriptor: DeclarationDescriptor
|
||||||
) : PsiElementMemberChooserObject(psiElement, DescriptorMemberChooserObject.getText(descriptor), DescriptorMemberChooserObject.getIcon(psiElement, descriptor)), ClassMemberWithElement {
|
) : PsiElementMemberChooserObject(psiElement, DescriptorMemberChooserObject.getText(descriptor), DescriptorMemberChooserObject.getIcon(psiElement, descriptor)), ClassMemberWithElement {
|
||||||
|
|
||||||
override fun getParentNodeDelegate(): MemberChooserObject {
|
override fun getParentNodeDelegate(): MemberChooserObject {
|
||||||
@@ -74,29 +74,29 @@ public open class DescriptorMemberChooserObject(
|
|||||||
nameShortness = NameShortness.SHORT
|
nameShortness = NameShortness.SHORT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getText(descriptor: DeclarationDescriptor): String {
|
public fun getText(descriptor: DeclarationDescriptor): String {
|
||||||
return if (descriptor is ClassDescriptor)
|
return if (descriptor is ClassDescriptor)
|
||||||
descriptor.fqNameSafe.render()
|
descriptor.fqNameSafe.render()
|
||||||
else
|
else
|
||||||
MEMBER_RENDERER.render(descriptor)
|
MEMBER_RENDERER.render(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIcon(element: PsiElement, descriptor: DeclarationDescriptor): Icon {
|
public fun getIcon(declaration: PsiElement?, descriptor: DeclarationDescriptor): Icon {
|
||||||
if (element.isValid) {
|
if (declaration != null && declaration.isValid) {
|
||||||
val isClass = element is PsiClass || element is JetClass
|
val isClass = declaration is PsiClass || declaration is JetClass
|
||||||
val flags = if (isClass) 0 else Iconable.ICON_FLAG_VISIBILITY
|
val flags = if (isClass) 0 else Iconable.ICON_FLAG_VISIBILITY
|
||||||
if (element is JetDeclaration) {
|
if (declaration is JetDeclaration) {
|
||||||
// kotlin declaration
|
// kotlin declaration
|
||||||
// visibility and abstraction better detect by a descriptor
|
// visibility and abstraction better detect by a descriptor
|
||||||
return JetDescriptorIconProvider.getIcon(descriptor, element, flags)
|
return JetDescriptorIconProvider.getIcon(descriptor, declaration, flags)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// it is better to show java icons for java code
|
// it is better to show java icons for java code
|
||||||
return element.getIcon(flags)
|
return declaration.getIcon(flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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>())
|
val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, javaClass<JetClassOrObject>())
|
||||||
?: error("Caret should be inside class or object")
|
?: 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)
|
performGenerateCommand(classOrObject, chooserObjects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,4 +214,8 @@ public final class OverrideImplementTest extends AbstractOverrideImplementTest {
|
|||||||
public void testAmbiguousSuper() {
|
public void testAmbiguousSuper() {
|
||||||
doMultiOverrideFileTest();
|
doMultiOverrideFileTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testImplementFunctionType() {
|
||||||
|
doMultiImplementFileTest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user