JVM: produce a better error on @JvmStatic external in interface
Java does not permit `static native` methods in interfaces, so this never worked on any existing JRE. #KT-43696 Fixed
This commit is contained in:
+6
-3
@@ -90,7 +90,7 @@ class JvmStaticChecker(jvmTarget: JvmTarget, languageVersionSettings: LanguageVe
|
||||
supportJvmStaticInInterface &&
|
||||
descriptor is DeclarationDescriptorWithVisibility
|
||||
) {
|
||||
checkVisibility(descriptor, diagnosticHolder, declaration)
|
||||
checkForInterface(descriptor, diagnosticHolder, declaration)
|
||||
if (isLessJVM18) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_IN_INTERFACE_1_6.on(declaration))
|
||||
}
|
||||
@@ -116,15 +116,18 @@ class JvmStaticChecker(jvmTarget: JvmTarget, languageVersionSettings: LanguageVe
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkVisibility(
|
||||
private fun checkForInterface(
|
||||
descriptor: DeclarationDescriptorWithVisibility,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
declaration: KtDeclaration
|
||||
) {
|
||||
if (descriptor.visibility != DescriptorVisibilities.PUBLIC) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_ON_NON_PUBLIC_MEMBER.on(declaration))
|
||||
} else if (descriptor is MemberDescriptor && descriptor.isExternal) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE.on(declaration))
|
||||
} else if (descriptor is PropertyDescriptor) {
|
||||
descriptor.setter?.let { checkVisibility(it, diagnosticHolder, declaration) }
|
||||
descriptor.getter?.let { checkForInterface(it, diagnosticHolder, declaration) }
|
||||
descriptor.setter?.let { checkForInterface(it, diagnosticHolder, declaration) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(JVM_STATIC_ON_NON_PUBLIC_MEMBER, "Only public members in interface companion objects can be annotated with '@JvmStatic'");
|
||||
MAP.put(JVM_STATIC_IN_INTERFACE_1_6, "'@JvmStatic' annotation in interface supported only with JVM target 1.8 and above. Recompile with '-jvm-target 1.8'\"");
|
||||
MAP.put(JVM_STATIC_ON_CONST_OR_JVM_FIELD, "'@JvmStatic' annotation is useless for const or '@JvmField' properties");
|
||||
MAP.put(JVM_STATIC_ON_EXTERNAL_IN_INTERFACE, "'@JvmStatic' annotation cannot be used on 'external' members of interface companions");
|
||||
MAP.put(OVERRIDE_CANNOT_BE_STATIC, "Override member cannot be '@JvmStatic' in object");
|
||||
MAP.put(OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS, "'@JvmOverloads' annotation has no effect for methods without default arguments");
|
||||
MAP.put(OVERLOADS_ABSTRACT, "'@JvmOverloads' annotation cannot be used on abstract methods");
|
||||
|
||||
@@ -34,6 +34,7 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_ON_NON_PUBLIC_MEMBER = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_IN_INTERFACE_1_6 = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_ON_CONST_OR_JVM_FIELD = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_ON_EXTERNAL_IN_INTERFACE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_JVM_NAME = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtAnnotationEntry> ILLEGAL_JVM_NAME = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
Vendored
+7
@@ -18,6 +18,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
@JvmStatic external fun a5()
|
||||
|
||||
@JvmStatic
|
||||
var foo = 1
|
||||
|
||||
@@ -49,6 +51,11 @@ interface B {
|
||||
|
||||
public var foo9 = 1
|
||||
@JvmStatic private set
|
||||
|
||||
@JvmStatic
|
||||
val foo10: Int external get
|
||||
|
||||
val foo11: Int @JvmStatic external get
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+7
@@ -18,6 +18,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic external fun a5()<!>
|
||||
|
||||
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic
|
||||
var foo<!> = 1
|
||||
|
||||
@@ -49,6 +51,11 @@ interface B {
|
||||
|
||||
public var foo9 = 1
|
||||
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic private set<!>
|
||||
|
||||
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic
|
||||
val foo10: Int<!> external get
|
||||
|
||||
val foo11: Int <!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic external get<!>
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -9,6 +9,8 @@ public interface B {
|
||||
private constructor Companion()
|
||||
@kotlin.jvm.JvmStatic public final var foo: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo1: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final val foo10: kotlin.Int
|
||||
@get:kotlin.jvm.JvmStatic public final val foo11: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo2: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic private final var foo3: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic protected final var foo4: kotlin.Int
|
||||
@@ -21,6 +23,7 @@ public interface B {
|
||||
@kotlin.jvm.JvmStatic private final fun a2(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic protected final fun a3(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic internal final fun a4(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic public final external fun a5(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
+6
@@ -20,6 +20,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
@JvmStatic external fun a5()
|
||||
|
||||
@JvmStatic
|
||||
var foo = 1
|
||||
|
||||
@@ -52,6 +54,10 @@ interface B {
|
||||
public var foo9 = 1
|
||||
@JvmStatic private set
|
||||
|
||||
@JvmStatic
|
||||
val foo10: Int external get
|
||||
|
||||
val foo11: Int @JvmStatic external get
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+6
@@ -20,6 +20,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
<!JVM_STATIC_IN_INTERFACE_1_6, JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external fun a5()<!>
|
||||
|
||||
<!JVM_STATIC_IN_INTERFACE_1_6!>@JvmStatic
|
||||
var foo<!> = 1
|
||||
|
||||
@@ -52,6 +54,10 @@ interface B {
|
||||
public var foo9 = 1
|
||||
<!JVM_STATIC_IN_INTERFACE_1_6, JVM_STATIC_ON_NON_PUBLIC_MEMBER!>@JvmStatic private set<!>
|
||||
|
||||
<!JVM_STATIC_IN_INTERFACE_1_6, JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic
|
||||
val foo10: Int<!> external get
|
||||
|
||||
val foo11: Int <!JVM_STATIC_IN_INTERFACE_1_6, JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external get<!>
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -9,6 +9,8 @@ public interface B {
|
||||
private constructor Companion()
|
||||
@kotlin.jvm.JvmStatic public final var foo: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo1: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final val foo10: kotlin.Int
|
||||
@get:kotlin.jvm.JvmStatic public final val foo11: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo2: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic private final var foo3: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic protected final var foo4: kotlin.Int
|
||||
@@ -21,6 +23,7 @@ public interface B {
|
||||
@kotlin.jvm.JvmStatic private final fun a2(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic protected final fun a3(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic internal final fun a4(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic public final external fun a5(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
+6
@@ -19,6 +19,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
@JvmStatic external fun a5()
|
||||
|
||||
@JvmStatic
|
||||
var foo = 1
|
||||
|
||||
@@ -51,6 +53,10 @@ interface B {
|
||||
public var foo9 = 1
|
||||
@JvmStatic private set
|
||||
|
||||
@JvmStatic
|
||||
val foo10: Int external get
|
||||
|
||||
val foo11: Int @JvmStatic external get
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+6
@@ -19,6 +19,8 @@ interface B {
|
||||
|
||||
}
|
||||
|
||||
<!JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external fun a5()<!>
|
||||
|
||||
@JvmStatic
|
||||
var foo = 1
|
||||
|
||||
@@ -51,6 +53,10 @@ interface B {
|
||||
public var foo9 = 1
|
||||
<!JVM_STATIC_ON_NON_PUBLIC_MEMBER!>@JvmStatic private set<!>
|
||||
|
||||
<!JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic
|
||||
val foo10: Int<!> external get
|
||||
|
||||
val foo11: Int <!JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external get<!>
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -9,6 +9,8 @@ public interface B {
|
||||
private constructor Companion()
|
||||
@kotlin.jvm.JvmStatic public final var foo: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo1: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final val foo10: kotlin.Int
|
||||
@get:kotlin.jvm.JvmStatic public final val foo11: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic public final var foo2: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic private final var foo3: kotlin.Int
|
||||
@kotlin.jvm.JvmStatic protected final var foo4: kotlin.Int
|
||||
@@ -21,6 +23,7 @@ public interface B {
|
||||
@kotlin.jvm.JvmStatic private final fun a2(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic protected final fun a3(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic internal final fun a4(): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic public final external fun a5(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
Reference in New Issue
Block a user