Split ProtoBuf.Callable to three messages: constructor, function, property

Serialize both at the moment, will drop the old one after bootstrap
This commit is contained in:
Alexander Udalov
2015-09-30 16:41:12 +03:00
parent 041af28166
commit ad735cd788
10 changed files with 12155 additions and 191 deletions
@@ -129,6 +129,10 @@ public class DescriptorSerializer {
}
}
for (ConstructorDescriptor descriptor : classDescriptor.getConstructors()) {
builder.addConstructor(constructorProto(descriptor));
}
for (ConstructorDescriptor constructorDescriptor : getSecondaryConstructors(classDescriptor)) {
builder.addSecondaryConstructor(callableProto(constructorDescriptor));
}
@@ -138,6 +142,13 @@ public class DescriptorSerializer {
CallableMemberDescriptor member = (CallableMemberDescriptor) descriptor;
if (member.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue;
builder.addMember(callableProto(member));
if (descriptor instanceof PropertyDescriptor) {
builder.addProperty(propertyProto((PropertyDescriptor) descriptor));
}
else if (descriptor instanceof FunctionDescriptor) {
builder.addFunction(functionProto((FunctionDescriptor) descriptor));
}
}
}
@@ -161,6 +172,143 @@ public class DescriptorSerializer {
return builder;
}
@NotNull
public ProtoBuf.Property.Builder propertyProto(@NotNull PropertyDescriptor descriptor) {
ProtoBuf.Property.Builder builder = ProtoBuf.Property.newBuilder();
DescriptorSerializer local = createChildSerializer();
boolean hasGetter = false;
boolean hasSetter = false;
boolean lateInit = descriptor.isLateInit();
boolean isConst = descriptor.isConst();
ConstantValue<?> compileTimeConstant = descriptor.getCompileTimeInitializer();
boolean hasConstant = !(compileTimeConstant == null || compileTimeConstant instanceof NullValue);
boolean hasAnnotations = !descriptor.getAnnotations().getAllAnnotations().isEmpty();
int propertyFlags = Flags.getAccessorFlags(
hasAnnotations,
descriptor.getVisibility(),
descriptor.getModality(),
false
);
PropertyGetterDescriptor getter = descriptor.getGetter();
if (getter != null) {
hasGetter = true;
int accessorFlags = getAccessorFlags(getter);
if (accessorFlags != propertyFlags) {
builder.setGetterFlags(accessorFlags);
}
}
PropertySetterDescriptor setter = descriptor.getSetter();
if (setter != null) {
hasSetter = true;
int accessorFlags = getAccessorFlags(setter);
if (accessorFlags != propertyFlags) {
builder.setSetterFlags(accessorFlags);
}
if (!setter.isDefault()) {
for (ValueParameterDescriptor valueParameterDescriptor : setter.getValueParameters()) {
builder.setSetterValueParameter(local.valueParameter(valueParameterDescriptor));
}
}
}
builder.setFlags(Flags.getPropertyFlags(
hasAnnotations,
descriptor.getVisibility(),
descriptor.getModality(),
descriptor.getKind(),
descriptor.isVar(),
hasGetter,
hasSetter,
hasConstant,
isConst,
lateInit
));
builder.setName(getSimpleNameIndex(descriptor.getName()));
builder.setReturnType(local.type(descriptor.getType()));
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
builder.addTypeParameter(local.typeParameter(typeParameterDescriptor));
}
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
if (receiverParameter != null) {
builder.setReceiverType(local.type(receiverParameter.getType()));
}
extension.serializeProperty(descriptor, builder);
return builder;
}
@NotNull
public ProtoBuf.Function.Builder functionProto(@NotNull FunctionDescriptor descriptor) {
ProtoBuf.Function.Builder builder = ProtoBuf.Function.newBuilder();
DescriptorSerializer local = createChildSerializer();
builder.setFlags(Flags.getFunctionFlags(
hasAnnotations(descriptor),
descriptor.getVisibility(),
descriptor.getModality(),
descriptor.getKind(),
descriptor.isOperator(),
descriptor.isInfix()
));
builder.setName(getSimpleNameIndex(descriptor.getName()));
//noinspection ConstantConditions
builder.setReturnType(local.type(descriptor.getReturnType()));
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
builder.addTypeParameter(local.typeParameter(typeParameterDescriptor));
}
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
if (receiverParameter != null) {
builder.setReceiverType(local.type(receiverParameter.getType()));
}
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
builder.addValueParameter(local.valueParameter(valueParameterDescriptor));
}
extension.serializeFunction(descriptor, builder);
return builder;
}
@NotNull
public ProtoBuf.Constructor.Builder constructorProto(@NotNull ConstructorDescriptor descriptor) {
ProtoBuf.Constructor.Builder builder = ProtoBuf.Constructor.newBuilder();
DescriptorSerializer local = createChildSerializer();
builder.setFlags(Flags.getConstructorFlags(
hasAnnotations(descriptor),
descriptor.getVisibility(),
!descriptor.isPrimary()
));
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
builder.addValueParameter(local.valueParameter(valueParameterDescriptor));
}
extension.serializeConstructor(descriptor, builder);
return builder;
}
@NotNull
public ProtoBuf.Callable.Builder callableProto(@NotNull CallableMemberDescriptor descriptor) {
ProtoBuf.Callable.Builder builder = ProtoBuf.Callable.newBuilder();
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.types.JetType;
import java.util.Collection;
@@ -35,6 +32,15 @@ public abstract class SerializerExtension {
public void serializePackage(@NotNull Collection<PackageFragmentDescriptor> packageFragments, @NotNull ProtoBuf.Package.Builder proto) {
}
public void serializeConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull ProtoBuf.Constructor.Builder proto) {
}
public void serializeFunction(@NotNull FunctionDescriptor descriptor, @NotNull ProtoBuf.Function.Builder proto) {
}
public void serializeProperty(@NotNull PropertyDescriptor descriptor, @NotNull ProtoBuf.Property.Builder proto) {
}
public void serializeCallable(@NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto) {
}
File diff suppressed because it is too large Load Diff
@@ -173,6 +173,10 @@ message Class {
repeated int32 nested_class_name = 7 [packed = true, (name_id_in_table) = true];
repeated Constructor constructor = 8;
repeated Function function = 9;
repeated Property property = 10;
repeated Callable member = 11;
repeated int32 enum_entry = 12 [packed = true, (name_id_in_table) = true];
@@ -194,6 +198,84 @@ message Class {
message Package {
repeated Callable member = 1;
repeated Constructor constructor = 2;
repeated Function function = 3;
repeated Property property = 4;
extensions 100 to 199;
}
message Constructor {
/*
hasAnnotations
Visibility
isSecondary
*/
optional int32 flags = 1;
repeated ValueParameter value_parameter = 2;
extensions 100 to 199;
}
message Function {
/*
hasAnnotations
Visibility
Modality
MemberKind
isOperator
isInfix
*/
optional int32 flags = 1;
required int32 name = 2 [(name_id_in_table) = true];
required Type return_type = 3;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
repeated ValueParameter value_parameter = 6;
extensions 100 to 199;
}
message Property {
/*
hasAnnotations
Visibility
Modality
MemberKind
isVar
hasGetter
hasSetter
isConst
lateinit
hasConstant
*/
optional int32 flags = 1;
required int32 name = 2 [(name_id_in_table) = true];
required Type return_type = 3;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
optional ValueParameter setter_value_parameter = 6;
/*
hasAnnotations
Visibility
Modality
isNotDefault
*/
optional int32 getter_flags = 7 /* absent => same as property */;
optional int32 setter_flags = 8 /* absent => same as property */;
extensions 100 to 199;
}
@@ -26,34 +26,47 @@ public class Flags {
// Common
public static final FlagField<Boolean> HAS_ANNOTATIONS = FlagField.booleanFirst();
public static final FlagField<ProtoBuf.Visibility> VISIBILITY = FlagField.after(HAS_ANNOTATIONS, ProtoBuf.Visibility.values());
public static final FlagField<ProtoBuf.Modality> MODALITY = FlagField.after(VISIBILITY, ProtoBuf.Modality.values());
// Class
public static final FlagField<ProtoBuf.Class.Kind> CLASS_KIND = FlagField.after(MODALITY, ProtoBuf.Class.Kind.values());
public static final FlagField<Boolean> INNER = FlagField.booleanAfter(CLASS_KIND);
// Callables
public static final FlagField<ProtoBuf.CallableKind> CALLABLE_KIND = FlagField.after(MODALITY, ProtoBuf.CallableKind.values());
public static final FlagField<ProtoBuf.MemberKind> MEMBER_KIND = FlagField.after(CALLABLE_KIND, ProtoBuf.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);
public static final FlagField<Boolean> IS_CONST = FlagField.booleanAfter(HAS_CONSTANT);
// Constructors
public static final FlagField<Boolean> LATE_INIT = FlagField.booleanAfter(IS_CONST);
public static final FlagField<Boolean> IS_SECONDARY = FlagField.booleanAfter(VISIBILITY);
public static final FlagField<Boolean> IS_OPERATOR = FlagField.booleanAfter(LATE_INIT);
// Functions
public static final FlagField<Boolean> IS_OPERATOR = FlagField.booleanAfter(MEMBER_KIND);
public static final FlagField<Boolean> IS_INFIX = FlagField.booleanAfter(IS_OPERATOR);
// Properties
public static final FlagField<Boolean> IS_VAR = FlagField.booleanAfter(MEMBER_KIND);
public static final FlagField<Boolean> HAS_GETTER = FlagField.booleanAfter(IS_VAR);
public static final FlagField<Boolean> HAS_SETTER = FlagField.booleanAfter(HAS_GETTER);
public static final FlagField<Boolean> IS_CONST = FlagField.booleanAfter(HAS_SETTER);
public static final FlagField<Boolean> LATE_INIT = FlagField.booleanAfter(IS_CONST);
public static final FlagField<Boolean> HAS_CONSTANT = FlagField.booleanAfter(LATE_INIT);
// Old callables. TODO: delete
public static final FlagField<Boolean> OLD_HAS_GETTER = FlagField.booleanAfter(MEMBER_KIND);
public static final FlagField<Boolean> OLD_HAS_SETTER = FlagField.booleanAfter(OLD_HAS_GETTER);
public static final FlagField<Boolean> OLD_HAS_CONSTANT = FlagField.booleanAfter(OLD_HAS_SETTER);
public static final FlagField<Boolean> OLD_IS_CONST = FlagField.booleanAfter(OLD_HAS_CONSTANT);
public static final FlagField<Boolean> OLD_LATE_INIT = FlagField.booleanAfter(OLD_IS_CONST);
public static final FlagField<Boolean> OLD_IS_OPERATOR = FlagField.booleanAfter(OLD_LATE_INIT);
public static final FlagField<Boolean> OLD_IS_INFIX = FlagField.booleanAfter(OLD_IS_OPERATOR);
// Parameters
public static final FlagField<Boolean> DECLARES_DEFAULT_VALUE = FlagField.booleanAfter(HAS_ANNOTATIONS);
@@ -129,14 +142,67 @@ public class Flags {
| VISIBILITY.toFlags(visibility(visibility))
| MEMBER_KIND.toFlags(memberKind(memberKind))
| CALLABLE_KIND.toFlags(callableKind)
| HAS_GETTER.toFlags(hasGetter)
| HAS_SETTER.toFlags(hasSetter)
| HAS_CONSTANT.toFlags(hasConstant)
| LATE_INIT.toFlags(lateInit)
| IS_CONST.toFlags(isConst)
| OLD_HAS_GETTER.toFlags(hasGetter)
| OLD_HAS_SETTER.toFlags(hasSetter)
| OLD_HAS_CONSTANT.toFlags(hasConstant)
| OLD_LATE_INIT.toFlags(lateInit)
| OLD_IS_CONST.toFlags(isConst)
| OLD_IS_OPERATOR.toFlags(isOperator)
| OLD_IS_INFIX.toFlags(isInfix)
;
}
public static int getConstructorFlags(
boolean hasAnnotations,
@NotNull Visibility visibility,
boolean isSecondary
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| VISIBILITY.toFlags(visibility(visibility))
| IS_SECONDARY.toFlags(isSecondary)
;
}
public static int getFunctionFlags(
boolean hasAnnotations,
@NotNull Visibility visibility,
@NotNull Modality modality,
@NotNull CallableMemberDescriptor.Kind memberKind,
boolean isOperator,
boolean isInfix
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| VISIBILITY.toFlags(visibility(visibility))
| MODALITY.toFlags(modality(modality))
| MEMBER_KIND.toFlags(memberKind(memberKind))
| IS_OPERATOR.toFlags(isOperator)
| IS_INFIX.toFlags(isInfix)
;
;
}
public static int getPropertyFlags(
boolean hasAnnotations,
@NotNull Visibility visibility,
@NotNull Modality modality,
@NotNull CallableMemberDescriptor.Kind memberKind,
boolean isVar,
boolean hasGetter,
boolean hasSetter,
boolean hasConstant,
boolean isConst,
boolean lateInit
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| VISIBILITY.toFlags(visibility(visibility))
| MODALITY.toFlags(modality(modality))
| MEMBER_KIND.toFlags(memberKind(memberKind))
| IS_VAR.toFlags(isVar)
| HAS_GETTER.toFlags(hasGetter)
| HAS_SETTER.toFlags(hasSetter)
| IS_CONST.toFlags(isConst)
| LATE_INIT.toFlags(lateInit)
| HAS_CONSTANT.toFlags(hasConstant)
;
}
public static int getAccessorFlags(
File diff suppressed because it is too large Load Diff
@@ -56,13 +56,13 @@ public class MemberDeserializer(private val c: DeserializationContext) {
Deserialization.memberKind(Flags.MEMBER_KIND.get(flags)),
proto,
c.nameResolver,
Flags.LATE_INIT.get(flags),
Flags.IS_CONST.get(flags)
Flags.OLD_LATE_INIT.get(flags),
Flags.OLD_IS_CONST.get(flags)
)
val local = c.childContext(property, proto.getTypeParameterList())
val hasGetter = Flags.HAS_GETTER.get(flags)
val hasGetter = Flags.OLD_HAS_GETTER.get(flags)
val receiverAnnotations = if (hasGetter)
getReceiverParameterAnnotations(proto, AnnotatedCallableKind.PROPERTY_GETTER)
else
@@ -99,7 +99,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
null
}
val setter = if (Flags.HAS_SETTER.get(flags)) {
val setter = if (Flags.OLD_HAS_SETTER.get(flags)) {
val setterFlags = proto.getSetterFlags()
val isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags)
if (isNotDefault) {
@@ -125,7 +125,7 @@ public class MemberDeserializer(private val c: DeserializationContext) {
null
}
if (Flags.HAS_CONSTANT.get(flags)) {
if (Flags.OLD_HAS_CONSTANT.get(flags)) {
property.setCompileTimeInitializer(
c.storageManager.createNullableLazyValue {
val container = c.containingDeclaration.asProtoContainer()!!
@@ -152,8 +152,8 @@ public class MemberDeserializer(private val c: DeserializationContext) {
local.typeDeserializer.type(proto.returnType),
Deserialization.modality(Flags.MODALITY.get(proto.flags)),
Deserialization.visibility(Flags.VISIBILITY.get(proto.flags)),
Flags.IS_OPERATOR.get(proto.flags),
Flags.IS_INFIX.get(proto.flags)
Flags.OLD_IS_OPERATOR.get(proto.flags),
Flags.OLD_IS_INFIX.get(proto.flags)
)
return function
}
@@ -188,25 +188,25 @@ enum class FlagsToModifiers {
CONST {
override fun getModifiers(flags: Int): JetModifierKeywordToken? {
return if (Flags.IS_CONST.get(flags)) JetTokens.CONST_KEYWORD else null
return if (Flags.OLD_IS_CONST.get(flags)) JetTokens.CONST_KEYWORD else null
}
},
LATEINIT {
override fun getModifiers(flags: Int): JetModifierKeywordToken? {
return if (Flags.LATE_INIT.get(flags)) JetTokens.LATE_INIT_KEYWORD else null
return if (Flags.OLD_LATE_INIT.get(flags)) JetTokens.LATE_INIT_KEYWORD else null
}
},
OPERATOR {
override fun getModifiers(flags: Int): JetModifierKeywordToken? {
return if (Flags.IS_OPERATOR.get(flags)) JetTokens.OPERATOR_KEYWORD else null
return if (Flags.OLD_IS_OPERATOR.get(flags)) JetTokens.OPERATOR_KEYWORD else null
}
},
INFIX {
override fun getModifiers(flags: Int): JetModifierKeywordToken? {
return if (Flags.IS_INFIX.get(flags)) JetTokens.INFIX_KEYWORD else null
return if (Flags.OLD_IS_INFIX.get(flags)) JetTokens.INFIX_KEYWORD else null
}
};
@@ -37,10 +37,19 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
open fun checkEquals(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
if (!checkEqualsPackageMember(old, new)) return false
if (!checkEqualsPackageConstructor(old, new)) return false
if (!checkEqualsPackageFunction(old, new)) return false
if (!checkEqualsPackageProperty(old, new)) return false
return true
}
public enum class ProtoBufPackageKind {
MEMBER_LIST
MEMBER_LIST,
CONSTRUCTOR_LIST,
FUNCTION_LIST,
PROPERTY_LIST
}
public fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
@@ -48,6 +57,12 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
if (!checkEqualsPackageMember(old, new)) result.add(ProtoBufPackageKind.MEMBER_LIST)
if (!checkEqualsPackageConstructor(old, new)) result.add(ProtoBufPackageKind.CONSTRUCTOR_LIST)
if (!checkEqualsPackageFunction(old, new)) result.add(ProtoBufPackageKind.FUNCTION_LIST)
if (!checkEqualsPackageProperty(old, new)) result.add(ProtoBufPackageKind.PROPERTY_LIST)
return result
}
@@ -70,6 +85,12 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
if (!checkEqualsClassNestedClassName(old, new)) return false
if (!checkEqualsClassConstructor(old, new)) return false
if (!checkEqualsClassFunction(old, new)) return false
if (!checkEqualsClassProperty(old, new)) return false
if (!checkEqualsClassMember(old, new)) return false
if (!checkEqualsClassEnumEntry(old, new)) return false
@@ -96,6 +117,9 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
TYPE_PARAMETER_LIST,
SUPERTYPE_LIST,
NESTED_CLASS_NAME_LIST,
CONSTRUCTOR_LIST,
FUNCTION_LIST,
PROPERTY_LIST,
MEMBER_LIST,
ENUM_ENTRY_LIST,
PRIMARY_CONSTRUCTOR,
@@ -124,6 +148,12 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
if (!checkEqualsClassNestedClassName(old, new)) result.add(ProtoBufClassKind.NESTED_CLASS_NAME_LIST)
if (!checkEqualsClassConstructor(old, new)) result.add(ProtoBufClassKind.CONSTRUCTOR_LIST)
if (!checkEqualsClassFunction(old, new)) result.add(ProtoBufClassKind.FUNCTION_LIST)
if (!checkEqualsClassProperty(old, new)) result.add(ProtoBufClassKind.PROPERTY_LIST)
if (!checkEqualsClassMember(old, new)) result.add(ProtoBufClassKind.MEMBER_LIST)
if (!checkEqualsClassEnumEntry(old, new)) result.add(ProtoBufClassKind.ENUM_ENTRY_LIST)
@@ -191,6 +221,74 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEquals(old: ProtoBuf.Constructor, new: ProtoBuf.Constructor): Boolean {
if (old.hasFlags() != new.hasFlags()) return false
if (old.hasFlags()) {
if (old.flags != new.flags) return false
}
if (!checkEqualsConstructorValueParameter(old, new)) return false
return true
}
open fun checkEquals(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
if (old.hasFlags() != new.hasFlags()) return false
if (old.hasFlags()) {
if (old.flags != new.flags) return false
}
if (!checkStringEquals(old.name, new.name)) return false
if (!checkEquals(old.returnType, new.returnType)) return false
if (!checkEqualsFunctionTypeParameter(old, new)) return false
if (old.hasReceiverType() != new.hasReceiverType()) return false
if (old.hasReceiverType()) {
if (!checkEquals(old.receiverType, new.receiverType)) return false
}
if (!checkEqualsFunctionValueParameter(old, new)) return false
return true
}
open fun checkEquals(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
if (old.hasFlags() != new.hasFlags()) return false
if (old.hasFlags()) {
if (old.flags != new.flags) return false
}
if (!checkStringEquals(old.name, new.name)) return false
if (!checkEquals(old.returnType, new.returnType)) return false
if (!checkEqualsPropertyTypeParameter(old, new)) return false
if (old.hasReceiverType() != new.hasReceiverType()) return false
if (old.hasReceiverType()) {
if (!checkEquals(old.receiverType, new.receiverType)) return false
}
if (old.hasSetterValueParameter() != new.hasSetterValueParameter()) return false
if (old.hasSetterValueParameter()) {
if (!checkEquals(old.setterValueParameter, new.setterValueParameter)) return false
}
if (old.hasGetterFlags() != new.hasGetterFlags()) return false
if (old.hasGetterFlags()) {
if (old.getterFlags != new.getterFlags) return false
}
if (old.hasSetterFlags() != new.hasSetterFlags()) return false
if (old.hasSetterFlags()) {
if (old.setterFlags != new.setterFlags) return false
}
return true
}
open fun checkEquals(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
if (old.id != new.id) return false
@@ -416,6 +514,36 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEqualsPackageConstructor(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
if (old.constructorCount != new.constructorCount) return false
for(i in 0..old.constructorCount - 1) {
if (!checkEquals(old.getConstructor(i), new.getConstructor(i))) return false
}
return true
}
open fun checkEqualsPackageFunction(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
if (old.functionCount != new.functionCount) return false
for(i in 0..old.functionCount - 1) {
if (!checkEquals(old.getFunction(i), new.getFunction(i))) return false
}
return true
}
open fun checkEqualsPackageProperty(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
if (old.propertyCount != new.propertyCount) return false
for(i in 0..old.propertyCount - 1) {
if (!checkEquals(old.getProperty(i), new.getProperty(i))) return false
}
return true
}
open fun checkEqualsClassTypeParameter(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
if (old.typeParameterCount != new.typeParameterCount) return false
@@ -446,6 +574,36 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEqualsClassConstructor(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
if (old.constructorCount != new.constructorCount) return false
for(i in 0..old.constructorCount - 1) {
if (!checkEquals(old.getConstructor(i), new.getConstructor(i))) return false
}
return true
}
open fun checkEqualsClassFunction(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
if (old.functionCount != new.functionCount) return false
for(i in 0..old.functionCount - 1) {
if (!checkEquals(old.getFunction(i), new.getFunction(i))) return false
}
return true
}
open fun checkEqualsClassProperty(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
if (old.propertyCount != new.propertyCount) return false
for(i in 0..old.propertyCount - 1) {
if (!checkEquals(old.getProperty(i), new.getProperty(i))) return false
}
return true
}
open fun checkEqualsClassMember(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
if (old.memberCount != new.memberCount) return false
@@ -496,6 +654,46 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEqualsConstructorValueParameter(old: ProtoBuf.Constructor, new: ProtoBuf.Constructor): Boolean {
if (old.valueParameterCount != new.valueParameterCount) return false
for(i in 0..old.valueParameterCount - 1) {
if (!checkEquals(old.getValueParameter(i), new.getValueParameter(i))) return false
}
return true
}
open fun checkEqualsFunctionTypeParameter(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
if (old.typeParameterCount != new.typeParameterCount) return false
for(i in 0..old.typeParameterCount - 1) {
if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
}
return true
}
open fun checkEqualsFunctionValueParameter(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
if (old.valueParameterCount != new.valueParameterCount) return false
for(i in 0..old.valueParameterCount - 1) {
if (!checkEquals(old.getValueParameter(i), new.getValueParameter(i))) return false
}
return true
}
open fun checkEqualsPropertyTypeParameter(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
if (old.typeParameterCount != new.typeParameterCount) return false
for(i in 0..old.typeParameterCount - 1) {
if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
}
return true
}
open fun checkEqualsTypeParameterUpperBound(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
if (old.upperBoundCount != new.upperBoundCount) return false
@@ -574,6 +772,18 @@ public fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
hashCode = 31 * hashCode + getMember(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..constructorCount - 1) {
hashCode = 31 * hashCode + getConstructor(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..functionCount - 1) {
hashCode = 31 * hashCode + getFunction(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..propertyCount - 1) {
hashCode = 31 * hashCode + getProperty(i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -602,6 +812,18 @@ public fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (
hashCode = 31 * hashCode + stringIndexes(getNestedClassName(i))
}
for(i in 0..constructorCount - 1) {
hashCode = 31 * hashCode + getConstructor(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..functionCount - 1) {
hashCode = 31 * hashCode + getFunction(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..propertyCount - 1) {
hashCode = 31 * hashCode + getProperty(i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..memberCount - 1) {
hashCode = 31 * hashCode + getMember(i).hashCode(stringIndexes, fqNameIndexes)
}
@@ -671,6 +893,80 @@ public fun ProtoBuf.Callable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes
return hashCode
}
public fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
if (hasFlags()) {
hashCode = 31 * hashCode + flags
}
for(i in 0..valueParameterCount - 1) {
hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
public fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
if (hasFlags()) {
hashCode = 31 * hashCode + flags
}
hashCode = 31 * hashCode + stringIndexes(name)
hashCode = 31 * hashCode + returnType.hashCode(stringIndexes, fqNameIndexes)
for(i in 0..typeParameterCount - 1) {
hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes)
}
if (hasReceiverType()) {
hashCode = 31 * hashCode + receiverType.hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..valueParameterCount - 1) {
hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
public fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
if (hasFlags()) {
hashCode = 31 * hashCode + flags
}
hashCode = 31 * hashCode + stringIndexes(name)
hashCode = 31 * hashCode + returnType.hashCode(stringIndexes, fqNameIndexes)
for(i in 0..typeParameterCount - 1) {
hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes)
}
if (hasReceiverType()) {
hashCode = 31 * hashCode + receiverType.hashCode(stringIndexes, fqNameIndexes)
}
if (hasSetterValueParameter()) {
hashCode = 31 * hashCode + setterValueParameter.hashCode(stringIndexes, fqNameIndexes)
}
if (hasGetterFlags()) {
hashCode = 31 * hashCode + getterFlags
}
if (hasSetterFlags()) {
hashCode = 31 * hashCode + setterFlags
}
return hashCode
}
public fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.jps.incremental
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufClassKind
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufPackageKind
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.Deserialization
@@ -52,17 +55,16 @@ private abstract class DifferenceCalculator() {
protected fun membersOrNone(names: Collection<String>): DifferenceKind = if (names.isEmpty()) DifferenceKind.NONE else DifferenceKind.MEMBERS(names)
protected fun calcDifferenceForMembers(
oldList: List<ProtoBuf.Callable>,
newList: List<ProtoBuf.Callable>
): Collection<String> {
protected fun calcDifferenceForMembers(oldList: List<MessageLite>, newList: List<MessageLite>): Collection<String> {
val result = hashSetOf<String>()
val oldMap = oldList.groupBy { it.hashCode({ compareObject.oldGetIndexOfString(it) }, { compareObject.oldGetIndexOfClassId(it) } )}
val newMap = newList.groupBy { it.hashCode({ compareObject.newGetIndexOfString(it) }, { compareObject.newGetIndexOfClassId(it) } )}
fun List<MessageLite>.names(nameResolver: NameResolver): List<String> =
map { it.name(nameResolver) }
fun List<ProtoBuf.Callable>.names(nameResolver: NameResolver): List<String> =
map { nameResolver.getString(it.name) }
val oldMap =
oldList.groupBy { it.getHashCode({ compareObject.oldGetIndexOfString(it) }, { compareObject.oldGetIndexOfClassId(it) }) }
val newMap =
newList.groupBy { it.getHashCode({ compareObject.newGetIndexOfString(it) }, { compareObject.newGetIndexOfClassId(it) }) }
val hashes = oldMap.keySet() + newMap.keySet()
for (hash in hashes) {
@@ -81,8 +83,8 @@ private abstract class DifferenceCalculator() {
}
private fun calcDifferenceForEqualHashes(
oldList: List<ProtoBuf.Callable>,
newList: List<ProtoBuf.Callable>
oldList: List<MessageLite>,
newList: List<MessageLite>
): Collection<String> {
val result = hashSetOf<String>()
val newSet = HashSet(newList)
@@ -93,12 +95,12 @@ private abstract class DifferenceCalculator() {
newSet.remove(newMember)
}
else {
result.add(compareObject.oldNameResolver.getString(oldMember.name))
result.add(oldMember.name(compareObject.oldNameResolver))
}
}
newSet.forEach { newMember ->
result.add(compareObject.newNameResolver.getString(newMember.name))
result.add(newMember.name(compareObject.newNameResolver))
}
return result
@@ -113,8 +115,45 @@ private abstract class DifferenceCalculator() {
return HashSetUtil.symmetricDifference(oldNames, newNames)
}
protected val ProtoBuf.Callable.isPrivate: Boolean
get() = Visibilities.isPrivate(Deserialization.visibility(Flags.VISIBILITY.get(flags)))
protected val MessageLite.isPrivate: Boolean
get() = Visibilities.isPrivate(Deserialization.visibility(
when (this) {
is ProtoBuf.Callable -> Flags.VISIBILITY.get(flags)
is ProtoBuf.Constructor -> Flags.VISIBILITY.get(flags)
is ProtoBuf.Function -> Flags.VISIBILITY.get(flags)
is ProtoBuf.Property -> Flags.VISIBILITY.get(flags)
else -> error("Unknown message: $this")
}))
private fun MessageLite.getHashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
return when (this) {
is ProtoBuf.Callable -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.Constructor -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.Function -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.Property -> hashCode(stringIndexes, fqNameIndexes)
else -> error("Unknown message: $this")
}
}
private fun MessageLite.name(nameResolver: NameResolver): String {
return when (this) {
is ProtoBuf.Callable -> nameResolver.getString(name)
is ProtoBuf.Constructor -> "<init>"
is ProtoBuf.Function -> nameResolver.getString(name)
is ProtoBuf.Property -> nameResolver.getString(name)
else -> error("Unknown message: $this")
}
}
private fun ProtoCompareGenerated.checkEquals(old: MessageLite, new: MessageLite): Boolean {
return when {
old is ProtoBuf.Callable && new is ProtoBuf.Callable -> checkEquals(old, new)
old is ProtoBuf.Constructor && new is ProtoBuf.Constructor -> checkEquals(old, new)
old is ProtoBuf.Function && new is ProtoBuf.Function -> checkEquals(old, new)
old is ProtoBuf.Property && new is ProtoBuf.Property -> checkEquals(old, new)
else -> error("Unknown message: $this")
}
}
}
private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: ProtoMapValue) : DifferenceCalculator() {
@@ -122,11 +161,11 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
private val CONSTRUCTOR = "<init>"
private val CLASS_SIGNATURE_ENUMS = EnumSet.of(
ProtoCompareGenerated.ProtoBufClassKind.FLAGS,
ProtoCompareGenerated.ProtoBufClassKind.FQ_NAME,
ProtoCompareGenerated.ProtoBufClassKind.TYPE_PARAMETER_LIST,
ProtoCompareGenerated.ProtoBufClassKind.SUPERTYPE_LIST,
ProtoCompareGenerated.ProtoBufClassKind.CLASS_ANNOTATION_LIST
ProtoBufClassKind.FLAGS,
ProtoBufClassKind.FQ_NAME,
ProtoBufClassKind.TYPE_PARAMETER_LIST,
ProtoBufClassKind.SUPERTYPE_LIST,
ProtoBufClassKind.CLASS_ANNOTATION_LIST
)
}
@@ -155,34 +194,43 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
fun Int.oldToNames() = names.add(oldNameResolver.getString(this))
fun Int.newToNames() = names.add(newNameResolver.getString(this))
fun calcDifferenceForNonPrivateMembers(members: (ProtoBuf.Class) -> List<MessageLite>): Collection<String> {
val oldMembers = members(oldProto).filterNot { it.isPrivate }
val newMembers = members(newProto).filterNot { it.isPrivate }
return calcDifferenceForMembers(oldMembers, newMembers)
}
for (kind in diff) {
when (kind!!) {
ProtoCompareGenerated.ProtoBufClassKind.COMPANION_OBJECT_NAME -> {
ProtoBufClassKind.COMPANION_OBJECT_NAME -> {
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
}
ProtoCompareGenerated.ProtoBufClassKind.NESTED_CLASS_NAME_LIST ->
ProtoBufClassKind.NESTED_CLASS_NAME_LIST ->
names.addAll(calcDifferenceForNames(oldProto.nestedClassNameList, newProto.nestedClassNameList))
ProtoCompareGenerated.ProtoBufClassKind.MEMBER_LIST -> {
val oldMembers = oldProto.memberList.filter { !it.isPrivate }
val newMembers = newProto.memberList.filter { !it.isPrivate }
names.addAll(calcDifferenceForMembers(oldMembers, newMembers))
}
ProtoCompareGenerated.ProtoBufClassKind.ENUM_ENTRY_LIST ->
ProtoBufClassKind.CONSTRUCTOR_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList))
ProtoBufClassKind.FUNCTION_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getFunctionList))
ProtoBufClassKind.PROPERTY_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getPropertyList))
ProtoBufClassKind.MEMBER_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getMemberList))
ProtoBufClassKind.ENUM_ENTRY_LIST ->
names.addAll(calcDifferenceForNames(oldProto.enumEntryList, newProto.enumEntryList))
ProtoCompareGenerated.ProtoBufClassKind.PRIMARY_CONSTRUCTOR ->
ProtoBufClassKind.PRIMARY_CONSTRUCTOR ->
if (areNonPrivatePrimaryConstructorsDifferent()) {
names.add(CONSTRUCTOR)
}
ProtoCompareGenerated.ProtoBufClassKind.SECONDARY_CONSTRUCTOR_LIST ->
ProtoBufClassKind.SECONDARY_CONSTRUCTOR_LIST ->
if (areNonPrivateSecondaryConstructorsDifferent()) {
names.add(CONSTRUCTOR)
}
ProtoCompareGenerated.ProtoBufClassKind.FLAGS,
ProtoCompareGenerated.ProtoBufClassKind.FQ_NAME,
ProtoCompareGenerated.ProtoBufClassKind.TYPE_PARAMETER_LIST,
ProtoCompareGenerated.ProtoBufClassKind.SUPERTYPE_LIST,
ProtoCompareGenerated.ProtoBufClassKind.CLASS_ANNOTATION_LIST ->
ProtoBufClassKind.FLAGS,
ProtoBufClassKind.FQ_NAME,
ProtoBufClassKind.TYPE_PARAMETER_LIST,
ProtoBufClassKind.SUPERTYPE_LIST,
ProtoBufClassKind.CLASS_ANNOTATION_LIST ->
throw IllegalArgumentException("Unexpected kind: $kind")
else ->
throw IllegalArgumentException("Unsupported kind: $kind")
@@ -237,14 +285,27 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
private fun getChangedMembersNames(): Set<String> {
val names = hashSetOf<String>()
fun calcDifferenceForNonPrivateMembers(members: (ProtoBuf.Package) -> List<MessageLite>): Collection<String> {
val oldMembers = members(oldProto).filterNot { it.isPrivate }
val newMembers = members(newProto).filterNot { it.isPrivate }
return calcDifferenceForMembers(oldMembers, newMembers)
}
for (kind in diff) {
when (kind!!) {
ProtoCompareGenerated.ProtoBufPackageKind.MEMBER_LIST ->
names.addAll(calcDifferenceForMembers(oldProto.memberList.filter { !it.isPrivate }, newProto.memberList.filter { !it.isPrivate }))
ProtoBufPackageKind.CONSTRUCTOR_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getConstructorList))
ProtoBufPackageKind.FUNCTION_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getFunctionList))
ProtoBufPackageKind.PROPERTY_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getPropertyList))
ProtoBufPackageKind.MEMBER_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getMemberList))
else ->
throw IllegalArgumentException("Unsupported kind: $kind")
}
}
return names
}
}