From a4978c794f0ba73d1f0713b7269f73edf2d0b865 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 4 Oct 2016 14:14:58 +0300 Subject: [PATCH] Fix accidental overrides computation Consider the whole overridden tree instead of only direct overridden #KT-14146 Fixed --- ...FactoryForDuplicateSignatureDiagnostics.kt | 6 ++++- .../accidentalOverrideFromGrandparent.kt | 14 +++++++++++ .../accidentalOverrideFromGrandparent.txt | 25 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++++ .../kotlin/resolve/DescriptorUtils.kt | 13 +++++----- 5 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.kt create mode 100644 compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt index 8f263e073c7..61a82de01ef 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/BuilderFactoryForDuplicateSignatureDiagnostics.kt @@ -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()) diff --git a/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.kt b/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.kt new file mode 100644 index 00000000000..01aa3594e94 --- /dev/null +++ b/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.kt @@ -0,0 +1,14 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +interface Foo { + fun foo(x: X) +} + +open class FooImpl : Foo { + override fun foo(x: String) { + } +} + +open class FooImpl2 : FooImpl() { + fun foo(x: Any) { + } +} diff --git a/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.txt b/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.txt new file mode 100644 index 00000000000..57c1fe704bf --- /dev/null +++ b/compiler/testData/diagnostics/tests/duplicateJvmSignature/accidentalOverrides/accidentalOverrideFromGrandparent.txt @@ -0,0 +1,25 @@ +package + +public interface Foo { + 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 { + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2be8f56cb5b..06fc0e4fcfd 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index a270d475804..5eb4c1452a8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -237,16 +237,17 @@ fun CallableMemberDescriptor.overriddenTreeAsSequence(useOriginal: Boolean): Seq sequenceOf(this) + overriddenDescriptors.asSequence().flatMap { it.overriddenTreeAsSequence(useOriginal) } } -fun CallableDescriptor.overriddenTreeUniqueAsSequence(useOriginal: Boolean): Sequence { - val set = hashSetOf() +fun D.overriddenTreeUniqueAsSequence(useOriginal: Boolean): Sequence { + val set = hashSetOf() - fun CallableDescriptor.doBuildOverriddenTreeAsSequence(): Sequence { - return with(if (useOriginal) original else this) { + @Suppress("UNCHECKED_CAST") + fun D.doBuildOverriddenTreeAsSequence(): Sequence { + 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).asSequence().flatMap { it.doBuildOverriddenTreeAsSequence() } } } }