Load static final fields of appropriate types from Java as const

This commit is contained in:
Denis Zharkov
2015-09-21 17:32:17 +03:00
parent 98dd08109d
commit 8d13f08271
14 changed files with 94 additions and 23 deletions
@@ -9,7 +9,7 @@ public open class Test {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members // Static members
public final val FOO: kotlin.String = "test" public const final val FOO: kotlin.String = "test"
} }
package foo { package foo {
@@ -24,9 +24,9 @@ public open class Test {
// Static members // Static members
public final var i1: kotlin.Int public final var i1: kotlin.Int
public final val i2: kotlin.Int = 1 public const final val i2: kotlin.Int = 1
public final val i3: kotlin.Int public const final val i3: kotlin.Int
public final val i4: kotlin.Int = 1 public const final val i4: kotlin.Int = 1
public final var i5: kotlin.Int public final var i5: kotlin.Int
public final var i6: kotlin.Int public final var i6: kotlin.Int
} }
@@ -11,8 +11,8 @@ public open class JavaClass {
// Static members // Static members
private final val privateFinal: JavaClass! private final val privateFinal: JavaClass!
private final var privateMutable: kotlin.Throwable! 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 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! public final var publicMutable: kotlin.Any!
} }
@@ -15,5 +15,5 @@ public open class Test {
// Static members // Static members
public final var i1: kotlin.Int public final var i1: kotlin.Int
public final val i2: kotlin.Int = 2147483647 public const final val i2: kotlin.Int = 2147483647
} }
@@ -9,7 +9,7 @@ public open class Aaa {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members // Static members
public final val i: kotlin.Int = 1 public const final val i: kotlin.Int = 1
} }
public open class Bbb : Aaa { public open class Bbb : Aaa {
@@ -19,5 +19,5 @@ public open class Bbb : Aaa {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members // Static members
public final val i: kotlin.String = "s" public const final val i: kotlin.String = "s"
} }
@@ -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(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>A.Y<!>)
fun main2() {}
val q = A()
@Ann(<!ANNOTATION_PARAMETER_MUST_BE_CONST!>q.z<!>)
fun main3() {}
@@ -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
}
@@ -11,5 +11,5 @@ public open class AnnotatedField {
} }
// Static members // 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
} }
@@ -13,5 +13,5 @@ public interface StringConstantInParam {
} }
// Static members // Static members
public final val HEL: kotlin.String = "hel" public const final val HEL: kotlin.String = "hel"
} }
@@ -4,10 +4,10 @@ public open class StaticFinal {
public constructor StaticFinal() public constructor StaticFinal()
// Static members // Static members
public/*package*/ final val packageNonNull: kotlin.String = "bbb" public/*package*/ const final val packageNonNull: kotlin.String = "bbb"
public/*package*/ final val packageNull: kotlin.String! public/*package*/ const final val packageNull: kotlin.String!
private final val privateNonNull: kotlin.String = "bbb" private const final val privateNonNull: kotlin.String = "bbb"
private final val privateNull: kotlin.String! private const final val privateNull: kotlin.String!
public final val publicNonNull: kotlin.String = "aaa" public const final val publicNonNull: kotlin.String = "aaa"
public final val publicNull: kotlin.String! public const final val publicNull: kotlin.String!
} }
@@ -9128,6 +9128,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); 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") @TestMetadata("types.kt")
public void testTypes() throws Exception { public void testTypes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/types.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/const/types.kt");
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.types.JetType;
import java.util.List; import java.util.List;
public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor { public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor {
private final boolean isStaticFinal;
public JavaPropertyDescriptor( public JavaPropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull Annotations annotations, @NotNull Annotations annotations,
@@ -34,10 +35,13 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
boolean isVar, boolean isVar,
@NotNull Name name, @NotNull Name name,
@NotNull SourceElement source, @NotNull SourceElement source,
@Nullable PropertyDescriptor original @Nullable PropertyDescriptor original,
boolean isStaticFinal
) { ) {
super(containingDeclaration, original, annotations, Modality.FINAL, visibility, isVar, name, Kind.DECLARATION, source, super(containingDeclaration, original, annotations, Modality.FINAL, visibility, isVar, name, Kind.DECLARATION, source,
/* lateInit = */ false, /* isConst = */ false); /* lateInit = */ false, /* isConst = */ false);
this.isStaticFinal = isStaticFinal;
} }
@Override @Override
@@ -59,7 +63,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
isVar(), isVar(),
getName(), getName(),
getSource(), getSource(),
getOriginal() getOriginal(),
isStaticFinal
); );
assert getGetter() == null : "Field must not have a getter: " + this; assert getGetter() == null : "Field must not have a getter: " + this;
assert getSetter() == null : "Field must not have a setter: " + this; assert getSetter() == null : "Field must not have a setter: " + this;
@@ -76,4 +81,9 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
); );
return enhanced; return enhanced;
} }
@Override
public boolean isConst() {
return isStaticFinal && ConstUtil.canBeUsedForConstVal(getType());
}
} }
@@ -103,7 +103,8 @@ public class LazyJavaClassMemberScope(
val propertyDescriptor = JavaPropertyDescriptor( val propertyDescriptor = JavaPropertyDescriptor(
getContainingDeclaration(), annotations, method.getVisibility(), 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 // default getter is necessary because there is no real field in annotation
@@ -269,13 +269,15 @@ public abstract class LazyJavaScope(
val propertyName = field.getName() val propertyName = field.getName()
return JavaPropertyDescriptor(containingDeclaration, annotations, visibility, isVar, propertyName, 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 { private fun getPropertyType(field: JavaField, annotations: Annotations): JetType {
// Fields do not have their own generic parameters // 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: // simple static constants should not have flexible types:
val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field))
val propertyType = c.typeResolver.transformJavaType( val propertyType = c.typeResolver.transformJavaType(