Support only simple declarations for 'impl' type aliases
E.g. 'impl typealias Foo<A, B> = Bar<A, B>' is allowed; everything else (variance, changing order of parameters, etc.) is pretty much disallowed. This is done for simplicity: otherwise matching the platform/impl class scopes would be not so straightforward
This commit is contained in:
@@ -497,6 +497,11 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtParameter> PLATFORM_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtExpression> PLATFORM_PROPERTY_INITIALIZER = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtTypeAlias> IMPL_TYPE_ALIAS_NOT_TO_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtTypeAlias> IMPL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtTypeAlias> IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtTypeAlias> IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Errors/warnings inside code blocks
|
||||
|
||||
+5
@@ -263,6 +263,11 @@ public class DefaultErrorMessages {
|
||||
MAP.put(PLATFORM_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, "Platform class constructor cannot have a property parameter");
|
||||
MAP.put(PLATFORM_PROPERTY_INITIALIZER, "Platform property cannot have an initializer");
|
||||
|
||||
MAP.put(IMPL_TYPE_ALIAS_NOT_TO_CLASS, "Right-hand side of 'impl' type alias should be a class, not another type alias");
|
||||
MAP.put(IMPL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance");
|
||||
MAP.put(IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of 'impl' type alias cannot contain use-site variance or star projections");
|
||||
MAP.put(IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of 'impl' type alias should be its type parameters in the same order, e.g. 'impl typealias Foo<A, B> = Bar<A, B>'");
|
||||
|
||||
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
|
||||
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
|
||||
MAP.put(NOTHING_TO_OVERRIDE, "''{0}'' overrides nothing", NAME);
|
||||
|
||||
@@ -181,6 +181,35 @@ class DeclarationsChecker(
|
||||
trace.report(UNUSED_TYPEALIAS_PARAMETER.on(source, typeParameter, expandedType))
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.hasModifier(KtTokens.IMPL_KEYWORD)) {
|
||||
checkImplTypeAlias(declaration, typeAliasDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkImplTypeAlias(declaration: KtTypeAlias, typeAliasDescriptor: TypeAliasDescriptor) {
|
||||
val rhs = typeAliasDescriptor.underlyingType
|
||||
val classDescriptor = rhs.constructor.declarationDescriptor
|
||||
if (classDescriptor !is ClassDescriptor) {
|
||||
trace.report(IMPL_TYPE_ALIAS_NOT_TO_CLASS.on(declaration))
|
||||
return
|
||||
}
|
||||
|
||||
if (classDescriptor.declaredTypeParameters.any { it.variance != Variance.INVARIANT }) {
|
||||
trace.report(IMPL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE.on(declaration))
|
||||
return
|
||||
}
|
||||
|
||||
if (rhs.arguments.any { it.projectionKind != Variance.INVARIANT || it.isStarProjection }) {
|
||||
trace.report(IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE.on(declaration))
|
||||
return
|
||||
}
|
||||
|
||||
if (rhs.arguments.map { it.type.constructor.declarationDescriptor as? TypeParameterDescriptor } !=
|
||||
typeAliasDescriptor.declaredTypeParameters) {
|
||||
trace.report(IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION.on(declaration))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUsedTypeAliasParameters(type: KotlinType, typeAlias: TypeAliasDescriptor): Set<TypeParameterDescriptor> =
|
||||
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
|
||||
platform class C1
|
||||
platform class C2<A>
|
||||
platform class C3<B>
|
||||
platform class C4<D, E>
|
||||
platform class C5<F, G>
|
||||
platform class C6<H>
|
||||
platform class C7<I>
|
||||
platform class C8<J>
|
||||
platform class C9<K>
|
||||
platform class C10<L>
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
// FILE: jvm.kt
|
||||
|
||||
impl typealias C1 = String
|
||||
<!IMPL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE!>impl typealias C2<<!UNUSED_TYPEALIAS_PARAMETER!>A<!>> = List<String><!>
|
||||
<!IMPL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE!>impl typealias C3<B> = List<B><!>
|
||||
impl typealias C4<D, E> = MutableMap<D, E>
|
||||
<!IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION!>impl typealias C5<F, G> = MutableMap<G, F><!>
|
||||
impl typealias C6<H> = MutableList<H>
|
||||
<!IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE!>impl typealias C7<I> = MutableList<out I><!>
|
||||
<!IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE!>impl typealias C8<<!UNUSED_TYPEALIAS_PARAMETER!>J<!>> = MutableList<*><!>
|
||||
<!IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE!>impl typealias C9<K> = MutableList<in K><!>
|
||||
|
||||
typealias Tmp<K> = MutableList<K>
|
||||
<!IMPL_TYPE_ALIAS_NOT_TO_CLASS!>impl typealias C10<L> = Tmp<L><!>
|
||||
Vendored
+88
@@ -0,0 +1,88 @@
|
||||
// -- Module: <m1-common> --
|
||||
package
|
||||
|
||||
public final platform class C1 {
|
||||
public constructor C1()
|
||||
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 platform class C10</*0*/ L> {
|
||||
public constructor C10</*0*/ L>()
|
||||
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 platform class C2</*0*/ A> {
|
||||
public constructor C2</*0*/ A>()
|
||||
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 platform class C3</*0*/ B> {
|
||||
public constructor C3</*0*/ B>()
|
||||
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 platform class C4</*0*/ D, /*1*/ E> {
|
||||
public constructor C4</*0*/ D, /*1*/ E>()
|
||||
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 platform class C5</*0*/ F, /*1*/ G> {
|
||||
public constructor C5</*0*/ F, /*1*/ G>()
|
||||
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 platform class C6</*0*/ H> {
|
||||
public constructor C6</*0*/ H>()
|
||||
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 platform class C7</*0*/ I> {
|
||||
public constructor C7</*0*/ I>()
|
||||
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 platform class C8</*0*/ J> {
|
||||
public constructor C8</*0*/ J>()
|
||||
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 platform class C9</*0*/ K> {
|
||||
public constructor C9</*0*/ K>()
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2-jvm> --
|
||||
package
|
||||
|
||||
public typealias C1 = kotlin.String
|
||||
public typealias C10</*0*/ L> = Tmp<L>
|
||||
public typealias C2</*0*/ A> = kotlin.collections.List<kotlin.String>
|
||||
public typealias C3</*0*/ B> = kotlin.collections.List<B>
|
||||
public typealias C4</*0*/ D, /*1*/ E> = kotlin.collections.MutableMap<D, E>
|
||||
public typealias C5</*0*/ F, /*1*/ G> = kotlin.collections.MutableMap<G, F>
|
||||
public typealias C6</*0*/ H> = kotlin.collections.MutableList<H>
|
||||
public typealias C7</*0*/ I> = kotlin.collections.MutableList<out I>
|
||||
public typealias C8</*0*/ J> = kotlin.collections.MutableList<*>
|
||||
public typealias C9</*0*/ K> = kotlin.collections.MutableList<in K>
|
||||
public typealias Tmp</*0*/ K> = kotlin.collections.MutableList<K>
|
||||
@@ -12576,6 +12576,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericClassImplTypeAlias.kt")
|
||||
public void testGenericClassImplTypeAlias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/platformClass/genericClassImplTypeAlias.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("platformClassMember.kt")
|
||||
public void testPlatformClassMember() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/platformClass/platformClassMember.kt");
|
||||
|
||||
Reference in New Issue
Block a user