Fixed bug with duplicated members in Override Members dialog
This commit is contained in:
+11
-5
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.core.overrideImplement
|
package org.jetbrains.kotlin.idea.core.overrideImplement
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -29,14 +30,19 @@ public class OverrideMembersHandler : OverrideImplementMembersHandler() {
|
|||||||
val overridden = member.overriddenDescriptors
|
val overridden = member.overriddenDescriptors
|
||||||
if (overridden.any { it.modality == Modality.FINAL || it.visibility.normalize() == Visibilities.PRIVATE }) continue
|
if (overridden.any { it.modality == Modality.FINAL || it.visibility.normalize() == Visibilities.PRIVATE }) continue
|
||||||
|
|
||||||
val realSuperToImmediates = LinkedHashMap<CallableMemberDescriptor, MutableCollection<CallableMemberDescriptor>>()
|
class Data(
|
||||||
|
val realSuper: CallableMemberDescriptor,
|
||||||
|
val immediateSupers: MutableList<CallableMemberDescriptor> = SmartList()
|
||||||
|
)
|
||||||
|
|
||||||
|
val byOriginalRealSupers = LinkedHashMap<CallableMemberDescriptor, Data>()
|
||||||
for (immediateSuper in overridden) {
|
for (immediateSuper in overridden) {
|
||||||
for (realSuper in toRealSupers(immediateSuper)) {
|
for (realSuper in toRealSupers(immediateSuper)) {
|
||||||
realSuperToImmediates.getOrPut(realSuper) { ArrayList(1) }.add(immediateSuper)
|
byOriginalRealSupers.getOrPut(realSuper.original) { Data(realSuper) }.immediateSupers.add(immediateSuper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val realSupers = realSuperToImmediates.keySet()
|
val realSupers = byOriginalRealSupers.values().map { it.realSuper }
|
||||||
val nonAbstractRealSupers = realSupers.filter { it.modality != Modality.ABSTRACT }
|
val nonAbstractRealSupers = realSupers.filter { it.modality != Modality.ABSTRACT }
|
||||||
val realSupersToUse = if (nonAbstractRealSupers.isNotEmpty()) {
|
val realSupersToUse = if (nonAbstractRealSupers.isNotEmpty()) {
|
||||||
nonAbstractRealSupers
|
nonAbstractRealSupers
|
||||||
@@ -46,7 +52,7 @@ public class OverrideMembersHandler : OverrideImplementMembersHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (realSuper in realSupersToUse) {
|
for (realSuper in realSupersToUse) {
|
||||||
val immediateSupers = realSuperToImmediates[realSuper]!!
|
val immediateSupers = byOriginalRealSupers[realSuper.original]!!.immediateSupers
|
||||||
assert(immediateSupers.isNotEmpty())
|
assert(immediateSupers.isNotEmpty())
|
||||||
|
|
||||||
val immediateSuperToUse = if (immediateSupers.size() == 1) {
|
val immediateSuperToUse = if (immediateSupers.size() == 1) {
|
||||||
@@ -76,7 +82,7 @@ public class OverrideMembersHandler : OverrideImplementMembersHandler() {
|
|||||||
}
|
}
|
||||||
val overridden = immediateSuper.overriddenDescriptors
|
val overridden = immediateSuper.overriddenDescriptors
|
||||||
assert(overridden.isNotEmpty())
|
assert(overridden.isNotEmpty())
|
||||||
return overridden.flatMap { toRealSupers(it) }.toSet()
|
return overridden.flatMap { toRealSupers(it) }.distinctBy { it.original }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChooserTitle() = "Override Members"
|
override fun getChooserTitle() = "Override Members"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
open class A<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I
|
||||||
|
|
||||||
|
class B : A<String>(), I {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
open class A<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I
|
||||||
|
|
||||||
|
class B : A<String>(), I {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
<selection><caret>return super.equals(other)</selection>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return super.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return super.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.codeInsight
|
package org.jetbrains.kotlin.idea.codeInsight
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMembersHandler
|
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
|
|
||||||
public class OverrideImplementTest : AbstractOverrideImplementTest() {
|
public class OverrideImplementTest : AbstractOverrideImplementTest() {
|
||||||
@@ -228,4 +227,8 @@ public class OverrideImplementTest : AbstractOverrideImplementTest() {
|
|||||||
public fun testGenericSuperClass() {
|
public fun testGenericSuperClass() {
|
||||||
doOverrideFileTest("size")
|
doOverrideFileTest("size")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun testDuplicatedAnyMembersBug() {
|
||||||
|
doMultiOverrideFileTest()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user