private static boolean checkFieldEquivalency(BRecordType lhsType, BRecordType rhsType, List<TypePair> unresolvedTypes) { Map<String, BField> rhsFields = rhsType.getFields(); Set<String> lhsFieldNames = lhsType.getFields().keySet(); for (BField lhsField : lhsType.getFields().values()) { BField rhsField = rhsFields.get(lhsField.fieldName); // If the LHS field is a required one, there has to be a corresponding required field in the RHS record. if (!Flags.isFlagOn(lhsField.flags, Flags.OPTIONAL) && (rhsField == null || Flags.isFlagOn(rhsField.flags, Flags.OPTIONAL))) { return false; } if (rhsField == null || !isAssignable(rhsField.fieldType, lhsField.fieldType, unresolvedTypes)) { return false; } } if (lhsType.sealed) { return lhsFieldNames.containsAll(rhsFields.keySet()); } return rhsFields.values().stream() .filter(field -> !lhsFieldNames.contains(field.fieldName)) .allMatch(field -> isAssignable(field.fieldType, lhsType.restFieldType, unresolvedTypes)); }
@Override public void addAttributeInfo(AttributeInfo.Kind attributeKind, AttributeInfo attributeInfo) { attributeInfoMap.put(attributeKind, attributeInfo); if (attributeKind == AttributeInfo.Kind.VARIABLE_TYPE_COUNT_ATTRIBUTE) { // TODO Move this out of the program file to a program context.. Runtime representation of a program. // TODO ProgramFile is the static program data. VarTypeCountAttributeInfo varTypeCountAttribInfo = (VarTypeCountAttributeInfo) attributeInfo; int[] globalVarCount = varTypeCountAttribInfo.getVarTypeCount(); // TODO Introduce an abstraction for memory blocks // Initialize global memory block BStructureType dummyType = new BRecordType(null, "", "", 0); dummyType.setFieldTypeCount(globalVarCount); this.globalMemoryBlock = new GlobalMemoryBlock(dummyType); } }
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; }
@SuppressWarnings("unchecked") @Override public BRecordType toObject(BPacket packet, BValueDeserializer bValueDeserializer) { String typeName = packet.get(TYPE_NAME).stringValue(); String pkgPath = packet.get(PACKAGE_PATH).stringValue(); int flags = (int) ((BInteger) packet.get(FLAGS)).intValue(); int cpIndex = (int) ((BInteger) packet.get(REST_FIELD_SIGNATURE_CP_INDEX)).intValue(); BBoolean closed = (BBoolean) packet.get(CLOSED); RecordTypeInfo recTypeInfo = new RecordTypeInfo(); recTypeInfo.setRestFieldSignatureCPIndex(cpIndex); BValue restFieldTypeSig = packet.get(REST_FIELD_TYPE_SIGNATURE); if (restFieldTypeSig != null) { String typeSig = restFieldTypeSig.stringValue(); recTypeInfo.setRestFieldTypeSignature(typeSig); } BRecordType bRecType = new BRecordType(recTypeInfo, typeName, pkgPath, flags); Map<String, BField> fields = (Map<String, BField>) bValueDeserializer.deserialize(packet.getValue(), LinkedHashMap.class); bRecType.setFields(fields); recTypeInfo.setType(bRecType); bRecType.restFieldType = (BType) bValueDeserializer.deserialize(packet.get(REST_FIELD_TYPE), BType.class); bRecType.sealed = closed.booleanValue(); return bRecType; } }
private void initGlobalMemBlock(PackageInfo[] packageInfoArray) { for (PackageInfo packageInfo : packageInfoArray) { // Get the package-level variable count from the attribute. AttributeInfo attributeInfo = packageInfo.getAttributeInfo( AttributeInfo.Kind.VARIABLE_TYPE_COUNT_ATTRIBUTE); VarTypeCountAttributeInfo varTypeCountAttribInfo = (VarTypeCountAttributeInfo) attributeInfo; int[] globalVarCount = varTypeCountAttribInfo.getVarTypeCount(); // We are using the struct value to hold package-level variable values for the moment. BStructureType dummyType = new BRecordType(null, "", "", 0); dummyType.setFieldTypeCount(globalVarCount); globalMemBlock[packageInfo.pkgIndex] = new GlobalMemoryBlock(dummyType); } } }
BRecordType recordType = new BRecordType(recordInfo, typeDefInfo.name, packageInfo.getPkgPath(), typeDefInfo.flags); recordInfo.setType(recordType);
List<BType> fieldTypes = recordType.getFields().values().stream() .map(BField::getFieldType) .collect(Collectors.toList());
case TypeTags.RECORD_TYPE_TAG: BRecordType recType = (BRecordType) mapType; BField recField = recType.getFields().get(fieldName); BType recFieldType;
if (bType instanceof BRecordType) { bMapValue = BLangConnectorSPIUtil.createBStruct(programFile, bType.getPackagePath(), bType.getName()); for (BField messageField : ((BRecordType) bType).getFields().values()) { bMapFields.put(messageField.fieldName, messageField.fieldType);