Skip to content

Commit

Permalink
Port nBallerina readonly and error types
Browse files Browse the repository at this point in the history
  • Loading branch information
lochana-chathura committed Apr 30, 2024
1 parent b5cbe0c commit 06bb36c
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 70 deletions.
27 changes: 19 additions & 8 deletions semtypes/src/main/java/io/ballerina/types/Error.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@

import io.ballerina.types.subtypedata.AllOrNothingSubtype;
import io.ballerina.types.subtypedata.BddNode;
import io.ballerina.types.typeops.BddCommonOps;

import static io.ballerina.types.BasicTypeCode.BT_ERROR;
import static io.ballerina.types.Core.subtypeData;
import static io.ballerina.types.PredefinedType.BDD_SUBTYPE_RO;
import static io.ballerina.types.PredefinedType.ERROR;
import static io.ballerina.types.PredefinedType.NEVER;
import static io.ballerina.types.PredefinedType.basicSubtype;
import static io.ballerina.types.RecAtom.createRecAtom;
import static io.ballerina.types.typeops.BddCommonOps.bddAtom;
import static io.ballerina.types.typeops.BddCommonOps.bddIntersect;

/**
* Contain functions found in error.bal file.
Expand All @@ -28,22 +37,24 @@
*/
public class Error {
public static SemType errorDetail(SemType detail) {
SubtypeData sd = Core.subtypeData(detail, BasicTypeCode.BT_MAPPING); // TODO: type should be MAPPING_RO
SubtypeData sd = bddIntersect((Bdd) subtypeData(detail, BasicTypeCode.BT_MAPPING), BDD_SUBTYPE_RO);
if (sd instanceof AllOrNothingSubtype allOrNothingSubtype) {
if (allOrNothingSubtype.isAllSubtype()) {
return PredefinedType.ERROR;
return ERROR;
} else {
// XXX This should be reported as an error
return PredefinedType.NEVER;
return NEVER;
}
} else {
return PredefinedType.basicSubtype(BasicTypeCode.BT_ERROR, (ProperSubtypeData) sd);
}
if (sd == BDD_SUBTYPE_RO) {
return ERROR;
}
return basicSubtype(BT_ERROR, (ProperSubtypeData) sd);
}

// distinctId must be >= 0
public SemType errorDistinct(int distinctId) {
BddNode bdd = BddCommonOps.bddAtom(RecAtom.createRecAtom(-distinctId - 1));
return PredefinedType.basicSubtype(BasicTypeCode.BT_ERROR, bdd);
BddNode bdd = bddAtom(createRecAtom(-distinctId - 1));
return basicSubtype(BT_ERROR, bdd);
}
}
35 changes: 24 additions & 11 deletions semtypes/src/main/java/io/ballerina/types/PredefinedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import static io.ballerina.types.BasicTypeCode.BT_LIST;
import static io.ballerina.types.BasicTypeCode.BT_MAPPING;
import static io.ballerina.types.BasicTypeCode.BT_TABLE;
import static io.ballerina.types.BasicTypeCode.BT_XML;
import static io.ballerina.types.BasicTypeCode.VT_INHERENTLY_IMMUTABLE;
import static io.ballerina.types.ComplexSemType.createComplexSemType;
import static io.ballerina.types.Core.intersect;
import static io.ballerina.types.Core.union;
Expand All @@ -41,6 +43,7 @@
import static io.ballerina.types.subtypedata.XmlSubtype.xmlSequence;
import static io.ballerina.types.subtypedata.XmlSubtype.xmlSingleton;
import static io.ballerina.types.typeops.BddCommonOps.bddAtom;
import static io.ballerina.types.typeops.XmlOps.XML_SUBTYPE_RO;

/**
* Contain predefined types used for constructing other types.
Expand Down Expand Up @@ -148,7 +151,7 @@ BT_CELL, bddAtom(ATOM_CELL_INNER_MAPPING)

public static final int BDD_REC_ATOM_READONLY = 0;
// represents both readonly & map<readonly> and readonly & readonly[]
private static final BddNode BDD_SUBTYPE_RO = bddAtom(RecAtom.createRecAtom(BDD_REC_ATOM_READONLY));
public static final BddNode BDD_SUBTYPE_RO = bddAtom(RecAtom.createRecAtom(BDD_REC_ATOM_READONLY));
// represents (map<any|error>)[]
public static final ComplexSemType MAPPING_RO = basicSubtype(BT_MAPPING, BDD_SUBTYPE_RO);

Expand All @@ -167,10 +170,11 @@ BT_CELL, bddAtom(ATOM_CELL_INNER_MAPPING_RO)
// represents readonly & (map<readonly>)[]
static final BddNode LIST_SUBTYPE_MAPPING_RO = bddAtom(ATOM_LIST_MAPPING_RO);

public static final SemType VAL_READONLY = createComplexSemType(IMPLEMENTED_INHERENTLY_IMMUTABLE,
public static final SemType VAL_READONLY = createComplexSemType(VT_INHERENTLY_IMMUTABLE,
BasicSubtype.from(BT_LIST, BDD_SUBTYPE_RO),
BasicSubtype.from(BT_MAPPING, BDD_SUBTYPE_RO),
BasicSubtype.from(BT_TABLE, LIST_SUBTYPE_MAPPING_RO)
BasicSubtype.from(BT_TABLE, LIST_SUBTYPE_MAPPING_RO),
BasicSubtype.from(BT_XML, XML_SUBTYPE_RO)
);
public static final SemType IMPLEMENTED_VAL_READONLY = createComplexSemType(IMPLEMENTED_INHERENTLY_IMMUTABLE,
BasicSubtype.from(BT_LIST, BDD_SUBTYPE_RO)
Expand Down Expand Up @@ -244,27 +248,36 @@ static String toString(BasicTypeBitSet ut) {
if ((ut.bitset & ERROR.bitset) != 0) {
sb.add("error");
}
if ((ut.bitset & LIST.bitset) != 0) {
sb.add("list");
}
if ((ut.bitset & FUNCTION.bitset) != 0) {
sb.add("function");
}
if ((ut.bitset & TYPEDESC.bitset) != 0) {
sb.add("typedesc");
}
if ((ut.bitset & HANDLE.bitset) != 0) {
sb.add("handle");
}
if ((ut.bitset & BasicTypeCode.VT_INHERENTLY_IMMUTABLE) != 0) { // TODO: fix when porting readonly
sb.add("readonly");
if ((ut.bitset & FUNCTION.bitset) != 0) {
sb.add("function");
}
if ((ut.bitset & FUTURE.bitset) != 0) {
sb.add("future");
}
if ((ut.bitset & STREAM.bitset) != 0) {
sb.add("stream");
}
if ((ut.bitset & LIST.bitset) != 0) {
sb.add("list");
}
if ((ut.bitset & MAPPING.bitset) != 0) {
sb.add("map");
}
if ((ut.bitset & TABLE.bitset) != 0) {
sb.add("table");
}
if ((ut.bitset & XML.bitset) != 0) {
sb.add("xml");
}
if ((ut.bitset & OBJECT.bitset) != 0) {
sb.add("object");
}
if ((ut.bitset & CELL.bitset) != 0) {
sb.add("cell");
}
Expand Down
33 changes: 31 additions & 2 deletions semtypes/src/main/java/io/ballerina/types/typeops/ErrorOps.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,48 @@
package io.ballerina.types.typeops;

import io.ballerina.types.BasicTypeOps;
import io.ballerina.types.Bdd;
import io.ballerina.types.Context;
import io.ballerina.types.SubtypeData;

import static io.ballerina.types.Common.bddEveryPositive;
import static io.ballerina.types.Common.bddPosMaybeEmpty;
import static io.ballerina.types.Common.bddSubtypeDiff;
import static io.ballerina.types.Common.memoSubtypeIsEmpty;
import static io.ballerina.types.PredefinedType.BDD_SUBTYPE_RO;
import static io.ballerina.types.typeops.BddCommonOps.bddIntersect;

/**
* Basic type ops for error type.
*
* @since 2201.8.0
*/
public class ErrorOps extends CommonOps implements BasicTypeOps {

private static SubtypeData errorSubtypeComplement(SubtypeData t) {
return bddSubtypeDiff(BDD_SUBTYPE_RO, t);
}

private static boolean errorSubtypeIsEmpty(Context cx, SubtypeData t) {
Bdd b = (Bdd) t;
// The goal of this is to ensure that mappingFormulaIsEmpty call in errorBddIsEmpty beneath
// does not get an empty posList, because it will interpret that
// as `map<any|error>` rather than `readonly & map<readonly>`.
b = bddPosMaybeEmpty(b) ? bddIntersect(b, BDD_SUBTYPE_RO) : b;
return memoSubtypeIsEmpty(cx, cx.mappingMemo, ErrorOps::errorBddIsEmpty, b);
}

private static boolean errorBddIsEmpty(Context cx, Bdd b) {
return bddEveryPositive(cx, b, null, null, MappingOps::mappingFormulaIsEmpty);
}

@Override
public SubtypeData complement(SubtypeData d) {
return errorSubtypeComplement(d);
}

@Override
public boolean isEmpty(Context cx, SubtypeData t) {
// TODO: implement bddPosMaybeEmpty
throw new UnsupportedOperationException("Unimplemented");
return errorSubtypeIsEmpty(cx, t);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ public void stringTest() {
Assert.assertEquals(result.get(1).value, "d");
}

@Test(enabled = false)
public void roTest() {
SemType t1 = PredefinedType.basicType(BasicTypeCode.BT_LIST); // TODO: type should be LIST_RO
@Test
public void roListTest() {
SemType t1 = Core.intersect(PredefinedType.LIST, PredefinedType.VAL_READONLY);
Env env = new Env();
ListDefinition ld = new ListDefinition();
SemType t2 = ld.defineListTypeWrapped(env, new ArrayList<>(), 0, PredefinedType.VAL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.wso2.ballerinalang.compiler.tree.types.BLangArrayType;
import org.wso2.ballerinalang.compiler.tree.types.BLangBuiltInRefTypeNode;
import org.wso2.ballerinalang.compiler.tree.types.BLangConstrainedType;
import org.wso2.ballerinalang.compiler.tree.types.BLangErrorType;
import org.wso2.ballerinalang.compiler.tree.types.BLangFiniteTypeNode;
import org.wso2.ballerinalang.compiler.tree.types.BLangFunctionTypeNode;
import org.wso2.ballerinalang.compiler.tree.types.BLangIntersectionTypeNode;
Expand Down Expand Up @@ -165,6 +166,8 @@ public SemType resolveTypeDesc(Context cx, Map<String, BLangNode> mod, BLangType
return resolveTypeDesc(cx, mod, defn, depth, (BLangFunctionTypeNode) td);
case TABLE_TYPE:
return resolveTypeDesc(cx, mod, depth, (BLangTableTypeNode) td);
case ERROR_TYPE:
return resolveTypeDesc(cx, mod, defn, depth, (BLangErrorType) td);
default:
throw new UnsupportedOperationException("type not implemented: " + td.getKind());
}
Expand Down Expand Up @@ -503,4 +506,14 @@ private SemType resolveTypeDesc(Context cx, Map<String, BLangNode> mod, int dept
SemType memberType = resolveTypeDesc(cx, mod, (BLangTypeDefinition) td.constraint.defn, depth, td.constraint);
return SemTypes.tableContaining(cx.env, memberType);
}

private SemType resolveTypeDesc(Context cx, Map<String, BLangNode> mod, BLangTypeDefinition defn, int depth,
BLangErrorType td) {
if (td.detailType == null) {
return PredefinedType.ERROR;
}

SemType detail = resolveTypeDesc(cx, mod, defn, depth, td.detailType);
return SemTypes.errorDetail(detail);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,10 @@ public Object[] dataDirFileNameProvider() {

public final HashSet<String> dataDirSkipList() {
HashSet<String> hashSet = new HashSet<>();
// error type not supported yet
hashSet.add("basic.bal");
hashSet.add("error1.bal");
hashSet.add("error2.bal");

// readonly type not supported yet
hashSet.add("fixed-length-array.bal");
hashSet.add("fixed-length-array-tuple.bal");

// causes a stack overflow with mappingSubtypeIsEmpty
// https://github.com/ballerina-platform/ballerina-lang/issues/42662
hashSet.add("error1.bal");
hashSet.add("hard.bal");
// func type not supported yet
hashSet.add("function.bal"); // due to https://github.com/ballerina-platform/ballerina-lang/issues/35204
hashSet.add("never.bal");

// readonly type not supported yet
hashSet.add("readonly1.bal");
hashSet.add("readonly2.bal");
return hashSet;
}

Expand Down Expand Up @@ -175,18 +161,8 @@ public final HashSet<String> typeRelDirSkipList() {
hashSet.add("proj9-t.bal");
hashSet.add("proj10-t.bal");

// readonly type not supported yet
hashSet.add("fixed-length-array-t.bal");
hashSet.add("fixed-length-array-tuple-t.bal");

hashSet.add("xml-complex-ro-tv.bal");
hashSet.add("xml-readonly-tv.bal");
// Not a type test. This is an error test
hashSet.add("xml-te.bal");

// table type not supported yet
hashSet.add("anydata-tv.bal");
hashSet.add("table-t.bal");
hashSet.add("table2-t.bal");
return hashSet;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
// ROInt5<:IntArray
// ROInt5<:ROIntArray
// ROIntArray<:IntArray
// EmptyIntArray<:ROIntArray

type IntArray int[];

Expand All @@ -65,7 +66,6 @@ type Array5OfInt5 int[5][5];

type INT int;


type Array5OfIntArray int[5][];

type ROIntArray readonly & IntArray;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

type IntArray int[];
type Int5 int[5];
type ISTArray (1|2|3)[];

public const int MAX_VALUE = 9223372036854775807;

public const int MAX_VALUE_M_1 = MAX_VALUE - 1;

// -@type LargeArray < IntArray
type LargeArray int[MAX_VALUE];

// @type LargeArray2 < IntArray
// -@type LargeArray <> LargeArray2
type LargeArray2 int[MAX_VALUE_M_1];

// -@type Int5Intersection = Int5
type Int5Intersection int[5] & !LargeArray;

type Int10000 int[100000];

// -@type ISTArray < I10000A
type I10000A Int10000|(!Int10000 & IntArray);

Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ type ROIntArray readonly & IntArray;
// @type ROInt5 < ROIntArray
type ROInt5 readonly & int[5];

// ! not supported in JBallerina
// -@type ArrayExcept5 <> Int5;
// -@type ArrayExcept5 < IntArray;
//type ArrayExcept5 IntArray & !Int5;
type ArrayExcept5 IntArray & !Int5;

const FIVE = 5;

Expand Down Expand Up @@ -67,18 +66,3 @@ type Array7OfArray2OfInt5 Array2OfInt5[7];

// @type Array7x2x5 = Array7OfArray2OfInt5
type Array7x2x5 int[7][2][5];

//public const int MAX_VALUE = 9223372036854775807;
//public const int MAX_VALUE_M_1 = 9223372036854775806;
public const int MAX_VALUE = 2147483637;
public const int MAX_VALUE_M_1 = 2147483636;

// @type LargeArray < IntArray
type LargeArray int[MAX_VALUE];

// @type LargeArray2 < IntArray
// @type LargeArray <> LargeArray2
type LargeArray2 int[MAX_VALUE_M_1];

// -@type Int5Intersection = Int5
type Int5Intersection int[5] & !LargeArray;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type ReadOnlyFlat T|E|P|C;
// -@type C < NonEmptyRoSingletons
type NonEmptyRoSingletons ReadOnlyFlat & !N;

// @type NonEmptyRoSingletons < UX
// -@type NonEmptyRoSingletons < UX
type UX XE|XP|XC|T;

// -@type XNonEmptyRoSingletons = RX
Expand Down

0 comments on commit 06bb36c

Please sign in to comment.