public static boolean checkRecordEquivalency(BRecordType lhsType, BRecordType rhsType, List<TypePair> unresolvedTypes) { // Both records should be public or private. // Get the XOR of both flags(masks) // If both are public, then public bit should be 0; // If both are private, then public bit should be 0; // The public bit is on means, one is public, and the other one is private. if (Flags.isFlagOn(lhsType.flags ^ rhsType.flags, Flags.PUBLIC)) { return false; } // If both records are private, they should be in the same package. if (!Flags.isFlagOn(lhsType.flags, Flags.PUBLIC) && !rhsType.getPackagePath().equals(lhsType.getPackagePath())) { return false; } // Cannot assign open records to closed record types if (lhsType.sealed && !rhsType.sealed) { return false; } // The rest field types should match if they are open records if (!rhsType.sealed && !isAssignable(rhsType.restFieldType, lhsType.restFieldType, unresolvedTypes)) { return false; } return checkFieldEquivalency(lhsType, rhsType, unresolvedTypes); }
@Override public BPacket toBValue(BRecordType recType, BValueSerializer serializer) { String packagePath = recType.getPackagePath(); String typeName = recType.getName(); int flags = recType.flags; int restFieldSignatureCPIndex = recType.recordTypeInfo.getRestFieldSignatureCPIndex(); String restFieldTypeSignature = recType.recordTypeInfo.getRestFieldTypeSignature(); BPacket packet = BPacket.from(typeName(), serializer.toBValue(recType.getFields(), null)); packet.putString(PACKAGE_PATH, packagePath); packet.putString(TYPE_NAME, typeName); packet.put(FLAGS, new BInteger(flags)); packet.put(REST_FIELD_SIGNATURE_CP_INDEX, new BInteger(restFieldSignatureCPIndex)); packet.putString(REST_FIELD_TYPE_SIGNATURE, restFieldTypeSignature); packet.put(CLOSED, new BBoolean(recType.sealed)); packet.put(REST_FIELD_TYPE, serializer.toBValue(recType.restFieldType, null)); return packet; }