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<KtObjectDeclaration, ClassDescriptor> LOCAL_OBJECT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
|
||||||
DiagnosticFactory1<KtClass, ClassDescriptor> LOCAL_INTERFACE_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_OBJECT = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<KtTypeParameterList> TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
// Type parameter declarations
|
// 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_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(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_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(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated");
|
||||||
MAP.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed 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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
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.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
@@ -226,12 +230,23 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
|
KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
|
||||||
if (typeParameterList == null) return Collections.emptyList();
|
if (typeParameterList == null) return Collections.emptyList();
|
||||||
|
|
||||||
|
boolean isAnonymousObject = (classInfo.getClassKind() == ClassKind.CLASS) && (classInfo.getCorrespondingClassOrObject() instanceof KtObjectDeclaration);
|
||||||
|
|
||||||
if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
|
if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
|
||||||
c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
|
c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
|
||||||
}
|
}
|
||||||
if (classInfo.getClassKind() == ClassKind.OBJECT) {
|
if (classInfo.getClassKind() == ClassKind.OBJECT) {
|
||||||
c.getTrace().report(TYPE_PARAMETERS_IN_OBJECT.on(typeParameterList));
|
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();
|
List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
|
||||||
if (typeParameters.isEmpty()) return Collections.emptyList();
|
if (typeParameters.isEmpty()) return Collections.emptyList();
|
||||||
|
|||||||
+6
-6
@@ -2,23 +2,23 @@
|
|||||||
// ISSUE: KT-28999
|
// ISSUE: KT-28999
|
||||||
|
|
||||||
fun case_1() {
|
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() {
|
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() {
|
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 test() = 10 <!UNCHECKED_CAST!>as T<!> // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
fun case_4() {
|
fun case_4() {
|
||||||
val x = object<T> {
|
val x = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><T><!> {
|
||||||
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
fun test() = 10 <!UNCHECKED_CAST!>as T<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ fun case_4() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> case_5() {
|
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<!>
|
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");
|
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")
|
@TestMetadata("typeParametersInObject.kt")
|
||||||
public void testTypeParametersInObject() throws Exception {
|
public void testTypeParametersInObject() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInObject.kt");
|
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");
|
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")
|
@TestMetadata("typeParametersInObject.kt")
|
||||||
public void testTypeParametersInObject() throws Exception {
|
public void testTypeParametersInObject() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInObject.kt");
|
runTest("compiler/testData/diagnostics/tests/classObjects/typeParametersInObject.kt");
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ enum class LanguageFeature(
|
|||||||
ProhibitConcurrentHashMapContains(KOTLIN_1_4, kind = BUG_FIX),
|
ProhibitConcurrentHashMapContains(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
ProhibitTypeParametersForLocalVariables(KOTLIN_1_4, kind = BUG_FIX),
|
ProhibitTypeParametersForLocalVariables(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses(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),
|
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
|
||||||
// Temporarily disabled, see KT-27084/KT-22379
|
// Temporarily disabled, see KT-27084/KT-22379
|
||||||
|
|||||||
Reference in New Issue
Block a user