Fix #KT-28999. Prohibit type parameters on anonymous objects
This commit is contained in:
@@ -396,6 +396,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtObjectDeclaration, ClassDescriptor> LOCAL_OBJECT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
|
||||
DiagnosticFactory1<KtClass, ClassDescriptor> LOCAL_INTERFACE_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
|
||||
DiagnosticFactory0<KtTypeParameterList> TYPE_PARAMETERS_IN_OBJECT = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeParameterList> TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
// Type parameter declarations
|
||||
|
||||
|
||||
+1
@@ -381,6 +381,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", NAME);
|
||||
MAP.put(LOCAL_INTERFACE_NOT_ALLOWED, "''{0}'' is an interface so it cannot be local. Try to use anonymous object or abstract class instead", NAME);
|
||||
MAP.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects");
|
||||
MAP.put(TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT, "Type parameters for anonymous objects are deprecated");
|
||||
MAP.put(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated");
|
||||
MAP.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed types cannot be instantiated");
|
||||
|
||||
|
||||
+15
@@ -13,10 +13,14 @@ import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -226,12 +230,23 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
|
||||
if (typeParameterList == null) return Collections.emptyList();
|
||||
|
||||
boolean isAnonymousObject = (classInfo.getClassKind() == ClassKind.CLASS) && (classInfo.getCorrespondingClassOrObject() instanceof KtObjectDeclaration);
|
||||
|
||||
if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
|
||||
c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
|
||||
}
|
||||
if (classInfo.getClassKind() == ClassKind.OBJECT) {
|
||||
c.getTrace().report(TYPE_PARAMETERS_IN_OBJECT.on(typeParameterList));
|
||||
}
|
||||
if (isAnonymousObject) {
|
||||
DiagnosticFactory0<KtTypeParameterList> diagnosticFactory;
|
||||
if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ProhibitTypeParametersInAnonymousObjects)) {
|
||||
diagnosticFactory = TYPE_PARAMETERS_IN_OBJECT;
|
||||
} else {
|
||||
diagnosticFactory = TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT;
|
||||
}
|
||||
c.getTrace().report(diagnosticFactory.on(typeParameterList));
|
||||
}
|
||||
|
||||
List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
|
||||
if (typeParameters.isEmpty()) return Collections.emptyList();
|
||||
|
||||
+6
-6
@@ -2,23 +2,23 @@
|
||||
// ISSUE: KT-28999
|
||||
|
||||
fun case_1() {
|
||||
val x = object<T> { } // type of x is <anonymous object><T>
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> { } // type of x is <anonymous object><T>
|
||||
}
|
||||
|
||||
fun case_2() {
|
||||
val x = object<T : Number, K: Comparable<K>> { }
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T : Number, K: Comparable<K>><!> { }
|
||||
}
|
||||
|
||||
fun case_3() {
|
||||
val x = object<T> <!SYNTAX!>where <!DEBUG_INFO_MISSING_UNRESOLVED!>T<!> : <!DEBUG_INFO_MISSING_UNRESOLVED!>Comparable<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!> { } // ERROR: Where clause is not allowed for objects
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> <!SYNTAX!>where <!DEBUG_INFO_MISSING_UNRESOLVED!>T<!> : <!DEBUG_INFO_MISSING_UNRESOLVED!>Comparable<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!> { } // ERROR: Where clause is not allowed for objects
|
||||
}
|
||||
|
||||
val x = object<T, K: Comparable<K>> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T, K: Comparable<K>><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!> // OK
|
||||
}
|
||||
|
||||
fun case_4() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ fun case_4() {
|
||||
}
|
||||
|
||||
inline fun <reified T> case_5() {
|
||||
val x = object<T> {
|
||||
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
||||
}
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// !LANGUAGE: +ProhibitTypeParametersInAnonymousObjects
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE!
|
||||
// ISSUE: KT-28999
|
||||
|
||||
fun case_1() {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> { } // type of x is <anonymous object><T>
|
||||
}
|
||||
|
||||
fun case_2() {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T : Number, K: Comparable<K>><!> { }
|
||||
}
|
||||
|
||||
fun case_3() {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> <!SYNTAX!>where <!DEBUG_INFO_MISSING_UNRESOLVED!>T<!> : <!DEBUG_INFO_MISSING_UNRESOLVED!>Comparable<!><<!DEBUG_INFO_MISSING_UNRESOLVED!>T<!>><!> { } // ERROR: Where clause is not allowed for objects
|
||||
}
|
||||
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T, K: Comparable<K>><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!> // OK
|
||||
}
|
||||
|
||||
fun case_4() {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
||||
}
|
||||
|
||||
val y = x.test() // type y is T
|
||||
}
|
||||
|
||||
inline fun <reified T> case_5() {
|
||||
val x = object<!TYPE_PARAMETERS_IN_OBJECT!><T><!> {
|
||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
||||
}
|
||||
|
||||
val z = x.test()
|
||||
|
||||
if (z is T) {
|
||||
// z is {T!! & T!!} (smart cast from T)
|
||||
<!UNRESOLVED_REFERENCE!>println<!>(z)
|
||||
}
|
||||
}
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
public val x: kotlin.Any
|
||||
public fun case_1(): kotlin.Unit
|
||||
public fun case_2(): kotlin.Unit
|
||||
public fun case_3(): kotlin.Unit
|
||||
public fun case_4(): kotlin.Unit
|
||||
public inline fun </*0*/ reified T> case_5(): kotlin.Unit
|
||||
@@ -3114,6 +3114,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParametersInAnnonymousObject_after.kt")
|
||||
public void testTypeParametersInAnnonymousObject_after() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParametersInObject.kt")
|
||||
public void testTypeParametersInObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInObject.kt");
|
||||
|
||||
Generated
+5
@@ -3109,6 +3109,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParametersInAnnonymousObject_after.kt")
|
||||
public void testTypeParametersInAnnonymousObject_after() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParametersInObject.kt")
|
||||
public void testTypeParametersInObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInObject.kt");
|
||||
|
||||
@@ -96,6 +96,7 @@ enum class LanguageFeature(
|
||||
ProhibitConcurrentHashMapContains(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitTypeParametersForLocalVariables(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitTypeParametersInAnonymousObjects(KOTLIN_1_4, kind = BUG_FIX),
|
||||
|
||||
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
|
||||
Reference in New Issue
Block a user