Report incorrect JVM target only when @JvmRecord is actually used

This commit is contained in:
Denis.Zharkov
2020-12-08 16:48:31 +03:00
parent 920ed558ee
commit 92b402759b
15 changed files with 39 additions and 18 deletions
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.resolve.jvm.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors
@@ -26,7 +28,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.isJvmRecord
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
object JvmRecordApplicabilityChecker : DeclarationChecker {
class JvmRecordApplicabilityChecker(private val jvmTarget: JvmTarget) : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (descriptor !is ClassDescriptor || declaration !is KtClassOrObject) return
@@ -59,6 +61,13 @@ object JvmRecordApplicabilityChecker : DeclarationChecker {
return
}
if (!jvmTarget.areRecordsAllowed(context.languageVersionSettings.getFlag(JvmAnalysisFlags.enableJvmPreview))) {
context.trace.report(
ErrorsJvm.JVM_RECORDS_ILLEGAL_BYTECODE_TARGET.on(reportOn)
)
return
}
if (descriptor.kind == ClassKind.ENUM_CLASS) {
val modifierOrName =
declaration.modifierList?.getModifier(KtTokens.ENUM_KEYWORD)
@@ -153,3 +162,8 @@ object JvmRecordApplicabilityChecker : DeclarationChecker {
private fun KtModifierList.findOneOfModifiers(vararg modifierTokens: KtModifierKeywordToken): PsiElement? =
modifierTokens.firstNotNullResult(this::getModifier)
private fun JvmTarget.areRecordsAllowed(enableJvmPreview: Boolean): Boolean {
if (majorVersion < JvmTarget.JVM_15.majorVersion) return false
return enableJvmPreview || majorVersion > JvmTarget.JVM_15.majorVersion
}
@@ -165,6 +165,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
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, "Classes cannot have explicit 'java.lang.Record' supertype");
MAP.put(JVM_RECORDS_ILLEGAL_BYTECODE_TARGET, "Using @JvmRecord is only allowed with -jvm-target 15 and -Xjvm-enable-preview flag enabled");
String MESSAGE_FOR_CONCURRENT_HASH_MAP_CONTAINS =
"Method 'contains' from ConcurrentHashMap may have unexpected semantics: it calls 'containsValue' instead of 'containsKey'. " +
@@ -128,6 +128,7 @@ public interface ErrorsJvm {
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<PsiElement> JVM_RECORDS_ILLEGAL_BYTECODE_TARGET = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtDeclaration> NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
@@ -41,8 +41,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
JvmMultifileClassStateChecker,
SynchronizedOnInlineMethodChecker,
DefaultCheckerInTailrec,
FunctionDelegateMemberNameClashChecker,
JvmRecordApplicabilityChecker
FunctionDelegateMemberNameClashChecker
),
additionalCallCheckers = listOf(
@@ -111,6 +110,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
container.useImpl<JvmDefaultSuperCallChecker>()
container.useImpl<JvmSamConversionOracle>()
container.useImpl<JvmAdditionalClassPartsProvider>()
container.useImpl<JvmRecordApplicabilityChecker>()
container.useInstance(FunctionWithBigAritySupport.LanguageVersionDependent)
container.useInstance(GenericArrayClassLiteralSupport.Enabled)
container.useInstance(JavaActualAnnotationArgumentExtractor())