Skip to content

Commit

Permalink
Merge pull request #39987 from Nadeeshan96/master-typref-38717
Browse files Browse the repository at this point in the history
Support conversion to type-reference types
  • Loading branch information
warunalakshitha committed May 9, 2023
2 parents 742dd9d + e7d20df commit 8ccb4e8
Show file tree
Hide file tree
Showing 27 changed files with 793 additions and 760 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2197,7 +2197,7 @@ private static boolean checkIsLikeOnValue(List<String> errors, Object sourceValu
case TypeTags.UNSIGNED32_INT_TAG:
case TypeTags.UNSIGNED16_INT_TAG:
case TypeTags.UNSIGNED8_INT_TAG:
if (TypeTags.isIntegerTypeTag(sourceTypeTag) || targetTypeTag == TypeTags.BYTE_TAG) {
if (TypeTags.isIntegerTypeTag(sourceTypeTag)) {
return TypeConverter.isConvertibleToIntSubType(sourceValue, targetType);
}
return allowNumericConversion && TypeConverter.isConvertibleToIntSubType(sourceValue, targetType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,10 @@ public static Type getConvertibleType(Object inputValue, Type targetType, String
return getConvertibleFiniteType(inputValue, (BFiniteType) targetType, varName,
errors, unresolvedValues, allowNumericConversion);
case TypeTags.TYPE_REFERENCED_TYPE_TAG:
return getConvertibleType(inputValue, ((BTypeReferenceType) targetType).getReferredType(), varName,
unresolvedValues, errors, allowNumericConversion);
Type referredType = ((BTypeReferenceType) targetType).getReferredType();
Type convertibleType = getConvertibleType(inputValue, referredType, varName, unresolvedValues, errors,
allowNumericConversion);
return referredType == convertibleType ? targetType : convertibleType;
case TypeTags.TYPEDESC_TAG:
return getConvertibleType(inputValue, ((BTypedescType) targetType).getConstraint(), varName,
unresolvedValues, errors, allowNumericConversion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import io.ballerina.runtime.api.types.AnydataType;
import io.ballerina.runtime.api.types.ArrayType;
import io.ballerina.runtime.api.types.Field;
import io.ballerina.runtime.api.types.IntersectionType;
import io.ballerina.runtime.api.types.MapType;
import io.ballerina.runtime.api.types.RecordType;
import io.ballerina.runtime.api.types.TableType;
Expand All @@ -47,6 +46,11 @@
import io.ballerina.runtime.internal.util.exceptions.BallerinaErrorReasons;
import io.ballerina.runtime.internal.util.exceptions.BallerinaException;
import io.ballerina.runtime.internal.util.exceptions.RuntimeErrors;
import io.ballerina.runtime.internal.values.ArrayValue;
import io.ballerina.runtime.internal.values.ArrayValueImpl;
import io.ballerina.runtime.internal.values.MapValueImpl;
import io.ballerina.runtime.internal.values.TableValueImpl;
import io.ballerina.runtime.internal.values.TupleValueImpl;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -111,14 +115,14 @@ private static Object convert(Object value, Type targetType, Set<TypeValuePair>
switch (sourceType.getTag()) {
case TypeTags.MAP_TAG:
case TypeTags.RECORD_TYPE_TAG:
newValue = convertMap((BMap<?, ?>) value, matchingType, unresolvedValues);
newValue = convertMap((BMap<?, ?>) value, matchingType, convertibleType, unresolvedValues);
break;
case TypeTags.ARRAY_TAG:
case TypeTags.TUPLE_TAG:
newValue = convertArray((BArray) value, matchingType, unresolvedValues);
newValue = convertArray((BArray) value, matchingType, convertibleType, unresolvedValues);
break;
case TypeTags.TABLE_TAG:
newValue = convertTable((BTable<?, ?>) value, matchingType, unresolvedValues);
newValue = convertTable((BTable<?, ?>) value, matchingType, convertibleType, unresolvedValues);
break;
default:
if (TypeChecker.isRegExpType(targetType) && matchingType.getTag() == TypeTags.STRING_TAG) {
Expand Down Expand Up @@ -173,7 +177,8 @@ private static Type getTargetFromTypeDesc(Type targetType) {
return targetType;
}

private static Object convertMap(BMap<?, ?> map, Type targetType, Set<TypeValuePair> unresolvedValues) {
private static Object convertMap(BMap<?, ?> map, Type targetType, Type targetRefType,
Set<TypeValuePair> unresolvedValues) {
switch (targetType.getTag()) {
case TypeTags.MAP_TAG:
BMapInitialValueEntry[] initialValues = new BMapInitialValueEntry[map.entrySet().size()];
Expand All @@ -185,18 +190,16 @@ private static Object convertMap(BMap<?, ?> map, Type targetType, Set<TypeValueP
.createKeyFieldEntry(StringUtils.fromString(entry.getKey().toString()), newValue);
count++;
}
return ValueCreator.createMapValue((MapType) targetType, initialValues);
return new MapValueImpl<>(targetRefType, initialValues);
case TypeTags.RECORD_TYPE_TAG:
RecordType recordType = (RecordType) targetType;
Type restFieldType = recordType.getRestFieldType();
Map<String, Type> targetTypeField = new HashMap<>();
for (Field field : recordType.getFields().values()) {
targetTypeField.put(field.getFieldName(), field.getFieldType());
}
return convertToRecord(map, unresolvedValues, recordType, restFieldType,
return convertToRecord(map, unresolvedValues, targetRefType, restFieldType,
targetTypeField);
case TypeTags.INTERSECTION_TAG:
return convertMap(map, ((IntersectionType) targetType).getEffectiveType(), unresolvedValues);
default:
break;
}
Expand All @@ -205,14 +208,14 @@ private static Object convertMap(BMap<?, ?> map, Type targetType, Set<TypeValueP
}

private static BMap<BString, Object> convertToRecord(BMap<?, ?> map, Set<TypeValuePair> unresolvedValues,
RecordType recordType,
Type restFieldType, Map<String, Type> targetTypeField) {
Type recordRefType, Type restFieldType,
Map<String, Type> targetTypeField) {
Map<String, Object> valueMap = new HashMap<>();
for (Map.Entry<?, ?> entry : map.entrySet()) {
Object newValue = convertRecordEntry(unresolvedValues, restFieldType, targetTypeField, entry);
valueMap.put(entry.getKey().toString(), newValue);
}
return ValueCreator.createRecordValue(recordType.getPackage(), recordType.getName(), valueMap);
return ValueCreator.createRecordValue(recordRefType.getPackage(), recordRefType.getName(), valueMap);
}

private static Object convertRecordEntry(Set<TypeValuePair> unresolvedValues,
Expand All @@ -222,7 +225,8 @@ private static Object convertRecordEntry(Set<TypeValuePair> unresolvedValues,
return convert(entry.getValue(), fieldType, unresolvedValues);
}

private static Object convertArray(BArray array, Type targetType, Set<TypeValuePair> unresolvedValues) {
private static Object convertArray(BArray array, Type targetType, Type targetRefType,
Set<TypeValuePair> unresolvedValues) {
switch (targetType.getTag()) {
case TypeTags.ARRAY_TAG:
ArrayType arrayType = (ArrayType) targetType;
Expand All @@ -231,7 +235,7 @@ private static Object convertArray(BArray array, Type targetType, Set<TypeValueP
Object newValue = convert(array.get(i), arrayType.getElementType(), unresolvedValues);
arrayValues[i] = ValueCreator.createListInitialValueEntry(newValue);
}
return ValueCreator.createArrayValue(arrayType, arrayValues);
return new ArrayValueImpl(targetRefType, arrayType.getSize(), arrayValues);
case TypeTags.TUPLE_TAG:
TupleType tupleType = (TupleType) targetType;
int minLen = tupleType.getTupleTypes().size();
Expand All @@ -241,7 +245,7 @@ private static Object convertArray(BArray array, Type targetType, Set<TypeValueP
Object newValue = convert(array.get(i), elementType, unresolvedValues);
tupleValues[i] = ValueCreator.createListInitialValueEntry(newValue);
}
return ValueCreator.createTupleValue(tupleType, array.size(), tupleValues);
return new TupleValueImpl(targetRefType, tupleValues);
case TypeTags.TABLE_TAG:
TableType tableType = (TableType) targetType;
Object[] tableValues = new Object[array.size()];
Expand All @@ -252,12 +256,8 @@ private static Object convertArray(BArray array, Type targetType, Set<TypeValueP
}
BArray data = ValueCreator
.createArrayValue(tableValues, TypeCreator.createArrayType(tableType.getConstrainedType()));
BArray fieldNames;
fieldNames = StringUtils.fromStringArray(tableType.getFieldNames());
return ValueCreator.createTableValue(tableType, data, fieldNames);
case TypeTags.INTERSECTION_TAG:
return convertArray(array, ((IntersectionType) targetType).getEffectiveType(),
unresolvedValues);
BArray fieldNames = StringUtils.fromStringArray(tableType.getFieldNames());
return new TableValueImpl(targetRefType, (ArrayValue) data, (ArrayValue) fieldNames);
default:
break;
}
Expand All @@ -266,7 +266,7 @@ private static Object convertArray(BArray array, Type targetType, Set<TypeValueP
}

private static Object convertTable(BTable<?, ?> bTable, Type targetType,
Set<TypeValuePair> unresolvedValues) {
Type targetRefType, Set<TypeValuePair> unresolvedValues) {
TableType tableType = (TableType) targetType;
Object[] tableValues = new Object[bTable.size()];
int count = 0;
Expand All @@ -276,8 +276,7 @@ private static Object convertTable(BTable<?, ?> bTable, Type targetType,
}
BArray data = ValueCreator.createArrayValue(tableValues,
TypeCreator.createArrayType(tableType.getConstrainedType()));
BArray fieldNames;
fieldNames = StringUtils.fromStringArray(tableType.getFieldNames());
return ValueCreator.createTableValue(tableType, data, fieldNames);
BArray fieldNames = StringUtils.fromStringArray(tableType.getFieldNames());
return new TableValueImpl(targetRefType, (ArrayValue) data, (ArrayValue) fieldNames);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ private Object createUnionValue(TomlNode tomlValue, BUnionType unionType) {
Object balValue = Utils.getBalValueFromToml(tomlValue, new HashSet<>(), unionType, new HashSet<>(), "");
Type convertibleType = TypeConverter.getConvertibleType(balValue, unionType, null, new HashSet<>(),
new ArrayList<>(), false);
Type type = getEffectiveType(convertibleType);
Type type = getEffectiveType(TypeUtils.getReferredType(convertibleType));
if (isSimpleType(type.getTag()) || type.getTag() == TypeTags.FINITE_TYPE_TAG || isXMLType(type)) {
return balValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ private void validateUnionValue(TomlNode tomlValue, String variableName, BUnionT
if (convertibleType == null) {
throwTypeIncompatibleError(tomlValue, variableName, unionType);
}
Type type = getEffectiveType(convertibleType);
Type type = getEffectiveType(TypeUtils.getReferredType(convertibleType));

if (isSimpleType(type.getTag()) || isXMLType(type)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ public TupleValueImpl(TupleType type, long size, BListInitialValueEntry[] initia
public TupleValueImpl(Type type, BListInitialValueEntry[] initialValues) {
this.type = type;
this.tupleType = (TupleType) TypeUtils.getReferredType(type);

List<Type> memTypes = this.tupleType.getTupleTypes();
List<Type> memTypes = this.tupleType.getTupleTypes();
int memCount = memTypes.size();

if (tupleType.getRestType() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,19 @@ public static boolean isSimpleBasicType(BType bType) {
}
}

public static boolean needNoTypeGeneration(int bTypeTag) {
switch (bTypeTag) {
case TypeTags.RECORD:
case TypeTags.ERROR:
case TypeTags.OBJECT:
case TypeTags.UNION:
case TypeTags.TUPLE:
return false;
default:
return true;
}
}

public static BType getReferredType(BType type) {
BType constraint = type;
if (type != null && type.tag == TypeTags.TYPEREFDESC) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ private void linkModuleFunctions(BIRPackage birPackage, String initClass, boolea
Map<String, JavaClass> jvmClassMap) {
// filter out functions.
List<BIRFunction> functions = birPackage.functions;
if (functions.size() == 0) {
if (functions.isEmpty()) {
return;
}

Expand Down Expand Up @@ -771,8 +771,9 @@ CompiledJarFile generate(BIRPackage module, boolean isEntry) {
flattenedModuleImports, serviceEPAvailable, mainFunc);
TypeHashVisitor typeHashVisitor = new TypeHashVisitor();
JvmConstantsGen jvmConstantsGen = new JvmConstantsGen(module, moduleInitClass, types, typeHashVisitor);
JvmMethodsSplitter jvmMethodsSplitter = new JvmMethodsSplitter(this, jvmConstantsGen, module, moduleInitClass
, typeHashVisitor);
JvmTypeGen jvmTypeGen = new JvmTypeGen(jvmConstantsGen, module.packageID, typeHashVisitor, symbolTable);
JvmMethodsSplitter jvmMethodsSplitter = new JvmMethodsSplitter(this, jvmConstantsGen, module, moduleInitClass,
typeHashVisitor, jvmTypeGen);
configMethodGen.generateConfigMapper(flattenedModuleImports, module, moduleInitClass, jvmConstantsGen,
typeHashVisitor, jarEntries, symbolTable);

Expand All @@ -784,11 +785,9 @@ CompiledJarFile generate(BIRPackage module, boolean isEntry) {

// generate object/record value classes
JvmValueGen valueGen = new JvmValueGen(module, this, methodGen, typeHashVisitor, types);
JvmTypeGen jvmTypeGen = new JvmTypeGen(jvmConstantsGen, module.packageID, typeHashVisitor, symbolTable);
JvmCastGen jvmCastGen = new JvmCastGen(symbolTable, jvmTypeGen, types);
valueGen.generateValueClasses(jarEntries, jvmConstantsGen);


// generate frame classes
frameClassGen.generateFrameClasses(module, jarEntries);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,15 @@ public JvmTypeGen(JvmConstantsGen jvmConstantsGen, PackageID packageID, TypeHash
void generateUserDefinedTypeFields(ClassWriter cw, List<BIRTypeDefinition> typeDefs) {
// create the type
for (BIRTypeDefinition typeDef : typeDefs) {
BType bType = JvmCodeGenUtil.getReferredType(typeDef.type);
if (bType.tag == TypeTags.RECORD || bType.tag == TypeTags.ERROR || bType.tag == TypeTags.OBJECT
|| bType.tag == TypeTags.UNION || bType.tag == TypeTags.TUPLE) {
String name = typeDef.internalName.value;
generateTypeField(cw, name);
generateTypedescField(cw, name);
BType bType = typeDef.type;
int bTypeTag = bType.tag;
if (JvmCodeGenUtil.needNoTypeGeneration(bTypeTag)) {
// do not generate anything for other types (e.g.: finite type, type reference types etc.)
continue;
}
// do not generate anything for other types (e.g.: finite type, unions, etc.)
String name = typeDef.internalName.value;
generateTypeField(cw, name);
generateTypedescField(cw, name);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,19 @@ private int createTypesInstanceSplits(ClassWriter cw, List<BIRTypeDefinition> ty
// Create the type
for (BIRTypeDefinition optionalTypeDef : typeDefs) {
String name = optionalTypeDef.internalName.value;
BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type);
if (bType.tag != TypeTags.RECORD && bType.tag != TypeTags.OBJECT && bType.tag != TypeTags.ERROR &&
bType.tag != TypeTags.UNION && bType.tag != TypeTags.TUPLE) {
// do not generate anything for other types (e.g.: finite type, etc.)
continue;
} else {
BType bType = optionalTypeDef.type;
int bTypeTag = bType.tag;
if (JvmCodeGenUtil.needNoTypeGeneration(bTypeTag)) {
continue;
} else {
if (bTypesCount % MAX_TYPES_PER_METHOD == 0) {
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPE_INSTANCES_METHOD + methodCount++,
VOID_METHOD_DESC,
null, null);
mv.visitCode();
}
}
switch (bType.tag) {
switch (bTypeTag) {
case TypeTags.RECORD:
jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType, typeOwnerClass, name);
break;
Expand Down Expand Up @@ -320,10 +319,9 @@ private Map<String, String> populateTypes(ClassWriter cw, List<BIRTypeDefinition
Map<String, String> funcTypeClassMap = new HashMap<>();
String fieldName;
for (BIRTypeDefinition optionalTypeDef : typeDefs) {
BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type);
BType bType = optionalTypeDef.type;
int bTypeTag = bType.tag;
if (!(bTypeTag == TypeTags.RECORD || bTypeTag == TypeTags.ERROR || bTypeTag == TypeTags.OBJECT
|| bTypeTag == TypeTags.UNION || bTypeTag == TypeTags.TUPLE)) {
if (JvmCodeGenUtil.needNoTypeGeneration(bTypeTag)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,14 @@ public class JvmMethodsSplitter {
private final String moduleInitClass;

public JvmMethodsSplitter(JvmPackageGen jvmPackageGen, JvmConstantsGen jvmConstantsGen,
BIRNode.BIRPackage module, String moduleInitClass, TypeHashVisitor typeHashVisitor) {
BIRNode.BIRPackage module, String moduleInitClass, TypeHashVisitor typeHashVisitor,
JvmTypeGen jvmTypeGen) {
this.module = module;
this.jvmPackageGen = jvmPackageGen;
this.moduleInitClass = moduleInitClass;
JvmTypeGen jvmTypeGen = new JvmTypeGen(jvmConstantsGen, module.packageID, typeHashVisitor,
jvmPackageGen.symbolTable);
this.jvmCreateTypeGen = new JvmCreateTypeGen(jvmTypeGen, jvmConstantsGen, module.packageID, typeHashVisitor);
this.jvmAnnotationsGen = new JvmAnnotationsGen(module, jvmPackageGen, jvmTypeGen, jvmConstantsGen);
this.jvmValueCreatorGen = new JvmValueCreatorGen(module.packageID);
this.jvmValueCreatorGen = new JvmValueCreatorGen(module.packageID, jvmTypeGen);
jvmConstantsGen.setJvmCreateTypeGen(jvmCreateTypeGen);
}

Expand Down
Loading

0 comments on commit 8ccb4e8

Please sign in to comment.