- turn INACCESSIBLE_TYPE into a warning;
- improve diagnostic message for INACCESSIBLE_TYPE.
This commit is contained in:
Dmitry Petrov
2017-01-09 17:17:44 +03:00
parent 80af30fb4f
commit 7a8ec86cb9
4 changed files with 23 additions and 27 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.resolve.jvm.checkers package org.jetbrains.kotlin.resolve.jvm.checkers
import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -42,45 +41,44 @@ class JavaTypeAccessibilityChecker : AdditionalTypeChecker {
if (c.isDebuggerContext) return if (c.isDebuggerContext) return
val inaccessibleTypes = findInaccessibleJavaTypes(expressionType, c) val inaccessibleClasses = findInaccessibleJavaClasses(expressionType, c)
if (inaccessibleTypes.isNotEmpty()) { if (inaccessibleClasses.isNotEmpty()) {
c.trace.report(Errors.INACCESSIBLE_TYPE.on(expression, expressionType, inaccessibleTypes)) c.trace.report(Errors.INACCESSIBLE_TYPE.on(expression, expressionType, inaccessibleClasses))
return return
} }
if (expressionTypeWithSmartCast != expressionType) { if (expressionTypeWithSmartCast != expressionType) {
val inaccessibleTypesWithSmartCast = findInaccessibleJavaTypes(expressionTypeWithSmartCast, c) val inaccessibleClassesWithSmartCast = findInaccessibleJavaClasses(expressionTypeWithSmartCast, c)
if (inaccessibleTypesWithSmartCast.isNotEmpty()) { if (inaccessibleClassesWithSmartCast.isNotEmpty()) {
c.trace.report(Errors.INACCESSIBLE_TYPE.on(expression, expressionType, inaccessibleTypes)) c.trace.report(Errors.INACCESSIBLE_TYPE.on(expression, expressionType, inaccessibleClassesWithSmartCast))
} }
} }
} }
private fun findInaccessibleJavaTypes(type: KotlinType, c: ResolutionContext<*>): List<KotlinType> { private fun findInaccessibleJavaClasses(type: KotlinType, c: ResolutionContext<*>): Collection<ClassDescriptor> {
val scopeOwner = c.scope.ownerDescriptor val scopeOwner = c.scope.ownerDescriptor
val inaccessibleTypes = SmartList<KotlinType>() val inaccessibleJavaClasses = LinkedHashSet<ClassDescriptor>()
findInaccessibleJavaTypesRec(type, scopeOwner, inaccessibleTypes, hashSetOf()) findInaccessibleJavaClassesRec(type, scopeOwner, inaccessibleJavaClasses)
return inaccessibleTypes return inaccessibleJavaClasses
} }
private fun findInaccessibleJavaTypesRec( private fun findInaccessibleJavaClassesRec(
type: KotlinType, type: KotlinType,
scopeOwner: DeclarationDescriptor, scopeOwner: DeclarationDescriptor,
inaccessibleTypes: SmartList<KotlinType>, inaccessibleClasses: MutableCollection<ClassDescriptor>
visitedTypeConstructors: MutableSet<DeclarationDescriptor>
) { ) {
val typeConstructor = type.constructor.declarationDescriptor val declarationDescriptor = type.constructor.declarationDescriptor
if (typeConstructor is ClassDescriptor) {
if (visitedTypeConstructors.contains(typeConstructor)) return
visitedTypeConstructors.add(typeConstructor)
if (typeConstructor is JavaClassDescriptor && !Visibilities.isVisibleIgnoringReceiver(typeConstructor, scopeOwner)) { if (declarationDescriptor is JavaClassDescriptor) {
inaccessibleTypes.add(type) if (!Visibilities.isVisibleIgnoringReceiver(declarationDescriptor, scopeOwner)) {
} inaccessibleClasses.add(declarationDescriptor)
for (typeProjection in type.arguments) {
findInaccessibleJavaTypesRec(typeProjection.type, scopeOwner, inaccessibleTypes, visitedTypeConstructors)
} }
} }
for (typeProjection in type.arguments) {
if (typeProjection.isStarProjection) continue
findInaccessibleJavaClassesRec(typeProjection.type, scopeOwner, inaccessibleClasses)
}
} }
} }
@@ -112,7 +112,7 @@ public interface Errors {
DiagnosticFactory3<KtSuperTypeListEntry, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_SUPER_INTERFACE = DiagnosticFactory3.create(ERROR); DiagnosticFactory3<KtSuperTypeListEntry, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_SUPER_INTERFACE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_TYPEALIAS_EXPANDED_TYPE = DiagnosticFactory3.create(ERROR); DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_TYPEALIAS_EXPANDED_TYPE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory2<KtExpression, KotlinType, Collection<KotlinType>> INACCESSIBLE_TYPE = DiagnosticFactory2.create(ERROR); DiagnosticFactory2<KtExpression, KotlinType, Collection<ClassDescriptor>> INACCESSIBLE_TYPE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory1<KtElement, Collection<ClassDescriptor>> PLATFORM_CLASS_MAPPED_TO_KOTLIN = DiagnosticFactory1.create(WARNING); DiagnosticFactory1<KtElement, Collection<ClassDescriptor>> PLATFORM_CLASS_MAPPED_TO_KOTLIN = DiagnosticFactory1.create(WARNING);
@@ -114,7 +114,7 @@ public class DefaultErrorMessages {
MAP.put(EXPOSED_SUPER_INTERFACE, "''{0}'' sub-interface 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(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "''{0}'' typealias exposes ''{2}'' in expanded type{1}", TO_STRING, TO_STRING, TO_STRING); MAP.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "''{0}'' typealias exposes ''{2}'' in expanded type{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); MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, commaSeparated(FQ_NAMES_IN_TYPES));
MAP.put(REDECLARATION, "Conflicting declarations: {0}", commaSeparated(COMPACT_WITH_MODIFIERS)); MAP.put(REDECLARATION, "Conflicting declarations: {0}", commaSeparated(COMPACT_WITH_MODIFIERS));
MAP.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", STRING); MAP.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", STRING);
@@ -39,9 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*