diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 71ce2eb1ccf..30706135fd3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorFactory; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; -import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; @@ -61,6 +60,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterfaceCompanionObject; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.PROPERTY_METADATA_TYPE; +import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.findJvmFieldAnnotation; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin; import static org.jetbrains.org.objectweb.asm.Opcodes.*; @@ -303,7 +303,7 @@ public class PropertyCodegen { ClassBuilder builder = v; - boolean hasPublicFieldAnnotation = AnnotationsPackage.findPublicFieldAnnotation(propertyDescriptor) != null; + boolean hasJvmFieldAnnotation = findJvmFieldAnnotation(propertyDescriptor) != null; FieldOwnerContext backingFieldContext = context; boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst(); @@ -313,7 +313,7 @@ public class PropertyCodegen { if (takeVisibilityFromDescriptor) { modifiers |= getVisibilityAccessFlag(propertyDescriptor); } - else if (hasPublicFieldAnnotation && !isDelegate) { + else if (hasJvmFieldAnnotation && !isDelegate) { modifiers |= ACC_PUBLIC; } else { @@ -330,7 +330,7 @@ public class PropertyCodegen { else if (takeVisibilityFromDescriptor) { modifiers |= getVisibilityAccessFlag(propertyDescriptor); } - else if (!isDelegate && hasPublicFieldAnnotation) { + else if (!isDelegate && hasJvmFieldAnnotation) { modifiers |= ACC_PUBLIC; } else if (kind != OwnerKind.PACKAGE || isDelegate) { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt index f109415a5cb..7a80f18b954 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt @@ -17,8 +17,13 @@ package org.jetbrains.kotlin.resolve.jvm.annotations import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.FqName public fun DeclarationDescriptor.hasJvmOverloadsAnnotation(): Boolean { return getAnnotations().findAnnotation(FqName("kotlin.jvm.JvmOverloads")) != null } + +public fun DeclarationDescriptor.findJvmFieldAnnotation(): AnnotationDescriptor? { + return annotations.findAnnotation(FqName("kotlin.jvm.JvmField")) +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt new file mode 100644 index 00000000000..96fef89ffab --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.jvm.checkers + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.psi.JetDeclaration +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DeclarationChecker +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmFieldAnnotation +import org.jetbrains.kotlin.resolve.jvm.checkers.JvmFieldApplicabilityChecker.Problem.* +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm + + +class JvmFieldApplicabilityChecker : DeclarationChecker { + + enum class Problem(val errorMessage: String) { + NOT_A_PROPERTY("JvmField can only be applied to a property"), + NOT_FINAL("JvmField can only be applied to final property"), + CUSTOM_ACCESSOR("JvmField cannot be applied to a property with a custom accessor"), + NO_BACKING_FIELD("JvmField can only be applied to a property with backing field"), + OVERRIDES("JvmField cannot be applied to a property that overrides some other property"), + LATEINIT("JvmField cannot be applied to lateinit property"), + CONST("JvmField cannot be applied to const property"), + INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"), + TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}") + } + + override fun check( + declaration: JetDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext + ) { + val annotation = descriptor.findJvmFieldAnnotation() ?: return + + val problem = when { + descriptor !is PropertyDescriptor -> NOT_A_PROPERTY + descriptor.modality.isOverridable -> NOT_FINAL + !descriptor.hasBackingField(bindingContext) -> NO_BACKING_FIELD + descriptor.hasCustomAccessor() -> CUSTOM_ACCESSOR + descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES + descriptor.isLateInit -> LATEINIT + descriptor.isConst -> CONST + descriptor.isInsideCompanionObjectOfInterface() -> INSIDE_COMPANION_OF_INTERFACE + DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() -> + TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE + else -> return + } + + val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: return + diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_FIELD.on(annotationEntry, problem.errorMessage)) + } + + private fun JetDeclaration.isInsideJvmMultifileClassFile() = JvmFileClassUtil.findAnnotationEntryOnFileNoResolve( + getContainingJetFile(), + JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT + ) != null + + private fun PropertyDescriptor.hasCustomAccessor() + = !(getter?.isDefault ?: true) || !(setter?.isDefault ?: true) + + private fun PropertyDescriptor.hasBackingField(bindingContext: BindingContext) + = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false + + private fun PropertyDescriptor.isInsideCompanionObjectOfInterface(): Boolean { + val containingClass = containingDeclaration as? ClassDescriptor ?: return false + if (!DescriptorUtils.isCompanionObject(containingClass)) return false + + val outerClassForObject = containingClass.containingDeclaration as? ClassDescriptor ?: return false + return DescriptorUtils.isInterface(outerClassForObject) + } +} \ No newline at end of file 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 29eb093c440..eb917a78a41 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 @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DeclarationChecker import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.annotations.findPublicFieldAnnotation import org.jetbrains.kotlin.resolve.annotations.hasInlineAnnotation import org.jetbrains.kotlin.resolve.annotations.hasIntrinsicAnnotation import org.jetbrains.kotlin.resolve.annotations.hasPlatformStaticAnnotation @@ -159,27 +158,6 @@ public class OverloadsAnnotationChecker: DeclarationChecker { } } -public class PublicFieldAnnotationChecker: DeclarationChecker { - override fun check( - declaration: JetDeclaration, - descriptor: DeclarationDescriptor, - diagnosticHolder: DiagnosticSink, - bindingContext: BindingContext - ) { - val annotation = descriptor.findPublicFieldAnnotation() ?: return - - fun report() { - val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: return - diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_PUBLIC_FIELD.on(annotationEntry)) - } - - if (descriptor is PropertyDescriptor - && !bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor)!!) { - report() - } - } -} - public class TypeParameterBoundIsNotArrayChecker : 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 3ecd8d6ffa1..e834e840545 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 @@ -74,8 +74,6 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.WHEN_ENUM_CAN_BE_NULL_IN_JAVA, "Enum argument can be null in Java, but exhaustive when contains no null branch"); - MAP.put(ErrorsJvm.INAPPLICABLE_PUBLIC_FIELD, "publicField annotation is not applicable to this declaration"); - MAP.put(ErrorsJvm.JAVA_CLASS_ON_COMPANION, "The resulting type of this ''javaClass'' call is {0} and not {1}. " + "Please use the more clear ''::class.java'' syntax to avoid confusion", @@ -88,6 +86,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.DUPLICATE_CLASS_NAMES, "Duplicate JVM class name ''{0}'' generated from: {1}", Renderers.TO_STRING, Renderers.TO_STRING); MAP.put(ErrorsJvm.UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of a type parameter cannot be an array"); + + MAP.put(ErrorsJvm.INAPPLICABLE_JVM_FIELD, "{0}", Renderers.TO_STRING); } @NotNull 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 41da0fa12c4..51816dc07c7 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 @@ -48,6 +48,8 @@ public interface ErrorsJvm { DiagnosticFactory0 INAPPLICABLE_JVM_NAME = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ILLEGAL_JVM_NAME = DiagnosticFactory0.create(ERROR); + DiagnosticFactory1 INAPPLICABLE_JVM_FIELD = DiagnosticFactory1.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); @@ -65,8 +67,6 @@ 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 21f82b2470d..8e9443bf941 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 @@ -35,7 +35,7 @@ public object JvmPlatformConfigurator : PlatformConfigurator( ReifiedTypeParameterAnnotationChecker(), NativeFunChecker(), OverloadsAnnotationChecker(), - PublicFieldAnnotationChecker(), + JvmFieldApplicabilityChecker(), TypeParameterBoundIsNotArrayChecker() ), diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt index 06ccedc7675..b694f68498b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt @@ -37,10 +37,6 @@ public fun DeclarationDescriptor.hasPlatformStaticAnnotation(): Boolean { getAnnotations().findAnnotation(FqName("kotlin.jvm.JvmStatic")) != null } -public fun DeclarationDescriptor.findPublicFieldAnnotation(): AnnotationDescriptor? { - return getAnnotations().findAnnotation(FqName("kotlin.jvm.publicField")) -} - public fun DeclarationDescriptor.hasJvmSyntheticAnnotation(): Boolean { val jvmSyntheticName = FqName("kotlin.jvm.JvmSynthetic") return annotations.findAnnotation(jvmSyntheticName) != null || diff --git a/compiler/testData/asJava/lightClasses/publicField/CompanionObject.java b/compiler/testData/asJava/lightClasses/publicField/CompanionObject.java index 693221e4667..6f869b8c056 100644 --- a/compiler/testData/asJava/lightClasses/publicField/CompanionObject.java +++ b/compiler/testData/asJava/lightClasses/publicField/CompanionObject.java @@ -1,5 +1,5 @@ public final class C { - @kotlin.jvm.publicField + @kotlin.jvm.JvmField public static final java.lang.String foo = "A"; public static final C.Companion Companion; diff --git a/compiler/testData/asJava/lightClasses/publicField/CompanionObject.kt b/compiler/testData/asJava/lightClasses/publicField/CompanionObject.kt index d51b5963d95..e453f391ce8 100644 --- a/compiler/testData/asJava/lightClasses/publicField/CompanionObject.kt +++ b/compiler/testData/asJava/lightClasses/publicField/CompanionObject.kt @@ -2,6 +2,6 @@ class C { companion object { - @[publicField] private val foo: String = "A" + @[kotlin.jvm.JvmField] private val foo: String = "A" } } diff --git a/compiler/testData/asJava/lightClasses/publicField/Simple.java b/compiler/testData/asJava/lightClasses/publicField/Simple.java index 96daa4f378a..333cdc060f6 100644 --- a/compiler/testData/asJava/lightClasses/publicField/Simple.java +++ b/compiler/testData/asJava/lightClasses/publicField/Simple.java @@ -1,5 +1,5 @@ public final class C { - @kotlin.jvm.publicField + @kotlin.jvm.JvmField public final java.lang.String foo = "A"; public C() { /* compiled code */ } diff --git a/compiler/testData/asJava/lightClasses/publicField/Simple.kt b/compiler/testData/asJava/lightClasses/publicField/Simple.kt index d6225c5a956..cd81bc19384 100644 --- a/compiler/testData/asJava/lightClasses/publicField/Simple.kt +++ b/compiler/testData/asJava/lightClasses/publicField/Simple.kt @@ -1,5 +1,5 @@ // C class C { - @[kotlin.jvm.publicField] private val foo: String = "A" + @[kotlin.jvm.JvmField] private val foo: String = "A" } diff --git a/compiler/testData/codegen/boxWithJava/publicField/simple/Test.java b/compiler/testData/codegen/boxWithJava/jvmField/simple/Test.java similarity index 100% rename from compiler/testData/codegen/boxWithJava/publicField/simple/Test.java rename to compiler/testData/codegen/boxWithJava/jvmField/simple/Test.java diff --git a/compiler/testData/codegen/boxWithJava/publicField/simple/simple.kt b/compiler/testData/codegen/boxWithJava/jvmField/simple/simple.kt similarity index 62% rename from compiler/testData/codegen/boxWithJava/publicField/simple/simple.kt rename to compiler/testData/codegen/boxWithJava/jvmField/simple/simple.kt index 798704c4d84..027ee17ad19 100644 --- a/compiler/testData/codegen/boxWithJava/publicField/simple/simple.kt +++ b/compiler/testData/codegen/boxWithJava/jvmField/simple/simple.kt @@ -1,5 +1,5 @@ class C { - @publicField private val foo: String = "OK" + @JvmField private val foo: String = "OK" } fun box(): String { diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.kt new file mode 100644 index 00000000000..68d41dd5109 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.kt @@ -0,0 +1,13 @@ +@file:kotlin.jvm.JvmMultifileClass +@file:JvmName("SomeName") + +@JvmField +val c = 4 + +@JvmField +var g = 5 + +class C { + @JvmField + var g = 5 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.txt similarity index 66% rename from compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.txt rename to compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.txt index 0fc7b0bc899..ddd1d82a6f6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.txt @@ -1,8 +1,11 @@ package +@kotlin.jvm.JvmField() public val c: kotlin.Int = 4 +@kotlin.jvm.JvmField() public var g: kotlin.Int + public final class C { public constructor C() - @kotlin.jvm.publicField() private final val a: kotlin.String + @kotlin.jvm.JvmField() public final var g: 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/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt new file mode 100644 index 00000000000..5422d3c7004 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt @@ -0,0 +1,12 @@ +@file:JvmName("SomeName") + +@JvmField +val c = 4 + +@JvmField +var g = 5 + +class C { + @JvmField + var g = 5 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.txt similarity index 56% rename from compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.txt rename to compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.txt index 6935d098bdc..ddd1d82a6f6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.txt @@ -1,11 +1,12 @@ package -@kotlin.jvm.publicField() public fun foo(): kotlin.Unit +@kotlin.jvm.JvmField() public val c: kotlin.Int = 4 +@kotlin.jvm.JvmField() public var g: kotlin.Int public final class C { - @kotlin.jvm.publicField() public constructor C(/*0*/ s: kotlin.String) + public constructor C() + @kotlin.jvm.JvmField() public final var g: kotlin.Int public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - @kotlin.jvm.publicField() private final fun foo(/*0*/ s: kotlin.String = ...): 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/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt new file mode 100644 index 00000000000..c55df86013f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt @@ -0,0 +1,74 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE +@kotlin.jvm.JvmField +fun foo() { + @kotlin.jvm.JvmField val x = "A" +} + +@JvmField +abstract class C : I{ + + @kotlin.jvm.JvmField constructor(s: String) { + } + + @kotlin.jvm.JvmField private fun foo(s: String = "OK") { + } + + @JvmField val a: String by lazy { "A" } + + @JvmField open val b: Int = 3 + + @JvmField abstract val c: Int + + @JvmField + val customGetter: String = "" + get() = field + + @JvmField + var customSetter: String = "" + set(s) { + field = s + } + + @JvmField + val noBackingField: String + get() = "a" + + @JvmField + final override val ai = 3 +} + +interface I { + @JvmField val ai: Int + @JvmField val bi: Int + get() = 5 +} + +class G { + @JvmField + lateinit var lateInit: String +} + +@JvmField +const val Const = 4 + +@JvmField +var i = 5 + +class H { + companion object { + @JvmField + var c = 3 + } +} + +interface K { + companion object { + @JvmField + var c = 3 + } +} + +object O { + @JvmField + val c = 3 +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt new file mode 100644 index 00000000000..e7ca3e717c1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt @@ -0,0 +1,74 @@ +package + +@kotlin.jvm.JvmField() public const val Const: kotlin.Int = 4 +@kotlin.jvm.JvmField() public var i: kotlin.Int +@kotlin.jvm.JvmField() public fun foo(): kotlin.Unit + +@kotlin.jvm.JvmField() public abstract class C : I { + @kotlin.jvm.JvmField() public constructor C(/*0*/ s: kotlin.String) + @kotlin.jvm.JvmField() public final val a: kotlin.String + @kotlin.jvm.JvmField() public final override /*1*/ val ai: kotlin.Int = 3 + @kotlin.jvm.JvmField() public open val b: kotlin.Int = 3 + @kotlin.jvm.JvmField() public open override /*1*/ /*fake_override*/ val bi: kotlin.Int + @kotlin.jvm.JvmField() public abstract val c: kotlin.Int + @kotlin.jvm.JvmField() public final val customGetter: kotlin.String = "" + @kotlin.jvm.JvmField() public final var customSetter: kotlin.String + @kotlin.jvm.JvmField() public final val noBackingField: kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @kotlin.jvm.JvmField() private final fun foo(/*0*/ s: kotlin.String = ...): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class G { + public constructor G() + @kotlin.jvm.JvmField() public final lateinit var lateInit: kotlin.String + 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 class H { + public constructor H() + 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 companion object Companion { + private constructor Companion() + @kotlin.jvm.JvmField() public final var c: 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 interface I { + @kotlin.jvm.JvmField() public abstract val ai: kotlin.Int + @kotlin.jvm.JvmField() public open val bi: 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 interface K { + 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 companion object Companion { + private constructor Companion() + @kotlin.jvm.JvmField() public final var c: 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 object O { + private constructor O() + @kotlin.jvm.JvmField() public final val c: kotlin.Int = 3 + 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/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.kt deleted file mode 100644 index ed8a83014f2..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.kt +++ /dev/null @@ -1,16 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -class C { - - @kotlin.jvm.publicField constructor(s: String) { - - } - - @kotlin.jvm.publicField private fun foo(s: String = "OK") { - - } -} - -@kotlin.jvm.publicField -fun foo() { - @kotlin.jvm.publicField val x = "A" -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.kt deleted file mode 100644 index a12181abb9f..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.kt +++ /dev/null @@ -1,3 +0,0 @@ -class C { - private @publicField val a: String by lazy { "A" } -} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index a47a8ecda91..c61d40ac201 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -322,6 +322,33 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic } } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class JvmField extends AbstractJetDiagnosticsTestWithStdLib { + public void testAllFilesPresentInJvmField() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("inMultiFileFacade.kt") + public void testInMultiFileFacade() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inMultiFileFacade.kt"); + doTest(fileName); + } + + @TestMetadata("inSingleFileFacade.kt") + public void testInSingleFileFacade() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt"); + doTest(fileName); + } + + @TestMetadata("jvmFieldApplicability.kt") + public void testJvmFieldApplicability() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -477,27 +504,6 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } } - - @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/publicField") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class PublicField extends AbstractJetDiagnosticsTestWithStdLib { - public void testAllFilesPresentInPublicField() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/publicField"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("publicFieldNotOnProperty.kt") - public void testPublicFieldNotOnProperty() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldNotOnProperty.kt"); - doTest(fileName); - } - - @TestMetadata("publicFieldOnDelegatedProperty.kt") - public void testPublicFieldOnDelegatedProperty() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/publicField/publicFieldOnDelegatedProperty.kt"); - doTest(fileName); - } - } } @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/duplicateJvmSignature") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 004ccd3f7a4..87f002ff38e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -273,6 +273,22 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } + @TestMetadata("compiler/testData/codegen/boxWithJava/jvmField") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class JvmField extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInJvmField() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/jvmField"), Pattern.compile("^([^\\.]+)$"), true); + } + + @TestMetadata("simple") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/jvmField/simple/"); + doTestWithJava(fileName); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithJava/jvmOverloads") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -385,22 +401,6 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } - @TestMetadata("compiler/testData/codegen/boxWithJava/publicField") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class PublicField extends AbstractBlackBoxCodegenTest { - public void testAllFilesPresentInPublicField() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/publicField"), Pattern.compile("^([^\\.]+)$"), true); - } - - @TestMetadata("simple") - public void testSimple() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/publicField/simple/"); - doTestWithJava(fileName); - } - - } - @TestMetadata("compiler/testData/codegen/boxWithJava/reflection") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/libraries/stdlib/src/kotlin/jvm/JvmPlatformAnnotations.kt b/libraries/stdlib/src/kotlin/jvm/JvmPlatformAnnotations.kt index dbb1c33d82d..43d33094b09 100644 --- a/libraries/stdlib/src/kotlin/jvm/JvmPlatformAnnotations.kt +++ b/libraries/stdlib/src/kotlin/jvm/JvmPlatformAnnotations.kt @@ -65,15 +65,6 @@ public annotation class JvmMultifileClass @Retention(AnnotationRetention.SOURCE) public annotation class JvmSynthetic -/** - * Instructs the Kotlin compiler to generate a public backing field for this property. - */ -@Target(AnnotationTarget.FIELD) -@Retention(AnnotationRetention.SOURCE) -@MustBeDocumented -@Deprecated("Use lateinit instead") -public annotation class publicField - /** * This annotation indicates what exceptions should be declared by a function when compiled to a JVM method. * @@ -101,4 +92,11 @@ public annotation class Throws(public vararg val exceptionClasses: KClass