Modifiers checking for type aliases.

Exposed type checking for type aliases.
This commit is contained in:
Dmitry Petrov
2016-06-10 13:10:53 +03:00
parent 139e219ebd
commit 0ff677596f
10 changed files with 142 additions and 3 deletions
@@ -85,6 +85,7 @@ public interface Errors {
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);
DiagnosticFactory3<PsiElement, EffectiveVisibility, DescriptorWithRelation, EffectiveVisibility> EXPOSED_TYPEALIAS_EXPANDED_TYPE = DiagnosticFactory3.create(ERROR);
DiagnosticFactory2<KtExpression, KotlinType, Collection<KotlinType>> INACCESSIBLE_TYPE = DiagnosticFactory2.create(ERROR);
@@ -106,6 +106,7 @@ public class DefaultErrorMessages {
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(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);
@@ -200,6 +200,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
else
TargetLists.T_TOP_LEVEL_FUNCTION
}
is KtTypeAlias -> TargetLists.T_TYPEALIAS
is KtPropertyAccessor -> if (annotated.isGetter) TargetLists.T_PROPERTY_GETTER else TargetLists.T_PROPERTY_SETTER
is KtTypeReference -> TargetLists.T_TYPE_REFERENCE
is KtFile -> TargetLists.T_FILE
@@ -217,6 +218,7 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
private object TargetLists {
val T_CLASSIFIER = targetList(CLASS)
val T_TYPEALIAS = targetList(TYPEALIAS)
val T_LOCAL_VARIABLE = targetList(LOCAL_VARIABLE) {
onlyWithUseSiteTarget(PROPERTY_SETTER, VALUE_PARAMETER)
@@ -145,7 +145,7 @@ class DeclarationsChecker(
for ((declaration, typeAliasDescriptor) in bodiesResolveContext.typeAliases.entries) {
checkTypeAliasDeclaration(typeAliasDescriptor, declaration)
modifiersChecker.checkModifiersForDeclaration(declaration, typeAliasDescriptor)
// TODO exposedChecker.checkTypeAlias(declaration, typeAliasDescriptor)
exposedChecker.checkTypeAlias(declaration, typeAliasDescriptor)
}
}
@@ -52,6 +52,18 @@ class ExposedVisibilityChecker(private val trace: DiagnosticSink = DO_NOTHING) {
}
}
fun checkTypeAlias(typeAlias: KtTypeAlias, typeAliasDescriptor: TypeAliasDescriptor) {
val expandedType = typeAliasDescriptor.expandedType
if (expandedType.isError) return
val typeAliasVisibility = typeAliasDescriptor.effectiveVisibility()
val restricting = expandedType.leastPermissiveDescriptor(typeAliasVisibility)
if (restricting != null) {
trace.report(Errors.EXPOSED_TYPEALIAS_EXPANDED_TYPE.on(typeAlias.nameIdentifier ?: typeAlias,
typeAliasVisibility, restricting, restricting.effectiveVisibility()))
}
}
fun checkFunction(function: KtFunction,
functionDescriptor: FunctionDescriptor,
// for checking situation with modified basic visibility
@@ -56,7 +56,7 @@ object ModifierCheckerCore {
private val defaultVisibilityTargets = EnumSet.of(CLASS_ONLY, OBJECT, INTERFACE, INNER_CLASS, ENUM_CLASS, ANNOTATION_CLASS,
MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR)
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR, TYPEALIAS)
val possibleTargetMap = mapOf<KtModifierKeywordToken, Set<KotlinTarget>>(
ENUM_KEYWORD to EnumSet.of(ENUM_CLASS),
@@ -71,7 +71,7 @@ object ModifierCheckerCore {
PUBLIC_KEYWORD to defaultVisibilityTargets,
INTERNAL_KEYWORD to defaultVisibilityTargets,
PROTECTED_KEYWORD to EnumSet.of(CLASS_ONLY, OBJECT, INTERFACE, INNER_CLASS, ENUM_CLASS, ANNOTATION_CLASS,
MEMBER_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, MEMBER_PROPERTY, CONSTRUCTOR),
MEMBER_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, MEMBER_PROPERTY, CONSTRUCTOR, TYPEALIAS),
IN_KEYWORD to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
OUT_KEYWORD to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
REIFIED_KEYWORD to EnumSet.of(TYPE_PARAMETER),
@@ -0,0 +1,43 @@
typealias L<T> = List<T>
class Outer {
private class Private
protected class Protected
internal class Internal
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate1<!> = Private
protected typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate2<!> = Private
internal typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate3<!> = Private
private typealias TestPrivate4 = Private
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate5<!> = L<Private>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate6<!> = L<TestPrivate1>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestProtected1<!> = Protected
protected typealias TestProtected2 = Protected
internal typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestProtected3<!> = Protected
private typealias TestProtected4 = Protected
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestProtected5<!> = L<Protected>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestProtected6<!> = L<TestProtected1>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal1<!> = Internal
protected typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal2<!> = Internal
internal typealias TestInternal3 = Internal
private typealias TestInternal4 = Internal
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal5<!> = L<Internal>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal6<!> = L<TestInternal1>
}
private class Private
internal class Internal
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate1<!> = Private
internal typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate2<!> = Private
private typealias TestPrivate3 = Private
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate4<!> = L<Private>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestPrivate5<!> = L<TestPrivate1>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal1<!> = Internal
internal typealias TestInternal2 = Internal
private typealias TestInternal3 = Internal
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal4<!> = L<Internal>
typealias <!EXPOSED_TYPEALIAS_EXPANDED_TYPE!>TestInternal5<!> = L<TestInternal1>
@@ -0,0 +1,73 @@
package
public typealias L</*0*/ T> = kotlin.collections.List<T>
public typealias TestInternal1 = Internal
internal typealias TestInternal2 = Internal
private typealias TestInternal3 = Internal
public typealias TestInternal4 = L<Internal>
public typealias TestInternal5 = L<TestInternal1>
public typealias TestPrivate1 = Private
internal typealias TestPrivate2 = Private
private typealias TestPrivate3 = Private
public typealias TestPrivate4 = L<Private>
public typealias TestPrivate5 = L<TestPrivate1>
internal final class Internal {
public constructor Internal()
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
}
public final class Outer {
public typealias TestInternal1 = Outer.Internal
protected typealias TestInternal2 = Outer.Internal
internal typealias TestInternal3 = Outer.Internal
private typealias TestInternal4 = Outer.Internal
public typealias TestInternal5 = L<Outer.Internal>
public typealias TestInternal6 = L<Outer.TestInternal1>
public typealias TestPrivate1 = Outer.Private
protected typealias TestPrivate2 = Outer.Private
internal typealias TestPrivate3 = Outer.Private
private typealias TestPrivate4 = Outer.Private
public typealias TestPrivate5 = L<Outer.Private>
public typealias TestPrivate6 = L<Outer.TestPrivate1>
public typealias TestProtected1 = Outer.Protected
protected typealias TestProtected2 = Outer.Protected
internal typealias TestProtected3 = Outer.Protected
private typealias TestProtected4 = Outer.Protected
public typealias TestProtected5 = L<Outer.Protected>
public typealias TestProtected6 = L<Outer.TestProtected1>
public constructor Outer()
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
internal final class Internal {
public constructor Internal()
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 class Private {
public constructor Private()
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
}
protected final class Protected {
public constructor Protected()
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 class Private {
public constructor Private()
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
}
@@ -19491,6 +19491,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("exposedExpandedType.kt")
public void testExposedExpandedType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/exposedExpandedType.kt");
doTest(fileName);
}
@TestMetadata("functionTypeInTypeAlias.kt")
public void testFunctionTypeInTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/functionTypeInTypeAlias.kt");
@@ -38,6 +38,7 @@ enum class KotlinTarget(val description: String, val isDefault: Boolean = true)
TYPE("type usage", false),
EXPRESSION("expression", false), // includes FUNCTION_LITERAL, OBJECT_LITERAL
FILE("file", false),
TYPEALIAS("typealias"), // TODO support typealias as annotation target
TYPE_PROJECTION("type projection", false),
STAR_PROJECTION("star projection", false),