From 5a16e4357985c186c5a88665823eb1f448c64d08 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 13 Oct 2015 11:42:52 +0300 Subject: [PATCH] Synchronized is no more allowed on abstract functions --- .../jvm/checkers/declarationCheckers.kt | 15 ++++++++++++ .../diagnostics/DefaultErrorMessagesJvm.java | 1 + .../resolve/jvm/diagnostics/ErrorsJvm.java | 1 + .../jvm/platform/JvmPlatformConfigurator.kt | 1 + .../annotations/Synchronized.kt | 23 +++++++++++++++++++ .../annotations/Synchronized.txt | 22 ++++++++++++++++++ ...JetDiagnosticsTestWithStdLibGenerated.java | 6 +++++ .../kotlin/resolve/DescriptorUtils.java | 6 +++++ 8 files changed, 75 insertions(+) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.txt diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt index cc332fb293a..527d68e41a2 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt @@ -143,6 +143,21 @@ public class VolatileAnnotationChecker : DeclarationChecker { } } +public class SynchronizedAnnotationChecker : DeclarationChecker { + + override fun check(declaration: JetDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext + ) { + val synchronizedAnnotation = DescriptorUtils.getSynchronizedAnnotation(descriptor) + if (synchronizedAnnotation != null && descriptor is FunctionDescriptor && descriptor.modality == Modality.ABSTRACT) { + val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(synchronizedAnnotation) ?: return + diagnosticHolder.report(ErrorsJvm.SYNCHRONIZED_ON_ABSTRACT.on(annotationEntry)) + } + } +} + public class OverloadsAnnotationChecker: DeclarationChecker { override fun check( declaration: JetDeclaration, 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 a1a3e4f18c1..5666362396b 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 @@ -54,6 +54,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.INAPPLICABLE_JVM_NAME, "''JvmName'' annotation is not applicable to this declaration"); MAP.put(ErrorsJvm.ILLEGAL_JVM_NAME, "Illegal JVM name"); MAP.put(ErrorsJvm.VOLATILE_ON_VALUE, "''Volatile'' annotation cannot be used on immutable properties"); + MAP.put(ErrorsJvm.SYNCHRONIZED_ON_ABSTRACT, "''Synchronized'' annotation cannot be used on abstract functions"); MAP.put(ErrorsJvm.EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT, "External declaration can not be abstract"); MAP.put(ErrorsJvm.EXTERNAL_DECLARATION_CANNOT_HAVE_BODY, "External declaration can not have a body"); MAP.put(ErrorsJvm.EXTERNAL_DECLARATION_IN_INTERFACE, "Members of interfaces can not be external"); 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 3e2235f6b00..52c047741fc 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 @@ -51,6 +51,7 @@ public interface ErrorsJvm { DiagnosticFactory1 INAPPLICABLE_JVM_FIELD = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 VOLATILE_ON_VALUE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 SYNCHRONIZED_ON_ABSTRACT = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); DiagnosticFactory0 OVERLOADS_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 8da6d788585..d4d70c702a5 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -32,6 +32,7 @@ public object JvmPlatformConfigurator : PlatformConfigurator( PlatformStaticAnnotationChecker(), JvmNameAnnotationChecker(), VolatileAnnotationChecker(), + SynchronizedAnnotationChecker(), LocalFunInlineChecker(), ReifiedTypeParameterAnnotationChecker(), NativeFunChecker(), diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.kt new file mode 100644 index 00000000000..c5a3f130a50 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.kt @@ -0,0 +1,23 @@ +import kotlin.jvm.Synchronized + +interface My { + @Synchronized fun foo() + + @Synchronized fun bar() = 1 + + @Synchronized fun baz(): String { + return "abc" + } +} + +abstract class Your { + @Synchronized abstract fun foo() + + @Synchronized fun bar() = 1 + + @Synchronized open fun baz(): String { + return "xyz" + } +} + +@Synchronized fun gav() = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.txt new file mode 100644 index 00000000000..d7142608359 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.txt @@ -0,0 +1,22 @@ +package + +@kotlin.jvm.Synchronized() public fun gav(): kotlin.Int + +public interface My { + @kotlin.jvm.Synchronized() public open fun bar(): kotlin.Int + @kotlin.jvm.Synchronized() public open fun baz(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.jvm.Synchronized() public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class Your { + public constructor Your() + @kotlin.jvm.Synchronized() public final fun bar(): kotlin.Int + @kotlin.jvm.Synchronized() public open fun baz(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.jvm.Synchronized() public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 5f7820972b9..1c305b8834c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -103,6 +103,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("Synchronized.kt") + public void testSynchronized() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/Synchronized.kt"); + doTest(fileName); + } + @TestMetadata("targetuse.kt") public void testTargetuse() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/targetuse.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 616e7d03f20..c31f4f5a1e7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -55,6 +55,7 @@ public class DescriptorUtils { public static final FqName JVM_NAME = new FqName("kotlin.jvm.JvmName"); public static final FqName PLATFORM_NAME = new FqName("kotlin.platform.platformName"); public static final FqName VOLATILE = new FqName("kotlin.jvm.Volatile"); + public static final FqName SYNCHRONIZED = new FqName("kotlin.jvm.Synchronized"); private DescriptorUtils() { } @@ -611,6 +612,11 @@ public class DescriptorUtils { return annotated.getAnnotations().findAnnotation(VOLATILE); } + @Nullable + public static AnnotationDescriptor getSynchronizedAnnotation(@NotNull Annotated annotated) { + return annotated.getAnnotations().findAnnotation(SYNCHRONIZED); + } + @NotNull public static SourceFile getContainingSourceFile(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof PropertySetterDescriptor) {