diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java index 60796bf0fa39..6bba6a9b1038 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java @@ -21,7 +21,6 @@ import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ErrorType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; @@ -31,13 +30,9 @@ import io.ballerina.runtime.api.types.semtype.SemType; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; -import io.ballerina.runtime.internal.TypeChecker; -import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.types.semtype.ErrorUtils; -import io.ballerina.runtime.internal.types.semtype.MappingDefinition; import io.ballerina.runtime.internal.values.ErrorValue; -import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; @@ -171,7 +166,7 @@ public Optional shapeOf(Context cx, Object object) { } SemType detailType = Builder.from(cx, errorDetails.getType()); boolean hasBType = !Core.isNever(Core.intersect(detailType, Core.B_TYPE_TOP)); - return BMapType.shapeOfInner(cx, errorDetails) + return BMapType.readonlyShape(cx, errorDetails) .map(ErrorUtils::errorDetail) .map(err -> distinctIdSupplier.get().stream().map(ErrorUtils::errorDistinct) .reduce(err, Core::intersect)) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java index 2c39ca308258..30706bfcb341 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java @@ -219,10 +219,10 @@ public Optional shapeOf(Context cx, Object object) { return Optional.of(cachedShape); } - return shapeOfInner(cx, value); + return readonlyShape(cx, value); } - static Optional shapeOfInner(Context cx, BMap value) { + static Optional readonlyShape(Context cx, BMap value) { int nFields = value.size(); MappingDefinition.Field[] fields = new MappingDefinition.Field[nFields]; Map.Entry[] entries = (Map.Entry[]) value.entrySet().toArray(Map.Entry[]::new); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/DistinctIdSupplier.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/DistinctIdSupplier.java index b490b208f1ae..3ea468ab9bb3 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/DistinctIdSupplier.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/DistinctIdSupplier.java @@ -26,13 +26,14 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; final class DistinctIdSupplier implements Supplier> { private List ids = null; - private static final Map allocatedIds = new ConcurrentHashMap<>(); + private static final Map allocatedIds = new ConcurrentHashMap<>(); private final Env env; private final TypeIdSet typeIdSet; @@ -48,9 +49,27 @@ public synchronized Collection get() { if (typeIdSet == null) { return List.of(); } - ids = typeIdSet.getIds().stream().map(typeId -> allocatedIds.computeIfAbsent(typeId, + ids = typeIdSet.getIds().stream().map(TypeIdWrapper::new).map(typeId -> allocatedIds.computeIfAbsent(typeId, ignored -> env.distinctAtomCountGetAndIncrement())) .toList(); return ids; } + + // This is to avoid whether id is primary or not affecting the hashcode. + private record TypeIdWrapper(TypeId typeId) { + + @Override + public boolean equals(Object obj) { + if (obj instanceof TypeIdWrapper other) { + return typeId.getName().equals(other.typeId().getName()) && + typeId.getPkg().equals(other.typeId().getPkg()); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(typeId.getPkg(), typeId.getName()); + } + } }