From 1be04c748da849968d532da3aa21f28abb4aa56e Mon Sep 17 00:00:00 2001 From: MaryamZi Date: Thu, 21 Apr 2022 01:03:06 +0530 Subject: [PATCH 1/2] Fix BIR/JAR for anon types --- .../compiler/BIRPackageSymbolEnter.java | 47 +- .../compiler/bir/codegen/JvmTypeGen.java | 2 +- .../compiler/semantics/analyzer/Types.java | 426 ++++++++++++++++++ 3 files changed, 470 insertions(+), 5 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java index 1ed27eefaf3d..2007c24db94f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java @@ -86,6 +86,8 @@ import org.wso2.ballerinalang.compiler.semantics.model.types.BXMLType; import org.wso2.ballerinalang.compiler.semantics.model.types.TypeFlags; import org.wso2.ballerinalang.compiler.tree.BLangConstantValue; +import org.wso2.ballerinalang.compiler.tree.BLangPackage; +import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.expressions.BLangLiteral; import org.wso2.ballerinalang.compiler.util.BArrayState; import org.wso2.ballerinalang.compiler.util.CompilerContext; @@ -1211,7 +1213,7 @@ public BType readType(int cpI) throws IOException { } SymbolEnv pkgEnv = symTable.pkgEnvMap.get(packageCache.getSymbol(pkgId)); - return symbolResolver.lookupSymbolInMainSpace(pkgEnv, names.fromString(recordName)).type; + return getType(recordType, pkgEnv, names.fromString(recordName)); case TypeTags.TYPEDESC: BTypedescType typedescType = new BTypedescType(null, symTable.typeDesc.tsymbol); typedescType.constraint = readTypeFromCp(); @@ -1373,8 +1375,7 @@ public BType readType(int cpI) throws IOException { } else { pkgEnv = symTable.pkgEnvMap.get(packageCache.getSymbol(unionsPkgId)); if (pkgEnv != null) { - BType existingUnionType = - symbolResolver.lookupSymbolInMainSpace(pkgEnv, unionName).type; + BType existingUnionType = getType(unionType, pkgEnv, unionName); if (existingUnionType != symTable.noType) { return existingUnionType; } @@ -1577,7 +1578,7 @@ public BType readType(int cpI) throws IOException { } pkgEnv = symTable.pkgEnvMap.get(packageCache.getSymbol(pkgId)); - return symbolResolver.lookupSymbolInMainSpace(pkgEnv, names.fromString(objName)).type; + return getType(objectType, pkgEnv, names.fromString(objName)); case TypeTags.BYTE_ARRAY: // TODO fix break; @@ -1720,6 +1721,44 @@ private void populateIntersectionTypeReferencedFunctions(DataInputStream inputSt } } + private BType getType(BType readShape, SymbolEnv pkgEnv, Name name) { + BType type = symbolResolver.lookupSymbolInMainSpace(pkgEnv, name).type; + + if (types.isSameBIRShape(readShape, type)) { + return type; + } + + if (pkgEnv.node != null) { + for (BLangTypeDefinition typeDefinition : ((BLangPackage) pkgEnv.node).typeDefinitions) { + BSymbol symbol = typeDefinition.symbol; + + if (Symbols.isFlagOn(symbol.flags, Flags.ANONYMOUS)) { + BType anonType = symbol.type; + + if (types.isSameBIRShape(readShape, anonType)) { + return anonType; + } + } else if (typeDefinition.name.value.equals(name.value)) { + return symbol.type; + } + } + } else { + for (Scope.ScopeEntry value : pkgEnv.scope.entries.values()) { + BSymbol symbol = value.symbol; + + if (Symbols.isFlagOn(symbol.flags, Flags.ANONYMOUS)) { + BType anonType = symbol.type; + + if (types.isSameBIRShape(readShape, anonType)) { + return anonType; + } + } + } + } + + return type; + } + private byte[] readDocBytes(DataInputStream inputStream) throws IOException { int docLength = inputStream.readInt(); byte[] docBytes = new byte[docLength]; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java index ecc68e784fdd..c5ad85f02bde 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java @@ -832,7 +832,7 @@ private void loadUserDefinedType(MethodVisitor mv, BType bType) { //class symbols String fieldName = defName.isEmpty() ? getTypeFieldName(toNameString(typeToLoad)) : defName; - boolean samePackage = JvmCodeGenUtil.isSameModule(this.packageID, packageID); + boolean samePackage = JvmCodeGenUtil.isSameModule(this.packageID, pkgID); // if name contains $anon and doesn't belong to the same package, load type using getAnonType() method. if (!samePackage && (fieldName.contains(BLangAnonymousModelHelper.ANON_PREFIX) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java index 9f76c1482740..490eebfc4787 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java @@ -92,6 +92,7 @@ import org.wso2.ballerinalang.compiler.tree.types.BLangRecordTypeNode; import org.wso2.ballerinalang.compiler.util.BArrayState; import org.wso2.ballerinalang.compiler.util.CompilerContext; +import org.wso2.ballerinalang.compiler.util.CompilerUtils; import org.wso2.ballerinalang.compiler.util.ImmutableTypeCloner; import org.wso2.ballerinalang.compiler.util.Names; import org.wso2.ballerinalang.compiler.util.NumericLiteralSupport; @@ -2793,6 +2794,431 @@ public Boolean visit(BTypeReferenceType t, BType s) { } }; + @Deprecated + public boolean isSameBIRShape(BType source, BType target) { + return isSameBIRShape(source, target, new HashSet<>()); + } + + private boolean isSameBIRShape(BType source, BType target, Set unresolvedTypes) { + // If we encounter two types that we are still resolving, then skip it. + // This is done to avoid recursive checking of the same type. + if (!unresolvedTypes.add(new TypePair(source, target))) { + return true; + } + + BIRSameShapeVisitor birSameShapeVisitor = new BIRSameShapeVisitor(unresolvedTypes); + return target.accept(birSameShapeVisitor, source); + } + + @Deprecated + private class BIRSameShapeVisitor implements BTypeVisitor { + + Set unresolvedTypes; + + BIRSameShapeVisitor(Set unresolvedTypes) { + this.unresolvedTypes = unresolvedTypes; + } + + @Override + public Boolean visit(BType target, BType source) { + if (source.tag == TypeTags.TYPEREFDESC || target.tag == TypeTags.TYPEREFDESC) { + if (source.tag != target.tag) { + return false; + } + + BTypeReferenceType sourceRefType = (BTypeReferenceType) source; + BTypeReferenceType targetRefType = (BTypeReferenceType) target; + + BTypeSymbol sourceTSymbol = sourceRefType.tsymbol; + BTypeSymbol targetTSymbol = targetRefType.tsymbol; + String sourcePkgId = CompilerUtils.getPackageIDStringWithMajorVersion(sourceTSymbol.pkgID); + String targetPkgId = CompilerUtils.getPackageIDStringWithMajorVersion(targetTSymbol.pkgID); + return sourcePkgId.equals(targetPkgId) && sourceTSymbol.name.equals(targetTSymbol.name); + } + + BType t = getReferredType(target); + BType s = getReferredType(source); + if (t == s) { + return true; + } + switch (t.tag) { + case TypeTags.INT: + case TypeTags.BYTE: + case TypeTags.FLOAT: + case TypeTags.DECIMAL: + case TypeTags.STRING: + case TypeTags.BOOLEAN: + return t.tag == s.tag + && ((TypeParamAnalyzer.isTypeParam(t) || TypeParamAnalyzer.isTypeParam(s)) || + (t.tag == TypeTags.TYPEREFDESC || s.tag == TypeTags.TYPEREFDESC)); + case TypeTags.ANY: + case TypeTags.ANYDATA: + return t.tag == s.tag && hasSameReadonlyFlag(s, t) + && (TypeParamAnalyzer.isTypeParam(t) || TypeParamAnalyzer.isTypeParam(s)); + default: + break; + } + return false; + + } + + @Override + public Boolean visit(BBuiltInRefType t, BType s) { + return t == s; + } + + @Override + public Boolean visit(BAnyType t, BType s) { + return t == s; + } + + @Override + public Boolean visit(BAnydataType t, BType s) { + if (t == s) { + return true; + } + return t.tag == s.tag; + } + + @Override + public Boolean visit(BMapType t, BType s) { + if (s.tag != TypeTags.MAP || !hasSameReadonlyFlag(s, t)) { + return false; + } + // At this point both source and target types are of map types. Inorder to be equal in type as whole + // constraints should be in equal type. + BMapType sType = ((BMapType) s); + return isSameBIRShape(sType.constraint, t.constraint, this.unresolvedTypes); + } + + @Override + public Boolean visit(BFutureType t, BType s) { + return s.tag == TypeTags.FUTURE && + isSameBIRShape(t.constraint, ((BFutureType) s).constraint, this.unresolvedTypes); + } + + @Override + public Boolean visit(BXMLType t, BType s) { + return visit((BBuiltInRefType) t, s); + } + + @Override + public Boolean visit(BJSONType t, BType s) { + return s.tag == TypeTags.JSON && hasSameReadonlyFlag(s, t); + } + + @Override + public Boolean visit(BArrayType t, BType s) { + return s.tag == TypeTags.ARRAY && hasSameReadonlyFlag(s, t) && isSameArrayType(s, t, this.unresolvedTypes); + } + + @Override + public Boolean visit(BObjectType t, BType s) { + if (t == s) { + return true; + } + + if (s.tag != TypeTags.OBJECT) { + return false; + } + + return t.tsymbol.pkgID.equals(s.tsymbol.pkgID) && t.tsymbol.name.equals(s.tsymbol.name); + } + + @Override + public Boolean visit(BRecordType t, BType s) { + if (t == s) { + return true; + } + + if (s.tag != TypeTags.RECORD || !hasSameReadonlyFlag(s, t)) { + return false; + } + + BRecordType source = (BRecordType) s; + + if (source.fields.size() != t.fields.size()) { + return false; + } + + for (BField sourceField : source.fields.values()) { + if (t.fields.containsKey(sourceField.name.value)) { + BField targetField = t.fields.get(sourceField.name.value); + if (isSameBIRShape(sourceField.type, targetField.type, this.unresolvedTypes) && + hasSameOptionalFlag(sourceField.symbol, targetField.symbol) && + (!Symbols.isFlagOn(targetField.symbol.flags, Flags.READONLY) || + Symbols.isFlagOn(sourceField.symbol.flags, Flags.READONLY))) { + continue; + } + } + return false; + } + return isSameBIRShape(source.restFieldType, t.restFieldType, this.unresolvedTypes); + } + + private boolean hasSameOptionalFlag(BVarSymbol s, BVarSymbol t) { + return ((s.flags & Flags.OPTIONAL) ^ (t.flags & Flags.OPTIONAL)) != Flags.OPTIONAL; + } + + private boolean hasSameReadonlyFlag(BType source, BType target) { + return Symbols.isFlagOn(target.flags, Flags.READONLY) == Symbols.isFlagOn(source.flags, Flags.READONLY); + } + + public Boolean visit(BTupleType t, BType s) { + if (((!t.tupleTypes.isEmpty() && checkAllTupleMembersBelongNoType(t.tupleTypes)) || + (t.restType != null && t.restType.tag == TypeTags.NONE)) && + !(s.tag == TypeTags.ARRAY && ((BArrayType) s).state == BArrayState.OPEN)) { + return true; + } + + if (s.tag != TypeTags.TUPLE || !hasSameReadonlyFlag(s, t)) { + return false; + } + BTupleType source = (BTupleType) s; + if (source.tupleTypes.size() != t.tupleTypes.size()) { + return false; + } + + BType sourceRestType = source.restType; + BType targetRestType = t.restType; + if ((sourceRestType == null || targetRestType == null) && sourceRestType != targetRestType) { + return false; + } + + for (int i = 0; i < source.tupleTypes.size(); i++) { + if (t.getTupleTypes().get(i) == symTable.noType) { + continue; + } + if (!isSameBIRShape(source.getTupleTypes().get(i), t.tupleTypes.get(i), this.unresolvedTypes)) { + return false; + } + } + + if (sourceRestType == null || targetRestType == symTable.noType) { + return true; + } + + return isSameBIRShape(sourceRestType, targetRestType, this.unresolvedTypes); + } + + @Override + public Boolean visit(BStreamType t, BType s) { + return s.tag == TypeTags.STREAM && isSameStreamType(s, t, this.unresolvedTypes); + } + + @Override + public Boolean visit(BTableType t, BType s) { + return t == s; + } + + @Override + public Boolean visit(BInvokableType t, BType s) { + return s.tag == TypeTags.INVOKABLE && isSameFunctionType((BInvokableType) s, t, this.unresolvedTypes); + } + + @Override + public Boolean visit(BUnionType tUnionType, BType s) { + if (s.tag != TypeTags.UNION || !hasSameReadonlyFlag(s, tUnionType)) { + return false; + } + + BUnionType sUnionType = (BUnionType) s; + + if (sUnionType.getMemberTypes().size() + != tUnionType.getMemberTypes().size()) { + return false; + } + + Set sourceTypes = new LinkedHashSet<>(sUnionType.getMemberTypes().size()); + Set targetTypes = new LinkedHashSet<>(tUnionType.getMemberTypes().size()); + + if (sUnionType.isCyclic) { + sourceTypes.add(sUnionType); + } + sourceTypes.addAll(sUnionType.getMemberTypes()); + if (tUnionType.isCyclic) { + targetTypes.add(tUnionType); + } + targetTypes.addAll(tUnionType.getMemberTypes()); + + boolean notSameType = false; + for (BType sT : sourceTypes) { + boolean foundSameType = false; + for (BType it : targetTypes) { + if (isSameBIRShape(it, sT, this.unresolvedTypes)) { + foundSameType = true; + break; + } + } + if (!foundSameType) { + notSameType = true; + break; + } + } + return !notSameType; + } + + @Override + public Boolean visit(BIntersectionType tIntersectionType, BType s) { + if (s.tag != TypeTags.INTERSECTION || !hasSameReadonlyFlag(s, tIntersectionType)) { + return false; + } + + BIntersectionType sIntersectionType = (BIntersectionType) s; + + if (sIntersectionType.getConstituentTypes().size() != tIntersectionType.getConstituentTypes().size()) { + return false; + } + + Set sourceTypes = new LinkedHashSet<>(sIntersectionType.getConstituentTypes()); + Set targetTypes = new LinkedHashSet<>(tIntersectionType.getConstituentTypes()); + + for (BType sourceType : sourceTypes) { + boolean foundSameType = false; + + for (BType targetType : targetTypes) { + if (isSameBIRShape(sourceType, targetType, this.unresolvedTypes)) { + foundSameType = true; + break; + } + } + + if (!foundSameType) { + return false; + } + } + + return true; + } + + @Override + public Boolean visit(BErrorType t, BType s) { + if (s.tag != TypeTags.ERROR) { + return false; + } + BErrorType source = (BErrorType) s; + + if (!source.typeIdSet.equals(t.typeIdSet)) { + return false; + } + + if (source.detailType == t.detailType) { + return true; + } + + return isSameBIRShape(source.detailType, t.detailType, this.unresolvedTypes); + } + + @Override + public Boolean visit(BTypedescType t, BType s) { + + if (s.tag != TypeTags.TYPEDESC) { + return false; + } + BTypedescType sType = ((BTypedescType) s); + return isSameBIRShape(sType.constraint, t.constraint, this.unresolvedTypes); + } + + + @Override + public Boolean visit(BFiniteType t, BType s) { + if (s.tag != TypeTags.FINITE) { + return false; + } + + Set sourceValueSpace = ((BFiniteType) s).getValueSpace(); + Set targetValueSpace = t.getValueSpace(); + + if (sourceValueSpace.size() != targetValueSpace.size()) { + return false; + } + + return hasSameMembers(sourceValueSpace, targetValueSpace); + } + + @Override + public Boolean visit(BParameterizedType t, BType s) { + if (s.tag != TypeTags.PARAMETERIZED_TYPE) { + return false; + } + + BParameterizedType sType = (BParameterizedType) s; + return isSameBIRShape(sType.paramValueType, t.paramValueType) && sType.paramSymbol.equals(t.paramSymbol); + } + + public Boolean visit(BTypeReferenceType t, BType s) { + if (s.tag != TypeTags.TYPEREFDESC) { + return false; + } + + BTypeReferenceType sTypeRefType = (BTypeReferenceType) s; + + BTypeSymbol sourceTSymbol = sTypeRefType.tsymbol; + BTypeSymbol targetTSymbol = t.tsymbol; + String sourcePkgId = CompilerUtils.getPackageIDStringWithMajorVersion(sourceTSymbol.pkgID); + String targetPkgId = CompilerUtils.getPackageIDStringWithMajorVersion(targetTSymbol.pkgID); + return sourcePkgId.equals(targetPkgId) && sourceTSymbol.name.equals(targetTSymbol.name); + } + } + + private boolean hasSameMembers(Set sourceValueSpace, Set targetValueSpace) { + Set setOne = new HashSet<>(sourceValueSpace); + Set setTwo = new HashSet<>(targetValueSpace); + + Iterator setOneIterator = setOne.iterator(); + Iterator setTwoIterator = setTwo.iterator(); + + while (setOneIterator.hasNext()) { + BLangLiteral setOneMem = (BLangLiteral) setOneIterator.next(); + + if (!setTwoIterator.hasNext()) { + return false; + } + + boolean hasEqualValue = false; + while (setTwoIterator.hasNext()) { + BLangLiteral setTwoMem = (BLangLiteral) setTwoIterator.next(); + if (setOneMem.value.equals(setTwoMem.value) && setOneMem.getBType() == setTwoMem.getBType()) { + hasEqualValue = true; + setOneIterator.remove(); + setTwoIterator.remove(); + break; + } + } + + if (!hasEqualValue) { + return false; + } + } + + return !setOneIterator.hasNext() && !setTwoIterator.hasNext(); + +// if (!checkSameMembers(sourceValueSpace, targetValueSpace)) { +// return false; +// } +// +// return checkSameMembers(targetValueSpace, sourceValueSpace); + } + +// private boolean checkSameMembers(Set setOne, Set setTwo) { +// for (BLangExpression sourceExpr : setOne) { +// boolean hasEqualValue = false; +// for (BLangExpression targetExpr : setTwo) { +// BLangLiteral targetLiteral = (BLangLiteral) targetExpr; +// BLangLiteral sourceLiteral = (BLangLiteral) sourceExpr; +// if (targetLiteral.value.equals(sourceLiteral.value) && +// targetLiteral.getBType() == sourceLiteral.getBType()) { +// hasEqualValue = true; +// break; +// } +// } +// if (!hasEqualValue) { +// return false; +// } +// } +// return true; +// } + private class BOrderedTypeVisitor implements BTypeVisitor { Set unresolvedTypes; From e70994427188f11e67371104c0de05f0c86a6eb2 Mon Sep 17 00:00:00 2001 From: MaryamZi Date: Fri, 22 Apr 2022 15:13:04 +0530 Subject: [PATCH 2/2] Fix checks --- .../compiler/BIRPackageSymbolEnter.java | 14 +++-- .../compiler/semantics/analyzer/Types.java | 58 +++++++++---------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java index 2007c24db94f..f409c2814488 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/BIRPackageSymbolEnter.java @@ -119,6 +119,7 @@ import static org.ballerinalang.model.symbols.SymbolOrigin.COMPILED_SOURCE; import static org.ballerinalang.model.symbols.SymbolOrigin.VIRTUAL; import static org.ballerinalang.model.symbols.SymbolOrigin.toOrigin; +import static org.wso2.ballerinalang.compiler.parser.BLangAnonymousModelHelper.ANON_PREFIX; import static org.wso2.ballerinalang.compiler.semantics.model.Scope.NOT_FOUND_ENTRY; import static org.wso2.ballerinalang.util.LambdaExceptionUtils.rethrow; @@ -1724,7 +1725,7 @@ private void populateIntersectionTypeReferencedFunctions(DataInputStream inputSt private BType getType(BType readShape, SymbolEnv pkgEnv, Name name) { BType type = symbolResolver.lookupSymbolInMainSpace(pkgEnv, name).type; - if (types.isSameBIRShape(readShape, type)) { + if (type != symTable.noType && (!name.value.contains(ANON_PREFIX) || types.isSameBIRShape(readShape, type))) { return type; } @@ -1732,21 +1733,22 @@ private BType getType(BType readShape, SymbolEnv pkgEnv, Name name) { for (BLangTypeDefinition typeDefinition : ((BLangPackage) pkgEnv.node).typeDefinitions) { BSymbol symbol = typeDefinition.symbol; - if (Symbols.isFlagOn(symbol.flags, Flags.ANONYMOUS)) { + String typeDefName = typeDefinition.name.value; + if (typeDefName.contains(ANON_PREFIX)) { BType anonType = symbol.type; if (types.isSameBIRShape(readShape, anonType)) { return anonType; } - } else if (typeDefinition.name.value.equals(name.value)) { + } else if (typeDefName.equals(name.value)) { return symbol.type; } } } else { - for (Scope.ScopeEntry value : pkgEnv.scope.entries.values()) { - BSymbol symbol = value.symbol; + for (Map.Entry value : pkgEnv.scope.entries.entrySet()) { + BSymbol symbol = value.getValue().symbol; - if (Symbols.isFlagOn(symbol.flags, Flags.ANONYMOUS)) { + if (value.getKey().value.contains(ANON_PREFIX)) { BType anonType = symbol.type; if (types.isSameBIRShape(readShape, anonType)) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java index 490eebfc4787..f26b8eb28a5d 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java @@ -2909,7 +2909,18 @@ public Boolean visit(BJSONType t, BType s) { @Override public Boolean visit(BArrayType t, BType s) { - return s.tag == TypeTags.ARRAY && hasSameReadonlyFlag(s, t) && isSameArrayType(s, t, this.unresolvedTypes); + if (s.tag != TypeTags.ARRAY || !hasSameReadonlyFlag(s, t)) { + return false; + } + + BArrayType sArrayType = (BArrayType) s; + + boolean hasSameTypeElements = isSameBIRShape(t.eType, sArrayType.eType, unresolvedTypes); + if (t.state == BArrayState.OPEN) { + return (sArrayType.state == BArrayState.OPEN) && hasSameTypeElements; + } + + return t.size == sArrayType.size && hasSameTypeElements; } @Override @@ -3003,7 +3014,14 @@ public Boolean visit(BTupleType t, BType s) { @Override public Boolean visit(BStreamType t, BType s) { - return s.tag == TypeTags.STREAM && isSameStreamType(s, t, this.unresolvedTypes); + if (s.tag != TypeTags.STREAM) { + return false; + } + + BStreamType sStreamType = (BStreamType) s; + + return isSameBIRShape(t.constraint, sStreamType.constraint, unresolvedTypes) + && isSameBIRShape(t.completionType, sStreamType.completionType, unresolvedTypes); } @Override @@ -3013,7 +3031,7 @@ public Boolean visit(BTableType t, BType s) { @Override public Boolean visit(BInvokableType t, BType s) { - return s.tag == TypeTags.INVOKABLE && isSameFunctionType((BInvokableType) s, t, this.unresolvedTypes); + return s.tag == TypeTags.INVOKABLE && isSameFunctionBIRShape((BInvokableType) s, t, this.unresolvedTypes); } @Override @@ -3161,6 +3179,11 @@ public Boolean visit(BTypeReferenceType t, BType s) { } } + private boolean isSameFunctionBIRShape(BInvokableType source, BInvokableType target, + Set unresolvedTypes) { + return checkFunctionTypeEquality(source, target, unresolvedTypes, this::isSameBIRShape); + } + private boolean hasSameMembers(Set sourceValueSpace, Set targetValueSpace) { Set setOne = new HashSet<>(sourceValueSpace); Set setTwo = new HashSet<>(targetValueSpace); @@ -3191,33 +3214,8 @@ private boolean hasSameMembers(Set sourceValueSpace, Set setOne, Set setTwo) { -// for (BLangExpression sourceExpr : setOne) { -// boolean hasEqualValue = false; -// for (BLangExpression targetExpr : setTwo) { -// BLangLiteral targetLiteral = (BLangLiteral) targetExpr; -// BLangLiteral sourceLiteral = (BLangLiteral) sourceExpr; -// if (targetLiteral.value.equals(sourceLiteral.value) && -// targetLiteral.getBType() == sourceLiteral.getBType()) { -// hasEqualValue = true; -// break; -// } -// } -// if (!hasEqualValue) { -// return false; -// } -// } -// return true; -// } + return !setTwoIterator.hasNext(); + } private class BOrderedTypeVisitor implements BTypeVisitor {