Report exposed type for properties in class primary constructor
Before this commit, we compared property visibility with constructor visibility only, which is incorrect. Now we compare property visibility also with class visibility #KT-19613 Fixed
This commit is contained in:
@@ -116,6 +116,7 @@ public interface Errors {
|
||||
|
||||
// Exposed visibility group
|
||||
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR = DiagnosticFactory3.create(WARNING);
|
||||
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_FUNCTION_RETURN_TYPE = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<KtParameter, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PARAMETER_TYPE = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<KtTypeReference, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_RECEIVER_TYPE = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
+1
@@ -69,6 +69,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(PROTECTED_CONSTRUCTOR_NOT_IN_SUPER_CALL, "Protected constructor ''{0}'' from other classes can only be used in super-call", Renderers.SHORT_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(EXPOSED_PROPERTY_TYPE, "''{0}'' property exposes its ''{2}'' type{1}", TO_STRING, TO_STRING, TO_STRING);
|
||||
MAP.put(EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR, "''{0}'' property exposes its ''{2}'' type{1}", TO_STRING, TO_STRING, TO_STRING);
|
||||
MAP.put(EXPOSED_FUNCTION_RETURN_TYPE, "''{0}'' function exposes its ''{2}'' return type{1}", TO_STRING, TO_STRING, TO_STRING);
|
||||
MAP.put(EXPOSED_PARAMETER_TYPE, "''{0}'' function exposes its ''{2}'' parameter type{1}", TO_STRING, TO_STRING, TO_STRING);
|
||||
MAP.put(EXPOSED_RECEIVER_TYPE, "''{0}'' member exposes its ''{2}'' receiver type{1}", TO_STRING, TO_STRING, TO_STRING);
|
||||
|
||||
@@ -91,15 +91,31 @@ class ExposedVisibilityChecker(private val trace: DiagnosticSink = DO_NOTHING) {
|
||||
}
|
||||
}
|
||||
functionDescriptor.valueParameters.forEachIndexed { i, parameterDescriptor ->
|
||||
val restricting = parameterDescriptor.type.leastPermissiveDescriptor(functionVisibility)
|
||||
if (restricting != null && i < function.valueParameters.size) {
|
||||
trace.report(
|
||||
Errors.EXPOSED_PARAMETER_TYPE.on(
|
||||
function.valueParameters[i], functionVisibility,
|
||||
restricting, restricting.effectiveVisibility()
|
||||
if (i < function.valueParameters.size) {
|
||||
val valueParameter = function.valueParameters[i]
|
||||
val restricting = parameterDescriptor.type.leastPermissiveDescriptor(functionVisibility)
|
||||
if (restricting != null) {
|
||||
trace.report(
|
||||
Errors.EXPOSED_PARAMETER_TYPE.on(
|
||||
valueParameter, functionVisibility,
|
||||
restricting, restricting.effectiveVisibility()
|
||||
)
|
||||
)
|
||||
)
|
||||
result = false
|
||||
result = false
|
||||
} else if (functionDescriptor is ClassConstructorDescriptor && valueParameter.hasValOrVar()) {
|
||||
val propertyDescriptor = (trace as? BindingTrace)?.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor)
|
||||
val propertyOrClassVisibility = (propertyDescriptor ?: functionDescriptor.constructedClass).effectiveVisibility()
|
||||
val restrictingByProperty = parameterDescriptor.type.leastPermissiveDescriptor(propertyOrClassVisibility)
|
||||
if (restrictingByProperty != null) {
|
||||
trace.report(
|
||||
Errors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR.on(
|
||||
valueParameter, propertyOrClassVisibility,
|
||||
restrictingByProperty, restrictingByProperty.effectiveVisibility()
|
||||
)
|
||||
)
|
||||
result = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result and checkMemberReceiver(function.receiverTypeReference, functionDescriptor)
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
private enum class Foo { A, B }
|
||||
|
||||
class Bar private constructor(private val foo: Foo)
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public final class Bar {
|
||||
private constructor Bar(/*0*/ foo: Foo)
|
||||
private final val foo: Foo
|
||||
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
|
||||
}
|
||||
|
||||
private final enum class Foo : kotlin.Enum<Foo> {
|
||||
enum entry A
|
||||
|
||||
enum entry B
|
||||
|
||||
private constructor Foo()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Foo!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Foo
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Foo>
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
private enum class Foo { A, B }
|
||||
|
||||
private class Bar(val foo: Foo)
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
private final class Bar {
|
||||
public constructor Bar(/*0*/ foo: Foo)
|
||||
public final val foo: Foo
|
||||
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
|
||||
}
|
||||
|
||||
private final enum class Foo : kotlin.Enum<Foo> {
|
||||
enum entry A
|
||||
|
||||
enum entry B
|
||||
|
||||
private constructor Foo()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Foo!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Foo
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Foo>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
private enum class Foo { A, B }
|
||||
|
||||
class Bar private constructor(<!EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR!>val foo: Foo<!>)
|
||||
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public final class Bar {
|
||||
private constructor Bar(/*0*/ foo: Foo)
|
||||
public final val foo: Foo
|
||||
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
|
||||
}
|
||||
|
||||
private final enum class Foo : kotlin.Enum<Foo> {
|
||||
enum entry A
|
||||
|
||||
enum entry B
|
||||
|
||||
private constructor Foo()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Foo!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Foo
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Foo>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
private enum class Foo { A, B }
|
||||
|
||||
class Bar(<!EXPOSED_PARAMETER_TYPE!>val foo: Foo<!>)
|
||||
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public final class Bar {
|
||||
public constructor Bar(/*0*/ foo: Foo)
|
||||
public final val foo: Foo
|
||||
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
|
||||
}
|
||||
|
||||
private final enum class Foo : kotlin.Enum<Foo> {
|
||||
enum entry A
|
||||
|
||||
enum entry B
|
||||
|
||||
private constructor Foo()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Foo!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Foo
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<Foo>
|
||||
}
|
||||
@@ -7315,6 +7315,26 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
||||
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/privatePropertyInPrivateConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInConstructorOfPrivateClass.kt")
|
||||
public void testPropertyInConstructorOfPrivateClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInConstructorOfPrivateClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInPrivateConstructor.kt")
|
||||
public void testPropertyInPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInSimpleConstructor.kt")
|
||||
public void testPropertyInSimpleConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInSimpleConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("protected.kt")
|
||||
public void testProtected() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/protected.kt");
|
||||
|
||||
Generated
+20
@@ -7315,6 +7315,26 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privatePropertyInPrivateConstructor.kt")
|
||||
public void testPrivatePropertyInPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/privatePropertyInPrivateConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInConstructorOfPrivateClass.kt")
|
||||
public void testPropertyInConstructorOfPrivateClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInConstructorOfPrivateClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInPrivateConstructor.kt")
|
||||
public void testPropertyInPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInPrivateConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyInSimpleConstructor.kt")
|
||||
public void testPropertyInSimpleConstructor() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/propertyInSimpleConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("protected.kt")
|
||||
public void testProtected() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/exposed/protected.kt");
|
||||
|
||||
@@ -188,8 +188,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
INVISIBLE_SETTER.registerFactory(MakeVisibleFactory)
|
||||
|
||||
for (exposed in listOf(
|
||||
EXPOSED_FUNCTION_RETURN_TYPE, EXPOSED_PARAMETER_TYPE, EXPOSED_PROPERTY_TYPE, EXPOSED_RECEIVER_TYPE,
|
||||
EXPOSED_SUPER_CLASS, EXPOSED_SUPER_INTERFACE, EXPOSED_TYPE_PARAMETER_BOUND
|
||||
EXPOSED_FUNCTION_RETURN_TYPE, EXPOSED_PARAMETER_TYPE, EXPOSED_PROPERTY_TYPE, EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR,
|
||||
EXPOSED_RECEIVER_TYPE, EXPOSED_SUPER_CLASS, EXPOSED_SUPER_INTERFACE, EXPOSED_TYPE_PARAMETER_BOUND
|
||||
)) {
|
||||
exposed.registerFactory(ChangeVisibilityOnExposureFactory)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user