Allow to use @JvmStatic in interface companion object
This commit is contained in:
+40
-10
@@ -17,6 +17,9 @@
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
@@ -51,7 +54,12 @@ class LocalFunInlineChecker : SimpleDeclarationChecker {
|
||||
}
|
||||
}
|
||||
|
||||
class PlatformStaticAnnotationChecker : SimpleDeclarationChecker {
|
||||
class JvmStaticChecker(jvmTarget: JvmTarget, languageVersionSettings: LanguageVersionSettings) : SimpleDeclarationChecker {
|
||||
|
||||
private val isLessJVM18 = jvmTarget.bytecodeVersion < JvmTarget.JVM_1_8.bytecodeVersion
|
||||
|
||||
private val supportJvmStaticInInterface = languageVersionSettings.supportsFeature(LanguageFeature.JvmStaticInInterface)
|
||||
|
||||
|
||||
override fun check(
|
||||
declaration: KtDeclaration,
|
||||
@@ -75,13 +83,24 @@ class PlatformStaticAnnotationChecker : SimpleDeclarationChecker {
|
||||
diagnosticHolder: DiagnosticSink
|
||||
) {
|
||||
val container = descriptor.containingDeclaration
|
||||
val insideObject = container != null && DescriptorUtils.isNonCompanionObject(container)
|
||||
val insideCompanionObjectInClass =
|
||||
container != null && DescriptorUtils.isCompanionObject(container) &&
|
||||
DescriptorUtils.isClassOrEnumClass(container.containingDeclaration)
|
||||
val insideObject = DescriptorUtils.isObject(container)
|
||||
val insideCompanionObjectInInterface = DescriptorUtils.isCompanionObject(container) &&
|
||||
DescriptorUtils.isInterface(container!!.containingDeclaration)
|
||||
|
||||
if (!insideObject && !insideCompanionObjectInClass) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_NOT_IN_OBJECT.on(declaration))
|
||||
if (!insideObject || insideCompanionObjectInInterface) {
|
||||
if (insideCompanionObjectInInterface &&
|
||||
supportJvmStaticInInterface &&
|
||||
descriptor is DeclarationDescriptorWithVisibility) {
|
||||
checkVisibility(descriptor, diagnosticHolder, declaration)
|
||||
if (isLessJVM18) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_IN_INTERFACE_1_6.on(declaration))
|
||||
}
|
||||
} else {
|
||||
diagnosticHolder.report(
|
||||
(if (supportJvmStaticInInterface) ErrorsJvm.JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION
|
||||
else ErrorsJvm.JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION).on(declaration)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val checkDeclaration = when (declaration) {
|
||||
@@ -89,7 +108,7 @@ class PlatformStaticAnnotationChecker : SimpleDeclarationChecker {
|
||||
else -> declaration
|
||||
}
|
||||
|
||||
if (insideObject && checkDeclaration.modifierList?.hasModifier(KtTokens.OVERRIDE_KEYWORD) == true) {
|
||||
if (DescriptorUtils.isNonCompanionObject(container) && checkDeclaration.modifierList?.hasModifier(KtTokens.OVERRIDE_KEYWORD) == true) {
|
||||
diagnosticHolder.report(ErrorsJvm.OVERRIDE_CANNOT_BE_STATIC.on(declaration))
|
||||
}
|
||||
|
||||
@@ -97,6 +116,18 @@ class PlatformStaticAnnotationChecker : SimpleDeclarationChecker {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_ON_CONST_OR_JVM_FIELD.on(declaration))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkVisibility(
|
||||
descriptor: DeclarationDescriptorWithVisibility,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
declaration: KtDeclaration
|
||||
) {
|
||||
if (descriptor.visibility != Visibilities.PUBLIC) {
|
||||
diagnosticHolder.report(ErrorsJvm.JVM_STATIC_ON_NON_PUBLIC_MEMBER.on(declaration))
|
||||
} else if (descriptor is PropertyDescriptor) {
|
||||
descriptor.setter?.let { checkVisibility(it, diagnosticHolder, declaration) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JvmNameAnnotationChecker : SimpleDeclarationChecker {
|
||||
@@ -129,8 +160,7 @@ class JvmNameAnnotationChecker : SimpleDeclarationChecker {
|
||||
}
|
||||
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
val callableMemberDescriptor = descriptor
|
||||
if (DescriptorUtils.isOverride(callableMemberDescriptor) || callableMemberDescriptor.isOverridable) {
|
||||
if (DescriptorUtils.isOverride(descriptor) || descriptor.isOverridable) {
|
||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -50,7 +50,10 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(ACCIDENTAL_OVERRIDE, "Accidental override: {0}", CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
MAP.put(CONFLICTING_INHERITED_JVM_DECLARATIONS, "Inherited platform declarations clash: {0}", CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
|
||||
MAP.put(JVM_STATIC_NOT_IN_OBJECT, "Only functions in named objects and companion objects of classes can be annotated with '@JvmStatic'");
|
||||
MAP.put(JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION, "Only members in named objects and companion objects of classes can be annotated with '@JvmStatic'");
|
||||
MAP.put(JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION, "Only members in named objects and companion objects can be annotated with '@JvmStatic'");
|
||||
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(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");
|
||||
|
||||
+4
-1
@@ -41,7 +41,10 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> OVERRIDE_CANNOT_BE_STATIC = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_NOT_IN_OBJECT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtDeclaration> JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
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<PsiElement> INAPPLICABLE_JVM_NAME = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+1
-1
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.types.DynamicTypesSettings
|
||||
object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
DynamicTypesSettings(),
|
||||
additionalDeclarationCheckers = listOf(
|
||||
PlatformStaticAnnotationChecker(),
|
||||
JvmNameAnnotationChecker(),
|
||||
VolatileAnnotationChecker(),
|
||||
SynchronizedAnnotationChecker(),
|
||||
@@ -87,6 +86,7 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
declarationReturnTypeSanitizer = JvmDeclarationReturnTypeSanitizer
|
||||
) {
|
||||
override fun configureModuleComponents(container: StorageComponentContainer) {
|
||||
container.useImpl<JvmStaticChecker>()
|
||||
container.useImpl<JvmReflectionAPICallChecker>()
|
||||
container.useImpl<JavaSyntheticScopes>()
|
||||
container.useImpl<SamConversionResolverImpl>()
|
||||
|
||||
Reference in New Issue
Block a user