From 23e8adb7933f111776caf4ca3a0579fad565311e Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 29 Mar 2018 16:41:47 +0200 Subject: [PATCH] Add custom diagnostic checker for @JvmDefault annotation --- .../arguments/K2JVMCompilerArguments.kt | 4 ++ .../kotlin/config/JVMConfigurationKeys.java | 3 + .../resolve/jvm/checkers/JvmDefaultChecker.kt | 42 ++++++++++++-- .../diagnostics/DefaultErrorMessagesJvm.java | 3 + .../resolve/jvm/diagnostics/ErrorsJvm.java | 3 + .../annotations/jvmDefault/generic.kt | 1 + .../jvmDefault/jvmDefaultInInheritance.kt | 19 +++++++ .../jvmDefault/jvmDefaultInInheritance.txt | 55 +++++++++++++++++++ .../jvmDefault/noJvmDefaultFlag.kt | 30 ++++++++++ .../jvmDefault/noJvmDefaultFlag.txt | 14 +++++ .../jvmDefault/propertyAccessor.kt | 1 + .../annotations/jvmDefault/simpleOverride.kt | 1 + .../jvmDefault/simpleOverrideWithFeature.kt | 28 ---------- .../jvmDefault/simpleOverrideWithFeature.txt | 2 +- .../jvmDefault/simplePropertyOverride.kt | 1 + .../annotations/jvmDefault/target6.kt | 1 - .../annotations/jvmDefault/target8.kt | 1 + .../CompilerTestLanguageVersionSettings.kt | 4 +- .../DiagnosticsTestWithStdLibGenerated.java | 18 ++++-- ...ticsTestWithStdLibUsingJavacGenerated.java | 18 ++++-- .../jetbrains/kotlin/config/AnalysisFlag.kt | 3 + 21 files changed, 205 insertions(+), 47 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.txt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index b0907025570..5b9043a149c 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -228,6 +228,9 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { ) var noExceptionOnExplicitEqualsForBoxedNull by FreezableVar(false) + @Argument(value = "-Xenable-jvm-default", description = "Allow to use '@JvmDefault' for JVM default method support") + var enableJvmDefault: Boolean by FreezableVar(false) + // Paths to output directories for friend modules. var friendPaths: Array? by FreezableVar(null) @@ -237,6 +240,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { jsr305, supportCompatqualCheckerFrameworkAnnotations ) + result[AnalysisFlag.enableJvmDefault] = enableJvmDefault return result } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index 7d6f052e6f8..814f139467c 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -129,4 +129,7 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey> ADDITIONAL_JAVA_MODULES = CompilerConfigurationKey.create("additional Java modules"); + + public static final CompilerConfigurationKey ENABLE_JVM_DEFAULT = + CompilerConfigurationKey.create("Allow to use '@JvmDefault'"); } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt index ebbcbfc2b1e..6480ca39cd8 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt @@ -5,26 +5,28 @@ package org.jetbrains.kotlin.resolve.jvm.checkers +import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.JvmTarget -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils 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.getSuperInterfaces +import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { companion object { val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault") - } + override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { + val enableJvmDefault = context.languageVersionSettings.getFlag(AnalysisFlag.enableJvmDefault) descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)?.let { annotationDescriptor -> val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration @@ -32,10 +34,23 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { context.trace.report(ErrorsJvm.JVM_DEFAULT_NOT_IN_INTERFACE.on(reportOn)) } else if (jvmTarget == JvmTarget.JVM_1_6) { context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn)) + } else if (!enableJvmDefault) { + context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_DECLARATION.on(declaration)) } return@check } + if (descriptor is ClassDescriptor) { + val hasDeclaredJvmDefaults = + descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance().any { + it.kind.isReal && it.hasJvmDefaultAnnotation() + } + if (!hasDeclaredJvmDefaults && !checkJvmDefaultThroughInheritance(descriptor, enableJvmDefault)) { + context.trace.report(ErrorsJvm.JVM_DEFAULT_THROUGH_INHERITANCE.on(declaration)) + } + } + + if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return if (descriptor is PropertyAccessorDescriptor) return @@ -44,4 +59,23 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration)) } } + + private fun checkJvmDefaultThroughInheritance(descriptor: DeclarationDescriptor, enableJvmDefault: Boolean): Boolean { + if (enableJvmDefault) return true + + if (descriptor !is ClassDescriptor) return true + + if (!DescriptorUtils.isInterface(descriptor) && + !DescriptorUtils.isAnnotationClass(descriptor) + ) { + return descriptor.getSuperInterfaces().all { + checkJvmDefaultThroughInheritance(it, enableJvmDefault) + } + } + + + return descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance().all { + !it.hasJvmDefaultAnnotation() + } + } } \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java index 49be6635d1f..cfc8b9528f0 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java @@ -137,6 +137,9 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(JVM_DEFAULT_NOT_IN_INTERFACE,"'@JvmDefault' is only supported on interface members"); MAP.put(JVM_DEFAULT_IN_JVM6_TARGET,"'@JvmDefault' is only supported since JVM target 1.8. Recompile with '-jvm-target 1.8'"); 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 '@JvmDefault' is only allowed if the flag -Xenable-jvm-default is enabled"); + MAP.put(JVM_DEFAULT_THROUGH_INHERITANCE, "Inheritance from an interface with '@JvmDefault' members is only allowed if the flag -Xenable-jvm-default is enabled"); + MAP.put(USAGE_OF_JVM_THROUGH_SUPER_CALL, "Super calls of '@JvmDefault' members are only allowed if the flag -Xenable-jvm-default is enabled"); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index 2ac2037428b..9147ae9da7d 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -117,6 +117,9 @@ public interface ErrorsJvm { DiagnosticFactory0 JVM_DEFAULT_NOT_IN_INTERFACE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 JVM_DEFAULT_IN_JVM6_TARGET = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 JVM_DEFAULT_REQUIRED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 JVM_DEFAULT_IN_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 JVM_DEFAULT_THROUGH_INHERITANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 USAGE_OF_JVM_THROUGH_SUPER_CALL = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); enum NullabilityInformationSource { KOTLIN { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt index b70931e6170..31a89896e7b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/generic.kt @@ -1,6 +1,7 @@ // !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE // !API_VERSION: 1.3 // !JVM_TARGET: 1.8 +// !ENABLE_JVM_DEFAULT interface A { @JvmDefault fun test(p: T) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt new file mode 100644 index 00000000000..d9fddee354f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt @@ -0,0 +1,19 @@ +// !API_VERSION: 1.3 +// !JVM_TARGET: 1.8 +interface A { + @JvmDefault + fun test() { + } +} + +interface B : A { + +} + + +open class Foo : B +open class Foo2 : B, A + +class Bar : Foo() +class Bar2 : Foo(), A +class Bar3 : Foo(), B \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.txt new file mode 100644 index 00000000000..303acf5ac9c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.txt @@ -0,0 +1,55 @@ +package + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*1*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Bar : Foo { + public constructor Bar() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*1*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Bar2 : Foo, A { + public constructor Bar2() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*2*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Bar3 : Foo, B { + public constructor Bar3() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*2*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class Foo : B { + public constructor Foo() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*1*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class Foo2 : B, A { + public constructor Foo2() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open override /*2*/ /*fake_override*/ fun test(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt new file mode 100644 index 00000000000..ab60070b4b6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt @@ -0,0 +1,30 @@ +// !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE +// !API_VERSION: 1.3 +// !JVM_TARGET: 1.8 +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) {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.txt new file mode 100644 index 00000000000..e804d227eb0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.txt @@ -0,0 +1,14 @@ +package + +public interface B { + @kotlin.jvm.JvmDefault public abstract val prop: kotlin.String + @kotlin.jvm.JvmDefault public abstract val prop2: kotlin.String + @kotlin.jvm.JvmDefault public open val prop3: kotlin.String + @kotlin.jvm.JvmDefault public open var prop4: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.jvm.JvmDefault public open fun test(): kotlin.Unit + @kotlin.jvm.JvmDefault public abstract fun test2(/*0*/ s: kotlin.String = ...): kotlin.Unit + @kotlin.jvm.JvmDefault public abstract fun test3(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/propertyAccessor.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/propertyAccessor.kt index 82c1cc7acdc..fb61f4d1196 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/propertyAccessor.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/propertyAccessor.kt @@ -1,6 +1,7 @@ // !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE // !API_VERSION: 1.3 // !JVM_TARGET: 1.8 +// !ENABLE_JVM_DEFAULT interface B { @JvmDefault diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt index cf31faa9d37..b2c9af5c71a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverride.kt @@ -1,6 +1,7 @@ // !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE // !API_VERSION: 1.3 // !JVM_TARGET: 1.8 +// !ENABLE_JVM_DEFAULT interface A { @JvmDefault fun test() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt deleted file mode 100644 index 05ca4eca7f2..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt +++ /dev/null @@ -1,28 +0,0 @@ -// !API_VERSION: 1.3 -// !JVM_TARGET: 1.8 -@JvmDefaultFeature -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() {} -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.txt index a897d2a323d..b112aafa747 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.txt @@ -1,6 +1,6 @@ package -@kotlin.jvm.JvmDefaultFeature public interface A { +public interface A { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int @kotlin.jvm.JvmDefault public open fun test(): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt index 52f3337baf6..0293ba09643 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt @@ -1,6 +1,7 @@ // !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE // !API_VERSION: 1.3 // !JVM_TARGET: 1.8 +// !ENABLE_JVM_DEFAULT interface A { @JvmDefault val test: String diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt index 4e5e4a2eb12..7de60063972 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target6.kt @@ -13,7 +13,6 @@ interface B { abstract fun test3() - @JvmDefault abstract val prop: String diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt index e6eadfeffe3..c16df7d6253 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt @@ -1,6 +1,7 @@ // !DIAGNOSTICS: -EXPERIMENTAL_API_USAGE // !API_VERSION: 1.3 // !JVM_TARGET: 1.8 +// !ENABLE_JVM_DEFAULT interface B { @JvmDefault diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt index fefffd3e1be..5f481bf3383 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt @@ -28,6 +28,7 @@ const val API_VERSION_DIRECTIVE = "API_VERSION" const val EXPERIMENTAL_DIRECTIVE = "EXPERIMENTAL" const val USE_EXPERIMENTAL_DIRECTIVE = "USE_EXPERIMENTAL" +const val ENABLE_JVM_DEFAULT = "ENABLE_JVM_DEFAULT" data class CompilerTestLanguageVersionSettings( private val initialLanguageFeatures: Map, @@ -57,6 +58,7 @@ fun parseLanguageVersionSettings(directiveMap: Map): LanguageVer val languageFeaturesString = directiveMap[LANGUAGE_DIRECTIVE] val experimental = directiveMap[EXPERIMENTAL_DIRECTIVE]?.split(' ')?.let { AnalysisFlag.experimental to it } val useExperimental = directiveMap[USE_EXPERIMENTAL_DIRECTIVE]?.split(' ')?.let { AnalysisFlag.useExperimental to it } + val enableJvmDefault = AnalysisFlag.enableJvmDefault to directiveMap.containsKey(ENABLE_JVM_DEFAULT) if (apiVersionString == null && languageFeaturesString == null && experimental == null && useExperimental == null) return null @@ -69,7 +71,7 @@ fun parseLanguageVersionSettings(directiveMap: Map): LanguageVer return CompilerTestLanguageVersionSettings( languageFeatures, apiVersion, languageVersion, - mapOf(*listOfNotNull(experimental, useExperimental).toTypedArray()) + mapOf(*listOfNotNull(experimental, useExperimental, enableJvmDefault).toTypedArray()) ) } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 22ec11e035b..934081d5015 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -482,6 +482,18 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW doTest(fileName); } + @TestMetadata("jvmDefaultInInheritance.kt") + public void testJvmDefaultInInheritance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt"); + doTest(fileName); + } + + @TestMetadata("noJvmDefaultFlag.kt") + public void testNoJvmDefaultFlag() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt"); + doTest(fileName); + } + @TestMetadata("notInterface.kt") public void testNotInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt"); @@ -500,12 +512,6 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW doTest(fileName); } - @TestMetadata("simpleOverrideWithFeature.kt") - public void testSimpleOverrideWithFeature() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt"); - doTest(fileName); - } - @TestMetadata("simplePropertyOverride.kt") public void testSimplePropertyOverride() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 527a01bbf78..ec4a50152e4 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -482,6 +482,18 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno doTest(fileName); } + @TestMetadata("jvmDefaultInInheritance.kt") + public void testJvmDefaultInInheritance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt"); + doTest(fileName); + } + + @TestMetadata("noJvmDefaultFlag.kt") + public void testNoJvmDefaultFlag() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/noJvmDefaultFlag.kt"); + doTest(fileName); + } + @TestMetadata("notInterface.kt") public void testNotInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/notInterface.kt"); @@ -500,12 +512,6 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno doTest(fileName); } - @TestMetadata("simpleOverrideWithFeature.kt") - public void testSimpleOverrideWithFeature() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simpleOverrideWithFeature.kt"); - doTest(fileName); - } - @TestMetadata("simplePropertyOverride.kt") public void testSimplePropertyOverride() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/simplePropertyOverride.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt b/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt index c9719968b26..8b96aebcd3f 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/AnalysisFlag.kt @@ -69,5 +69,8 @@ class AnalysisFlag internal constructor( @JvmStatic val explicitApiVersion by Flag.Boolean + + @JvmStatic + val enableJvmDefault by Flag.Boolean } }