From ccf0c363fa15f10f5a86a1e75a22eaa817764911 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 13 Oct 2015 11:33:25 +0300 Subject: [PATCH] Volatile is no more allowed on values #KT-7670 Fixed --- .../resolve/jvm/checkers/declarationCheckers.kt | 14 ++++++++++++++ .../jvm/diagnostics/DefaultErrorMessagesJvm.java | 1 + .../kotlin/resolve/jvm/diagnostics/ErrorsJvm.java | 4 ++++ .../jvm/platform/JvmPlatformConfigurator.kt | 4 +++- .../testsWithStdLib/annotations/Volatile.kt | 7 +++++++ .../testsWithStdLib/annotations/Volatile.txt | 10 ++++++++++ .../JetDiagnosticsTestWithStdLibGenerated.java | 6 ++++++ .../jetbrains/kotlin/resolve/DescriptorUtils.java | 6 ++++++ 8 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.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 eb917a78a41..cc332fb293a 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 @@ -128,6 +128,20 @@ public class JvmNameAnnotationChecker : DeclarationChecker { } } +public class VolatileAnnotationChecker : DeclarationChecker { + + override fun check(declaration: JetDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext + ) { + val volatileAnnotation = DescriptorUtils.getVolatileAnnotation(descriptor) + if (volatileAnnotation != null && descriptor is PropertyDescriptor && !descriptor.isVar) { + val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(volatileAnnotation) ?: return + diagnosticHolder.report(ErrorsJvm.VOLATILE_ON_VALUE.on(annotationEntry)) + } + } +} public class OverloadsAnnotationChecker: DeclarationChecker { override fun check( 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 e834e840545..a1a3e4f18c1 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 @@ -53,6 +53,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.OVERLOADS_PRIVATE, "''JvmOverloads'' annotation has no effect on private and local declarations"); 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.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 51816dc07c7..3e2235f6b00 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 @@ -50,6 +50,8 @@ public interface ErrorsJvm { DiagnosticFactory1 INAPPLICABLE_JVM_FIELD = DiagnosticFactory1.create(ERROR); + DiagnosticFactory0 VOLATILE_ON_VALUE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); DiagnosticFactory0 OVERLOADS_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 OVERLOADS_PRIVATE = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); @@ -67,6 +69,8 @@ public interface ErrorsJvm { DiagnosticFactory0 INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 INAPPLICABLE_PUBLIC_FIELD = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 NO_REFLECTION_IN_CLASS_PATH = DiagnosticFactory0.create(WARNING); DiagnosticFactory2 JAVA_CLASS_ON_COMPANION = DiagnosticFactory2.create(WARNING); 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 8e9443bf941..8da6d788585 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 @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.jvm.RuntimeAssertionsTypeChecker import org.jetbrains.kotlin.load.kotlin.JavaAnnotationCallChecker import org.jetbrains.kotlin.load.kotlin.JavaAnnotationMethodCallChecker import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeFunChecker -import org.jetbrains.kotlin.resolve.PlatformConfigurator +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.jvm.checkers.* import org.jetbrains.kotlin.types.DynamicTypesSettings @@ -31,6 +31,7 @@ public object JvmPlatformConfigurator : PlatformConfigurator( additionalDeclarationCheckers = listOf( PlatformStaticAnnotationChecker(), JvmNameAnnotationChecker(), + VolatileAnnotationChecker(), LocalFunInlineChecker(), ReifiedTypeParameterAnnotationChecker(), NativeFunChecker(), @@ -67,3 +68,4 @@ public object JvmPlatformConfigurator : PlatformConfigurator( container.useImpl() } } + diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt new file mode 100644 index 00000000000..47af0490450 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt @@ -0,0 +1,7 @@ +import kotlin.jvm.Volatile + +class My { + @Volatile val x = 0 + // ok + @Volatile var y = 1 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.txt new file mode 100644 index 00000000000..afe159569a1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.txt @@ -0,0 +1,10 @@ +package + +public final class My { + public constructor My() + @kotlin.jvm.Volatile() public final val x: kotlin.Int = 0 + @kotlin.jvm.Volatile() public final var y: 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 8c66268f1db..5f7820972b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -109,6 +109,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } + @TestMetadata("Volatile.kt") + public void testVolatile() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index b2df0ce5698..616e7d03f20 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -54,6 +54,7 @@ public class DescriptorUtils { public static final Name ENUM_VALUE_OF = Name.identifier("valueOf"); 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"); private DescriptorUtils() { } @@ -605,6 +606,11 @@ public class DescriptorUtils { return getJvmNameAnnotation(annotated.getAnnotations()); } + @Nullable + public static AnnotationDescriptor getVolatileAnnotation(@NotNull Annotated annotated) { + return annotated.getAnnotations().findAnnotation(VOLATILE); + } + @NotNull public static SourceFile getContainingSourceFile(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof PropertySetterDescriptor) {