Serialize compile time constant for property initializer

This commit is contained in:
Natalia Ukhorskaya
2014-02-06 14:53:13 +04:00
parent bb7312b47f
commit 9b5050dddd
23 changed files with 80 additions and 38 deletions
@@ -158,7 +158,7 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM4) {
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
final AnnotationVisitor v = memberVisitor.visitField(Name.guess(name), desc);
final AnnotationVisitor v = memberVisitor.visitField(Name.guess(name), desc, value);
if (v == null) return null;
return new FieldVisitor(ASM4) {
@@ -234,4 +234,4 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
e
);
}
}
}
@@ -170,6 +170,7 @@ message Callable {
MemberKind
hasGetter
hasSetter
hasConstant
*/
optional int32 flags = 1;
optional string extra_visibility = 2; // for things like java-specific visibilities
@@ -18,15 +18,13 @@ package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers;
import org.jetbrains.jet.descriptors.serialization.descriptors.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.storage.StorageManager;
@@ -195,6 +193,11 @@ public class DescriptorDeserializer {
}
}
property.setCompileTimeInitializer(
getPropertyConstant(containingDeclaration, proto, flags, AnnotatedCallableKind.PROPERTY,
deserializers.getConstantDeserializer(), nameResolver)
);
property.initialize(getter, setter);
return property;
@@ -269,6 +272,23 @@ public class DescriptorDeserializer {
: Annotations.EMPTY;
}
@Nullable
public static CompileTimeConstant<?> getPropertyConstant(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Callable proto,
int flags,
@NotNull AnnotatedCallableKind kind,
@NotNull ConstantDeserializer constantDeserializer,
@NotNull NameResolver nameResolver
) {
assert containingDeclaration instanceof ClassOrPackageFragmentDescriptor
: "Only members in classes or package fragments should be serialized: " + containingDeclaration;
return Flags.HAS_CONSTANT.get(flags)
? constantDeserializer
.loadPropertyConstant((ClassOrPackageFragmentDescriptor) containingDeclaration, proto, nameResolver, kind)
: null;
}
public static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
switch (memberKind) {
case DECLARATION:
@@ -161,6 +161,7 @@ public class DescriptorSerializer {
boolean hasGetter = false;
boolean hasSetter = false;
boolean hasConstant = false;
if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
@@ -194,6 +195,8 @@ public class DescriptorSerializer {
}
}
}
hasConstant = propertyDescriptor.getCompileTimeInitializer() != null;
}
builder.setFlags(Flags.getCallableFlags(
@@ -203,7 +206,8 @@ public class DescriptorSerializer {
descriptor.getKind(),
callableKind(descriptor),
hasGetter,
hasSetter
hasSetter,
hasConstant
));
//TODO builder.setExtraVisibility()
@@ -30,6 +30,7 @@ public class Flags {
ProtoBuf.Callable.MemberKind.values());
public static final FlagField<Boolean> HAS_GETTER = FlagField.booleanAfter(MEMBER_KIND);
public static final FlagField<Boolean> HAS_SETTER = FlagField.booleanAfter(HAS_GETTER);
public static final FlagField<Boolean> HAS_CONSTANT = FlagField.booleanAfter(HAS_SETTER);
// Parameters
@@ -93,7 +94,8 @@ public class Flags {
@NotNull CallableMemberDescriptor.Kind memberKind,
@NotNull ProtoBuf.Callable.CallableKind callableKind,
boolean hasGetter,
boolean hasSetter
boolean hasSetter,
boolean hasConstant
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| MODALITY.toFlags(modality(modality))
@@ -102,6 +104,7 @@ public class Flags {
| CALLABLE_KIND.toFlags(callableKind)
| HAS_GETTER.toFlags(hasGetter)
| HAS_SETTER.toFlags(hasSetter)
| HAS_CONSTANT.toFlags(hasConstant)
;
}
@@ -8,7 +8,7 @@ internal final class A {
internal class object <class-object-for-B> {
/*primary*/ private constructor <class-object-for-B>()
internal final val TEST: kotlin.Int
internal final val TEST: kotlin.Int = 1.toInt()
internal final fun <get-TEST>(): kotlin.Int
}
}
@@ -1,6 +1,6 @@
package test
test.Anno(t = ElementType.FIELD: java.lang.annotation.ElementType) internal val bar: kotlin.Int
test.Anno(t = ElementType.FIELD: java.lang.annotation.ElementType) internal val bar: kotlin.Int = 42.toInt()
internal fun <get-bar>(): kotlin.Int
test.Anno(t = ElementType.METHOD: java.lang.annotation.ElementType) internal fun foo(): kotlin.Unit
@@ -2,12 +2,12 @@ package test
internal final class ConstructorTypeParamClassObjectConflict</*0*/ test> {
/*primary*/ public constructor ConstructorTypeParamClassObjectConflict</*0*/ test>()
internal final val some: kotlin.Int
internal final val some: kotlin.Int = 12.toInt()
internal final fun <get-some>(): kotlin.Int
internal class object <class-object-for-ConstructorTypeParamClassObjectConflict> {
/*primary*/ private constructor <class-object-for-ConstructorTypeParamClassObjectConflict>()
internal final val test: kotlin.Int
internal final val test: kotlin.Int = 12.toInt()
internal final fun <get-test>(): kotlin.Int
}
}
@@ -27,14 +27,14 @@ internal final class ConstructorTypeParamClassObjectTypeConflict</*0*/ test> {
internal final class TestClassObjectAndClassConflict {
/*primary*/ public constructor TestClassObjectAndClassConflict()
internal final val bla: kotlin.String
internal final val bla: kotlin.String = "More"
internal final fun <get-bla>(): kotlin.String
internal final val some: kotlin.String
internal final val some: kotlin.String = "More"
internal final fun <get-some>(): kotlin.String
internal class object <class-object-for-TestClassObjectAndClassConflict> {
/*primary*/ private constructor <class-object-for-TestClassObjectAndClassConflict>()
internal final val bla: kotlin.Int
internal final val bla: kotlin.Int = 12.toInt()
internal final fun <get-bla>(): kotlin.Int
}
}
@@ -46,7 +46,7 @@ internal final class TestConstructorParamClassObjectConflict {
internal class object <class-object-for-TestConstructorParamClassObjectConflict> {
/*primary*/ private constructor <class-object-for-TestConstructorParamClassObjectConflict>()
internal final val test: kotlin.Int
internal final val test: kotlin.Int = 12.toInt()
internal final fun <get-test>(): kotlin.Int
}
}
@@ -60,7 +60,7 @@ internal final class TestConstructorValClassObjectConflict {
internal class object <class-object-for-TestConstructorValClassObjectConflict> {
/*primary*/ private constructor <class-object-for-TestConstructorValClassObjectConflict>()
internal final val test: kotlin.Int
internal final val test: kotlin.Int = 12.toInt()
internal final fun <get-test>(): kotlin.Int
}
}
@@ -1,6 +1,6 @@
package test
internal val x: kotlin.Int
internal val x: kotlin.Int = 5.toInt()
internal fun <get-x>(): kotlin.Int
public object Obj {
@@ -5,7 +5,7 @@ internal final class ClassObjectDeclaresProperty {
internal class object <class-object-for-ClassObjectDeclaresProperty> {
/*primary*/ private constructor <class-object-for-ClassObjectDeclaresProperty>()
internal final val i: kotlin.Int
internal final val i: kotlin.Int = 1.toInt()
internal final fun <get-i>(): kotlin.Int
}
}
@@ -2,12 +2,12 @@ package test
internal final class A {
/*primary*/ public constructor A()
internal final val other: kotlin.Int
internal final val other: kotlin.Int = 1.toInt()
internal final fun <get-other>(): kotlin.Int
internal class object <class-object-for-A> {
/*primary*/ private constructor <class-object-for-A>()
internal final val some: kotlin.Int
internal final val some: kotlin.Int = 1.toInt()
internal final fun <get-some>(): kotlin.Int
}
}
@@ -2,6 +2,6 @@ package test
internal final class ClassVal {
/*primary*/ public constructor ClassVal()
internal final val aa: kotlin.Int
internal final val aa: kotlin.Int = 1.toInt()
internal final fun <get-aa>(): kotlin.Int
}
@@ -1,4 +1,4 @@
package test
internal val nsVal: kotlin.Int
internal val nsVal: kotlin.Int = 1.toInt()
internal fun <get-nsVal>(): kotlin.Int
@@ -2,12 +2,12 @@ package test
internal open class BaseClass {
/*primary*/ public constructor BaseClass()
internal open val shape: kotlin.String
internal open val shape: kotlin.String = "square"
internal open fun <get-shape>(): kotlin.String
}
internal open class Subclass : test.BaseClass {
/*primary*/ public constructor Subclass()
internal open override /*1*/ val shape: kotlin.String
internal open override /*1*/ val shape: kotlin.String = "circle"
internal open override /*1*/ fun <get-shape>(): kotlin.String
}
@@ -2,7 +2,7 @@ package test
internal open class Subclass : test.Trait {
/*primary*/ public constructor Subclass()
internal open override /*1*/ val shape: kotlin.String
internal open override /*1*/ val shape: kotlin.String = "circle"
internal open override /*1*/ fun <get-shape>(): kotlin.String
}
@@ -2,7 +2,7 @@ package test
internal open class BaseClass {
/*primary*/ public constructor BaseClass()
internal final val exactly: kotlin.Int
internal final val exactly: kotlin.Int = 17.toInt()
internal final fun <get-exactly>(): kotlin.Int
}
@@ -2,9 +2,9 @@ package test
internal final class ClassVal {
/*primary*/ public constructor ClassVal()
internal final val property1: kotlin.Int
internal final val property1: kotlin.Int = 1.toInt()
internal final fun <get-property1>(): kotlin.Int
internal final val property2: kotlin.Int
internal final val property2: kotlin.Int = 1.toInt()
internal final fun <get-property2>(): kotlin.Int
private final val property3: java.lang.Object
private final fun <get-property3>(): java.lang.Object
@@ -2,9 +2,9 @@ package test
internal final class ClassVal {
/*primary*/ public constructor ClassVal()
internal final val property1: kotlin.Int
internal final val property1: kotlin.Int = 1.toInt()
internal final fun <get-property1>(): kotlin.Int
internal final val property2: kotlin.Int
internal final val property2: kotlin.Int = 1.toInt()
internal final fun <get-property2>(): kotlin.Int
private final val property3: java.lang.Object
private final fun <get-property3>(): java.lang.Object
@@ -1,5 +1,5 @@
package test
internal val x: kotlin.Int
internal val x: kotlin.Int = 0.toInt()
internal fun <get-x>(): kotlin.Int
internal fun f(): kotlin.Int
@@ -1,4 +1,4 @@
package test
private val topLevelVal: kotlin.Int
private val topLevelVal: kotlin.Int = 0.toInt()
private fun <get-topLevelVal>(): kotlin.Int
@@ -56,6 +56,16 @@ public class RecursiveDescriptorComparator {
public static final Configuration RECURSIVE = new Configuration(false, false, true,
Predicates.<FqName>alwaysTrue(),
FORBID_ERROR_TYPES, DEFAULT_RENDERER);
public static final Configuration WITHOUT_COMPILE_TIME_CONSTANTS = new Configuration(false, false, true,
Predicates.<FqName>alwaysTrue(),
FORBID_ERROR_TYPES,
new DescriptorRendererBuilder()
.setWithDefinedIn(false)
.setExcludedAnnotationClasses(Arrays.asList(new FqName(ExpectedLoadErrorsUtil.ANNOTATION_CLASS_NAME)))
.setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE)
.setVerbose(true)
.setIncludePropertyConstant(false)
.build());
public static final Configuration RECURSIVE_ALL = new Configuration(true, true, true,
Predicates.<FqName>alwaysTrue(),
@@ -20,11 +20,10 @@ import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.ResolverPackage;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver;
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
@@ -87,8 +86,13 @@ public class DescriptorDeserializersStorage {
@Nullable
@Override
public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc) {
return new MemberAnnotationVisitor(MemberSignature.fromFieldNameAndDesc(name, desc));
public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc, @Nullable Object initializer) {
MemberSignature signature = MemberSignature.fromFieldNameAndDesc(name, desc);
if (initializer != null) {
propertyConstants.put(signature, ConstantUtils.createCompileTimeConstant(
initializer, /* canBeUsedInAnnotation */ true, /* isPureIntConstant */ true, /* expectedType */ null));
}
return new MemberAnnotationVisitor(signature);
}
class AnnotationVisitorForMethod extends MemberAnnotationVisitor implements KotlinJvmBinaryClass.MethodAnnotationVisitor {
@@ -40,7 +40,7 @@ public interface KotlinJvmBinaryClass {
MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc);
@Nullable
AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc);
AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc, @Nullable Object initializer);
}
interface AnnotationVisitor {