From 0f350f5db8807983b46f663df7707fbb506e311d Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Wed, 21 Jun 2017 19:10:16 +0300 Subject: [PATCH] Don't report error on member that overrides open member from final class #KT-14598 Fixed --- .../kotlin/resolve/OverrideResolver.kt | 21 +++--- .../override/overrideMemberFromFinalClass.kt | 28 ++++++++ .../override/overrideMemberFromFinalClass.txt | 67 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 ++ .../jetbrains/kotlin/descriptors/Modality.kt | 2 +- .../overridingOpenMethodInFinalClass.kt | 1 - 6 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.kt create mode 100644 compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt index 9d59197d35c..ac7d1b26f79 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. + * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,25 +22,22 @@ import com.intellij.psi.PsiElement import com.intellij.util.SmartList import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.SmartHashSet -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2 import org.jetbrains.kotlin.diagnostics.DiagnosticFactoryWithPsiElement +import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.* -import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.checker.KotlinTypeChecker - -import java.util.* - -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE -import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized +import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.utils.addToStdlib.assertedCast +import java.util.* class OverrideResolver( private val trace: BindingTrace, @@ -741,7 +738,7 @@ class OverrideResolver( val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null for (overridden in overriddenDescriptors) { - if (!overridden.isOverridable) { + if (overridden.modality == Modality.FINAL) { reportError.overridingFinalMember(memberDescriptor, overridden) } diff --git a/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.kt b/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.kt new file mode 100644 index 00000000000..b27b226aa91 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.kt @@ -0,0 +1,28 @@ +class Foo { + open fun openFoo() {} + fun finalFoo() {} +} + +class Bar : Foo() { + override fun openFoo() {} + override fun finalFoo() {} +} + + +open class A1 { + open fun foo() {} +} + +class B1 : A1() +class C1 : B1() { + override fun foo() {} +} + +abstract class A2 { + abstract fun foo() +} + +class B2 : A2() +class C2 : B2() { + override fun foo() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.txt b/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.txt new file mode 100644 index 00000000000..cd22f042999 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.txt @@ -0,0 +1,67 @@ +package + +public open class A1 { + public constructor A1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class A2 { + public constructor A2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B1 : A1 { + public constructor B1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B2 : A2 { + public constructor B2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Bar : Foo { + public constructor Bar() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun finalFoo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun openFoo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C1 : B1 { + public constructor C1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C2 : B2 { + public constructor C2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Foo { + public constructor Foo() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun finalFoo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open fun openFoo(): kotlin.Unit + 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 f3df628988e..a5cba29ef98 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14857,6 +14857,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("overrideMemberFromFinalClass.kt") + public void testOverrideMemberFromFinalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/overrideMemberFromFinalClass.kt"); + doTest(fileName); + } + @TestMetadata("OverrideWithErrors.kt") public void testOverrideWithErrors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/OverrideWithErrors.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.kt index d4cb99666d9..31da0171cb1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt b/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt index 4e199577ad2..de33d393d30 100644 --- a/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt +++ b/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt @@ -1,6 +1,5 @@ // "Make A.foo open" "false" // ACTION: Convert to expression body -// ERROR: 'foo' in 'A' is final and cannot be overridden // ERROR: This type is final, so it cannot be inherited from class A() { open fun foo() {}