diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java index 1b4e188e22d..009e981f7bb 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java @@ -83,7 +83,7 @@ public class DescriptorDeserializer { @NotNull public CallableMemberDescriptor loadCallable(@NotNull Callable proto) { - Callable.CallableKind callableKind = Flags.getCallableKind(proto.getFlags()); + Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(proto.getFlags()); switch (callableKind) { case FUN: return loadFunction(proto); @@ -102,11 +102,11 @@ public class DescriptorDeserializer { PropertyDescriptorImpl property = new PropertyDescriptorImpl( containingDeclaration, getAnnotations(proto), - modality(Flags.getModality(flags)), - visibility(Flags.getVisibility(flags)), - Flags.getCallableKind(flags) == Callable.CallableKind.VAR, + modality(Flags.MODALITY.get(flags)), + visibility(Flags.VISIBILITY.get(flags)), + Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR, nameResolver.getName(proto.getName()), - memberKind(Flags.getMemberKind(flags)) + memberKind(Flags.MEMBER_KIND.get(flags)) ); DescriptorDeserializer local = createChildDeserializer(property); List typeParameters = local.typeParameters(proto.getTypeParametersList()); @@ -127,7 +127,7 @@ public class DescriptorDeserializer { containingDeclaration, getAnnotations(proto), nameResolver.getName(proto.getName()), - memberKind(Flags.getMemberKind(flags)) + memberKind(Flags.MEMBER_KIND.get(flags)) ); DescriptorDeserializer local = createChildDeserializer(function); List typeParameters = local.typeParameters(proto.getTypeParametersList()); @@ -138,9 +138,9 @@ public class DescriptorDeserializer { typeParameters, local.valueParameters(proto.getValueParametersList()), local.typeDeserializer.type(proto.getReturnType()), - modality(Flags.getModality(flags)), - visibility(Flags.getVisibility(flags)), - Flags.isInline(flags) + modality(Flags.MODALITY.get(flags)), + visibility(Flags.VISIBILITY.get(flags)), + Flags.INLINE.get(flags) ); return function; @@ -158,14 +158,14 @@ public class DescriptorDeserializer { descriptor.initialize( classDescriptor.getTypeConstructor().getParameters(), local.valueParameters(proto.getValueParametersList()), - visibility(Flags.getVisibility(proto.getFlags())), + visibility(Flags.VISIBILITY.get(proto.getFlags())), !classDescriptor.isInner() ); return descriptor; } private List getAnnotations(Callable proto) { - return Flags.hasAnnotations(proto.getFlags()) + return Flags.HAS_ANNOTATIONS.get(proto.getFlags()) ? annotationDeserializer.loadCallableAnnotations(proto) : Collections.emptyList(); } @@ -304,12 +304,12 @@ public class DescriptorDeserializer { getAnnotations(proto), nameResolver.getName(proto.getName()), typeDeserializer.type(proto.getType()), - Flags.declaresDefaultValue(proto.getFlags()), + Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()), typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null)); } private List getAnnotations(Callable.ValueParameter proto) { - return Flags.hasAnnotations(proto.getFlags()) + return Flags.HAS_ANNOTATIONS.get(proto.getFlags()) ? annotationDeserializer.loadValueParameterAnnotations(proto) : Collections.emptyList(); } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/Flags.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/Flags.java index d67db3a0215..d91bdbe21f8 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/Flags.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/Flags.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.descriptors.serialization; +import com.google.protobuf.Internal; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; @@ -8,44 +9,34 @@ public class Flags { // Common - public static final int HAS_ANNOTATIONS_BIT_COUNT = 1; - public static final int HAS_ANNOTATIONS_OFFSET = 0; + public static final FlagField HAS_ANNOTATIONS = FlagField.booleanFirst(); - public static final int VISIBILITY_BIT_COUNT = bitWidth(ProtoBuf.Visibility.values()); - public static final int VISIBILITY_OFFSET = HAS_ANNOTATIONS_OFFSET + HAS_ANNOTATIONS_BIT_COUNT; + public static final FlagField VISIBILITY = FlagField.after(HAS_ANNOTATIONS, ProtoBuf.Visibility.values()); - public static final int MODALITY_BIT_COUNT = bitWidth(ProtoBuf.Modality.values()); - public static final int MODALITY_OFFSET = VISIBILITY_OFFSET + VISIBILITY_BIT_COUNT; + public static final FlagField MODALITY = FlagField.after(VISIBILITY, ProtoBuf.Modality.values()); // Class - public static final int CLASS_KIND_BIT_COUNT = bitWidth(ProtoBuf.Class.Kind.values()); - public static final int CLASS_KIND_OFFSET = MODALITY_OFFSET + MODALITY_BIT_COUNT; + public static final FlagField CLASS_KIND = FlagField.after(MODALITY, ProtoBuf.Class.Kind.values()); - public static final int INNER_BIT_COUNT = 1; - public static final int INNER_OFFSET = CLASS_KIND_OFFSET + CLASS_KIND_BIT_COUNT; + public static final FlagField INNER = FlagField.booleanAfter(CLASS_KIND); // Callables - public static final int CALLABLE_KIND_BIT_COUNT = bitWidth(ProtoBuf.Callable.CallableKind.values()); - public static final int CALLABLE_KIND_OFFSET = MODALITY_OFFSET + MODALITY_BIT_COUNT; + public static final FlagField CALLABLE_KIND = FlagField.after(MODALITY, + ProtoBuf.Callable.CallableKind.values()); - public static final int MEMBER_KIND_BIT_COUNT = bitWidth(ProtoBuf.Callable.MemberKind.values()); - public static final int MEMBER_KIND_OFFSET = CALLABLE_KIND_OFFSET + CALLABLE_KIND_BIT_COUNT; - - public static final int INLINE_BIT_COUNT = 1; - public static final int INLINE_OFFSET = MEMBER_KIND_OFFSET + MEMBER_KIND_BIT_COUNT; + public static final FlagField MEMBER_KIND = FlagField.after(CALLABLE_KIND, + ProtoBuf.Callable.MemberKind.values()); + public static final FlagField INLINE = FlagField.booleanAfter(MEMBER_KIND); // Parameters - public static final int DECLARES_DEFAULT_VALUE_BIT_COUNT = 1; - public static final int DECLARES_DEFAULT_VALUE_OFFSET = HAS_ANNOTATIONS_OFFSET + HAS_ANNOTATIONS_BIT_COUNT; + public static final FlagField DECLARES_DEFAULT_VALUE = FlagField.booleanAfter(HAS_ANNOTATIONS); // --- - private static final Boolean[] BOOLEANS = { false, true }; - - private static > int bitWidth(@NotNull E[] enumEntries) { + private static int bitWidth(@NotNull E[] enumEntries) { int length = enumEntries.length - 1; if (length == 0) return 1; for (int i = 31; i >= 0; i--) { @@ -54,55 +45,6 @@ public class Flags { throw new IllegalStateException("Empty enum: " + enumEntries.getClass()); } - @NotNull - private static E getValue(int flags, @NotNull E[] values, int count, int offset) { - int maskUnshifted = (1 << count) - 1; - int mask = maskUnshifted << offset; - int value = (flags & mask) >> offset; - return values[value]; - } - - @NotNull - public static ProtoBuf.Visibility getVisibility(int flags) { - return getValue(flags, ProtoBuf.Visibility.values(), VISIBILITY_BIT_COUNT, VISIBILITY_OFFSET); - } - - @NotNull - public static ProtoBuf.Modality getModality(int flags) { - return getValue(flags, ProtoBuf.Modality.values(), MODALITY_BIT_COUNT, MODALITY_OFFSET); - } - - @NotNull - public static ProtoBuf.Class.Kind getClassKind(int flags) { - return getValue(flags, ProtoBuf.Class.Kind.values(), CLASS_KIND_BIT_COUNT, CLASS_KIND_OFFSET); - } - - public static boolean isInner(int flags) { - return getValue(flags, BOOLEANS, INNER_BIT_COUNT, INNER_OFFSET); - } - - @NotNull - public static ProtoBuf.Callable.CallableKind getCallableKind(int flags) { - return getValue(flags, ProtoBuf.Callable.CallableKind.values(), CALLABLE_KIND_BIT_COUNT, CALLABLE_KIND_OFFSET); - } - - @NotNull - public static ProtoBuf.Callable.MemberKind getMemberKind(int flags) { - return getValue(flags, ProtoBuf.Callable.MemberKind.values(), MEMBER_KIND_BIT_COUNT, MEMBER_KIND_OFFSET); - } - - public static boolean isInline(int flags) { - return getValue(flags, BOOLEANS, INLINE_BIT_COUNT, INLINE_OFFSET); - } - - public static boolean declaresDefaultValue(int flags) { - return getValue(flags, BOOLEANS, DECLARES_DEFAULT_VALUE_BIT_COUNT, DECLARES_DEFAULT_VALUE_OFFSET); - } - - public static boolean hasAnnotations(int flags) { - return getValue(flags, BOOLEANS, HAS_ANNOTATIONS_BIT_COUNT, HAS_ANNOTATIONS_OFFSET); - } - public static int getClassFlags( boolean hasAnnotations, Visibility visibility, @@ -110,16 +52,11 @@ public class Flags { ClassKind kind, boolean inner ) { - int hasAnnotationsInt = hasAnnotations ? 1 : 0; - int visibilityInt = visibility(visibility).getNumber(); - int modalityInt = modality(modality).getNumber(); - int classKindInt = classKind(kind).getNumber(); - int innerInt = inner ? 1 : 0; - return hasAnnotationsInt << HAS_ANNOTATIONS_OFFSET - | modalityInt << MODALITY_OFFSET - | visibilityInt << VISIBILITY_OFFSET - | classKindInt << CLASS_KIND_OFFSET - | innerInt << INNER_OFFSET + return HAS_ANNOTATIONS.toFlags(hasAnnotations) + | MODALITY.toFlags(modality(modality)) + | VISIBILITY.toFlags(visibility(visibility)) + | CLASS_KIND.toFlags(classKind(kind)) + | INNER.toFlags(inner) ; } @@ -144,24 +81,19 @@ public class Flags { } public static int getCallableFlags( - boolean hasAnnotations, @NotNull Visibility visibility, + boolean hasAnnotations, + @NotNull Visibility visibility, @NotNull Modality modality, @NotNull CallableMemberDescriptor.Kind memberKind, @NotNull ProtoBuf.Callable.CallableKind callableKind, boolean inline ) { - int hasAnnotationsInt = hasAnnotations ? 1 : 0; - int visibilityInt = visibility(visibility).getNumber(); - int modalityInt = modality(modality).getNumber(); - int memberKindInt = memberKind(memberKind).getNumber(); - int callableKindInt = callableKind.getNumber(); - int inlineInt = inline ? 1 : 0; - return hasAnnotationsInt << HAS_ANNOTATIONS_OFFSET - | modalityInt << MODALITY_OFFSET - | visibilityInt << VISIBILITY_OFFSET - | memberKindInt << MEMBER_KIND_OFFSET - | callableKindInt << CALLABLE_KIND_OFFSET - | inlineInt << INLINE_OFFSET + return HAS_ANNOTATIONS.toFlags(hasAnnotations) + | MODALITY.toFlags(modality(modality)) + | VISIBILITY.toFlags(visibility(visibility)) + | MEMBER_KIND.toFlags(memberKind(memberKind)) + | CALLABLE_KIND.toFlags(callableKind) + | INLINE.toFlags(inline) ; } @@ -211,10 +143,79 @@ public class Flags { } public static int getValueParameterFlags(boolean hasAnnotations, boolean declaresDefaultValue) { - int hasAnnotationsInt = hasAnnotations ? 1 : 0; - int declaresDefaultValueInt = declaresDefaultValue ? 1 : 0; - return hasAnnotationsInt << HAS_ANNOTATIONS_OFFSET - | declaresDefaultValueInt << DECLARES_DEFAULT_VALUE_OFFSET + return HAS_ANNOTATIONS.toFlags(hasAnnotations) + | DECLARES_DEFAULT_VALUE.toFlags(declaresDefaultValue) ; } + + // Infrastructure + + public static abstract class FlagField { + public static FlagField after(FlagField previousField, E[] values) { + int offset = previousField.offset + previousField.bitWidth; + return new EnumLiteFlagField(offset, values); + } + + public static FlagField first(E[] values) { + return new EnumLiteFlagField(0, values); + } + + public static FlagField booleanFirst() { + return new BooleanFlagField(0); + } + + public static FlagField booleanAfter(FlagField previousField) { + int offset = previousField.offset + previousField.bitWidth; + return new BooleanFlagField(offset); + } + + private final int offset; + private final int bitWidth; + private final E[] values; + + private FlagField(int offset, E[] values) { + this.offset = offset; + this.bitWidth = bitWidth(values); + this.values = values; + } + + public E get(int flags) { + int maskUnshifted = (1 << bitWidth) - 1; + int mask = maskUnshifted << offset; + int value = (flags & mask) >> offset; + return values[value]; + } + + public int toFlags(E value) { + return getIntValue(value) << offset; + } + + protected abstract int getIntValue(E value); + + } + + private static class BooleanFlagField extends FlagField { + private static final Boolean[] BOOLEAN = { false, true }; + + public BooleanFlagField(int offset) { + super(offset, BOOLEAN); + } + + @Override + protected int getIntValue(Boolean value) { + return value ? 1 : 0; + } + } + + private static class EnumLiteFlagField extends FlagField { + public EnumLiteFlagField(int offset, E[] values) { + super(offset, values); + } + + @Override + protected int getIntValue(E value) { + return value.getNumber(); + } + } + } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java index 013b9729139..510eb55f10e 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -81,10 +81,10 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements this.name = nameResolver.getName(classProto.getName()); int flags = classProto.getFlags(); - this.modality = DescriptorDeserializer.modality(Flags.getModality(flags)); - this.visibility = DescriptorDeserializer.visibility(Flags.getVisibility(flags)); - this.kind = DescriptorDeserializer.classKind(Flags.getClassKind(flags)); - this.isInner = Flags.isInner(flags); + this.modality = DescriptorDeserializer.modality(Flags.MODALITY.get(flags)); + this.visibility = DescriptorDeserializer.visibility(Flags.VISIBILITY.get(flags)); + this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags)); + this.isInner = Flags.INNER.get(flags); this.annotationDeserializer = annotationResolver; this.annotations = new NotNullLazyValueImpl>() { @@ -181,7 +181,7 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements } private List computeAnnotations() { - if (!Flags.hasAnnotations(classProto.getFlags())) { + if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) { return Collections.emptyList(); } return annotationDeserializer.loadClassAnnotations(classProto); diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java index a348ccbdd76..8a96a40901c 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java @@ -117,7 +117,7 @@ public abstract class DeserializedMemberScope implements JetScope { Collection descriptors = new LinkedHashSet(memberProtos != null ? memberProtos.size() : 0); if (memberProtos != null) { for (ProtoBuf.Callable memberProto : memberProtos) { - if (callableKind.accept(Flags.getCallableKind(memberProto.getFlags()))) { + if (callableKind.accept(Flags.CALLABLE_KIND.get(memberProto.getFlags()))) { //noinspection unchecked descriptors.add((D) deserializer.loadCallable(memberProto)); }