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:
Mikhail Glukhikh
2018-11-06 17:52:48 +03:00
parent f160eabaf6
commit b3857e85e0
14 changed files with 200 additions and 10 deletions
@@ -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);
@@ -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)