Effective visibility: concise diagnostic messages #KT-10761 Fixed

Also #KT-9760 Fixed
This commit is contained in:
Mikhail Glukhikh
2016-02-10 14:44:47 +03:00
committed by Mikhail Glukhikh
parent 3049961b9a
commit 1bbc46729c
15 changed files with 158 additions and 68 deletions
@@ -74,13 +74,13 @@ public interface Errors {
DiagnosticFactory3<PsiElement, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_MEMBER = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
// Exposed visibility group
DiagnosticFactory2<PsiElement, EffectiveVisibility, EffectiveVisibility> EXPOSED_PROPERTY_TYPE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<PsiElement, EffectiveVisibility, EffectiveVisibility> EXPOSED_FUNCTION_RETURN_TYPE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtParameter, EffectiveVisibility, EffectiveVisibility> EXPOSED_PARAMETER_TYPE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtTypeReference, EffectiveVisibility, EffectiveVisibility> EXPOSED_RECEIVER_TYPE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtTypeParameter, EffectiveVisibility, EffectiveVisibility> EXPOSED_TYPE_PARAMETER_BOUND = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtSuperTypeListEntry, EffectiveVisibility, EffectiveVisibility> EXPOSED_SUPER_CLASS = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<KtSuperTypeListEntry, EffectiveVisibility, EffectiveVisibility> EXPOSED_SUPER_INTERFACE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_PROPERTY_TYPE = DiagnosticFactory3.create(ERROR);
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);
DiagnosticFactory3<KtTypeParameter, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_TYPE_PARAMETER_BOUND = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<KtSuperTypeListEntry, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_SUPER_CLASS = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<KtSuperTypeListEntry, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_SUPER_INTERFACE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory2<KtExpression, KotlinType, Collection<KotlinType>> INACCESSIBLE_TYPE = DiagnosticFactory2.create(ERROR);
@@ -114,13 +114,13 @@ public class DefaultErrorMessages {
MAP.put(INVISIBLE_REFERENCE, "Cannot access ''{0}'': it is ''{1}'' in {2}", NAME, TO_STRING, NAME_OF_PARENT_OR_FILE);
MAP.put(INVISIBLE_MEMBER, "Cannot access ''{0}'': it is ''{1}'' in {2}", NAME, TO_STRING, NAME_OF_PARENT_OR_FILE);
MAP.put(EXPOSED_PROPERTY_TYPE, "Property effective visibility ''{0}'' should be the same or less permissive than its type effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_FUNCTION_RETURN_TYPE, "Function effective visibility ''{0}'' should be the same or less permissive than its return type effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_PARAMETER_TYPE, "Function effective visibility ''{0}'' should be the same or less permissive than its parameter type effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_RECEIVER_TYPE, "Member effective visibility ''{0}'' should be the same or less permissive than its receiver type effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_TYPE_PARAMETER_BOUND, "Generic effective visibility ''{0}'' should be the same or less permissive than its type parameter bound effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_SUPER_CLASS, "Subclass effective visibility ''{0}'' should be the same or less permissive than its superclass effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_SUPER_INTERFACE, "Sub-interface effective visibility ''{0}'' should be the same or less permissive than its super-interface effective visibility ''{1}''", TO_STRING, TO_STRING);
MAP.put(EXPOSED_PROPERTY_TYPE, "''{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);
MAP.put(EXPOSED_TYPE_PARAMETER_BOUND, "''{0}'' generic exposes its ''{2}'' parameter bound type{1}", TO_STRING, TO_STRING, TO_STRING);
MAP.put(EXPOSED_SUPER_CLASS, "''{0}'' subclass exposes its ''{2}'' supertype{1}", TO_STRING, TO_STRING, TO_STRING);
MAP.put(EXPOSED_SUPER_INTERFACE, "''{0}'' sub-interface exposes its ''{2}'' supertype{1}", TO_STRING, TO_STRING, TO_STRING);
MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, RENDER_COLLECTION_OF_TYPES);
@@ -278,9 +278,10 @@ class DeclarationsChecker(
classDescriptor.declaredTypeParameters.forEachIndexed { i, typeParameterDescriptor ->
if (i >= typeParameterList.size) return
for (upperBound in typeParameterDescriptor.upperBounds) {
val upperBoundVisibility = upperBound.effectiveVisibility()
if (!upperBoundVisibility.sameOrMorePermissive(classVisibility)) {
trace.report(EXPOSED_TYPE_PARAMETER_BOUND.on(typeParameterList[i], classVisibility, upperBoundVisibility))
val restricting = upperBound.dependentDescriptors().leastPermissive(classVisibility)
if (restricting != null) {
trace.report(EXPOSED_TYPE_PARAMETER_BOUND.on(typeParameterList[i], classVisibility,
restricting, restricting.effectiveVisibility()))
break
}
}
@@ -298,13 +299,15 @@ class DeclarationsChecker(
if (superIsInterface != isInterface) {
return@forEachIndexed
}
val superTypeVisibility = superType.effectiveVisibility()
if (!superTypeVisibility.sameOrMorePermissive(classVisibility)) {
val restricting = superType.dependentDescriptors().leastPermissive(classVisibility)
if (restricting != null) {
if (isInterface) {
trace.report(EXPOSED_SUPER_INTERFACE.on(delegationList[i], classVisibility, superTypeVisibility))
trace.report(EXPOSED_SUPER_INTERFACE.on(delegationList[i], classVisibility,
restricting, restricting.effectiveVisibility()))
}
else {
trace.report(EXPOSED_SUPER_CLASS.on(delegationList[i], classVisibility, superTypeVisibility))
trace.report(EXPOSED_SUPER_CLASS.on(delegationList[i], classVisibility,
restricting, restricting.effectiveVisibility()))
}
}
}
@@ -635,17 +638,19 @@ class DeclarationsChecker(
if (typeReference == null) return
val receiverParameterDescriptor = memberDescriptor.extensionReceiverParameter ?: return
val memberVisibility = memberDescriptor.effectiveVisibility()
val receiverTypeVisibility = receiverParameterDescriptor.type.effectiveVisibility()
if (!receiverTypeVisibility.sameOrMorePermissive(memberVisibility)) {
trace.report(EXPOSED_RECEIVER_TYPE.on(typeReference, memberVisibility, receiverTypeVisibility))
val restricting = receiverParameterDescriptor.type.dependentDescriptors().leastPermissive(memberVisibility)
if (restricting != null) {
trace.report(EXPOSED_RECEIVER_TYPE.on(typeReference, memberVisibility,
restricting, restricting.effectiveVisibility()))
}
}
private fun checkPropertyExposedType(property: KtProperty, propertyDescriptor: PropertyDescriptor) {
val propertyVisibility = propertyDescriptor.effectiveVisibility()
val typeVisibility = propertyDescriptor.type.effectiveVisibility()
if (!typeVisibility.sameOrMorePermissive(propertyVisibility)) {
trace.report(EXPOSED_PROPERTY_TYPE.on(property.nameIdentifier ?: property, propertyVisibility, typeVisibility))
val restricting = propertyDescriptor.type.dependentDescriptors().leastPermissive(propertyVisibility)
if (restricting != null) {
trace.report(EXPOSED_PROPERTY_TYPE.on(property.nameIdentifier ?: property, propertyVisibility,
restricting, restricting.effectiveVisibility()))
}
checkMemberReceiverExposedType(property.receiverTypeReference, propertyDescriptor)
}
@@ -712,15 +717,17 @@ class DeclarationsChecker(
private fun checkFunctionExposedType(function: KtFunction, functionDescriptor: FunctionDescriptor) {
val functionVisibility = functionDescriptor.effectiveVisibility()
if (function !is KtConstructor<*>) {
val returnTypeVisibility = functionDescriptor.returnType?.effectiveVisibility()
if (returnTypeVisibility != null && !returnTypeVisibility.sameOrMorePermissive(functionVisibility)) {
trace.report(EXPOSED_FUNCTION_RETURN_TYPE.on(function.nameIdentifier ?: function, functionVisibility, returnTypeVisibility))
val restricting = functionDescriptor.returnType?.dependentDescriptors()?.leastPermissive(functionVisibility)
if (restricting != null) {
trace.report(EXPOSED_FUNCTION_RETURN_TYPE.on(function.nameIdentifier ?: function, functionVisibility,
restricting, restricting.effectiveVisibility()))
}
}
functionDescriptor.valueParameters.forEachIndexed { i, parameterDescriptor ->
val typeVisibility = parameterDescriptor.type.effectiveVisibility()
if (!typeVisibility.sameOrMorePermissive(functionVisibility) && i < function.valueParameters.size) {
trace.report(EXPOSED_PARAMETER_TYPE.on(function.valueParameters[i], functionVisibility, typeVisibility))
val restricting = parameterDescriptor.type.dependentDescriptors().leastPermissive(functionVisibility)
if (restricting != null && i < function.valueParameters.size) {
trace.report(EXPOSED_PARAMETER_TYPE.on(function.valueParameters[i], functionVisibility,
restricting, restricting.effectiveVisibility()))
}
}
checkMemberReceiverExposedType(function.receiverTypeReference, functionDescriptor)