diff --git a/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.txt b/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.txt index 1f9f742f209..661d2767f6d 100644 --- a/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.txt +++ b/compiler/testData/diagnostics/tests/SafeCallOnFakePackage.txt @@ -9,7 +9,7 @@ public open class Test { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String // Static members - public final val FOO: kotlin.String = "test" + public const final val FOO: kotlin.String = "test" } package foo { diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/javaProperties.txt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/javaProperties.txt index 241b23958de..746bfd5aaaa 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/javaProperties.txt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/javaProperties.txt @@ -24,9 +24,9 @@ public open class Test { // Static members public final var i1: kotlin.Int - public final val i2: kotlin.Int = 1 - public final val i3: kotlin.Int - public final val i4: kotlin.Int = 1 + public const final val i2: kotlin.Int = 1 + public const final val i3: kotlin.Int + public const final val i4: kotlin.Int = 1 public final var i5: kotlin.Int public final var i6: kotlin.Int } diff --git a/compiler/testData/diagnostics/tests/callableReference/property/javaStaticFieldViaImport.txt b/compiler/testData/diagnostics/tests/callableReference/property/javaStaticFieldViaImport.txt index 79876ec0460..d28fccd035c 100644 --- a/compiler/testData/diagnostics/tests/callableReference/property/javaStaticFieldViaImport.txt +++ b/compiler/testData/diagnostics/tests/callableReference/property/javaStaticFieldViaImport.txt @@ -11,8 +11,8 @@ public open class JavaClass { // Static members private final val privateFinal: JavaClass! private final var privateMutable: kotlin.Throwable! - protected/*protected static*/ final val protectedFinal: kotlin.Double + protected/*protected static*/ const final val protectedFinal: kotlin.Double protected/*protected static*/ final var protectedMutable: kotlin.Char - public final val publicFinal: kotlin.String! + public const final val publicFinal: kotlin.String! public final var publicMutable: kotlin.Any! } diff --git a/compiler/testData/diagnostics/tests/evaluate/intOverflowWithJavaProperties.txt b/compiler/testData/diagnostics/tests/evaluate/intOverflowWithJavaProperties.txt index 35df063e71a..045944ed2c4 100644 --- a/compiler/testData/diagnostics/tests/evaluate/intOverflowWithJavaProperties.txt +++ b/compiler/testData/diagnostics/tests/evaluate/intOverflowWithJavaProperties.txt @@ -15,5 +15,5 @@ public open class Test { // Static members public final var i1: kotlin.Int - public final val i2: kotlin.Int = 2147483647 + public const final val i2: kotlin.Int = 2147483647 } diff --git a/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.txt b/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.txt index 2246ab91ac9..8e3658fdfdf 100644 --- a/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.txt +++ b/compiler/testData/diagnostics/tests/j+k/StaticMembersFromSuperclasses.txt @@ -9,7 +9,7 @@ public open class Aaa { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String // Static members - public final val i: kotlin.Int = 1 + public const final val i: kotlin.Int = 1 } public open class Bbb : Aaa { @@ -19,5 +19,5 @@ public open class Bbb : Aaa { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String // Static members - public final val i: kotlin.String = "s" + public const final val i: kotlin.String = "s" } diff --git a/compiler/testData/diagnostics/tests/modifiers/const/fromJava.kt b/compiler/testData/diagnostics/tests/modifiers/const/fromJava.kt new file mode 100644 index 00000000000..0b83d4b182e --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/fromJava.kt @@ -0,0 +1,26 @@ +// FILE: A.java + +public class A { + public static final int X = 1; + public static final int Y; + + public final int z = 3; + + static { + Y = 2; + } +} + +// FILE: main.kt + +annotation class Ann(val x: Int) + +@Ann(A.X) +fun main1() {} + +@Ann(A.Y) +fun main2() {} + +val q = A() +@Ann(q.z) +fun main3() {} diff --git a/compiler/testData/diagnostics/tests/modifiers/const/fromJava.txt b/compiler/testData/diagnostics/tests/modifiers/const/fromJava.txt new file mode 100644 index 00000000000..30f97aed659 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/const/fromJava.txt @@ -0,0 +1,26 @@ +package + +public val q: A +@Ann(x = 1) public fun main1(): kotlin.Unit +@Ann() public fun main2(): kotlin.Unit +@Ann(x = 3) public fun main3(): kotlin.Unit + +public open class A { + public constructor A() + public final val z: 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 + + // Static members + public const final val X: kotlin.Int = 1 + public const final val Y: kotlin.Int +} + +@kotlin.annotation.annotation() public final class Ann : kotlin.Annotation { + public constructor Ann(/*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 +} diff --git a/compiler/testData/loadJava/compiledJava/annotations/AnnotatedField.txt b/compiler/testData/loadJava/compiledJava/annotations/AnnotatedField.txt index 1f44738c1c8..3ca90cf2652 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/AnnotatedField.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/AnnotatedField.txt @@ -11,5 +11,5 @@ public open class AnnotatedField { } // Static members - @test.AnnotatedField.Anno(value = "static") public final val x: kotlin.Int = 0 + @test.AnnotatedField.Anno(value = "static") public const final val x: kotlin.Int = 0 } diff --git a/compiler/testData/loadJava/compiledJava/annotations/StringConstantInParam.txt b/compiler/testData/loadJava/compiledJava/annotations/StringConstantInParam.txt index 098b486cbe7..449bad49ef9 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/StringConstantInParam.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/StringConstantInParam.txt @@ -13,5 +13,5 @@ public interface StringConstantInParam { } // Static members - public final val HEL: kotlin.String = "hel" + public const final val HEL: kotlin.String = "hel" } diff --git a/compiler/testData/loadJava/compiledJava/static/StaticFinal.txt b/compiler/testData/loadJava/compiledJava/static/StaticFinal.txt index 28485dcc39b..dd19f1756e6 100644 --- a/compiler/testData/loadJava/compiledJava/static/StaticFinal.txt +++ b/compiler/testData/loadJava/compiledJava/static/StaticFinal.txt @@ -4,10 +4,10 @@ public open class StaticFinal { public constructor StaticFinal() // Static members - public/*package*/ final val packageNonNull: kotlin.String = "bbb" - public/*package*/ final val packageNull: kotlin.String! - private final val privateNonNull: kotlin.String = "bbb" - private final val privateNull: kotlin.String! - public final val publicNonNull: kotlin.String = "aaa" - public final val publicNull: kotlin.String! + public/*package*/ const final val packageNonNull: kotlin.String = "bbb" + public/*package*/ const final val packageNull: kotlin.String! + private const final val privateNonNull: kotlin.String = "bbb" + private const final val privateNull: kotlin.String! + public const final val publicNonNull: kotlin.String = "aaa" + public const final val publicNull: kotlin.String! } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 06ed4ed2734..6a6373e9ed0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9128,6 +9128,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("fromJava.kt") + public void testFromJava() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/fromJava.kt"); + doTest(fileName); + } + @TestMetadata("types.kt") public void testTypes() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/types.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java index 0084fb0a57e..2ca9f3c8141 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaPropertyDescriptor.java @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.types.JetType; import java.util.List; public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor { + private final boolean isStaticFinal; public JavaPropertyDescriptor( @NotNull DeclarationDescriptor containingDeclaration, @NotNull Annotations annotations, @@ -34,10 +35,13 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja boolean isVar, @NotNull Name name, @NotNull SourceElement source, - @Nullable PropertyDescriptor original + @Nullable PropertyDescriptor original, + boolean isStaticFinal ) { super(containingDeclaration, original, annotations, Modality.FINAL, visibility, isVar, name, Kind.DECLARATION, source, /* lateInit = */ false, /* isConst = */ false); + + this.isStaticFinal = isStaticFinal; } @Override @@ -59,7 +63,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja isVar(), getName(), getSource(), - getOriginal() + getOriginal(), + isStaticFinal ); assert getGetter() == null : "Field must not have a getter: " + this; assert getSetter() == null : "Field must not have a setter: " + this; @@ -76,4 +81,9 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja ); return enhanced; } + + @Override + public boolean isConst() { + return isStaticFinal && ConstUtil.canBeUsedForConstVal(getType()); + } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index bc8708ad862..bd735d76d4d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -103,7 +103,8 @@ public class LazyJavaClassMemberScope( val propertyDescriptor = JavaPropertyDescriptor( getContainingDeclaration(), annotations, method.getVisibility(), - /* isVar = */ false, method.getName(), c.components.sourceElementFactory.source(method), /* original */ null + /* isVar = */ false, method.getName(), c.components.sourceElementFactory.source(method), /* original */ null, + /* isStaticFinal = */ false ) // default getter is necessary because there is no real field in annotation diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index 8e3fd75e92e..cfb4190c3bd 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -269,13 +269,15 @@ public abstract class LazyJavaScope( val propertyName = field.getName() return JavaPropertyDescriptor(containingDeclaration, annotations, visibility, isVar, propertyName, - c.components.sourceElementFactory.source(field), /* original = */ null) + c.components.sourceElementFactory.source(field), /* original = */ null, /*isConst= */ field.isFinalStatic) } + private val JavaField.isFinalStatic: Boolean + get() = isFinal && isStatic + private fun getPropertyType(field: JavaField, annotations: Annotations): JetType { // Fields do not have their own generic parameters - val finalStatic = field.isFinal() && field.isStatic() - + val finalStatic = field.isFinalStatic // simple static constants should not have flexible types: val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) val propertyType = c.typeResolver.transformJavaType(