From d94930149b0842ee28c0a65bb12db69078cac909 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 25 Jan 2016 17:56:16 +0300 Subject: [PATCH] Warning for open members in objects --- .../src/org/jetbrains/kotlin/diagnostics/Errors.java | 3 +++ .../diagnostics/rendering/DefaultErrorMessages.java | 1 + .../jetbrains/kotlin/resolve/DeclarationsChecker.kt | 10 ++++++++-- .../diagnostics/tests/objects/OpenInObject.kt | 9 +++++++++ .../diagnostics/tests/objects/OpenInObject.txt | 12 ++++++++++++ .../annotations/platformStatic/finalAndAbstract.kt | 4 ++-- .../annotations/platformStatic/property.kt | 2 +- .../kotlin/checkers/DiagnosticsTestGenerated.java | 6 ++++++ .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 2 ++ 9 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/objects/OpenInObject.kt create mode 100644 compiler/testData/diagnostics/tests/objects/OpenInObject.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index ffe3b583f01..4a41b223c56 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -301,6 +301,9 @@ public interface Errors { DiagnosticFactory0 NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition( KtTokens.OPEN_KEYWORD)); + DiagnosticFactory0 NON_FINAL_MEMBER_IN_OBJECT = DiagnosticFactory0.create(WARNING, modifierSetPosition( + KtTokens.OPEN_KEYWORD)); + DiagnosticFactory1 NOTHING_TO_OVERRIDE = DiagnosticFactory1.create(ERROR, OVERRIDE_MODIFIER); DiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 39beb156f6c..59a98edbff5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -249,6 +249,7 @@ public class DefaultErrorMessages { MAP.put(FUNCTION_DECLARATION_WITH_NO_NAME, "Function declaration must have a name"); MAP.put(ANONYMOUS_FUNCTION_WITH_NAME, "Anonymous functions with names are prohibited"); MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "\"open\" has no effect in a final class"); + MAP.put(NON_FINAL_MEMBER_IN_OBJECT, "\"open\" has no effect in an object"); MAP.put(ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE, "An anonymous function is not allowed to specify default values for its parameters"); MAP.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 96f0d0c31e5..47804740a9d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -310,7 +310,8 @@ class DeclarationsChecker( } } - private fun checkObject(declaration: KtObjectDeclaration, classDescriptor: ClassDescriptor) { + private fun checkObject(declaration: KtObjectDeclaration, classDescriptor: ClassDescriptorWithResolutionScopes) { + checkOpenMembers(classDescriptor) if (declaration.isLocal() && !declaration.isCompanion() && !declaration.isObjectLiteral()) { trace.report(LOCAL_OBJECT_NOT_ALLOWED.on(declaration, classDescriptor)) } @@ -433,7 +434,12 @@ class DeclarationsChecker( if (memberDescriptor.kind != CallableMemberDescriptor.Kind.DECLARATION) continue val member = DescriptorToSourceUtils.descriptorToDeclaration(memberDescriptor) as? KtNamedDeclaration if (member != null && member.hasModifier(KtTokens.OPEN_KEYWORD)) { - trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member)) + if (classDescriptor.kind == ClassKind.OBJECT) { + trace.report(NON_FINAL_MEMBER_IN_OBJECT.on(member)) + } + else { + trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member)) + } } } } diff --git a/compiler/testData/diagnostics/tests/objects/OpenInObject.kt b/compiler/testData/diagnostics/tests/objects/OpenInObject.kt new file mode 100644 index 00000000000..0d032133499 --- /dev/null +++ b/compiler/testData/diagnostics/tests/objects/OpenInObject.kt @@ -0,0 +1,9 @@ +object Obj { + fun foo() {} + + open fun bar() {} + + var x: Int = 0 + + open var y: Int = 1 +} diff --git a/compiler/testData/diagnostics/tests/objects/OpenInObject.txt b/compiler/testData/diagnostics/tests/objects/OpenInObject.txt new file mode 100644 index 00000000000..f30bc89f953 --- /dev/null +++ b/compiler/testData/diagnostics/tests/objects/OpenInObject.txt @@ -0,0 +1,12 @@ +package + +public object Obj { + private constructor Obj() + public final var x: kotlin.Int + public open var y: kotlin.Int + public open fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): 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/testData/diagnostics/testsWithStdLib/annotations/platformStatic/finalAndAbstract.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/finalAndAbstract.kt index 7a97f8c5caa..bf771e68fe6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/finalAndAbstract.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/finalAndAbstract.kt @@ -18,7 +18,7 @@ object B: A() { @JvmStatic final override fun c() {} - @JvmStatic open fun d() {} + @JvmStatic open fun d() {} } class C { @@ -30,6 +30,6 @@ class C { @JvmStatic final override fun c() {} - @JvmStatic open fun d() {} + @JvmStatic open fun d() {} } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/property.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/property.kt index 99d43381785..a341d629ad6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/property.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic/property.kt @@ -31,7 +31,7 @@ class A { @JvmStatic override val base1: Int = 0 - @JvmStatic open fun f() {} + @JvmStatic open fun f() {} override val base2: Int = 0 @JvmStatic get diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 6a0c1017c2a..2b543abc095 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -11349,6 +11349,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("OpenInObject.kt") + public void testOpenInObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/objects/OpenInObject.kt"); + doTest(fileName); + } + @TestMetadata("upperBoundViolated.kt") public void testUpperBoundViolated() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/objects/upperBoundViolated.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 5f13a211e77..cd4a95eae9a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -111,6 +111,8 @@ class QuickFixRegistrar : QuickFixContributor { val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD) NON_FINAL_MEMBER_IN_FINAL_CLASS.registerFactory(AddModifierFix.createFactory(OPEN_KEYWORD, KtClass::class.java), removeOpenModifierFactory) + NON_FINAL_MEMBER_IN_OBJECT.registerFactory(AddModifierFix.createFactory(OPEN_KEYWORD, KtClass::class.java), + removeOpenModifierFactory) val removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory() GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory)