Prohibit extending java.lang.Record from non-@JvmRecord classes
This commit is contained in:
+9
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.JAVA_LANG_RECORD_FQ_NAME
|
||||
@@ -27,7 +28,14 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
object JvmRecordApplicabilityChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is ClassDescriptor || declaration !is KtClassOrObject || !descriptor.isJvmRecord()) return
|
||||
if (descriptor !is ClassDescriptor || declaration !is KtClassOrObject) return
|
||||
|
||||
if (!descriptor.isJvmRecord()) {
|
||||
if (descriptor.typeConstructor.supertypes.any { it.constructor.declarationDescriptor?.fqNameOrNull() == JAVA_LANG_RECORD_FQ_NAME }) {
|
||||
context.trace.report(ErrorsJvm.ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE.on(declaration))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val reportOn =
|
||||
declaration.annotationEntries.firstOrNull { it.shortName == JVM_RECORD_ANNOTATION_FQ_NAME.shortName() }
|
||||
|
||||
+1
@@ -164,6 +164,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(FIELD_IN_JVM_RECORD, "It's not allowed to have non-constructor properties with backing filed in @JvmRecord class");
|
||||
MAP.put(DELEGATION_BY_IN_JVM_RECORD, "Delegation is not allowed for @JvmRecord classes");
|
||||
MAP.put(NON_DATA_CLASS_JVM_RECORD, "Only data classes are allowed to be marked as @JvmRecord");
|
||||
MAP.put(ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE, "Only @JvmRecord classes are allowed to have java.lang.Record supertype");
|
||||
|
||||
String MESSAGE_FOR_CONCURRENT_HASH_MAP_CONTAINS =
|
||||
"Method 'contains' from ConcurrentHashMap may have unexpected semantics: it calls 'containsValue' instead of 'containsKey'. " +
|
||||
|
||||
@@ -127,6 +127,7 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<PsiElement> FIELD_IN_JVM_RECORD = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> DELEGATION_BY_IN_JVM_RECORD = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NON_DATA_CLASS_JVM_RECORD = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
|
||||
|
||||
@@ -17,3 +17,7 @@ data class A4(val x: String) : java.lang.Record(), I
|
||||
|
||||
@JvmRecord
|
||||
data class A5(val x: String) : I
|
||||
|
||||
<!ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE!>data class A6(val x: String) : Record(), I<!>
|
||||
|
||||
<!ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE!>data class A7(val x: String) : java.lang.Record(), I<!>
|
||||
|
||||
@@ -50,6 +50,26 @@ package
|
||||
public open override /*2*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final data class A6 : java.lang.Record, I {
|
||||
public constructor A6(/*0*/ x: kotlin.String)
|
||||
public final val x: kotlin.String
|
||||
public final operator /*synthesized*/ fun component1(): kotlin.String
|
||||
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.String = ...): A6
|
||||
public open override /*2*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*2*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final data class A7 : java.lang.Record, I {
|
||||
public constructor A7(/*0*/ x: kotlin.String)
|
||||
public final val x: kotlin.String
|
||||
public final operator /*synthesized*/ fun component1(): kotlin.String
|
||||
public final /*synthesized*/ fun copy(/*0*/ x: kotlin.String = ...): A7
|
||||
public open override /*2*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*2*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public abstract class Abstract {
|
||||
public constructor Abstract()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
Reference in New Issue
Block a user