Fix accidental overrides computation
Consider the whole overridden tree instead of only direct overridden #KT-14146 Fixed
This commit is contained in:
+5
-1
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.load.java.descriptors.getParentJavaStaticClassScope
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -220,7 +221,10 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
else if (member is FunctionDescriptor) {
|
||||
val signatures =
|
||||
if (member.kind == FAKE_OVERRIDE)
|
||||
member.overriddenDescriptors.mapTo(HashSet()) { it.original.asRawSignature() }
|
||||
member.overriddenTreeUniqueAsSequence(useOriginal = true)
|
||||
// drop the root (itself)
|
||||
.drop(1)
|
||||
.mapTo(HashSet()) { it.asRawSignature() }
|
||||
else
|
||||
setOf(member.asRawSignature())
|
||||
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
interface Foo<X> {
|
||||
fun foo(x: X)
|
||||
}
|
||||
|
||||
open class FooImpl : Foo<String> {
|
||||
override fun foo(x: String) {
|
||||
}
|
||||
}
|
||||
|
||||
open class FooImpl2 : FooImpl() {
|
||||
<!ACCIDENTAL_OVERRIDE!>fun foo(x: Any)<!> {
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package
|
||||
|
||||
public interface Foo</*0*/ X> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun foo(/*0*/ x: X): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class FooImpl : Foo<kotlin.String> {
|
||||
public constructor FooImpl()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun foo(/*0*/ x: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class FooImpl2 : FooImpl {
|
||||
public constructor FooImpl2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(/*0*/ x: kotlin.Any): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -6037,6 +6037,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AccidentalOverrides extends AbstractDiagnosticsTest {
|
||||
@TestMetadata("accidentalOverrideFromGrandparent.kt")
|
||||
public void testAccidentalOverrideFromGrandparent() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAccidentalOverrides() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@@ -237,16 +237,17 @@ fun CallableMemberDescriptor.overriddenTreeAsSequence(useOriginal: Boolean): Seq
|
||||
sequenceOf(this) + overriddenDescriptors.asSequence().flatMap { it.overriddenTreeAsSequence(useOriginal) }
|
||||
}
|
||||
|
||||
fun CallableDescriptor.overriddenTreeUniqueAsSequence(useOriginal: Boolean): Sequence<CallableDescriptor> {
|
||||
val set = hashSetOf<CallableDescriptor>()
|
||||
fun <D : CallableDescriptor> D.overriddenTreeUniqueAsSequence(useOriginal: Boolean): Sequence<D> {
|
||||
val set = hashSetOf<D>()
|
||||
|
||||
fun CallableDescriptor.doBuildOverriddenTreeAsSequence(): Sequence<CallableDescriptor> {
|
||||
return with(if (useOriginal) original else this) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun D.doBuildOverriddenTreeAsSequence(): Sequence<D> {
|
||||
return with(if (useOriginal) original as D else this) {
|
||||
if (original in set)
|
||||
emptySequence()
|
||||
else {
|
||||
set += original
|
||||
sequenceOf(this) + overriddenDescriptors.asSequence().flatMap { it.doBuildOverriddenTreeAsSequence() }
|
||||
set += original as D
|
||||
sequenceOf(this) + (overriddenDescriptors as Collection<D>).asSequence().flatMap { it.doBuildOverriddenTreeAsSequence() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user