From cfd28352546e9ba2a9db6ad9d91446a77f58fb85 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Fri, 27 Aug 2021 23:17:27 +0300 Subject: [PATCH] [FIR] Add JVM Default diagnostics --- .../CliLightClassGenerationSupport.kt | 1 - .../diagnostics/FirJvmDiagnosticsList.kt | 15 ++ .../analysis/diagnostics/jvm/FirJvmErrors.kt | 11 ++ .../jvm/checkers/FirJvmAnnotationHelper.kt | 0 .../jvm/checkers/JvmDeclarationCheckers.kt | 1 + .../declaration/FirJvmDefaultChecker.kt | 185 ++++++++++++++++++ .../FirInterfaceDefaultMethodCallChecker.kt | 0 .../diagnostics/FirJvmDefaultErrorMessages.kt | 29 +++ .../checkers/CommonDeclarationCheckers.kt | 2 +- .../fir/session/ComponentsContainers.kt | 5 + .../fir/java/JvmDefaultModeContainer.kt | 17 ++ .../impl/AbstractFirUseSiteMemberScope.kt | 2 +- .../annotations/jvmDefault/generic.fir.kt | 60 ------ .../annotations/jvmDefault/generic.kt | 1 + .../jvmDefault/javaOverride.fir.kt | 72 ------- .../annotations/jvmDefault/javaOverride.kt | 1 + .../jvmDefault/jvmDefaultInInheritance.fir.kt | 17 +- .../jvmDefault/jvmDefaultInInheritance.kt | 1 - .../target6.fir.kt | 7 - .../jvmDefaultWithoutCompatibility/target6.kt | 1 + .../target8Disabled.fir.kt | 9 - .../target8Disabled.kt | 1 + .../jvmDefault/noJvmDefaultFlag.fir.kt | 14 +- .../jvmDefault/notInterface.fir.kt | 22 --- .../annotations/jvmDefault/notInterface.kt | 1 + .../jvmDefault/simpleOverride.fir.kt | 31 --- .../annotations/jvmDefault/simpleOverride.kt | 1 + .../annotations/jvmDefault/superCall.fir.kt | 14 +- .../jvmDefault/superCallAmbiguity.fir.kt | 12 +- .../jvmDefault/superCallAmbiguity2.fir.kt | 4 +- .../jvmDefault/superCallAmbiguity3.fir.kt | 10 +- .../annotations/jvmDefault/target6.fir.kt | 29 --- .../annotations/jvmDefault/target6.kt | 1 + .../diagnostics/KtFirDataClassConverters.kt | 44 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 30 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 51 +++++ 36 files changed, 432 insertions(+), 270 deletions(-) create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirInterfaceDefaultMethodCallChecker.kt create mode 100644 compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmDefaultModeContainer.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.fir.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt index a8d6aa1e6a4..4ac6d6ea113 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt @@ -32,7 +32,6 @@ import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.JvmAnalysisFlags import org.jetbrains.kotlin.config.JvmTarget -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index b179dea2604..498ad6c839e 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -14,6 +14,8 @@ import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement @Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused") @OptIn(PrivateForInline::class) @@ -88,4 +90,17 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE by error() } + val JVM_DEFAULT by object : DiagnosticGroup("JVM Default") { + val JVM_DEFAULT_NOT_IN_INTERFACE by error() + val JVM_DEFAULT_IN_JVM6_TARGET by error { + parameter("annotation") + } + val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error(PositioningStrategy.DECLARATION_SIGNATURE) + val JVM_DEFAULT_IN_DECLARATION by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { + parameter("annotation") + } + val JVM_DEFAULT_THROUGH_INHERITANCE by error(PositioningStrategy.DECLARATION_SIGNATURE) + val USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error() + val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning(PositioningStrategy.DECLARATION_SIGNATURE) + } } diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index 5b8adf05e45..2982fe32a26 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -12,6 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStr import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression /* @@ -72,4 +74,13 @@ object FirJvmErrors { val JVM_RECORD_EXTENDS_CLASS by error1(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME) val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE by error0() + // JVM Default + val JVM_DEFAULT_NOT_IN_INTERFACE by error0() + val JVM_DEFAULT_IN_JVM6_TARGET by error1() + val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val JVM_DEFAULT_IN_DECLARATION by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) + val JVM_DEFAULT_THROUGH_INHERITANCE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error0() + val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt index f4aa1ba5eed..78260144ca3 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt @@ -13,6 +13,7 @@ object JvmDeclarationCheckers : DeclarationCheckers() { get() = setOf( FirJvmExternalDeclarationChecker, FirJvmNameChecker, + FirJvmDefaultChecker ) override val annotatedDeclarationCheckers: Set diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt new file mode 100644 index 00000000000..0d17ace1d94 --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt @@ -0,0 +1,185 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration + +import org.jetbrains.kotlin.config.JvmDefaultMode +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker +import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.containingClass +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isInterface +import org.jetbrains.kotlin.fir.declarations.utils.modality +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.java.jvmDefaultModeState +import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.resolve.toFirRegularClass +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions +import org.jetbrains.kotlin.fir.scopes.impl.FirClassUseSiteMemberScope +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol +import org.jetbrains.kotlin.name.FqName + +object FirJvmDefaultChecker : FirBasicDeclarationChecker() { + private val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault") + private val JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithoutCompatibility") + + override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + val jvmDefaultMode = context.session.jvmDefaultModeState + var defaultAnnotation: FirAnnotationCall? = null + val containingDeclaration = context.findClosest() + + if (declaration is FirAnnotatedDeclaration) { + val isJvm16 = context.session.moduleData.platform.componentPlatforms.any { it.targetName == "1.6" } + defaultAnnotation = declaration.getAnnotationByFqName(JVM_DEFAULT_FQ_NAME) + + if (defaultAnnotation != null) { + if (containingDeclaration !is FirClass || !containingDeclaration.isInterface) { + reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE, context) + return + } else if (isJvm16) { + reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, "JvmDefault", context) + return + } else if (!jvmDefaultMode.isEnabled) { + reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context) + return + } + } else { + val annotation = declaration.getAnnotationByFqName(JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME) + if (annotation != null) { + if (isJvm16) { + reporter.reportOn( + annotation.source, + FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, + "JvmDefaultWithoutCompatibility", + context + ) + return + } else if (!jvmDefaultMode.isEnabled) { + reporter.reportOn( + annotation.source, + FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, + "JvmDefaultWithoutCompatibility", + context + ) + return + } + } + } + } + + if (declaration is FirClass) { + val unsubstitutedScope = declaration.unsubstitutedScope(context) + val hasDeclaredJvmDefaults = unsubstitutedScope is FirClassUseSiteMemberScope && + unsubstitutedScope.directOverriddenFunctions.keys.any { + it.isCompiledToJvmDefault(jvmDefaultMode) + } + if (!hasDeclaredJvmDefaults && !declaration.checkJvmDefaultsInHierarchy(jvmDefaultMode, context)) { + reporter.reportOn(declaration.source, FirJvmErrors.JVM_DEFAULT_THROUGH_INHERITANCE, context) + } + } + + checkNonJvmDefaultOverridesJavaDefault(defaultAnnotation, jvmDefaultMode, declaration, containingDeclaration, context, reporter) + } + + private fun FirDeclaration.checkJvmDefaultsInHierarchy(jvmDefaultMode: JvmDefaultMode, context: CheckerContext): Boolean { + if (jvmDefaultMode.isEnabled) return true + + if (this !is FirClass) return true + + val unsubstitutedScope = unsubstitutedScope(context) + if (unsubstitutedScope is FirClassUseSiteMemberScope) { + val directOverriddenFunctions = unsubstitutedScope.directOverriddenFunctions.flatMap { it.value }.toSet() + + for (key in unsubstitutedScope.overrideByBase.keys) { + if (directOverriddenFunctions.contains(key)) { + continue + } + + if (key.getOverriddenDeclarations().all { + it.containingClass()?.toFirRegularClassSymbol(context.session)?.isInterface != true || + !it.isCompiledToJvmDefaultWithProperMode(jvmDefaultMode) || + it.modality == Modality.ABSTRACT + } + ) { + continue + } + + return false + } + } + + return true + } + + private fun checkNonJvmDefaultOverridesJavaDefault( + defaultAnnotation: FirAnnotationCall?, + jvmDefaultMode: JvmDefaultMode, + declaration: FirDeclaration, + containingDeclaration: FirClassLikeDeclaration?, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + if (defaultAnnotation == null && + !jvmDefaultMode.forAllMethodsWithBody && + containingDeclaration is FirClass && + containingDeclaration.isInterface + ) { + val member = declaration as? FirSimpleFunction ?: return + if (declaration is FirPropertyAccessor) return + + val unsubstitutedScope = containingDeclaration.unsubstitutedScope(context) + unsubstitutedScope.processFunctionsByName(member.name) {} + val overriddenFunctions = unsubstitutedScope.getDirectOverriddenFunctions(member.symbol) + + if (overriddenFunctions.any { it.getAnnotationByFqName(JVM_DEFAULT_FQ_NAME) != null }) { + reporter.reportOn(declaration.source, FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, context) + } else if (jvmDefaultMode.isEnabled) { + for (overriddenFunction in overriddenFunctions) { + val overriddenDeclarations = overriddenFunction.getOverriddenDeclarations() + for (overriddenDeclaration in overriddenDeclarations) { + val containingClass = overriddenDeclaration.containingClass()?.toSymbol(context.session) + if (containingClass?.origin is FirDeclarationOrigin.Java && + overriddenDeclaration.modality != Modality.ABSTRACT + ) { + reporter.reportOn(declaration.source, FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, context) + return + } + } + } + } + } + } + + fun FirCallableSymbol<*>.getOverriddenDeclarations(): List> { + val result = mutableListOf>() + + if (this is FirIntersectionCallableSymbol) { + result.addAll(this.intersections) + } else { + result.add(this) + } + + return result + } + + fun FirCallableSymbol<*>.isCompiledToJvmDefaultWithProperMode(jvmDefaultMode: JvmDefaultMode): Boolean { + // TODO: Fix support for all cases + return isCompiledToJvmDefault(jvmDefaultMode) + } + + fun FirCallableSymbol<*>.isCompiledToJvmDefault(): Boolean { + // TODO: Fix support for all cases + if (getAnnotationByFqName(JVM_DEFAULT_FQ_NAME) != null) return true + return false + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirInterfaceDefaultMethodCallChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirInterfaceDefaultMethodCallChecker.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt index d4e55ccd272..94a3e0aa50a 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.analysis.jvm.diagnostics +import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING @@ -18,6 +19,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.ILLEGAL_JV import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INAPPLICABLE_JVM_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.INNER_JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_TYPE_MISMATCH +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_IN_DECLARATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_THROUGH_INHERITANCE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_CANNOT_BE_EMPTY import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_MUST_BE_VALID_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_NOT_SUPPORTED_IN_FILES_WITH_CLASSES @@ -33,6 +39,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.LOCAL_JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_DATA_CLASS_JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_FINAL_JVM_RECORD +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_ABSTRACT import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_INTERFACE @@ -46,6 +53,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_ABSTRACT import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VOLATILE_ON_DELEGATE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VOLATILE_ON_VALUE @@ -126,6 +134,27 @@ object FirJvmDefaultErrorMessages { map.put(INAPPLICABLE_JVM_NAME, "'@JvmName' annotation is not applicable to this declaration") map.put(ILLEGAL_JVM_NAME, "Illegal JVM name") + + map.put(JVM_DEFAULT_NOT_IN_INTERFACE, "'@JvmDefault' is only supported on interface members") + map.put( + JVM_DEFAULT_IN_JVM6_TARGET, + "''@{0}'' is only supported since JVM target 1.8. Recompile with ''-jvm-target 1.8''", + STRING + ) + map.put(JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, "'@JvmDefault' is required for an override of a '@JvmDefault' member") + map.put(JVM_DEFAULT_IN_DECLARATION, "Usage of ''@{0}'' is only allowed with -Xjvm-default option", STRING) + map.put( + JVM_DEFAULT_THROUGH_INHERITANCE, + "Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option" + ) + map.put( + USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL, + "Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option" + ) + map.put( + NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, + "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault or enable `-Xjvm-default=all|all-compatibility`" + ) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 8d57c405335..113b42d89d9 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -27,7 +27,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirExposedVisibilityDeclarationChecker, FirCyclicTypeBoundsChecker, FirExpectActualDeclarationChecker, - FirInvalidAndDangerousCharactersChecker + FirInvalidAndDangerousCharactersChecker, ) override val functionCheckers: Set diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 3db90bfe99c..0da1fc958dc 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResolver +import org.jetbrains.kotlin.fir.java.FirJvmDefaultModeComponent import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider @@ -71,6 +72,10 @@ fun FirSession.registerCliCompilerOnlyComponents() { fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolver) { val jsr305State = languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState) register(FirAnnotationTypeQualifierResolver::class, FirAnnotationTypeQualifierResolver(this, jsr305State, javaModuleResolver)) + register( + FirJvmDefaultModeComponent::class, + FirJvmDefaultModeComponent(languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)) + ) } // -------------------------- Resolve components -------------------------- diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmDefaultModeContainer.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmDefaultModeContainer.kt new file mode 100644 index 00000000000..5975a3010ac --- /dev/null +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JvmDefaultModeContainer.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.java + +import org.jetbrains.kotlin.config.JvmDefaultMode +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent + +class FirJvmDefaultModeComponent(val jvmDefaultMode: JvmDefaultMode) : FirSessionComponent + +private val FirSession.jvmDefaultModeComponent: FirJvmDefaultModeComponent by FirSession.sessionComponentAccessor() + +val FirSession.jvmDefaultModeState: JvmDefaultMode + get() = jvmDefaultModeComponent.jvmDefaultMode diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt index ab8af3c86df..2a89c886259 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt @@ -19,7 +19,7 @@ abstract class AbstractFirUseSiteMemberScope( ) : AbstractFirOverrideScope(session, overrideChecker) { private val functions = hashMapOf>() - protected val directOverriddenFunctions = hashMapOf>() + val directOverriddenFunctions = hashMapOf>() protected val directOverriddenProperties = hashMapOf>() private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.fir.kt deleted file mode 100644 index 885c9417f61..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.fir.kt +++ /dev/null @@ -1,60 +0,0 @@ -// !JVM_TARGET: 1.8 -// !JVM_DEFAULT_MODE: enable - -interface A { - @JvmDefault - fun test(p: T) { - } -} - -interface ANonDefault { - fun test(p: String) {} -} - -interface B : A { - - override fun test(p: T) - {} -} - -interface C : A, ANonDefault { - - override fun test(p: T) - {} - - override fun test(p: String) { - } -} - -interface C1 : C { - override fun test(p: String) { - - } -} - -interface C2 : C, ANonDefault { - override fun test(p: String) { - - } -} - -interface D : ANonDefault, A { - - override fun test(p: T) - {} - - override fun test(p: String) { - } -} - -interface D1 : D { - override fun test(p: String) { - - } -} - -interface D2 : ANonDefault, D { - override fun test(p: String) { - - } -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt index df3ea58ec10..5e66b511a5f 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.8 // !JVM_DEFAULT_MODE: enable diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt deleted file mode 100644 index 964005615d4..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.fir.kt +++ /dev/null @@ -1,72 +0,0 @@ -// !JVM_DEFAULT_MODE: enable -// !JVM_TARGET: 1.8 - -// FILE: JavaInterface.java -public interface JavaInterface { - default void test() {} - - default void testForNonDefault() {} - - void testAbstract(); -} - -// FILE: 1.kt - -interface KotlinInterface : JavaInterface { - @JvmDefault - override fun test() {} - - override fun testForNonDefault() {} - - override fun testAbstract() {} -} - -interface KotlinInterface2 : JavaInterface, KotlinInterface { - @JvmDefault - override fun test() {} - - override fun testForNonDefault() {} - - override fun testAbstract() {} -} - - -interface KotlinInterfaceForIndirect : JavaInterface { - -} - -interface KotlinInterfaceIndirectInheritance : KotlinInterfaceForIndirect { - - @JvmDefault - override fun test() {} - - override fun testForNonDefault() {} - - override fun testAbstract() {} -} - -open class KotlinClass : JavaInterface { - override fun test() {} - - override fun testForNonDefault() {} - - override fun testAbstract() {} -} - -interface KotlinInterfaceX { - - fun test() {} - - fun testForNonDefault() {} - - fun testAbstract() {} -} - -interface KotlinInterfaceManySuper: JavaInterface, KotlinInterfaceX { - @JvmDefault - override fun test() {} - - override fun testForNonDefault() {} - - override fun testAbstract() {} -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt index 9a87a0a26a0..542afa1506d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_DEFAULT_MODE: enable // !JVM_TARGET: 1.8 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.fir.kt index 5b887d1b909..6dfd972f415 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.fir.kt @@ -1,18 +1,17 @@ // !JVM_TARGET: 1.8 interface A { - @JvmDefault + @JvmDefault fun test() { } } -interface B : A { - +interface B : A { } -open class Foo : B -open class Foo2 : B, A +open class Foo : B +open class Foo2 : B, A open class FooNoError : B { override fun test() { @@ -23,12 +22,12 @@ open class Foo2NoError : B, A { } } -class Bar : Foo() -class Bar2 : Foo(), A -class Bar3 : Foo(), B +class Bar : Foo() +class Bar2 : Foo(), A +class Bar3 : Foo(), B open class BarWithJvmDefault : B { - @JvmDefault + @JvmDefault override fun test() { } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt index 3139cf76563..87241b038c7 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt @@ -7,7 +7,6 @@ interface A { } interface B : A { - } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.fir.kt deleted file mode 100644 index 59ca46ef803..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.fir.kt +++ /dev/null @@ -1,7 +0,0 @@ -// !JVM_TARGET: 1.6 - -@JvmDefaultWithoutCompatibility -interface A {} - -@JvmDefaultWithoutCompatibility -class B : A {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.kt index 9cc2d727324..ddeb1611c04 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target6.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.6 @JvmDefaultWithoutCompatibility diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.fir.kt deleted file mode 100644 index 634fd6615e8..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -// !JVM_TARGET: 1.8 - -@JvmDefaultWithoutCompatibility -interface A { - fun test(p: T) {} -} - -@JvmDefaultWithoutCompatibility -class B : A {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.kt index 86bf86fd3bc..e43346e7a59 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility/target8Disabled.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.8 @JvmDefaultWithoutCompatibility diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.fir.kt index 404ef6a0d79..dabda030cf9 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.fir.kt @@ -2,27 +2,27 @@ interface B { - @JvmDefault + @JvmDefault fun test() {} - @JvmDefault + @JvmDefault abstract fun test2(s: String = "") - @JvmDefault + @JvmDefault abstract fun test3() - @JvmDefault + @JvmDefault abstract val prop: String - @JvmDefault + @JvmDefault abstract val prop2: String - @JvmDefault + @JvmDefault val prop3: String get() = "" - @JvmDefault + @JvmDefault var prop4: String get() = "" set(value) {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.fir.kt deleted file mode 100644 index 06ac43b1967..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// !JVM_TARGET: 1.8 - -abstract class A { - - @JvmDefault - fun test() {} - - @JvmDefault - abstract fun test2(s: String = "") - - @JvmDefault - abstract fun test3() -} - -object B { - - @JvmDefault - fun test() {} - - @JvmDefault - fun test2(s: String = "") {} -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt index b1372742eef..22451a9a42a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.8 abstract class A { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.fir.kt deleted file mode 100644 index 58c8254552a..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.fir.kt +++ /dev/null @@ -1,31 +0,0 @@ -// !JVM_TARGET: 1.8 -// !JVM_DEFAULT_MODE: enable - -interface A { - @JvmDefault - fun test() {} -} - -interface Abstract : A { - override fun test() -} - -interface ANonDefault { - fun test() {} -} - -interface B: A { - override fun test() {} -} - -interface C: ANonDefault, A { - override fun test() {} -} - -interface D: A, ANonDefault { - override fun test() {} -} - -class Foo : A { - override fun test() {} -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt index 9ac34d7ac9b..60624676191 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.8 // !JVM_DEFAULT_MODE: enable diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCall.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCall.fir.kt index cccd5e782bb..7886e3126e7 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCall.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCall.fir.kt @@ -1,18 +1,18 @@ // !JVM_TARGET: 1.8 // FILE: 1.kt interface A { - @JvmDefault + @JvmDefault fun test() { } } // FILE: 2.kt -interface B : A { +interface B : A { } interface C : B { - @JvmDefault + @JvmDefault override fun test() { super.test() } @@ -23,7 +23,7 @@ open class Foo : B { super.test() } } -open class Foo2 : B +open class Foo2 : B open class Bar : Foo2() { override fun test() { @@ -37,7 +37,7 @@ open class Bar2 : Bar() { } } -class ManySupers: Foo2(), B { +class ManySupers: Foo2(), B { fun foo() { super.test() super<B>.test() @@ -45,7 +45,7 @@ class ManySupers: Foo2(), B { } } -class ManySupers2: Foo2(), C { +class ManySupers2: Foo2(), C { fun foo() { super.test() super.test() @@ -53,7 +53,7 @@ class ManySupers2: Foo2(), C { } } -class ManySupers3: Bar2(), C { +class ManySupers3: Bar2(), C { fun foo() { super.test() super.test() diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity.fir.kt index dcae633bc07..6f2d7d8b24e 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity.fir.kt @@ -1,6 +1,6 @@ // !JVM_TARGET: 1.8 interface A { - @JvmDefault + @JvmDefault fun test() { } } @@ -10,13 +10,13 @@ interface B{ } } -interface AB: A, B +interface AB: A, B -interface BA: B, A +interface BA: B, A interface C : A, B { - @JvmDefault + @JvmDefault override fun test() { super.test() super.test() @@ -24,9 +24,9 @@ interface C : A, B { } interface D : B, A { - @JvmDefault + @JvmDefault override fun test() { super.test() super.test() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity2.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity2.fir.kt index 9dc6fde6b19..115d09ff450 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity2.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity2.fir.kt @@ -1,6 +1,6 @@ // !JVM_TARGET: 1.8 interface A { - @JvmDefault + @JvmDefault fun test() } @@ -29,4 +29,4 @@ class D : B, A { fun foo() { super.test() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity3.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity3.fir.kt index d424cd6b7e3..12f52930bc2 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity3.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/superCallAmbiguity3.fir.kt @@ -1,6 +1,6 @@ // !JVM_TARGET: 1.8 interface A { - @JvmDefault + @JvmDefault fun test() { } @@ -9,8 +9,8 @@ interface A { interface B{ fun test() } -interface AB : A, B -interface BA : B, A +interface AB : A, B +interface BA : B, A class C : A, B { override fun test() { @@ -24,8 +24,8 @@ class D : B, A { } } -class E: B, A { +class E: B, A { fun foo() { super.test() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.fir.kt deleted file mode 100644 index 9e879657d7e..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -// !JVM_TARGET: 1.6 - -interface B { - - @JvmDefault - fun test() {} - - @JvmDefault - abstract fun test2(s: String = "") - - @JvmDefault - abstract fun test3() - - - @JvmDefault - abstract val prop: String - - @JvmDefault - abstract val prop2: String - - @JvmDefault - val prop3: String - get() = "" - - @JvmDefault - var prop4: String - get() = "" - set(value) {} -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt index 348e891b8eb..0d5a6dd8ab3 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !JVM_TARGET: 1.6 interface B { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index bb879acd875..64006ef53b5 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3712,4 +3712,48 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE) { firDiagnostic -> + JvmDefaultNotInInterfaceImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET) { firDiagnostic -> + JvmDefaultInJvm6TargetImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE) { firDiagnostic -> + JvmDefaultRequiredForOverrideImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.JVM_DEFAULT_IN_DECLARATION) { firDiagnostic -> + JvmDefaultInDeclarationImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.JVM_DEFAULT_THROUGH_INHERITANCE) { firDiagnostic -> + JvmDefaultThroughInheritanceImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL) { firDiagnostic -> + UsageOfJvmDefaultThroughSuperCallImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT) { firDiagnostic -> + NonJvmDefaultOverridesJavaDefaultImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 99237e86e6d..0bf7f17b687 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2582,4 +2582,34 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = IllegalJavaLangRecordSupertype::class } + abstract class JvmDefaultNotInInterface : KtFirDiagnostic() { + override val diagnosticClass get() = JvmDefaultNotInInterface::class + } + + abstract class JvmDefaultInJvm6Target : KtFirDiagnostic() { + override val diagnosticClass get() = JvmDefaultInJvm6Target::class + abstract val annotation: String + } + + abstract class JvmDefaultRequiredForOverride : KtFirDiagnostic() { + override val diagnosticClass get() = JvmDefaultRequiredForOverride::class + } + + abstract class JvmDefaultInDeclaration : KtFirDiagnostic() { + override val diagnosticClass get() = JvmDefaultInDeclaration::class + abstract val annotation: String + } + + abstract class JvmDefaultThroughInheritance : KtFirDiagnostic() { + override val diagnosticClass get() = JvmDefaultThroughInheritance::class + } + + abstract class UsageOfJvmDefaultThroughSuperCall : KtFirDiagnostic() { + override val diagnosticClass get() = UsageOfJvmDefaultThroughSuperCall::class + } + + abstract class NonJvmDefaultOverridesJavaDefault : KtFirDiagnostic() { + override val diagnosticClass get() = NonJvmDefaultOverridesJavaDefault::class + } + } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 19091d41a85..3fc1cacf285 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4194,3 +4194,54 @@ internal class IllegalJavaLangRecordSupertypeImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class JvmDefaultNotInInterfaceImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmDefaultNotInInterface(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class JvmDefaultInJvm6TargetImpl( + override val annotation: String, + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmDefaultInJvm6Target(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class JvmDefaultRequiredForOverrideImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmDefaultRequiredForOverride(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class JvmDefaultInDeclarationImpl( + override val annotation: String, + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmDefaultInDeclaration(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class JvmDefaultThroughInheritanceImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmDefaultThroughInheritance(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class UsageOfJvmDefaultThroughSuperCallImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.UsageOfJvmDefaultThroughSuperCall(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class NonJvmDefaultOverridesJavaDefaultImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.NonJvmDefaultOverridesJavaDefault(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} +