Remove '-Xjvm-default-allow-non-default-inheritance' flag. Enable such inheritance by default

#KT-47000 Fixed
This commit is contained in:
Mikhael Bogdanov
2021-12-02 10:17:24 +01:00
parent 7440c726d0
commit c0ffbe03c6
16 changed files with 14 additions and 59 deletions
@@ -333,9 +333,6 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
) )
var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description) var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description)
@Argument(value = "-Xjvm-default-allow-non-default-inheritance", description = "Allow inheritance from 'all*' modes for 'disable' one")
var jvmDefaultAllowDisableAgainstAll: Boolean by FreezableVar(false)
@Argument( @Argument(
value = "-Xdefault-script-extension", value = "-Xdefault-script-extension",
valueDescription = "<script filename extension>", valueDescription = "<script filename extension>",
@@ -530,7 +527,6 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
result[AnalysisFlags.allowUnstableDependencies] = allowUnstableDependencies || useFir result[AnalysisFlags.allowUnstableDependencies] = allowUnstableDependencies || useFir
result[JvmAnalysisFlags.disableUltraLightClasses] = disableUltraLightClasses result[JvmAnalysisFlags.disableUltraLightClasses] = disableUltraLightClasses
result[JvmAnalysisFlags.useIR] = !useOldBackend result[JvmAnalysisFlags.useIR] = !useOldBackend
result[JvmAnalysisFlags.jvmDefaultAllowNonDefaultInheritance] = jvmDefaultAllowDisableAgainstAll
return result return result
} }
@@ -18,9 +18,6 @@ object JvmAnalysisFlags {
@JvmStatic @JvmStatic
val jvmDefaultMode by Delegates.JvmDefaultModeDisabledByDefault val jvmDefaultMode by Delegates.JvmDefaultModeDisabledByDefault
@JvmStatic
val jvmDefaultAllowNonDefaultInheritance by AnalysisFlag.Delegates.Boolean
@JvmStatic @JvmStatic
val inheritMultifileParts by AnalysisFlag.Delegates.Boolean val inheritMultifileParts by AnalysisFlag.Delegates.Boolean
@@ -29,13 +29,12 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation
class JvmDefaultChecker(private val jvmTarget: JvmTarget, private val project: Project) : DeclarationChecker { class JvmDefaultChecker(private val jvmTarget: JvmTarget, project: Project) : DeclarationChecker {
private val ideService = LanguageVersionSettingsProvider.getInstance(project) private val ideService = LanguageVersionSettingsProvider.getInstance(project)
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
val jvmDefaultMode = context.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode) val jvmDefaultMode = context.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
val allowNonDefaultInheritance = context.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultAllowNonDefaultInheritance)
val jvmDefaultAnnotation = descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME) val jvmDefaultAnnotation = descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)
jvmDefaultAnnotation?.let { annotationDescriptor -> jvmDefaultAnnotation?.let { annotationDescriptor ->
@@ -63,19 +62,6 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, private val project: P
} }
} }
if (!allowNonDefaultInheritance) {
if (descriptor is ClassDescriptor) {
val hasDeclaredJvmDefaults =
descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>().any {
it.kind.isReal && it.isCompiledToJvmDefault(jvmDefaultMode)
}
if (!hasDeclaredJvmDefaults && !checkJvmDefaultsInHierarchy(descriptor, jvmDefaultMode)) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_THROUGH_INHERITANCE.on(declaration))
}
}
}
if (jvmDefaultAnnotation == null && !jvmDefaultMode.forAllMethodsWithBody && isInterface(descriptor.containingDeclaration)) { if (jvmDefaultAnnotation == null && !jvmDefaultMode.forAllMethodsWithBody && isInterface(descriptor.containingDeclaration)) {
val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return
if (descriptor is PropertyAccessorDescriptor) return if (descriptor is PropertyAccessorDescriptor) return
@@ -219,19 +205,6 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, private val project: P
return classMembers.firstNotNullOfOrNull { findPossibleClashMember(it, jvmDefaultMode) } return classMembers.firstNotNullOfOrNull { findPossibleClashMember(it, jvmDefaultMode) }
} }
private fun checkJvmDefaultsInHierarchy(descriptor: DeclarationDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean {
if (jvmDefaultMode.isEnabled) return true
if (descriptor !is ClassDescriptor) return true
return descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>()
.all { memberDescriptor ->
memberDescriptor.kind.isReal || OverridingUtil.filterOutOverridden(memberDescriptor.overriddenDescriptors.toSet()).all {
!isInterface(it.containingDeclaration) || !it.isCompiledToJvmDefaultWithProperMode(jvmDefaultMode) || it.modality == Modality.ABSTRACT
}
}
}
private fun CallableMemberDescriptor.isCompiledToJvmDefaultWithProperMode(compilationDefaultMode: JvmDefaultMode) = private fun CallableMemberDescriptor.isCompiledToJvmDefaultWithProperMode(compilationDefaultMode: JvmDefaultMode) =
isCompiledToJvmDefaultWithProperMode(ideService, compilationDefaultMode) isCompiledToJvmDefaultWithProperMode(ideService, compilationDefaultMode)
@@ -166,7 +166,6 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
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_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_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_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(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`"); 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`");
MAP.put(EXPLICIT_METADATA_IS_DISALLOWED, "Explicit @Metadata is disallowed"); MAP.put(EXPLICIT_METADATA_IS_DISALLOWED, "Explicit @Metadata is disallowed");
@@ -124,7 +124,6 @@ public interface ErrorsJvm {
DiagnosticFactory1<PsiElement, String> JVM_DEFAULT_IN_JVM6_TARGET = DiagnosticFactory1.create(ERROR); DiagnosticFactory1<PsiElement, String> JVM_DEFAULT_IN_JVM6_TARGET = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtDeclaration> JVM_DEFAULT_REQUIRED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0<KtDeclaration> JVM_DEFAULT_REQUIRED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory1<KtElement, String> JVM_DEFAULT_IN_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory1<KtElement, String> JVM_DEFAULT_IN_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtDeclaration> JVM_DEFAULT_THROUGH_INHERITANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<PsiElement> USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> LOCAL_JVM_RECORD = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> LOCAL_JVM_RECORD = DiagnosticFactory0.create(ERROR);
@@ -71,7 +71,6 @@ class LanguageVersionSettingsBuilder {
analysisFlag(AnalysisFlags.allowKotlinPackage, trueOrNull(LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE in directives)), analysisFlag(AnalysisFlags.allowKotlinPackage, trueOrNull(LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE in directives)),
analysisFlag(JvmAnalysisFlags.jvmDefaultMode, directives.singleOrZeroValue(LanguageSettingsDirectives.JVM_DEFAULT_MODE)), analysisFlag(JvmAnalysisFlags.jvmDefaultMode, directives.singleOrZeroValue(LanguageSettingsDirectives.JVM_DEFAULT_MODE)),
analysisFlag(JvmAnalysisFlags.jvmDefaultAllowNonDefaultInheritance, trueOrNull(LanguageSettingsDirectives.JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE in directives)),
analysisFlag(JvmAnalysisFlags.inheritMultifileParts, trueOrNull(LanguageSettingsDirectives.INHERIT_MULTIFILE_PARTS in directives)), analysisFlag(JvmAnalysisFlags.inheritMultifileParts, trueOrNull(LanguageSettingsDirectives.INHERIT_MULTIFILE_PARTS in directives)),
analysisFlag(JvmAnalysisFlags.sanitizeParentheses, trueOrNull(LanguageSettingsDirectives.SANITIZE_PARENTHESES in directives)), analysisFlag(JvmAnalysisFlags.sanitizeParentheses, trueOrNull(LanguageSettingsDirectives.SANITIZE_PARENTHESES in directives)),
analysisFlag(JvmAnalysisFlags.enableJvmPreview, trueOrNull(LanguageSettingsDirectives.ENABLE_JVM_PREVIEW in directives)), analysisFlag(JvmAnalysisFlags.enableJvmPreview, trueOrNull(LanguageSettingsDirectives.ENABLE_JVM_PREVIEW in directives)),
@@ -59,10 +59,6 @@ object LanguageSettingsDirectives : SimpleDirectivesContainer() {
additionalParser = JvmDefaultMode.Companion::fromStringOrNull additionalParser = JvmDefaultMode.Companion::fromStringOrNull
) )
val JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE by directive(
description = "Configures corresponding analysis flag (JvmAnalysisFlags.jvmDefaultAllowNonDefaultInheritance)",
)
val INHERIT_MULTIFILE_PARTS by directive( val INHERIT_MULTIFILE_PARTS by directive(
description = "Enables corresponding analysis flag (JvmAnalysisFlags.inheritMultifileParts)" description = "Enables corresponding analysis flag (JvmAnalysisFlags.inheritMultifileParts)"
) )
@@ -14,7 +14,6 @@ interface Foo {
// MODULE: main(lib) // MODULE: main(lib)
// !JVM_DEFAULT_MODE: disable // !JVM_DEFAULT_MODE: disable
// !JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE
// FILE: main.kt // FILE: main.kt
interface Derived : Foo { interface Derived : Foo {
@@ -14,7 +14,6 @@ interface Foo {
// MODULE: main(lib) // MODULE: main(lib)
// !JVM_DEFAULT_MODE: disable // !JVM_DEFAULT_MODE: disable
// !JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE
// FILE: main.kt // FILE: main.kt
interface Derived : Foo { interface Derived : Foo {
@@ -16,7 +16,6 @@ interface Foo2<T> {
// MODULE: main(lib) // MODULE: main(lib)
// !JVM_DEFAULT_MODE: disable // !JVM_DEFAULT_MODE: disable
// !JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE
// FILE: main.kt // FILE: main.kt
class DerivedClass : Foo<String> class DerivedClass : Foo<String>
@@ -14,7 +14,6 @@ interface Foo<T> {
// MODULE: main(lib) // MODULE: main(lib)
// !JVM_DEFAULT_MODE: disable // !JVM_DEFAULT_MODE: disable
// !JVM_DEFAULT_ALLOW_NON_DEFAULT_INHERITANCE
// FILE: main.kt // FILE: main.kt
interface DerivedInterface<T> : Foo<T> interface DerivedInterface<T> : Foo<T>
@@ -6,12 +6,12 @@ interface A {
} }
} }
interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>B<!> : A { interface B : A {
} }
open class <!JVM_DEFAULT_THROUGH_INHERITANCE!>Foo<!> : B open class Foo : B
open class <!JVM_DEFAULT_THROUGH_INHERITANCE!>Foo2<!> : B, A open class Foo2 : B, A
open class FooNoError : B { open class FooNoError : B {
override fun test() { override fun test() {
@@ -7,7 +7,7 @@ interface A {
} }
// FILE: 2.kt // FILE: 2.kt
interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>B<!> : A { interface B : A {
} }
@@ -23,7 +23,7 @@ open class Foo : B {
super.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>() super.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>()
} }
} }
open class <!JVM_DEFAULT_THROUGH_INHERITANCE!>Foo2<!> : B open class Foo2 : B
open class Bar : Foo2() { open class Bar : Foo2() {
override fun test() { override fun test() {
@@ -45,7 +45,7 @@ class ManySupers: Foo2(), B {
} }
} }
class <!JVM_DEFAULT_THROUGH_INHERITANCE!>ManySupers2<!>: Foo2(), C { class ManySupers2: Foo2(), C {
fun foo() { fun foo() {
super<Foo2>.test() super<Foo2>.test()
super<C>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>() super<C>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>()
@@ -53,7 +53,7 @@ class <!JVM_DEFAULT_THROUGH_INHERITANCE!>ManySupers2<!>: Foo2(), C {
} }
} }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class <!JVM_DEFAULT_THROUGH_INHERITANCE!>ManySupers3<!><!>: Bar2(), C { <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class ManySupers3<!>: Bar2(), C {
fun foo() { fun foo() {
super<Bar2>.test() super<Bar2>.test()
super<C>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>() super<C>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>()
@@ -10,9 +10,9 @@ interface B{
} }
} }
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>AB<!><!>: A, B <!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface AB<!>: A, B
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>BA<!><!>: B, A <!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface BA<!>: B, A
interface C : A, B { interface C : A, B {
@@ -9,8 +9,8 @@ interface A {
interface B{ interface B{
fun test() fun test()
} }
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>AB<!><!> : A, B <!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface AB<!> : A, B
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface <!JVM_DEFAULT_THROUGH_INHERITANCE!>BA<!><!> : B, A <!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>interface BA<!> : B, A
class C : A, B { class C : A, B {
override fun test() { override fun test() {
@@ -24,7 +24,7 @@ class D : B, A {
} }
} }
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class <!JVM_DEFAULT_THROUGH_INHERITANCE!>E<!><!>: B, A { <!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class E<!>: B, A {
fun foo() { fun foo() {
super<A>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>() super<A>.<!USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL!>test<!>()
} }
@@ -553,7 +553,7 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
"source.kt", "source.kt",
tmpdir, tmpdir,
listOf(library), listOf(library),
additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=disable", "-Xjvm-default-allow-non-default-inheritance") additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=disable")
) )
} }