diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 7e38d4e0439..e7444a8e9df 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -358,6 +358,7 @@ public interface Errors { DiagnosticFactory0 REDUNDANT_MODIFIER_IN_GETTER = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SETTER_VISIBILITY_DIFFERS_FROM_LATEINIT_VISIBILITY = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PRIVATE_SETTER_FOR_OPEN_PROPERTY = DiagnosticFactory0.create(ERROR); DiagnosticFactory2 WRONG_GETTER_RETURN_TYPE = DiagnosticFactory2.create(ERROR); 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 44d71636121..4b1e626faae 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -211,6 +211,7 @@ public class DefaultErrorMessages { MAP.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, "Getter visibility must be the same as property visibility"); MAP.put(SETTER_VISIBILITY_DIFFERS_FROM_LATEINIT_VISIBILITY, "Setter visibility must be the same as lateinit property visibility"); + MAP.put(SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY, "Setter visibility must be the same or less permissive than property visibility"); MAP.put(PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, "Private setters are not allowed for abstract properties"); MAP.put(PRIVATE_SETTER_FOR_OPEN_PROPERTY, "Private setters are deprecated for open properties"); MAP.put(BACKING_FIELD_IN_INTERFACE, "Property in an interface cannot have a backing field"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 989c98c775c..1207a51a4a7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -718,6 +718,12 @@ class DeclarationsChecker( else if (propertyDescriptor.isLateInit && accessorDescriptor.visibility != propertyDescriptor.visibility) { reportVisibilityModifierDiagnostics(tokens.values, Errors.SETTER_VISIBILITY_DIFFERS_FROM_LATEINIT_VISIBILITY) } + else { + val compare = Visibilities.compare(accessorDescriptor.visibility, propertyDescriptor.visibility) + if (compare == null || compare > 0) { + reportVisibilityModifierDiagnostics(tokens.values, Errors.SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY) + } + } } } diff --git a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt b/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt index bd2c6ad393b..a62c2e3f161 100644 --- a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt +++ b/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt @@ -17,7 +17,7 @@ class Test: ATest(), ITest { override var prop2 : Int get() = 14 - internal set(value) {} + internal set(value) {} } fun main(args: Array) { diff --git a/compiler/testData/diagnostics/tests/SetterVisibility.kt b/compiler/testData/diagnostics/tests/SetterVisibility.kt new file mode 100644 index 00000000000..6e3a44cff8e --- /dev/null +++ b/compiler/testData/diagnostics/tests/SetterVisibility.kt @@ -0,0 +1,25 @@ +class My { + var x: Int = 0 + // Ok + private set + + private var y: Int = 1 + // Error: better + public set + + protected var z: Int = 2 + // Ok + private set + + protected var w: Int = 3 + // Error: incompatible + internal set + + internal var v: Int = 4 + // Error: incompatible + protected set + + internal var t: Int = 5 + // Error: better + public set +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/SetterVisibility.txt b/compiler/testData/diagnostics/tests/SetterVisibility.txt new file mode 100644 index 00000000000..b50dd3a65bc --- /dev/null +++ b/compiler/testData/diagnostics/tests/SetterVisibility.txt @@ -0,0 +1,14 @@ +package + +public final class My { + public constructor My() + internal final var t: kotlin.Int + internal final var v: kotlin.Int + protected final var w: kotlin.Int + public final var x: kotlin.Int + private final var y: kotlin.Int + protected final var z: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + 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/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.kt b/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.kt index 0617b323ed2..b665783decc 100644 --- a/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.kt +++ b/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.kt @@ -16,12 +16,6 @@ class ClassVal() { protected var property5: String = "" private set - protected var property6: String = "" - internal set - - protected var property7: java.util.Date = java.util.Date() - public set - public var property8: Int = 1 set diff --git a/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.txt b/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.txt index 30f971d36d1..acfd541561d 100644 --- a/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.txt +++ b/compiler/testData/loadJava/compiledKotlin/prop/defaultAccessors/ClassVarWithSet.txt @@ -23,12 +23,6 @@ public final class ClassVal { protected final var property5: kotlin.String protected final fun (): kotlin.String private final fun (/*0*/ : kotlin.String): kotlin.Unit - protected final var property6: kotlin.String - protected final fun (): kotlin.String - internal final fun (/*0*/ : kotlin.String): kotlin.Unit - protected final var property7: java.util.Date - protected final fun (): java.util.Date - public final fun (/*0*/ : java.util.Date): kotlin.Unit public final var property8: kotlin.Int public final fun (): kotlin.Int public final fun (/*0*/ : kotlin.Int): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index d5a3969af6f..9b69bba3936 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -595,6 +595,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("SetterVisibility.kt") + public void testSetterVisibility() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/SetterVisibility.kt"); + doTest(fileName); + } + @TestMetadata("ShiftFunctionTypes.kt") public void testShiftFunctionTypes() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/ShiftFunctionTypes.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index fb1fc0c0582..5fb0b0054c1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -115,6 +115,7 @@ public class QuickFixRegistrar : QuickFixContributor { val removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory() GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory) SETTER_VISIBILITY_DIFFERS_FROM_LATEINIT_VISIBILITY.registerFactory(removeModifierFactory) + SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY.registerFactory(removeModifierFactory) PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY.registerFactory(removeModifierFactory) PRIVATE_SETTER_FOR_OPEN_PROPERTY.registerFactory(removeModifierFactory) REDUNDANT_MODIFIER_IN_GETTER.registerFactory(removeRedundantModifierFactory)