Prohibit JvmOverloads on constructors of annotation classes
In LV >= 1.4 & -progressive #KT-25702 Fixed
This commit is contained in:
+18
-4
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithCorrespondingExpectedDefault
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
|
||||
@@ -194,21 +195,34 @@ class OverloadsAnnotationChecker: DeclarationChecker {
|
||||
descriptor.findJvmOverloadsAnnotation()?.let { annotation ->
|
||||
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation)
|
||||
if (annotationEntry != null) {
|
||||
checkDeclaration(annotationEntry, descriptor, context.trace)
|
||||
checkDeclaration(annotationEntry, descriptor, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkDeclaration(annotationEntry: KtAnnotationEntry, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||
private fun checkDeclaration(
|
||||
annotationEntry: KtAnnotationEntry,
|
||||
descriptor: DeclarationDescriptor,
|
||||
context: DeclarationCheckerContext
|
||||
) {
|
||||
val diagnosticHolder = context.trace
|
||||
|
||||
if (descriptor !is CallableDescriptor) {
|
||||
return
|
||||
}
|
||||
if ((descriptor.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.INTERFACE) {
|
||||
} else if ((descriptor.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.INTERFACE) {
|
||||
diagnosticHolder.report(ErrorsJvm.OVERLOADS_INTERFACE.on(annotationEntry))
|
||||
} else if (descriptor is FunctionDescriptor && descriptor.modality == Modality.ABSTRACT) {
|
||||
diagnosticHolder.report(ErrorsJvm.OVERLOADS_ABSTRACT.on(annotationEntry))
|
||||
} else if (DescriptorUtils.isLocal(descriptor)) {
|
||||
diagnosticHolder.report(ErrorsJvm.OVERLOADS_LOCAL.on(annotationEntry))
|
||||
} else if (descriptor.isAnnotationConstructor()) {
|
||||
val diagnostic =
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses))
|
||||
ErrorsJvm.OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR
|
||||
else
|
||||
ErrorsJvm.OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING
|
||||
|
||||
diagnosticHolder.report(diagnostic.on(annotationEntry))
|
||||
} else if (!descriptor.visibility.isPublicAPI && descriptor.visibility != Visibilities.INTERNAL) {
|
||||
diagnosticHolder.report(ErrorsJvm.OVERLOADS_PRIVATE.on(annotationEntry))
|
||||
} else if (descriptor.valueParameters.none { it.declaresDefaultValue() || it.isActualParameterWithCorrespondingExpectedDefault }) {
|
||||
|
||||
+2
@@ -50,6 +50,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(OVERLOADS_INTERFACE, "'@JvmOverloads' annotation cannot be used on interface methods");
|
||||
MAP.put(OVERLOADS_PRIVATE, "'@JvmOverloads' annotation has no effect on private declarations");
|
||||
MAP.put(OVERLOADS_LOCAL, "'@JvmOverloads' annotation cannot be used on local declarations");
|
||||
MAP.put(OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING, "'@JvmOverloads' annotation on constructors of annotation classes is deprecated");
|
||||
MAP.put(OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR, "'@JvmOverloads' annotation cannot be used on constructors of annotation classes");
|
||||
MAP.put(INAPPLICABLE_JVM_NAME, "'@JvmName' annotation is not applicable to this declaration");
|
||||
MAP.put(ILLEGAL_JVM_NAME, "Illegal JVM name");
|
||||
MAP.put(VOLATILE_ON_VALUE, "'@Volatile' annotation cannot be used on immutable properties");
|
||||
|
||||
@@ -54,6 +54,9 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<KtAnnotationEntry> OVERLOADS_INTERFACE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtAnnotationEntry> OVERLOADS_PRIVATE = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<KtAnnotationEntry> OVERLOADS_LOCAL = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtAnnotationEntry> OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<KtAnnotationEntry> OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT = DiagnosticFactory0.create(ERROR, ABSTRACT_MODIFIER);
|
||||
DiagnosticFactory0<KtDeclaration> EXTERNAL_DECLARATION_CANNOT_HAVE_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// !LANGUAGE: -ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses
|
||||
|
||||
annotation class A1 <!OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING!>@JvmOverloads<!> constructor(val x: Int = 1)
|
||||
annotation class A2 <!OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING!>@JvmOverloads<!> constructor()
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
public final annotation class A1 : kotlin.Annotation {
|
||||
@kotlin.jvm.JvmOverloads public constructor A1(/*0*/ x: kotlin.Int = ...)
|
||||
public final val x: kotlin.Int
|
||||
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
|
||||
}
|
||||
|
||||
public final annotation class A2 : kotlin.Annotation {
|
||||
@kotlin.jvm.JvmOverloads public constructor A2()
|
||||
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
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// !LANGUAGE: +ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses
|
||||
|
||||
annotation class A1 <!OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR!>@JvmOverloads<!> constructor(val x: Int = 1)
|
||||
annotation class A2 <!OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR!>@JvmOverloads<!> constructor()
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
public final annotation class A1 : kotlin.Annotation {
|
||||
@kotlin.jvm.JvmOverloads public constructor A1(/*0*/ x: kotlin.Int = ...)
|
||||
public final val x: kotlin.Int
|
||||
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
|
||||
}
|
||||
|
||||
public final annotation class A2 : kotlin.Annotation {
|
||||
@kotlin.jvm.JvmOverloads public constructor A2()
|
||||
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
|
||||
}
|
||||
+10
@@ -604,6 +604,16 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnAnnotationClassConstructor_1_3.kt")
|
||||
public void testJvmOverloadsOnAnnotationClassConstructor_1_3() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAnnotationClassConstructor_1_3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnAnnotationClassConstructor_1_4.kt")
|
||||
public void testJvmOverloadsOnAnnotationClassConstructor_1_4() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAnnotationClassConstructor_1_4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnPrivate.kt")
|
||||
public void testJvmOverloadsOnPrivate() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt");
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+10
@@ -604,6 +604,16 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnAnnotationClassConstructor_1_3.kt")
|
||||
public void testJvmOverloadsOnAnnotationClassConstructor_1_3() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAnnotationClassConstructor_1_3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnAnnotationClassConstructor_1_4.kt")
|
||||
public void testJvmOverloadsOnAnnotationClassConstructor_1_4() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAnnotationClassConstructor_1_4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnPrivate.kt")
|
||||
public void testJvmOverloadsOnPrivate() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt");
|
||||
|
||||
@@ -95,6 +95,7 @@ enum class LanguageFeature(
|
||||
PolymorphicSignature(KOTLIN_1_4),
|
||||
ProhibitConcurrentHashMapContains(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitTypeParametersForLocalVariables(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses(KOTLIN_1_4, kind = BUG_FIX),
|
||||
|
||||
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
|
||||
@@ -513,6 +513,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
OVERLOADS_PRIVATE.registerFactory(RemoveAnnotationFix.JvmOverloads)
|
||||
OVERLOADS_LOCAL.registerFactory(RemoveAnnotationFix.JvmOverloads)
|
||||
OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS.registerFactory(RemoveAnnotationFix.JvmOverloads)
|
||||
OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR.registerFactory(RemoveAnnotationFix.JvmOverloads)
|
||||
OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING.registerFactory(RemoveAnnotationFix.JvmOverloads)
|
||||
|
||||
ACTUAL_WITHOUT_EXPECT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ACTUAL_KEYWORD))
|
||||
ACTUAL_WITHOUT_EXPECT.registerFactory(CreateExpectedFix)
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Remove @JvmOverloads annotation" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
annotation class A <caret>@JvmOverloads constructor(val x: Int = 1)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Remove @JvmOverloads annotation" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
annotation class A constructor(val x: Int = 1)
|
||||
@@ -9381,6 +9381,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
public void testJvmOverloads() throws Exception {
|
||||
runTest("idea/testData/quickfix/removeAnnotation/jvmOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloadsOnAnnotationClassConstructor.kt")
|
||||
public void testJvmOverloadsOnAnnotationClassConstructor() throws Exception {
|
||||
runTest("idea/testData/quickfix/removeAnnotation/jvmOverloadsOnAnnotationClassConstructor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/removeAtFromAnnotationArgument")
|
||||
|
||||
Reference in New Issue
Block a user