Skip to content

Commit

Permalink
Eliminate BUnionType's getMemberTypes() usages part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
lochana-chathura committed Sep 27, 2024
1 parent 41240b5 commit 47750a4
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.ballerina.tools.diagnostics.Location;
import io.ballerina.tools.text.LinePosition;
import io.ballerina.tools.text.LineRange;
import io.ballerina.types.PredefinedType;
import org.ballerinalang.model.TreeBuilder;
import org.ballerinalang.model.elements.Flag;
import org.ballerinalang.model.elements.PackageID;
Expand Down Expand Up @@ -59,6 +60,7 @@
import org.wso2.ballerinalang.compiler.bir.model.VarScope;
import org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer;
import org.wso2.ballerinalang.compiler.diagnostic.BLangDiagnosticLocation;
import org.wso2.ballerinalang.compiler.semantics.analyzer.SemTypeHelper;
import org.wso2.ballerinalang.compiler.semantics.analyzer.Types;
import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BAnnotationSymbol;
Expand Down Expand Up @@ -2801,10 +2803,7 @@ private void generateMappingAccess(BLangIndexBasedAccess astIndexBasedAccessExpr
if (astIndexBasedAccessExpr.getKind() == NodeKind.XML_ATTRIBUTE_ACCESS_EXPR) {
insKind = InstructionKind.XML_ATTRIBUTE_STORE;
keyRegIndex = getQNameOP(astIndexBasedAccessExpr.indexExpr, keyRegIndex);
} else if (astAccessExprExprType.tag == TypeTags.OBJECT ||
(astAccessExprExprType.tag == TypeTags.UNION &&
Types.getImpliedType(((BUnionType) astAccessExprExprType).getMemberTypes().iterator()
.next()).tag == TypeTags.OBJECT)) {
} else if (SemTypeHelper.isSubtypeSimple(astAccessExprExprType, PredefinedType.OBJECT)) {
insKind = InstructionKind.OBJECT_STORE;
} else {
insKind = InstructionKind.MAP_STORE;
Expand Down Expand Up @@ -2833,10 +2832,7 @@ private void generateMappingAccess(BLangIndexBasedAccess astIndexBasedAccessExpr
keyRegIndex);
this.varAssignment = false;
return;
} else if (astAccessExprExprType.tag == TypeTags.OBJECT ||
(astAccessExprExprType.tag == TypeTags.UNION &&
Types.getImpliedType(((BUnionType) astAccessExprExprType).getMemberTypes().iterator()
.next()).tag == TypeTags.OBJECT)) {
} else if (SemTypeHelper.isSubtypeSimple(astAccessExprExprType, PredefinedType.OBJECT)) {
insKind = InstructionKind.OBJECT_LOAD;
} else {
insKind = InstructionKind.MAP_LOAD;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ public static boolean isSubtypeSimple(BType bt, BasicTypeBitSet bbs) {
return SemTypes.isSubtypeSimple(t, bbs);
}

public static boolean isSubtypeSimpleNotNever(BType bt, BasicTypeBitSet bbs) {
SemType t = SemTypeHelper.semType(bt);
return SemTypes.isSubtypeSimpleNotNever(t, bbs);
}

public static boolean containsBasicType(BType bt, BasicTypeBitSet bbs) {
SemType t = SemTypeHelper.semType(bt);
return SemTypes.containsBasicType(t, bbs);
}

public static boolean containsType(Context ctx, BType bt, SemType bbs) {
SemType t = SemTypeHelper.semType(bt);
return SemTypes.containsType(ctx, t, bbs);
}

public static boolean isSubtype(Context context, BType bt, SemType st) {
SemType s = SemTypeHelper.semType(bt);
return SemTypes.isSubtype(context, s, st);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import io.ballerina.tools.diagnostics.DiagnosticCode;
import io.ballerina.tools.diagnostics.Location;
import io.ballerina.types.PredefinedType;
import org.ballerinalang.model.TreeBuilder;
import org.ballerinalang.model.elements.AttachPoint;
import org.ballerinalang.model.elements.Flag;
Expand Down Expand Up @@ -1551,32 +1552,11 @@ public BType transform(BLangConstrainedType constrainedTypeNode, AnalyzerData da
}

public void validateXMLConstraintType(BType type, Location pos) {
BType constraintType = Types.getImpliedType(type);
int constrainedTag = constraintType.tag;

if (constrainedTag == TypeTags.UNION) {
checkUnionTypeForXMLSubTypes((BUnionType) constraintType, pos);
return;
}

if (!TypeTags.isXMLTypeTag(constrainedTag) && constrainedTag != TypeTags.NEVER) {
if (!SemTypeHelper.isSubtypeSimple(type, PredefinedType.XML)) {
dlog.error(pos, DiagnosticErrorCode.INCOMPATIBLE_TYPE_CONSTRAINT, symTable.xmlType, type);
}
}

private void checkUnionTypeForXMLSubTypes(BUnionType constraintUnionType, Location pos) {
for (BType memberType : constraintUnionType.getMemberTypes()) {
memberType = Types.getImpliedType(memberType);
if (memberType.tag == TypeTags.UNION) {
checkUnionTypeForXMLSubTypes((BUnionType) memberType, pos);
}
if (!TypeTags.isXMLTypeTag(memberType.tag)) {
dlog.error(pos, DiagnosticErrorCode.INCOMPATIBLE_TYPE_CONSTRAINT, symTable.xmlType,
constraintUnionType);
}
}
}

@Override
public BType transform(BLangUserDefinedType userDefinedTypeNode, AnalyzerData data) {
String name = userDefinedTypeNode.typeName.value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ public SemType anydata() {
}

public boolean isAnydata(BType type) {
return SemTypeHelper.isSubtype(semTypeCtx, type, Core.createAnydata(semTypeCtx));
return isSubtype(type, Core.createAnydata(semTypeCtx));
}

private boolean isSameType(BType source, BType target, Set<TypePair> unresolvedTypes) {
Expand Down Expand Up @@ -447,44 +447,15 @@ boolean finiteTypeContainsNumericTypeValues(BFiniteType finiteType) {
}

public boolean containsErrorType(BType bType) {
BType type = getImpliedType(bType);
if (type.tag == TypeTags.UNION) {
return ((BUnionType) type).getMemberTypes().stream()
.anyMatch(this::containsErrorType);
}

if (type.tag == TypeTags.READONLY) {
return true;
}

return type.tag == TypeTags.ERROR;
return SemTypeHelper.containsBasicType(bType, PredefinedType.ERROR);
}

public boolean containsNilType(BType bType) {
BType type = getImpliedType(bType);
if (type.tag == TypeTags.UNION) {
for (BType memberType : ((BUnionType) type).getMemberTypes()) {
if (containsNilType(memberType)) {
return true;
}
}
return false;
}

if (type.tag == TypeTags.READONLY) {
return true;
}

return type.tag == TypeTags.NIL;
return SemTypeHelper.containsBasicType(bType, PredefinedType.NIL);
}

public boolean isSubTypeOfList(BType bType) {
BType type = getImpliedType(bType);
if (type.tag != TypeTags.UNION) {
return isSubTypeOfBaseType(type, TypeTags.ARRAY) || isSubTypeOfBaseType(type, TypeTags.TUPLE);
}

return ((BUnionType) type).getMemberTypes().stream().allMatch(this::isSubTypeOfList);
return SemTypeHelper.isSubtypeSimpleNotNever(bType, PredefinedType.LIST);
}

BType resolvePatternTypeFromMatchExpr(BLangErrorBindingPattern errorBindingPattern, BLangExpression matchExpr,
Expand Down Expand Up @@ -715,31 +686,11 @@ public BType resolvePatternTypeFromMatchExpr(BLangMappingBindingPattern mappingB
}

private boolean containsAnyType(BType type) {
type = getImpliedType(type);
if (type.tag != TypeTags.UNION) {
return type.tag == TypeTags.ANY;
}

for (BType memberTypes : ((BUnionType) type).getMemberTypes()) {
if (getImpliedType(memberTypes).tag == TypeTags.ANY) {
return true;
}
}
return false;
return SemTypeHelper.containsType(semTypeCtx, type, PredefinedType.ANY);
}

private boolean containsAnyDataType(BType type) {
type = getImpliedType(type);
if (type.tag != TypeTags.UNION) {
return type.tag == TypeTags.ANYDATA;
}

for (BType memberTypes : ((BUnionType) type).getMemberTypes()) {
if (getImpliedType(memberTypes).tag == TypeTags.ANYDATA) {
return true;
}
}
return false;
return SemTypeHelper.containsType(semTypeCtx, type, Core.createAnydata(semTypeCtx));
}

BType mergeTypes(BType typeFirst, BType typeSecond) {
Expand All @@ -762,11 +713,7 @@ BType mergeTypes(BType typeFirst, BType typeSecond) {
}

public boolean isSubTypeOfMapping(BType bType) {
BType type = getImpliedType(bType);
if (type.tag != TypeTags.UNION) {
return isSubTypeOfBaseType(type, TypeTags.MAP) || isSubTypeOfBaseType(type, TypeTags.RECORD);
}
return ((BUnionType) type).getMemberTypes().stream().allMatch(this::isSubTypeOfMapping);
return SemTypeHelper.isSubtypeSimpleNotNever(bType, PredefinedType.MAPPING);
}

public boolean isSubTypeOfBaseType(BType bType, int baseTypeTag) {
Expand Down Expand Up @@ -839,6 +786,10 @@ public boolean isSubtype(SemType t1, SemType t2) {
return SemTypes.isSubtype(semTypeCtx, t1, t2);
}

public boolean isSubtype(BType t1, SemType t2) {
return SemTypeHelper.isSubtype(semTypeCtx, t1, t2);
}

BField getTableConstraintField(BType constraintType, String fieldName) {
constraintType = getImpliedType(constraintType);
switch (constraintType.tag) {
Expand Down Expand Up @@ -2111,7 +2062,7 @@ boolean isNumericConversionPossible(BLangExpression expr, BType sourceType,
}

public boolean isAllErrorMembers(BUnionType actualType) {
return actualType.getMemberTypes().stream().allMatch(t -> isAssignable(t, symTable.errorType));
return isSubtype(actualType, PredefinedType.ERROR);
}

public void setImplicitCastExpr(BLangExpression expr, BType actualType, BType targetType) {
Expand Down Expand Up @@ -3456,51 +3407,13 @@ boolean validNumericTypeExists(BType type) {
}

boolean validIntegerTypeExists(BType bType) {
BType type = getImpliedType(bType);
if (type.isNullable() && type.tag != TypeTags.NIL) {
type = getSafeType(type, true, false);
}
if (TypeTags.isIntegerTypeTag(type.tag)) {
return true;
}
switch (type.tag) {
case TypeTags.BYTE:
return true;
case TypeTags.UNION:
LinkedHashSet<BType> memberTypes = ((BUnionType) type).getMemberTypes();
for (BType memberType : memberTypes) {
memberType = getImpliedType(memberType);
if (!validIntegerTypeExists(memberType)) {
return false;
}
}
return true;
case TypeTags.FINITE:
return !Core.isEmpty(semTypeCtx, SemTypes.intersect(type.semType(), PredefinedType.INT));
default:
return false;
}
SemType s = SemTypeHelper.semType(bType);
s = Core.diff(s, PredefinedType.NIL); // nil lift
return SemTypes.isSubtypeSimpleNotNever(s, PredefinedType.INT);
}

public boolean isStringSubType(BType type) {
type = getImpliedType(type);
if (TypeTags.isStringTypeTag(type.tag)) {
return true;
}
switch (type.tag) {
case TypeTags.UNION:
for (BType memType : ((BUnionType) type).getMemberTypes()) {
if (!isStringSubType(memType)) {
return false;
}
}
return true;
case TypeTags.FINITE:
SemType semType = type.semType();
return SemTypes.isSubtype(semTypeCtx, semType, PredefinedType.STRING);
default:
return false;
}
return SemTypeHelper.isSubtypeSimpleNotNever(type, PredefinedType.STRING);
}

/**
Expand Down Expand Up @@ -5055,13 +4968,8 @@ public boolean isSubTypeOfErrorOrNilContainingNil(BUnionType type) {
return false;
}

for (BType memType : type.getMemberTypes()) {
BType referredMemType = getImpliedType(memType);
if (referredMemType.tag != TypeTags.NIL && referredMemType.tag != TypeTags.ERROR) {
return false;
}
}
return true;
BasicTypeBitSet nilOrError = (BasicTypeBitSet) Core.union(PredefinedType.NIL, PredefinedType.ERROR);
return SemTypeHelper.isSubtypeSimpleNotNever(type, nilOrError);
}

/**
Expand Down Expand Up @@ -5420,24 +5328,8 @@ public BType findCompatibleType(BType type) {
}

public boolean isNonNilSimpleBasicTypeOrString(BType bType) {
BType type = getImpliedType(bType);
if (type.tag == TypeTags.UNION) {
Set<BType> memberTypes = ((BUnionType) type).getMemberTypes();
for (BType member : memberTypes) {
BType memType = getImpliedType(member);
if (memType.tag == TypeTags.FINITE || memType.tag == TypeTags.UNION) {
isNonNilSimpleBasicTypeOrString(memType);
continue;
}
if (memType.tag == TypeTags.NIL || !isSimpleBasicType(memType.tag)) {
return false;
}
}
return true;
} else if (type.tag == TypeTags.FINITE) {
return !type.isNullable();
}
return type.tag != TypeTags.NIL && isSimpleBasicType(type.tag);
return SemTypeHelper.isSubtypeSimpleNotNever(bType,
(BasicTypeBitSet) Core.diff(PredefinedType.SIMPLE_OR_STRING, PredefinedType.NIL));
}

public boolean isSubTypeOfReadOnlyOrIsolatedObjectUnion(BType bType) {
Expand Down Expand Up @@ -5563,14 +5455,7 @@ boolean isNeverTypeOrStructureTypeWithARequiredNeverMember(BType type, Set<BType
}

public boolean isNeverType(BType type) {
type = getImpliedType(type);
if (type.tag == NEVER) {
return true;
} else if (type.tag == TypeTags.UNION) {
LinkedHashSet<BType> memberTypes = ((BUnionType) type).getMemberTypes();
return memberTypes.stream().allMatch(this::isNeverType);
}
return false;
return Core.isNever(SemTypeHelper.semType(type));
}

boolean isSingletonType(BType bType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ public class BUnionType extends BType implements UnionType {
protected LinkedHashSet<BType> memberTypes;
public LinkedHashSet<SemType> memberSemTypes;

public Boolean isAnyData = null;
public Boolean isPureType = null;
public boolean isCyclic = false;


Expand Down
8 changes: 8 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/SemTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,18 @@ public static boolean isSubtypeSimple(SemType t1, BasicTypeBitSet t2) {
return Core.isSubtypeSimple(t1, t2);
}

public static boolean isSubtypeSimpleNotNever(SemType t1, BasicTypeBitSet t2) {
return !Core.isNever(t1) && Core.isSubtypeSimple(t1, t2);
}

public static boolean containsBasicType(SemType t1, BasicTypeBitSet t2) {
return (Core.widenToBasicTypes(t1).bitset & t2.bitset) != 0;
}

public static boolean containsType(Context context, SemType type, SemType typeToBeContained) {
return Core.isSameType(context, Core.intersect(type, typeToBeContained), typeToBeContained);
}

public static boolean isSameType(Context context, SemType t1, SemType t2) {
return Core.isSameType(context, t1, t2);
}
Expand Down

0 comments on commit 47750a4

Please sign in to comment.