From 68f099ccb47c80b32220c09040e31fbf7bfdc72c Mon Sep 17 00:00:00 2001 From: Heshan Padamsiri Date: Mon, 24 Feb 2025 17:48:58 +0530 Subject: [PATCH] WIP: semtype flyweight A --- .../api/types/ImmutableSemTypeFlyweight.java | 41 +++++++ .../api/types/MutableSemTypeFlyweight.java | 66 ++++++++++++ .../runtime/api/types/SemTypeFlyweight.java | 37 +++++++ .../api/types/semtype/BasicTypeBitSet.java | 30 +----- .../types/semtype/BasicTypeBitSetImpl.java | 47 ++++++++ .../runtime/api/types/semtype/Builder.java | 3 +- .../runtime/api/types/semtype/Core.java | 3 +- .../api/types/semtype/PredefinedTypeEnv.java | 6 +- .../runtime/api/types/semtype/SemType.java | 62 +++-------- .../api/types/semtype/SemTypeImpl.java | 56 ++++++++++ .../runtime/internal/TypeChecker.java | 3 +- .../runtime/internal/TypeConverter.java | 3 +- .../runtime/internal/types/BAnydataType.java | 32 +++--- .../runtime/internal/types/BArrayType.java | 21 +++- .../runtime/internal/types/BErrorType.java | 2 +- .../runtime/internal/types/BFiniteType.java | 16 ++- .../runtime/internal/types/BFunctionType.java | 6 +- .../runtime/internal/types/BFutureType.java | 2 +- .../runtime/internal/types/BJsonType.java | 36 ++++--- .../runtime/internal/types/BMapType.java | 16 ++- .../runtime/internal/types/BObjectType.java | 3 +- .../runtime/internal/types/BReadonlyType.java | 3 +- .../runtime/internal/types/BStreamType.java | 2 +- .../runtime/internal/types/BTableType.java | 4 +- .../runtime/internal/types/BType.java | 45 ++++---- .../internal/types/BTypeReferenceType.java | 2 +- .../runtime/internal/types/BTypedescType.java | 19 +++- .../runtime/internal/types/BXmlType.java | 19 +++- .../internal/types/TypeCheckableType.java | 43 ++++++-- .../internal/types/semtype/BListSubType.java | 3 +- .../types/semtype/ImmutableSemType.java | 35 ++---- .../types/semtype/MappingDefinition.java | 3 +- .../internal/types/semtype/TableUtils.java | 27 +++-- .../src/main/java/module-info.java | 2 +- .../runtime/test/semtype/CoreTests.java | 3 +- .../port/test/RuntimeSemTypeResolver.java | 29 ++--- .../semtype/port/test/RuntimeTypeTestAPI.java | 19 ++-- .../typecast/TypeCastExprTest.java | 4 +- .../expressions/let/let-expression-test.bal | 71 ++++++------ .../literals/numeric_literal_assignment.bal | 53 ++++----- .../expressions/object/object_closures.bal | 38 +++---- .../object/object_closures_annotations.bal | 101 +++++++++--------- .../rawtemplate/raw_template_literal_test.bal | 69 ++++++------ .../expressions/typecast/type-casting.bal | 32 +++--- 44 files changed, 705 insertions(+), 412 deletions(-) create mode 100644 bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/ImmutableSemTypeFlyweight.java create mode 100644 bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/MutableSemTypeFlyweight.java create mode 100644 bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/SemTypeFlyweight.java create mode 100644 bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSetImpl.java create mode 100644 bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemTypeImpl.java diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/ImmutableSemTypeFlyweight.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/ImmutableSemTypeFlyweight.java new file mode 100644 index 000000000000..a2fda6997c25 --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/ImmutableSemTypeFlyweight.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.runtime.api.types; + +import io.ballerina.runtime.api.types.semtype.SemType; +import io.ballerina.runtime.api.types.semtype.TypeCheckCache; + +public record ImmutableSemTypeFlyweight(SemType semType, int typeId, TypeCheckCache typeCheckCache) + implements SemTypeFlyweight { + + @Override + public void setSemType(SemType semType) { + throw new UnsupportedOperationException("Cannot mutate immutable semType flyweight"); + } + + @Override + public void setTypeId(int typeId) { + throw new UnsupportedOperationException("Cannot mutate immutable semType flyweight"); + } + + @Override + public void setTypeCheckCache(TypeCheckCache typeCheckCache) { + throw new UnsupportedOperationException("Cannot mutate immutable semType flyweight"); + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/MutableSemTypeFlyweight.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/MutableSemTypeFlyweight.java new file mode 100644 index 000000000000..683a6605fd0d --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/MutableSemTypeFlyweight.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.runtime.api.types; + +import io.ballerina.runtime.api.types.semtype.SemType; +import io.ballerina.runtime.api.types.semtype.TypeCheckCache; +import io.ballerina.runtime.internal.types.TypeCheckableType; + +import java.util.concurrent.atomic.AtomicReference; + +public class MutableSemTypeFlyweight implements SemTypeFlyweight { + + AtomicReference ref = new AtomicReference<>(); + int typeId = -1; + TypeCheckCache typeCheckCache = null; + + @Override + public SemType semType() { + return ref.get(); + } + + @Override + public int typeId() { + return typeId; + } + + @Override + public TypeCheckCache typeCheckCache() { + return typeCheckCache; + } + + @Override + public void setSemType(SemType semType) { + if (semType instanceof TypeCheckableType wrapper) { + ref.set(wrapper.semTypeFlyweight.semType()); + } else { + ref.set(semType); + } + } + + @Override + public void setTypeId(int typeId) { + this.typeId = typeId; + } + + @Override + public void setTypeCheckCache(TypeCheckCache typeCheckCache) { + this.typeCheckCache = typeCheckCache; + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/SemTypeFlyweight.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/SemTypeFlyweight.java new file mode 100644 index 000000000000..5c52d0c59a04 --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/SemTypeFlyweight.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.runtime.api.types; + +import io.ballerina.runtime.api.types.semtype.SemType; +import io.ballerina.runtime.api.types.semtype.TypeCheckCache; + +public interface SemTypeFlyweight { + + SemType semType(); + + int typeId(); + + TypeCheckCache typeCheckCache(); + + void setSemType(SemType semType); + + void setTypeId(int typeId); + + void setTypeCheckCache(TypeCheckCache typeCheckCache); +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSet.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSet.java index 2c667ab99677..d142b92d6e40 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSet.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSet.java @@ -15,34 +15,14 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.api.types.semtype; - -/** - * Abstraction on top of bit set used to represent union of "all" of a given basic type. - * - * @since 2201.12.0 - */ -public sealed class BasicTypeBitSet permits SemType { - - private int all; - public BasicTypeBitSet(int all) { - this.all = all; - } +package io.ballerina.runtime.api.types.semtype; - protected void setAll(int all) { - this.all = all; - } +public interface BasicTypeBitSet { - public final int all() { - return all; - } + int all(); - public BasicTypeBitSet union(BasicTypeBitSet basicTypeBitSet) { - return new BasicTypeBitSet(all() | basicTypeBitSet.all()); - } + BasicTypeBitSet union(BasicTypeBitSet basicTypeBitSet); - public BasicTypeBitSet intersection(BasicTypeBitSet basicTypeBitSet) { - return new BasicTypeBitSet(all() & basicTypeBitSet.all()); - } + BasicTypeBitSet intersection(BasicTypeBitSet basicTypeBitSet); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSetImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSetImpl.java new file mode 100644 index 000000000000..37e51bdb34a9 --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/BasicTypeBitSetImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.ballerina.runtime.api.types.semtype; + +/** + * Abstraction on top of bit set used to represent union of "all" of a given basic type. + * + * @since 2201.12.0 + */ +public sealed class BasicTypeBitSetImpl implements BasicTypeBitSet permits SemTypeImpl { + + private final int all; + + public BasicTypeBitSetImpl(int all) { + this.all = all; + } + + @Override + public int all() { + return all; + } + + @Override + public BasicTypeBitSet union(BasicTypeBitSet basicTypeBitSet) { + return new BasicTypeBitSetImpl(all() | basicTypeBitSet.all()); + } + + @Override + public BasicTypeBitSet intersection(BasicTypeBitSet basicTypeBitSet) { + return new BasicTypeBitSetImpl(all() & basicTypeBitSet.all()); + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Builder.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Builder.java index 71f083740819..9cd0a7b8fbde 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Builder.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Builder.java @@ -73,7 +73,8 @@ public final class Builder { private static final SemType INHERENTLY_IMMUTABLE = SemType.from(VT_INHERENTLY_IMMUTABLE); private static final SemType INNER = getBasicTypeUnion(VAL.all() | from(BasicTypeCode.BT_UNDEF).all()); - private static final SemType ANY = getBasicTypeUnion(BasicTypeCode.VT_MASK & ~(1 << BasicTypeCode.BT_ERROR.code())); + private static final SemType ANY = + getBasicTypeUnion(BasicTypeCode.VT_MASK & ~(1 << BasicTypeCode.BT_ERROR.code())); private static final SemType SIMPLE_OR_STRING = getBasicTypeUnion((1 << BasicTypeCode.BT_NIL.code()) | (1 << BasicTypeCode.BT_BOOLEAN.code()) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Core.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Core.java index 471c7e14994b..0ef1bed298e4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Core.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Core.java @@ -295,8 +295,7 @@ public static boolean isNever(SemType t) { } public static boolean isSubType(Context cx, SemType t1, SemType t2) { - boolean res = isEmpty(cx, diff(t1, t2)); - return res; + return isEmpty(cx, diff(t1, t2)); } public static boolean isSubtypeSimple(SemType t1, SemType t2) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/PredefinedTypeEnv.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/PredefinedTypeEnv.java index 75e1aad7c734..5db4436392dd 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/PredefinedTypeEnv.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/PredefinedTypeEnv.java @@ -146,7 +146,8 @@ final class PredefinedTypeEnv { basicSubType(BT_CELL, BCellSubType.createDelegate(bddAtom(atomCellMappingArray.get())))); private final Supplier listAtomicThreeElement = new ConcurrentLazySupplierWithCallback<>( () -> new ListAtomicType( - FixedLengthArray.from(new SemType[]{cellSemTypeListSubtypeMapping.get(), cellSemTypeVal.get()}, 3), + FixedLengthArray.from(new SemType[]{cellSemTypeListSubtypeMapping.get(), cellSemTypeVal.get()}, + 3), cellSemTypeVal.get()), this::addInitializedListAtom ); @@ -182,7 +183,8 @@ final class PredefinedTypeEnv { () -> basicSubType(BT_CELL, BCellSubType.createDelegate(bddAtom(atomCellMappingArrayRO.get())))); private final Supplier listAtomicThreeElementRO = new ConcurrentLazySupplierWithCallback<>( () -> new ListAtomicType( - FixedLengthArray.from(new SemType[]{cellSemTypeListSubtypeMappingRO.get(), cellSemTypeVal.get()}, + FixedLengthArray.from( + new SemType[]{cellSemTypeListSubtypeMappingRO.get(), cellSemTypeVal.get()}, 3), cellSemTypeUndef.get()), this::addInitializedListAtom diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemType.java index d6b0d23a15f0..c6767793a277 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemType.java @@ -19,68 +19,36 @@ package io.ballerina.runtime.api.types.semtype; import io.ballerina.runtime.api.types.Type; -import io.ballerina.runtime.internal.types.TypeCheckableType; import io.ballerina.runtime.internal.types.semtype.MutableSemType; -/** - * Represent a type in runtime. - * - * @since 2201.12.0 - */ -public sealed class SemType extends BasicTypeBitSet permits TypeCheckableType { - - private int some; - private SubType[] subTypeData; - private static final SemType NEVER = new SemType(0, 0, null); - - protected SemType(int all, int some, SubType[] subTypeData) { - super(all); - this.some = some; - this.subTypeData = subTypeData; - } +public interface SemType extends BasicTypeBitSet { - protected SemType() { - this(-1, -1, null); - } + SemType NEVER = new SemTypeImpl(0, 0, null); - public static SemType from(int all) { + static SemType from(int all) { if (all == 0) { return NEVER; } - return new SemType(all, 0, null); - } - - public static SemType from(int all, int some, SubType[] subTypes) { - return new SemType(all, some, subTypes); - } - - public final int some() { - return some; + return new SemTypeImpl(all, 0, null); } - public final SubType[] subTypeData() { - return subTypeData; + static SemType from(int all, int some, SubType[] subTypes) { + return new SemTypeImpl(all, some, subTypes); } - public final SubType subTypeByCode(int code) { - if ((some() & (1 << code)) == 0) { - return null; - } - int someMask = (1 << code) - 1; - int some = some() & someMask; - return subTypeData()[Integer.bitCount(some)]; - } - - protected void setSome(int some, SubType[] subTypeData) { - this.some = some; - this.subTypeData = subTypeData; - } - - public static SemType tryInto(Context cx, Type type) { + static SemType tryInto(Context cx, Type type) { if (type instanceof MutableSemType mutableSemType) { mutableSemType.updateInnerSemTypeIfNeeded(cx); } return (SemType) type; } + + int all(); + + int some(); + + SubType[] subTypeData(); + + SubType subTypeByCode(int code); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemTypeImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemTypeImpl.java new file mode 100644 index 000000000000..730e87000c60 --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/SemTypeImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.runtime.api.types.semtype; + +/** + * Represent a type in runtime. + * + * @since 2201.12.0 + */ +public final class SemTypeImpl extends BasicTypeBitSetImpl implements SemType { + + private int some; + private SubType[] subTypeData; + + SemTypeImpl(int all, int some, SubType[] subTypeData) { + super(all); + this.some = some; + this.subTypeData = subTypeData; + } + + @Override + public int some() { + return some; + } + + @Override + public SubType[] subTypeData() { + return subTypeData; + } + + @Override + public SubType subTypeByCode(int code) { + if ((some() & (1 << code)) == 0) { + return null; + } + int someMask = (1 << code) - 1; + int some = some() & someMask; + return subTypeData()[Integer.bitCount(some)]; + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java index cfa7a6fc7c36..e00c3054d254 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java @@ -383,8 +383,7 @@ private static boolean shapeBelongToType(Context cx, Object sourceValue, Type ta if (Core.isSubtypeSimple(shape, NumericTypeHolder.NUMERIC_TYPE) && allowNumericConversion) { targetSemType = appendNumericConversionTypes(targetSemType); } - boolean result = Core.isSubType(cx, shape, targetSemType); - return result; + return Core.isSubType(cx, shape, targetSemType); } private static SemType appendNumericConversionTypes(SemType semType) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java index 573be7c00f63..afcdc8075500 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java @@ -175,7 +175,8 @@ public static Object castValues(Type targetType, Object inputValue) { () -> ErrorUtils.createTypeCastError(inputValue, targetType)); } - static Object castValuesInner(Context cx, SemType targetType, Object inputValue, Supplier errorSupplier) { + static Object castValuesInner(Context cx, SemType targetType, Object inputValue, + Supplier errorSupplier) { if (Core.isSubType(cx, targetType, Builder.getIntType())) { return castValueToInt(cx, targetType, inputValue); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java index 48d982503078..05a68ecf7929 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java @@ -21,15 +21,17 @@ import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.AnydataType; +import io.ballerina.runtime.api.types.MutableSemTypeFlyweight; import io.ballerina.runtime.api.types.PredefinedTypes; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; +import io.ballerina.runtime.api.types.semtype.BasicTypeBitSetImpl; import io.ballerina.runtime.api.types.semtype.Builder; import io.ballerina.runtime.api.types.semtype.Context; import io.ballerina.runtime.api.types.semtype.Core; import io.ballerina.runtime.api.types.semtype.SemType; -import io.ballerina.runtime.api.types.semtype.TypeCheckCache; import io.ballerina.runtime.api.types.semtype.TypeCheckCacheFactory; import io.ballerina.runtime.internal.values.RefValue; @@ -41,13 +43,19 @@ public class BAnydataType extends BUnionType implements AnydataType { private static final BasicTypeBitSet BASIC_TYPE; - private static final int TYPE_ID_RW = TypeIdSupplier.getReservedId(); - private static final int TYPE_ID_RO = TypeIdSupplier.getReservedId(); - private static final TypeCheckCache TYPE_CHECK_CACHE_RW = TypeCheckCacheFactory.create(); - private static final TypeCheckCache TYPE_CHECK_CACHE_RO = TypeCheckCacheFactory.create(); + private static final SemTypeFlyweight FLYWEIGHT_RW = initFlyWeight(); + private static final SemTypeFlyweight FLYWEIGHT_RO = initFlyWeight(); + + private static SemTypeFlyweight initFlyWeight() { + SemTypeFlyweight flyweight = new MutableSemTypeFlyweight(); + flyweight.setTypeId(TypeIdSupplier.getReservedId()); + flyweight.setTypeCheckCache(TypeCheckCacheFactory.create()); + return flyweight; + } + static { SemType anydata = Builder.getAnyDataType(); - BASIC_TYPE = new BasicTypeBitSet(anydata.all() | anydata.some()); + BASIC_TYPE = new BasicTypeBitSetImpl(anydata.all() | anydata.some()); } /** * Create a {@code BAnydataType} which represents the anydata type. @@ -61,11 +69,9 @@ public BAnydataType(String typeName, Module pkg, boolean readonly) { this.immutableType = new BIntersectionType(pkg, new Type[]{ this, PredefinedTypes.TYPE_READONLY}, immutableAnydataType, TypeFlags.asMask(TypeFlags.NILABLE, TypeFlags.ANYDATA, TypeFlags.PURETYPE), true); - this.typeId = TYPE_ID_RW; - this.typeCheckCache = TYPE_CHECK_CACHE_RW; + this.semTypeFlyweight = FLYWEIGHT_RW; } else { - this.typeId = TYPE_ID_RO; - this.typeCheckCache = TYPE_CHECK_CACHE_RO; + this.semTypeFlyweight = FLYWEIGHT_RO; } this.mergeUnionType((BUnionType) PredefinedTypes.TYPE_ANYDATA); } @@ -78,11 +84,9 @@ public BAnydataType(BUnionType unionType, String typeName, boolean readonly) { immutableAnydataType, TypeFlags.asMask(TypeFlags.NILABLE, TypeFlags.ANYDATA, TypeFlags.PURETYPE), true); - this.typeId = TYPE_ID_RW; - this.typeCheckCache = TYPE_CHECK_CACHE_RW; + this.semTypeFlyweight = FLYWEIGHT_RW; } else { - this.typeId = TYPE_ID_RO; - this.typeCheckCache = TYPE_CHECK_CACHE_RO; + this.semTypeFlyweight = FLYWEIGHT_RO; } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java index e053bd5e21d8..47ac12dd8578 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java @@ -20,6 +20,7 @@ import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; @@ -38,6 +39,8 @@ import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.ReadOnlyUtils; +import java.util.IdentityHashMap; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -63,6 +66,8 @@ public class BArrayType extends BType implements ArrayType, TypeWithShape { private static final TypeCheckFlyweightStore FLYWEIGHT_STORE = new TypeCheckFlyweightStore<>(); private static final SemType[] EMPTY_SEMTYPE_ARR = new SemType[0]; + private static final Map, SemTypeFlyweight> CACHED_FLYWEIGHTS = + new IdentityHashMap<>(); private Type elementType; private int dimensions = 1; private int size = -1; @@ -73,8 +78,8 @@ public class BArrayType extends BType implements ArrayType, TypeWithShape { private IntersectionType immutableType; private IntersectionType intersectionType = null; private int typeFlags; - private DefinitionContainer defn = new DefinitionContainer<>(); - private DefinitionContainer acceptedTypeDefn = new DefinitionContainer<>(); + private final DefinitionContainer defn = new DefinitionContainer<>(); + private final DefinitionContainer acceptedTypeDefn = new DefinitionContainer<>(); public BArrayType(Type elementType) { this(elementType, false); } @@ -117,8 +122,14 @@ public void setElementType(Type elementType, int dimensions, boolean elementRO) if (size == -1) { TypeCheckCacheFlyweight flyweight = isReadOnly() ? FLYWEIGHT_STORE.getRO(elementType) : FLYWEIGHT_STORE.getRW(elementType); - this.typeId = flyweight.typeId(); - this.typeCheckCache = flyweight.typeCheckCache(); + SemTypeFlyweight cached = CACHED_FLYWEIGHTS.get(flyweight); + if (cached != null) { + this.semTypeFlyweight = cached; + } else { + this.semTypeFlyweight.setTypeId(flyweight.typeId()); + this.semTypeFlyweight.setTypeCheckCache(flyweight.typeCheckCache()); + CACHED_FLYWEIGHTS.put(flyweight, this.semTypeFlyweight); + } } else { initializeCache(); } @@ -258,7 +269,7 @@ public SemType createSemType(Context cx) { ListDefinition ld = result.definition(); CellAtomicType.CellMutability mut = isReadOnly() ? CellAtomicType.CellMutability.CELL_MUT_NONE : CellAtomicType.CellMutability.CELL_MUT_LIMITED; - return getSemTypePart(env, ld, size, tryInto(cx, getElementType()), mut); + return getSemTypePart(env, ld, size, SemType.tryInto(cx, getElementType()), mut); } private SemType getSemTypePart(Env env, ListDefinition defn, int size, SemType elementType, 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 00b358f4d6f3..f372135fb410 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 @@ -140,7 +140,7 @@ public SemType createSemType(Context cx) { if (detailType == null || isTopType()) { err = Builder.getErrorType(); } else { - err = ErrorUtils.errorDetail(tryInto(cx, getDetailType())); + err = ErrorUtils.errorDetail(SemType.tryInto(cx, getDetailType())); } initializeDistinctIdSupplierIfNeeded(cx); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java index f59a1f46411a..a04f64d7c9c0 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java @@ -20,6 +20,7 @@ import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.FiniteType; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; import io.ballerina.runtime.api.types.semtype.Builder; @@ -33,6 +34,7 @@ import io.ballerina.runtime.internal.types.semtype.CacheFactory; import io.ballerina.runtime.internal.values.RefValue; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; @@ -49,6 +51,8 @@ */ public class BFiniteType extends BType implements FiniteType { + private final static Map CACHED_FLYWEIGHTS = + new IdentityHashMap<>(); public Set valueSpace; private int typeFlags; private String originalName; @@ -68,9 +72,15 @@ public BFiniteType(String typeName, String originalName, Set values, int this.typeFlags = typeFlags; this.originalName = originalName; if (this.originalName != null && !originalName.isEmpty()) { - var flyweight = TypeCheckCacheData.get(originalName); - this.typeId = flyweight.typeId; - this.typeCheckCache = flyweight.typeCheckCache; + TypeCheckCacheData.TypeCheckFlyweight flyweight = TypeCheckCacheData.get(originalName); + SemTypeFlyweight cached = CACHED_FLYWEIGHTS.get(flyweight); + if (cached != null) { + semTypeFlyweight = cached; + } else { + semTypeFlyweight.setTypeCheckCache(flyweight.typeCheckCache); + semTypeFlyweight.setTypeId(flyweight.typeId); + CACHED_FLYWEIGHTS.put(flyweight, semTypeFlyweight); + } } else { initializeCache(); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java index 53986e54e27d..2bd18a55ef8f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java @@ -98,8 +98,8 @@ public BFunctionType(Module pkg, Parameter[] parameters, Type restType, Type ret } protected void resetTypeCheckCaches() { - typeCheckCache = TypeCheckCacheFactory.create(); - typeId = TypeIdSupplier.getAnonId(); + semTypeFlyweight.setTypeCheckCache(TypeCheckCacheFactory.create()); + semTypeFlyweight.setTypeId(TypeIdSupplier.getAnonId()); } public Type[] getParameterTypes() { @@ -289,7 +289,7 @@ FunctionQualifiers getQualifiers() { } private SemType getSemType(Context cx, Type type) { - return tryInto(cx, type); + return SemType.tryInto(cx, type); } protected boolean isFunctionTop() { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java index 3ce3c849493b..7fdf4b510175 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java @@ -112,7 +112,7 @@ public SemType createSemType(Context cx) { if (constraint == null) { return Builder.getFutureType(); } - return FutureUtils.futureContaining(cx.env, tryInto(cx, constraint)); + return FutureUtils.futureContaining(cx.env, SemType.tryInto(cx, constraint)); } @Override diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java index 743df37390bb..0556e83b9b09 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java @@ -21,13 +21,15 @@ import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.JsonType; +import io.ballerina.runtime.api.types.MutableSemTypeFlyweight; import io.ballerina.runtime.api.types.PredefinedTypes; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; +import io.ballerina.runtime.api.types.semtype.BasicTypeBitSetImpl; import io.ballerina.runtime.api.types.semtype.Builder; import io.ballerina.runtime.api.types.semtype.SemType; -import io.ballerina.runtime.api.types.semtype.TypeCheckCache; import io.ballerina.runtime.api.types.semtype.TypeCheckCacheFactory; import io.ballerina.runtime.internal.values.MapValueImpl; @@ -49,13 +51,18 @@ private static BasicTypeBitSet createBasicType() { Builder.getDecimalType(), Builder.getStringType(), Builder.getListType(), Builder.getMappingType()).map( SemType::all).reduce(0, (accum, bits) -> accum | bits); - return new BasicTypeBitSet(bitset); + return new BasicTypeBitSetImpl(bitset); } - private static final int TYPE_ID_RW = TypeIdSupplier.getReservedId(); - private static final int TYPE_ID_RO = TypeIdSupplier.getReservedId(); - private static final TypeCheckCache TYPE_CHECK_CACHE_RW = TypeCheckCacheFactory.create(); - private static final TypeCheckCache TYPE_CHECK_CACHE_RO = TypeCheckCacheFactory.create(); + private static final SemTypeFlyweight FLYWEIGHT_RW = initFlyWeight(); + private static final SemTypeFlyweight FLYWEIGHT_RO = initFlyWeight(); + + private static SemTypeFlyweight initFlyWeight() { + SemTypeFlyweight flyweight = new MutableSemTypeFlyweight(); + flyweight.setTypeId(TypeIdSupplier.getReservedId()); + flyweight.setTypeCheckCache(TypeCheckCacheFactory.create()); + return flyweight; + } /** * Create a {@code BJSONType} which represents the JSON type. * @@ -71,11 +78,9 @@ public BJsonType(String typeName, Module pkg, boolean readonly) { immutableJsonType, TypeFlags.asMask(TypeFlags.NILABLE, TypeFlags.ANYDATA, TypeFlags.PURETYPE), true); - typeId = TYPE_ID_RW; - typeCheckCache = TYPE_CHECK_CACHE_RW; + this.semTypeFlyweight = FLYWEIGHT_RW; } else { - typeId = TYPE_ID_RO; - typeCheckCache = TYPE_CHECK_CACHE_RO; + this.semTypeFlyweight = FLYWEIGHT_RO; } } @@ -86,8 +91,7 @@ public BJsonType() { immutableJsonType, TypeFlags.asMask(TypeFlags.NILABLE, TypeFlags.ANYDATA, TypeFlags.PURETYPE), true); - typeId = TYPE_ID_RW; - typeCheckCache = TYPE_CHECK_CACHE_RW; + this.semTypeFlyweight = FLYWEIGHT_RW; } public BJsonType(BUnionType unionType, String typeName, boolean readonly) { @@ -98,11 +102,9 @@ public BJsonType(BUnionType unionType, String typeName, boolean readonly) { immutableJsonType, TypeFlags.asMask(TypeFlags.NILABLE, TypeFlags.ANYDATA, TypeFlags.PURETYPE), true); - typeId = TYPE_ID_RW; - typeCheckCache = TYPE_CHECK_CACHE_RW; + this.semTypeFlyweight = FLYWEIGHT_RW; } else { - typeId = TYPE_ID_RO; - typeCheckCache = TYPE_CHECK_CACHE_RO; + this.semTypeFlyweight = FLYWEIGHT_RO; } } @@ -128,7 +130,7 @@ public boolean isNilable() { @Override public int typeId() { - return typeId; + return semTypeFlyweight.typeId(); } @Override 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 3a51706c6fa0..94656d3fed3f 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 @@ -22,6 +22,7 @@ import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; import io.ballerina.runtime.api.types.PredefinedTypes; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; @@ -38,6 +39,7 @@ import io.ballerina.runtime.internal.values.MapValueImpl; import io.ballerina.runtime.internal.values.ReadOnlyUtils; +import java.util.IdentityHashMap; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -59,6 +61,8 @@ public class BMapType extends BType implements MapType, TypeWithShape, Cloneable { private static final BasicTypeBitSet BASIC_TYPE = Builder.getMappingType(); + private static final Map, SemTypeFlyweight> CACHED_FLYWEIGHTS = + new IdentityHashMap<>(); private static final TypeCheckFlyweightStore FLYWEIGHT_STORE = new TypeCheckFlyweightStore<>(); public static final MappingDefinition.Field[] EMPTY_FIELD_ARR = new MappingDefinition.Field[0]; private final Type constraint; @@ -93,8 +97,14 @@ public BMapType(String typeName, Type constraint, Module pkg, boolean readonly) this.readonly = readonly; TypeCheckCacheFlyweight flyweight = readonly ? FLYWEIGHT_STORE.getRO(constraint) : FLYWEIGHT_STORE.getRW(constraint); - this.typeId = flyweight.typeId(); - this.typeCheckCache = flyweight.typeCheckCache(); + SemTypeFlyweight cached = CACHED_FLYWEIGHTS.get(flyweight); + if (cached != null) { + this.semTypeFlyweight = cached; + } else { + this.semTypeFlyweight.setTypeId(flyweight.typeId()); + this.semTypeFlyweight.setTypeCheckCache(flyweight.typeCheckCache()); + CACHED_FLYWEIGHTS.put(flyweight, this.semTypeFlyweight); + } this.defn = flyweight.defn(); this.acceptedTypeDefn = flyweight.acceptedTypeDefn(); } @@ -213,7 +223,7 @@ public SemType createSemType(Context cx) { MappingDefinition md = result.definition(); CellAtomicType.CellMutability mut = isReadOnly() ? CELL_MUT_NONE : CellAtomicType.CellMutability.CELL_MUT_LIMITED; - return createSemTypeInner(env, md, tryInto(cx, getConstrainedType()), mut); + return createSemTypeInner(env, md, SemType.tryInto(cx, getConstrainedType()), mut); } @Override diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java index 9c3ff1028051..659ef5fbea40 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java @@ -67,6 +67,7 @@ import java.util.function.BiFunction; import static io.ballerina.runtime.api.types.TypeTags.SERVICE_TAG; +import static io.ballerina.runtime.api.types.semtype.SemType.tryInto; /** * {@code BObjectType} represents a user defined object type in Ballerina. @@ -462,7 +463,7 @@ private SemType valueShape(Context cx, ShapeSupplier shapeSupplier, AbstractObje private static SemType fieldShape(Context cx, ShapeSupplier shapeSupplier, Field field, AbstractObjectValue objectValue, boolean isImmutable) { if (!isImmutable) { - return SemType.tryInto(cx, field.getFieldType()); + return tryInto(cx, field.getFieldType()); } BString fieldName = StringUtils.fromString(field.getFieldName()); Optional shape = shapeSupplier.get(cx, objectValue.get(fieldName)); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java index b8a84e5cefd8..d7cef14a1a01 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java @@ -21,6 +21,7 @@ import io.ballerina.runtime.api.types.ReadonlyType; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; +import io.ballerina.runtime.api.types.semtype.BasicTypeBitSetImpl; import io.ballerina.runtime.api.types.semtype.Builder; import io.ballerina.runtime.api.types.semtype.ConcurrentLazySupplier; import io.ballerina.runtime.api.types.semtype.SemType; @@ -36,7 +37,7 @@ public final class BReadonlyType extends BSemTypeWrapper 0) { semType = TableUtils.tableContainingKeySpecifier(cx, constraintType, fieldNames); } else if (keyType != null) { - semType = TableUtils.tableContainingKeyConstraint(cx, constraintType, tryInto(cx, keyType)); + semType = TableUtils.tableContainingKeyConstraint(cx, constraintType, SemType.tryInto(cx, keyType)); } else { semType = TableUtils.tableContaining(cx.env, constraintType); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java index 37647d4b01f4..a431b99f9a80 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java @@ -20,19 +20,22 @@ import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.MutableSemTypeFlyweight; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeIdentifier; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.semtype.CacheableTypeDescriptor; import io.ballerina.runtime.api.types.semtype.Context; import io.ballerina.runtime.api.types.semtype.SemType; -import io.ballerina.runtime.api.types.semtype.TypeCheckCache; import io.ballerina.runtime.api.types.semtype.TypeCheckCacheFactory; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.semtype.MutableSemType; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -47,18 +50,16 @@ * @since 0.995.0 */ public abstract non-sealed class BType extends TypeCheckableType - implements Type, MutableSemType, Cloneable, CacheableTypeDescriptor, MayBeDependentType { + implements Type, MutableSemType, Cloneable, MayBeDependentType { protected String typeName; protected Module pkg; protected Class valueClass; private int hashCode; - private volatile SemType cachedSemType = null; - protected TypeCheckCache typeCheckCache; - protected int typeId; + private final static Map CACHED_FLYWEIGHTS = new HashMap<>(); protected BType(String typeName, Module pkg, Class valueClass, boolean initializeCache) { - super(); + super(new MutableSemTypeFlyweight()); this.typeName = typeName; this.pkg = pkg; this.valueClass = valueClass; @@ -73,11 +74,17 @@ protected BType(String typeName, Module pkg, Class valueClass, protected void initializeCache() { if (isNamedType()) { TypeIdentifier identifier = new TypeIdentifier(this.pkg, this.typeName); - typeCheckCache = TypeCheckCacheFactory.get(identifier); - typeId = TypeIdSupplier.namedId(identifier); + SemTypeFlyweight cached = CACHED_FLYWEIGHTS.get(identifier); + if (cached != null) { + semTypeFlyweight = cached; + } else { + semTypeFlyweight.setTypeCheckCache(TypeCheckCacheFactory.get(identifier)); + semTypeFlyweight.setTypeId(TypeIdSupplier.namedId(identifier)); + CACHED_FLYWEIGHTS.put(identifier, semTypeFlyweight); + } } else { - typeCheckCache = TypeCheckCacheFactory.create(); - typeId = TypeIdSupplier.getAnonId(); + semTypeFlyweight.setTypeCheckCache(TypeCheckCacheFactory.create()); + semTypeFlyweight.setTypeId(TypeIdSupplier.getAnonId()); } } @@ -246,28 +253,26 @@ public SemType createSemType(Context cx) { @Override public void updateInnerSemTypeIfNeeded(Context cx) { - if (cachedSemType == null) { - cachedSemType = createSemType(cx); - setAll(cachedSemType.all()); - setSome(cachedSemType.some(), cachedSemType.subTypeData()); + if (semTypeFlyweight.semType() == null) { + SemType ty = createSemType(cx); + semTypeFlyweight.setSemType(ty); } } protected SemType getSemType(Context cx) { updateInnerSemTypeIfNeeded(cx); - return cachedSemType; + return semTypeFlyweight.semType(); } @Override public void resetSemType() { - cachedSemType = null; + } @Override public BType clone() { try { BType clone = (BType) super.clone(); - clone.cachedSemType = null; clone.setCachedImpliedType(null); clone.setCachedReferredType(null); return clone; @@ -283,12 +288,12 @@ protected boolean isNamedType() { @Override public final Boolean cachedTypeCheckResult(Context cx, CacheableTypeDescriptor other) { - return typeCheckCache.cachedTypeCheckResult(other); + return semTypeFlyweight.typeCheckCache().cachedTypeCheckResult(other); } @Override public final void cacheTypeCheckResult(CacheableTypeDescriptor other, boolean result) { - typeCheckCache.cacheTypeCheckResult(other, result); + semTypeFlyweight.typeCheckCache().cacheTypeCheckResult(other, result); } @Override @@ -310,6 +315,6 @@ protected boolean isDependentlyTypedInner(Set visited) { @Override public int typeId() { - return this.typeId; + return semTypeFlyweight.typeId(); } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java index c930025f10d9..af32e829992e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java @@ -149,7 +149,7 @@ public void setIntersectionType(IntersectionType intersectionType) { @Override public SemType createSemType(Context cx) { Type referredType = getReferredType(); - return tryInto(cx, referredType); + return SemType.tryInto(cx, referredType); } @Override diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java index ff4f99cdd8ca..4bd480694dda 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java @@ -22,6 +22,7 @@ import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.PredefinedTypes; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.TypedescType; @@ -37,6 +38,8 @@ import io.ballerina.runtime.internal.values.TypedescValue; import io.ballerina.runtime.internal.values.TypedescValueImpl; +import java.util.IdentityHashMap; +import java.util.Map; import java.util.Set; /** @@ -46,6 +49,8 @@ */ public class BTypedescType extends BType implements TypedescType { + private static final Map + SEMTYPE_FLYWEIGHT_CACHE = new IdentityHashMap<>(); private static final BasicTypeBitSet BASIC_TYPE = Builder.getTypeDescType(); private final Type constraint; @@ -58,9 +63,15 @@ public BTypedescType(String typeName, Module pkg) { public BTypedescType(Type constraint) { super(TypeConstants.TYPEDESC_TNAME, null, TypedescValue.class, false); this.constraint = constraint; - var flyweight = TypeCheckFlyweightStore.get(constraint); - this.typeCheckCache = flyweight.typeCheckCache(); - this.typeId = flyweight.typeId(); + TypeCheckFlyweightStore.TypeCheckFlyweight flyweight = TypeCheckFlyweightStore.get(constraint); + SemTypeFlyweight cached = SEMTYPE_FLYWEIGHT_CACHE.get(flyweight); + if (cached != null) { + semTypeFlyweight = cached; + } else { + semTypeFlyweight.setTypeId(flyweight.typeId()); + semTypeFlyweight.setTypeCheckCache(flyweight.typeCheckCache()); + SEMTYPE_FLYWEIGHT_CACHE.put(flyweight, semTypeFlyweight); + } } @Override @@ -114,7 +125,7 @@ public SemType createSemType(Context cx) { if (constraint == null) { return Builder.getTypeDescType(); } - SemType constraint = tryInto(cx, getConstraint()); + SemType constraint = SemType.tryInto(cx, getConstraint()); return TypedescUtils.typedescContaining(cx.env, constraint); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java index edf98606a559..4f8587cfd1fb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java @@ -21,6 +21,7 @@ import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.ParameterizedType; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.XmlType; @@ -54,6 +55,8 @@ public class BXmlType extends BType implements XmlType, TypeWithShape { private static final BasicTypeBitSet BASIC_TYPE = Builder.getXmlType(); + private static final Map SEMTYPE_FLYWEIGHT_CACHE = + new IdentityHashMap<>(); private final int tag; public final Type constraint; @@ -109,9 +112,15 @@ public BXmlType(Type constraint, boolean readonly) { @Override protected void initializeCache() { - var init = initCachedValues(this); - typeCheckCache = init.typeCheckCache; - typeId = init.typeId; + TypeCheckFlyweightCache.TypeCheckFlyweight init = initCachedValues(this); + SemTypeFlyweight cached = SEMTYPE_FLYWEIGHT_CACHE.get(init); + if (cached != null) { + this.semTypeFlyweight = cached; + } else { + this.semTypeFlyweight.setTypeCheckCache(init.typeCheckCache); + this.semTypeFlyweight.setTypeId(init.typeId); + SEMTYPE_FLYWEIGHT_CACHE.put(init, this.semTypeFlyweight); + } } private static TypeCheckFlyweightCache.TypeCheckFlyweight initCachedValues(BXmlType xmlType) { @@ -218,9 +227,9 @@ public SemType createSemType(Context cx) { } else { SemType contraintSemtype; if (constraint instanceof ParameterizedType parameterizedType) { - contraintSemtype = tryInto(cx, parameterizedType.getParamValueType()); + contraintSemtype = SemType.tryInto(cx, parameterizedType.getParamValueType()); } else { - contraintSemtype = tryInto(cx, constraint); + contraintSemtype = SemType.tryInto(cx, constraint); } semType = XmlUtils.xmlSequence(contraintSemtype); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeCheckableType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeCheckableType.java index 399466588f11..245961420a4a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeCheckableType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/TypeCheckableType.java @@ -18,23 +18,23 @@ package io.ballerina.runtime.internal.types; +import io.ballerina.runtime.api.types.SemTypeFlyweight; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.semtype.BasicTypeBitSet; +import io.ballerina.runtime.api.types.semtype.CacheableTypeDescriptor; import io.ballerina.runtime.api.types.semtype.SemType; import io.ballerina.runtime.api.types.semtype.SubType; import io.ballerina.runtime.internal.types.semtype.ImmutableSemType; -public abstract sealed class TypeCheckableType extends SemType implements Type permits BType, ImmutableSemType { +public abstract sealed class TypeCheckableType implements Type, SemType, CacheableTypeDescriptor + permits BType, ImmutableSemType { private Type referredType; private Type impliedType; + public SemTypeFlyweight semTypeFlyweight; - public TypeCheckableType(int all, int some, SubType[] subTypeData) { - super(all, some, subTypeData); - } - - public TypeCheckableType() { - super(); + protected TypeCheckableType(SemTypeFlyweight semType) { + this.semTypeFlyweight = semType; } /** @@ -83,4 +83,33 @@ public final Type getCachedImpliedType() { public abstract BasicTypeBitSet getBasicType(); + @Override + public int all() { + return semTypeFlyweight.semType().all(); + } + + @Override + public int some() { + return semTypeFlyweight.semType().some(); + } + + @Override + public SubType[] subTypeData() { + return semTypeFlyweight.semType().subTypeData(); + } + + @Override + public SubType subTypeByCode(int code) { + return semTypeFlyweight.semType().subTypeByCode(code); + } + + @Override + public BasicTypeBitSet union(BasicTypeBitSet basicTypeBitSet) { + throw new UnsupportedOperationException("Not a basic type"); + } + + @Override + public BasicTypeBitSet intersection(BasicTypeBitSet basicTypeBitSet) { + throw new UnsupportedOperationException("Not a basic type"); + } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/BListSubType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/BListSubType.java index 7d326c8600f8..e14f6983e9f3 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/BListSubType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/BListSubType.java @@ -337,7 +337,8 @@ public static boolean fixedArrayAnyEmpty(Context cx, FixedLengthArray array) { return false; } - public static Pair listIntersectWith(Env env, FixedLengthArray members1, SemType rest1, + public static Pair listIntersectWith(Env env, FixedLengthArray members1, + SemType rest1, FixedLengthArray members2, SemType rest2) { if (listLengthsDisjoint(members1, rest1, members2, rest2)) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/ImmutableSemType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/ImmutableSemType.java index 7e3f7a11756b..895caa7eafd8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/ImmutableSemType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/ImmutableSemType.java @@ -18,11 +18,10 @@ package io.ballerina.runtime.internal.types.semtype; +import io.ballerina.runtime.api.types.ImmutableSemTypeFlyweight; import io.ballerina.runtime.api.types.semtype.CacheableTypeDescriptor; import io.ballerina.runtime.api.types.semtype.Context; import io.ballerina.runtime.api.types.semtype.SemType; -import io.ballerina.runtime.api.types.semtype.SubType; -import io.ballerina.runtime.api.types.semtype.TypeCheckCache; import io.ballerina.runtime.api.types.semtype.TypeCheckCacheFactory; import io.ballerina.runtime.internal.types.BSemTypeWrapper; import io.ballerina.runtime.internal.types.TypeCheckableType; @@ -41,22 +40,11 @@ public abstract sealed class ImmutableSemType extends TypeCheckableType implements CacheableTypeDescriptor permits BSemTypeWrapper { - private static final SubType[] EMPTY_SUBTYPE_DATA = new SubType[0]; - private Integer hashCode; - private final TypeCheckCache typeCheckCache; - private final int typeId; - - // TODO: get rid of this and directly pass in the semtype to parent - ImmutableSemType(int all, int some, SubType[] subTypeData) { - super(all, some, subTypeData); - this.typeCheckCache = TypeCheckCacheFactory.create(); - this.typeId = TypeIdCache.getTypeId(all, some); - } - protected ImmutableSemType(SemType semType) { - this(semType.all(), semType.some(), semType.subTypeData()); + super(new ImmutableSemTypeFlyweight(semType, TypeIdCache.getTypeId(semType.all(), semType.some()), + TypeCheckCacheFactory.create())); } @Override @@ -89,28 +77,17 @@ private int computeHashCode() { return Objects.hash(all(), some(), Arrays.hashCode(subTypeData())); } - @Override - protected void setAll(int all) { - throw new UnsupportedOperationException("Immutable semtypes cannot be modified"); - } - - @Override - protected void setSome(int some, SubType[] subTypeData) { - throw new UnsupportedOperationException("Immutable semtypes cannot be modified"); - } - @Override public Boolean cachedTypeCheckResult(Context cx, CacheableTypeDescriptor other) { - return typeCheckCache.cachedTypeCheckResult(other); + return semTypeFlyweight.typeCheckCache().cachedTypeCheckResult(other); } public void cacheTypeCheckResult(CacheableTypeDescriptor other, boolean result) { - - typeCheckCache.cacheTypeCheckResult(other, result); + semTypeFlyweight.typeCheckCache().cacheTypeCheckResult(other, result); } public int typeId() { - return typeId; + return semTypeFlyweight.typeId(); } private static class TypeIdCache { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/MappingDefinition.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/MappingDefinition.java index ae8f1235784f..90746efbf9a7 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/MappingDefinition.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/MappingDefinition.java @@ -71,7 +71,8 @@ private SemType createSemType(Env env, Atom atom) { return this.semType; } - public SemType defineMappingTypeWrapped(Env env, Field[] fields, SemType rest, CellAtomicType.CellMutability mut) { + public SemType defineMappingTypeWrapped(Env env, Field[] fields, SemType rest, + CellAtomicType.CellMutability mut) { assert rest != null; BCellField[] cellFields = new BCellField[fields.length]; for (int i = 0; i < fields.length; i++) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/TableUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/TableUtils.java index c360a1059dc7..c16d2104092e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/TableUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/semtype/TableUtils.java @@ -44,15 +44,18 @@ public final class TableUtils { private TableUtils() { } - public static SemType acceptedTypeContainingKeySpecifier(Context cx, SemType tableConstraint, String[] fieldNames) { + public static SemType acceptedTypeContainingKeySpecifier(Context cx, SemType tableConstraint, + String[] fieldNames) { return tableContainingKeySpecifierInner(fieldNames, cx, tableConstraint, CELL_MUT_UNLIMITED); } - public static SemType tableContainingKeySpecifier(Context cx, SemType tableConstraint, String[] fieldNames) { + public static SemType tableContainingKeySpecifier(Context cx, SemType tableConstraint, + String[] fieldNames) { return tableContainingKeySpecifierInner(fieldNames, cx, tableConstraint, CELL_MUT_LIMITED); } - private static SemType tableContainingKeySpecifierInner(String[] fieldNames, Context cx, SemType tableConstraint, + private static SemType tableContainingKeySpecifierInner(String[] fieldNames, Context cx, + SemType tableConstraint, CellAtomicType.CellMutability cellMutLimited) { SemType[] fieldNameSingletons = new SemType[fieldNames.length]; SemType[] fieldTypes = new SemType[fieldNames.length]; @@ -66,7 +69,8 @@ private static SemType tableContainingKeySpecifierInner(String[] fieldNames, Con new ListDefinition().defineListTypeWrapped(cx.env, fieldNameSingletons, fieldNameSingletons.length, Builder.getNeverType(), CELL_MUT_NONE); - SemType normalizedKc = fieldNames.length > 1 ? new ListDefinition().defineListTypeWrapped(cx.env, fieldTypes, + SemType normalizedKc = + fieldNames.length > 1 ? new ListDefinition().defineListTypeWrapped(cx.env, fieldTypes, fieldTypes.length, Builder.getNeverType(), CELL_MUT_NONE) : fieldTypes[0]; return tableContaining(cx.env, tableConstraint, normalizedKc, normalizedKs, cellMutLimited); @@ -77,11 +81,13 @@ public static SemType acceptedTypeContainingKeyConstraint(Context cx, SemType ta return tableContainingKeyConstraintInner(cx, tableConstraint, keyConstraint, CELL_MUT_UNLIMITED); } - public static SemType tableContainingKeyConstraint(Context cx, SemType tableConstraint, SemType keyConstraint) { + public static SemType tableContainingKeyConstraint(Context cx, SemType tableConstraint, + SemType keyConstraint) { return tableContainingKeyConstraintInner(cx, tableConstraint, keyConstraint, CELL_MUT_LIMITED); } - private static SemType tableContainingKeyConstraintInner(Context cx, SemType tableConstraint, SemType keyConstraint, + private static SemType tableContainingKeyConstraintInner(Context cx, SemType tableConstraint, + SemType keyConstraint, CellAtomicType.CellMutability mut) { Optional lat = Core.listAtomicType(cx, keyConstraint); SemType normalizedKc = lat.map(atom -> { @@ -103,15 +109,18 @@ public static SemType acceptedType(Env env, SemType tableConstraint) { return tableContaining(env, tableConstraint, CELL_MUT_UNLIMITED); } - private static SemType tableContaining(Env env, SemType tableConstraint, CellAtomicType.CellMutability mut) { + private static SemType tableContaining(Env env, SemType tableConstraint, + CellAtomicType.CellMutability mut) { return tableContaining(env, tableConstraint, Builder.getValType(), Builder.getValType(), mut); } - private static SemType tableContaining(Env env, SemType tableConstraint, SemType normalizedKc, SemType normalizedKs, + private static SemType tableContaining(Env env, SemType tableConstraint, SemType normalizedKc, + SemType normalizedKs, CellAtomicType.CellMutability mut) { tableConstraint = Core.intersect(tableConstraint, Builder.getMappingType()); ListDefinition typeParamArrDef = new ListDefinition(); - SemType typeParamArray = typeParamArrDef.defineListTypeWrapped(env, EMPTY_SEMTYPE_ARR, 0, tableConstraint, mut); + SemType + typeParamArray = typeParamArrDef.defineListTypeWrapped(env, EMPTY_SEMTYPE_ARR, 0, tableConstraint, mut); ListDefinition listDef = new ListDefinition(); SemType tupleType = diff --git a/bvm/ballerina-runtime/src/main/java/module-info.java b/bvm/ballerina-runtime/src/main/java/module-info.java index 0ac5d77cd3d7..a3b659cd7b33 100644 --- a/bvm/ballerina-runtime/src/main/java/module-info.java +++ b/bvm/ballerina-runtime/src/main/java/module-info.java @@ -1,5 +1,4 @@ module io.ballerina.runtime { - requires java.xml; requires org.apache.commons.text; requires axiom.api; requires java.logging; @@ -19,6 +18,7 @@ requires jdk.unsupported; requires jdk.management; requires com.github.benmanes.caffeine; + requires java.desktop; // API exports exports io.ballerina.runtime.api; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/semtype/CoreTests.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/semtype/CoreTests.java index 7caae912d152..a49124e290a9 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/semtype/CoreTests.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/semtype/CoreTests.java @@ -36,7 +36,8 @@ public void testCellTypes() { SemType intTy = Builder.getIntType(); SemType readonlyInt = Builder.getCellContaining(env, intTy, CellAtomicType.CellMutability.CELL_MUT_NONE); assert Core.isSubType(cx, readonlyInt, readonlyInt); - SemType mutableInt = Builder.getCellContaining(env, intTy, CellAtomicType.CellMutability.CELL_MUT_UNLIMITED); + SemType mutableInt = + Builder.getCellContaining(env, intTy, CellAtomicType.CellMutability.CELL_MUT_UNLIMITED); assert Core.isSubType(cx, mutableInt, mutableInt); assert Core.isSubType(cx, readonlyInt, mutableInt); assert !Core.isSubType(cx, mutableInt, readonlyInt); diff --git a/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeSemTypeResolver.java b/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeSemTypeResolver.java index 14644cc3e289..8d8565284569 100644 --- a/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeSemTypeResolver.java +++ b/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeSemTypeResolver.java @@ -116,7 +116,7 @@ public void resolveConstant(TypeTestContext cx, Map } private SemType resolveTypeDefnRec(TypeTestContext cx, Map mod, - BLangTypeDefinition defn, int depth) { + BLangTypeDefinition defn, int depth) { SemType memo = semTypeMemo.get(defn); if (memo != null) { return memo; @@ -138,8 +138,9 @@ private SemType resolveTypeDefnRec(TypeTestContext cx, Map cx, Map mod, BLangTypeDefinition defn, - int depth, TypeNode td) { + private SemType resolveTypeDesc(TypeTestContext cx, Map mod, + BLangTypeDefinition defn, + int depth, TypeNode td) { if (td == null) { return null; } @@ -214,8 +215,9 @@ private static SemType getDistinctErrorType(Env env, SemType innerType) { return Core.intersect(ErrorUtils.errorDistinct(env.distinctAtomCountGetAndIncrement()), innerType); } - private SemType createErrorType(TypeTestContext cx, Map mod, BLangTypeDefinition defn, - int depth, BLangErrorType td) { + private SemType createErrorType(TypeTestContext cx, Map mod, + BLangTypeDefinition defn, + int depth, BLangErrorType td) { if (td.detailType == null) { return Builder.getErrorType(); } else { @@ -234,7 +236,7 @@ private SemType resolveObjectTypeDesc(TypeTestContext cx, Map cx, Map mod, - BLangTypeDefinition defn, int depth, BLangObjectTypeNode td) { + BLangTypeDefinition defn, int depth, BLangObjectTypeNode td) { Env env = (Env) cx.getInnerEnv(); Definition attachedDefinition = attachedDefinitions.get(td); if (attachedDefinition != null) { @@ -304,8 +306,8 @@ private SemType resolveFunctionType(TypeTestContext cx, Map cx, Map mod, - Map paramScope, BLangTypeDefinition defn, int depth, - BLangFunction functionType) { + Map paramScope, BLangTypeDefinition defn, int depth, + BLangFunction functionType) { List params = new ArrayList<>(); if (functionType instanceof BLangResourceFunction resourceFunctionType) { params.add(Builder.getStringConst(resourceFunctionType.methodName.value)); @@ -400,10 +402,10 @@ private SemType resolveReturnType(TypeTestContext cx, } private SemType resolveDependentlyTypedReturnType(TypeTestContext cx, - Map mod, - Map mayBeDependentlyTypeNodes, - BLangTypeDefinition defn, int depth, - TypeNode returnTypeNode) { + Map mod, + Map mayBeDependentlyTypeNodes, + BLangTypeDefinition defn, int depth, + TypeNode returnTypeNode) { Map combined = new HashMap<>(mod); combined.putAll(mayBeDependentlyTypeNodes); return resolveTypeDesc(cx, combined, defn, depth + 1, returnTypeNode); @@ -541,7 +543,8 @@ private SemType resolveListInner(TypeTestContext cx, int size, SemType return resolveListInner(cx, ld, size, eType); } - private static SemType resolveListInner(TypeTestContext cx, ListDefinition ld, int size, SemType eType) { + private static SemType resolveListInner(TypeTestContext cx, ListDefinition ld, int size, + SemType eType) { Env env = (Env) cx.getInnerEnv(); if (size != -1) { SemType[] members = {eType}; diff --git a/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeTypeTestAPI.java b/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeTypeTestAPI.java index cd2d6e0671ae..33864281355d 100644 --- a/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeTypeTestAPI.java +++ b/tests/jballerina-semtype-port-test/src/test/java/io/ballerina/semtype/port/test/RuntimeTypeTestAPI.java @@ -24,8 +24,9 @@ import io.ballerina.runtime.api.types.semtype.ListProj; import io.ballerina.runtime.api.types.semtype.MappingProj; import io.ballerina.runtime.api.types.semtype.SemType; +import io.ballerina.runtime.api.types.semtype.SemTypeImpl; -public class RuntimeTypeTestAPI implements TypeTestAPI { +public class RuntimeTypeTestAPI implements TypeTestAPI { private static final RuntimeTypeTestAPI INSTANCE = new RuntimeTypeTestAPI(); @@ -37,7 +38,7 @@ public static RuntimeTypeTestAPI getInstance() { } @Override - public boolean isSubtype(TypeTestContext cx, SemType t1, SemType t2) { + public boolean isSubtype(TypeTestContext cx, SemTypeImpl t1, SemTypeImpl t2) { return Core.isSubType(from(cx), t1, t2); } @@ -46,37 +47,37 @@ private static Context from(TypeTestContext cx) { } @Override - public boolean isSubtypeSimple(SemType t1, SemType t2) { + public boolean isSubtypeSimple(SemTypeImpl t1, SemTypeImpl t2) { return Core.isSubtypeSimple(t1, t2); } @Override - public boolean isListType(SemType t) { + public boolean isListType(SemTypeImpl t) { return Core.isSubtypeSimple(t, Builder.getListType()); } @Override - public boolean isMapType(SemType t) { + public boolean isMapType(SemTypeImpl t) { return Core.isSubtypeSimple(t, Builder.getMappingType()); } @Override - public SemType intConst(long l) { + public SemTypeImpl intConst(long l) { return Builder.getIntConst(l); } @Override - public SemType mappingMemberTypeInnerVal(TypeTestContext context, SemType t, SemType key) { + public SemTypeImpl mappingMemberTypeInnerVal(TypeTestContext context, SemTypeImpl t, SemTypeImpl key) { return MappingProj.mappingMemberTypeInnerVal(from(context), t, key); } @Override - public SemType listProj(TypeTestContext context, SemType t, SemType key) { + public SemTypeImpl listProj(TypeTestContext context, SemTypeImpl t, SemTypeImpl key) { return ListProj.listProjInnerVal(from(context), t, key); } @Override - public SemType listMemberType(TypeTestContext context, SemType t, SemType key) { + public SemTypeImpl listMemberType(TypeTestContext context, SemTypeImpl t, SemTypeImpl key) { return Core.listMemberTypeInnerVal(from(context), t, key); } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java index f8f157e2f45d..e5b4fc16daf6 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/expressions/typecast/TypeCastExprTest.java @@ -458,8 +458,8 @@ public void testInCompatibleStructForceCasting() { BError error = (BError) returns; String errorMsg = ((BMap) error.getDetails()).get(StringUtils.fromString("message")).toString(); - Assert.assertEquals(errorMsg, "'B' value cannot be converted to 'ATypedesc': " + - "\n\t\tmissing required field 'y' of type 'int' in record 'A'"); + Assert.assertEquals(errorMsg, "'BTC' value cannot be converted to 'ATypedescTC': " + + "\n\t\tmissing required field 'y' of type 'int' in record 'ATC'"); } @Test(description = "Test any to int casting happens without errors, error struct should be null") diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/let/let-expression-test.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/let/let-expression-test.bal index 5bc89a50ef37..787e73da8355 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/let/let-expression-test.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/let/let-expression-test.bal @@ -204,25 +204,25 @@ function testLetExpressionTupleBindingRef() { } function testLetExpressionRecordBindingSimple() { - int b = let Person { name: firstName, age: personAge, ...otherDetails } = getPerson(), int x = 1 in personAge + x; + int b = let PersonLET {name: firstName, age: personAge, ...otherDetails} = getPerson(), int x = 1 in personAge + x; assertTrue(b == 25, "b == 25"); } function testLetExpressionRecordBindingComplexVar() { - string city = let var { name: countryName, capital: { name: capitalName } } = getCountry(), string comma = ", " + string city = let var {name: countryName, capital: {name: capitalName}} = getCountry(), string comma = ", " in capitalName + comma + countryName; assertTrue(city == "Colombo, Sri Lanka", "city == \"Colombo, Sri Lanka\""); } function testLetExpressionErrorBindingSimple() { - int k = let SampleError error(reason, info = info, fatal = fatal) = getSampleError(), int x = 1 - in reason.length() + x; - assertTrue(k == 13, "k == 13"); + int k = let SampleErrorLET error(reason, info = info, fatal = fatal) = getSampleError(), int x = 1 + in reason.length() + x; + assertTrue(k == 13, "k == 13"); } function testLetExpressionErrorBindingVar() { - boolean k = checkpanic let var error(reasonTwo, ...params) = getSampleError() in params["fatal"]; - assertTrue(k, "k == true"); + boolean k = checkpanic let var error(reasonTwo, ...params) = getSampleError() in params["fatal"]; + assertTrue(k, "k == true"); } function testLetExpressionRecordConstrainedErrorBinding() { @@ -249,9 +249,8 @@ function testLetExpressionRecordConstrainedErrorBinding() { // assertTrue(s.year == 15, "s.year == 15"); //} - function useLetInReturn() returns int { - return let int x = 4, int z = 5 in z+x; + return let int x = 4, int z = 5 in z + x; } function func(int k) returns int { @@ -262,58 +261,62 @@ function func2(string y) returns int { return y.length(); } -type Person record { +type PersonLET record { string name; int age; string country; }; -type Country record { +type CountryLET record { string name; - Capital capital; + CapitalLET capital; }; -type Capital record {| +type CapitalLET record {| string name; |}; -function getPerson() returns Person { - Person person = { name: "Irshad", age: 24, country: "Sri Lanka", - "occupation": "Software Engineer" }; +function getPerson() returns PersonLET { + PersonLET person = { + name: "Irshad", + age: 24, + country: "Sri Lanka", + "occupation": "Software Engineer" + }; return person; } -function getCountry() returns Country { - Capital capital = { name: "Colombo" }; - Country country = { name: "Sri Lanka", capital: capital }; +function getCountry() returns CountryLET { + CapitalLET capital = {name: "Colombo"}; + CountryLET country = {name: "Sri Lanka", capital: capital}; return country; } -type SampleErrorData record { +type SampleErrorDataLET record { string message?; error cause?; string info; boolean fatal; }; -type SampleError error; +type SampleErrorLET error; -function getSampleError() returns SampleError { - SampleError e = error SampleError("Sample Error", info = "Detail Msg", fatal = true); +function getSampleError() returns SampleErrorLET { + SampleErrorLET e = error SampleErrorLET("Sample Error", info = "Detail Msg", fatal = true); return e; } -type Foo record {| +type FooLET record {| string message?; error cause?; string detailMsg; boolean isFatal; |}; -type FooError error; +type FooErrorLET error; -function getRecordConstrainedError() returns FooError { - FooError e = error FooError("Some Error", detailMsg = "Failed Message", isFatal = true); +function getRecordConstrainedError() returns FooErrorLET { + FooErrorLET e = error FooErrorLET("Some Error", detailMsg = "Failed Message", isFatal = true); return e; } @@ -322,24 +325,24 @@ public function testAnonymousRecordWithLetExpression() { int i; int j?; } rec = let int v = 1 in {i: v}; - + assert(1, rec.i); - + rec.j = 5; assert(5, rec?.j); } -type Rec record {| +type RecLET record {| int i; int j = 100; |}; - + public function testRecordWithLetExpression() { - Rec rec1 = let int v = 160 in {i: v}; + RecLET rec1 = let int v = 160 in {i: v}; assert(160, rec1.i); assert(100, rec1.j); - - Rec rec2 = let int v = 161 in {i: v, j: v}; + + RecLET rec2 = let int v = 161 in {i: v, j: v}; assert(161, rec2.i); assert(161, rec2.j); } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/literals/numeric_literal_assignment.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/literals/numeric_literal_assignment.bal index e5a1b254463a..03b9ed5477c4 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/literals/numeric_literal_assignment.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/literals/numeric_literal_assignment.bal @@ -63,16 +63,19 @@ const byte B2 = 13; const decimal D1 = 12.0; const decimal D2 = 13.0; -type Foo 12|13; -type Bar 12.0|13.0; -type Baz B1|B2; -type Qux D1|D2; +type FooNLA 12|13; + +type BarNLA 12.0|13.0; + +type BazNLA B1|B2; + +type QuxNLA D1|D2; function testIntLiteralAsIntInUnion() returns boolean { byte|float|int|decimal x = 12; boolean result = x is int && i == x; - int|Bar|string y = 12; + int|BarNLA|string y = 12; return result && y is int && i == y; } @@ -80,14 +83,14 @@ function testIntLiteralAsByteInUnion() returns boolean { float|byte|decimal x = 12; boolean result = x is byte && b == x; - string|byte|Bar y = 12; + string|byte|BarNLA y = 12; return result && y is byte && b == y; } -type TempOne 120|130; +type TempOneNLA 120|130; function testIntLiteralAsByteInUnion_2() returns boolean { - TempOne|byte|Bar y = 12; + TempOneNLA|byte|BarNLA y = 12; return y is byte && b == y; } @@ -95,12 +98,12 @@ function testIntLiteralAsFloatInUnion() returns boolean { float|decimal x = 12; boolean result = x is float && f == x; - Qux|float y = 12; + QuxNLA|float y = 12; return result && y is float && f == y; } function testIntLiteralAsFloatInUnion_2() returns boolean { - Baz|float y = 12; + BazNLA|float y = 12; return y is byte && 12 == b; } @@ -113,7 +116,7 @@ function testFloatLiteralAsFloatInUnion() returns boolean { float|decimal x = 12.0; boolean result = x is float && f == x; - boolean|float|Qux y = 12.0; + boolean|float|QuxNLA y = 12.0; return result && y is float && f == y; } @@ -129,56 +132,56 @@ function testFloatLiteralAsDecimalInUnion_2() returns boolean { } function testIntLiteralAsIntViaFiniteType() returns boolean { - Foo x = 12; + FooNLA x = 12; anydata y = x; boolean result = y is int && i == y; - float|Foo|Bar z = 12; + float|FooNLA|BarNLA z = 12; return result && z is int && i == z; } function testIntLiteralAsByteViaFiniteType() returns boolean { - Baz x = 12; + BazNLA x = 12; anydata y = x; boolean result = y is byte && b == y; - decimal|Baz|Bar z = 12; + decimal|BazNLA|BarNLA z = 12; return result && z is byte && b == z; } function testIntLiteralAsFloatViaFiniteType() returns boolean { - Bar x = 12; + BarNLA x = 12; anydata y = x; boolean result = y is float && f == y; - decimal|Bar|Qux z = 12; + decimal|BarNLA|QuxNLA z = 12; return result && z is float && f == z; } function testIntLiteralAsDecimalViaFiniteType() returns boolean { - Qux x = 12; + QuxNLA x = 12; anydata y = x; boolean result = y is decimal && d == y; - string|Qux z = 12; + string|QuxNLA z = 12; return result && z is decimal && d == z; } function testFloatLiteralAsFloatViaFiniteType() returns boolean { - Bar x = 12.0; + BarNLA x = 12.0; anydata y = x; boolean result = y is float && f == y; - decimal|Bar|Qux z = 12.0; + decimal|BarNLA|QuxNLA z = 12.0; return result && z is float && f == z; } function testFloatLiteralAsDecimalViaFiniteType() returns boolean { - Qux x = 12.0; + QuxNLA x = 12.0; anydata y = x; boolean result = y is decimal && d == y; - Qux|xml z = 12.0; + QuxNLA|xml z = 12.0; return result && z is decimal && d == z; } @@ -193,7 +196,7 @@ function testIntLiteralAsIntWithBuiltinUnion() returns boolean { return result && z is int && z == i; } -type TempTwo 123.0|124.0; +type TempTwoNLA 123.0|124.0; function testFloatLiteralAsFloatWithBuiltinUnion() returns boolean { anydata|decimal x = 12.0; @@ -202,6 +205,6 @@ function testFloatLiteralAsFloatWithBuiltinUnion() returns boolean { decimal|json y = 12.0; result = result && y is float && y == f; - TempTwo|any|decimal z = 12.0; + TempTwoNLA|any|decimal z = 12.0; return result && z is float && z == f; } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures.bal index ad6e5ff7cda0..39964221594e 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures.bal @@ -327,19 +327,19 @@ public function testAttachedMethodClosuresMapFromFunctionBlock() { assertValueEquality(getValue, 13); } -type Sum2 function (int x, int y) returns int; +type Sum2OC function (int x, int y) returns int; -final Sum2 sumF = function (int x, int y) returns int { +final Sum2OC sumF = function(int x, int y) returns int { return x + y; }; function testFunctionPointerAsFieldHelper(int y2) { final int i = 10; object { - function summer(int y2) returns int ; + function summer(int y2) returns int; } obj = object { int x; - private Sum2 func = sumF; + private Sum2OC func = sumF; function init() { self.x = y2; } @@ -374,14 +374,14 @@ final string A = "A"; const B = "B"; function checkClosuresWithObjectConstrExprAsFunctionDefaultParam(object { - string x; - function foo(string c) returns string; - } obj = object { - string x = A; - function foo(string c) returns string { - return A + B + self.x + c; - } - }) returns string { + string x; + function foo(string c) returns string; + } obj = object { + string x = A; + function foo(string c) returns string { + return A + B + self.x + c; + } + }) returns string { return A + B + obj.x + obj.foo("C"); } @@ -577,19 +577,19 @@ function checkClosuresWithServiceObjectConstrExpr(int b1) returns int { return 0; } -type Foo object { +type FooOC object { int i; function foo(int b2) returns int; }; -type Bar object { +type BarOC object { function bar(int b3) returns object {}; }; function checkClosuresWithObjectConstrExprsInObjectConstrExpr(int b1) returns int { final int a1 = 10; - var obj1 = object Foo { + var obj1 = object FooOC { int i; function init() { @@ -597,7 +597,7 @@ function checkClosuresWithObjectConstrExprsInObjectConstrExpr(int b1) returns in } function foo(int b2) returns int { - Bar obj2 = object { + BarOC obj2 = object { function bar(int b3) returns object { int i; function foo(int b4) returns int; @@ -610,7 +610,7 @@ function checkClosuresWithObjectConstrExprsInObjectConstrExpr(int b1) returns in }; } }; - Foo obj3 = obj2.bar(10); + FooOC obj3 = obj2.bar(10); return a1 + self.i + b1 + obj3.foo(50); } }; @@ -622,7 +622,7 @@ function checkClosuresWithObjectConstrExprAsArrayMember(int b1, string str) retu final int a1 = 10; var obj1 = object {string j = str; boolean k = false;}; - Foo[] arr = [ + FooOC[] arr = [ object { int i; @@ -631,7 +631,7 @@ function checkClosuresWithObjectConstrExprAsArrayMember(int b1, string str) retu } function foo(int b2) returns int { - Bar obj2 = object { + BarOC obj2 = object { function bar(int b3) returns object {} { return object {string j = str; boolean k = true;}; } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures_annotations.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures_annotations.bal index 087977b09d08..c2c47f086003 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures_annotations.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/object/object_closures_annotations.bal @@ -14,13 +14,14 @@ // specific language governing permissions and limitations // under the License. -public type HSC record {| +public type HSCOCA record {| string hostRecField = "default_host_name"; boolean boolRecField = true; |}; -public annotation HSC HSCfa on field; -public annotation HSC HSCsa on service; +public annotation HSCOCA HSCfa on field; + +public annotation HSCOCA HSCsa on service; function createService(string hosty, decimal maxAgeMy, boolean allowCredentials) returns service object { string xField; @@ -28,7 +29,7 @@ function createService(string hosty, decimal maxAgeMy, boolean allowCredentials) var httpService = @HSCsa { - hostRecField : hosty + hostRecField: hosty } isolated service object { @@ -46,28 +47,28 @@ public function testAnnotations() { assertValueEquality("hostKRv", obj.xField); typedesc t = typeof obj; - HSC annotationVal = t.@HSCsa; + HSCOCA annotationVal = t.@HSCsa; assertValueEquality("hostKRv", annotationVal.hostRecField); obj = createService("hostKRv boom", 200, true); typedesc t2 = typeof obj; - HSC annotationVal2 = t2.@HSCsa; + HSCOCA annotationVal2 = t2.@HSCsa; assertValueEquality("hostKRv boom", annotationVal2.hostRecField); } -public type ObjectData record {| +public type ObjectDataOCA record {| string descriptor = ""; |}; -public annotation ObjectData OBJAnnots on class; +public annotation ObjectDataOCA OBJAnnots on class; function testObjectConstructorAnnotationAttachment() { final string constructed = "ConstructedObject"; var obj = @OBJAnnots { descriptor: constructed - } + } object { int n = 0; string state = constructed; @@ -76,17 +77,19 @@ function testObjectConstructorAnnotationAttachment() { } }; typedesc t = typeof obj; - ObjectData annotationVal = t.@OBJAnnots; + ObjectDataOCA annotationVal = t.@OBJAnnots; assertValueEquality("ConstructedObject", annotationVal.descriptor); assertValueEquality("ConstructedObject", obj.state); } -type Record record {| +type RecordOCA record {| int[] x; |}; -annotation Record A on service; +annotation RecordOCA A on service; + annotation B on service; + annotation C on service; function fn(int[] arr) returns object {} { @@ -106,9 +109,9 @@ function testAnnotsOfServiceObjectConstructorInReturnStmt() { object {} ob = fn(arr); typedesc td = typeof ob; - Record? a = td.@A; + RecordOCA? a = td.@A; assertTrue(a !is ()); - int[] annotArr = ( a).x; + int[] annotArr = (a).x; assertTrue(annotArr == arr); assertValueEquality(annotArr, [1, 2, 3]); arr.push(4); @@ -126,7 +129,7 @@ const number = 10; int intVal = 60; -type AnnotRecord record {| +type AnnotRecordOCA record {| int x; |}; @@ -146,24 +149,24 @@ function checkClosuresWithObjectConstrExprWithAnnots(int a1) returns int { } }; - AnnotRecord annot = (typeof obj1).@Config; + AnnotRecordOCA annot = (typeof obj1).@Config; return obj1.foo(20) + obj1.x + annot.x; } -annotation AnnotRecord Config2 on class; +annotation AnnotRecordOCA Config2 on class; function checkClosuresWithObjectConstrExprWithAnnotsAsFunctionDefaultParam(int b, object { - int y; - function foo(int c) returns int; - } obj = @Config2 { - x: intVal - } object { - int y = number; - function foo(int c) returns int { - return c + number; - } - }) returns int { + int y; + function foo(int c) returns int; + } obj = @Config2 { + x: intVal + } object { + int y = number; + function foo(int c) returns int { + return c + number; + } + }) returns int { return number + b + obj.y + obj.foo(20); } @@ -180,7 +183,7 @@ function checkClosuresWithObjectConstrExprWithAnnotsInAnonFunc() returns (functi return a1 + self.a2 + a3 + intVal; } }; - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; return obj1.foo(50) + annot.x; }; } @@ -208,14 +211,14 @@ function checkClosuresWithObjectConstrExprWithAnnotsInObjectFunc(int b1) returns return intVal; } }; - AnnotRecord annot = (typeof obj2).@Config3; + AnnotRecordOCA annot = (typeof obj2).@Config3; return obj2.bam(obj2.bar("123")) + self.a2 + annot.x; } }; var res = obj1.foo(50); if res is int { - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; return res + annot.x; } return 0; @@ -245,15 +248,15 @@ function checkClosuresWithObjectConstrExprWithAnnotsInVarAssignment(int b1) retu } }; - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; return obj1.foo(50) + annot.x; } function checkClosuresWithObjectConstrExprWithAnnotsInReturnStmt(int b1) returns object { - int a2; - function foo(int b2) returns int; - } { + int a2; + function foo(int b2) returns int; +} { final int a1 = 10; return @Config3 { @@ -286,7 +289,7 @@ function checkClosuresWithClientObjectConstrExprWithAnnots(int b1) returns int { }; int res = obj1->bar(10); - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; return res + annot.x; } @@ -324,13 +327,13 @@ function checkClosuresWithObjectConstrExprWithAnnotsInClientObjectConstrExpr(int return sum; } }; - AnnotRecord annot = (typeof obj2).@Config3; + AnnotRecordOCA annot = (typeof obj2).@Config3; return obj2.foo(50) + self.a2 + self.obj2.foo(20) + annot.x; } }; - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; int res = obj1->bar(10); - return res + annot.x; + return res + annot.x; } function checkClosuresWithServiceObjectConstrExprWithAnnots(int b1) returns int { @@ -369,7 +372,7 @@ function checkClosuresWithServiceObjectConstrExprWithAnnots(int b1) returns int } }; lock { - AnnotRecord annot = (typeof self.obj2).@Config2; + AnnotRecordOCA annot = (typeof self.obj2).@Config2; return obj2.foo(50) + self.a2 + self.obj2.foo(20) + annot.x; } } @@ -390,7 +393,7 @@ function checkClosuresWithServiceObjectConstrExprWithAnnots(int b1) returns int } }; - AnnotRecord annot = (typeof obj1).@Config; + AnnotRecordOCA annot = (typeof obj1).@Config; return annot.x; } @@ -432,12 +435,12 @@ function checkClosuresWithObjectConstrExprWithAnnotsInObjectConstrExprWithAnnots } }; Foo obj3 = obj2.bar(10); - AnnotRecord annot = (typeof obj2).@Config3; + AnnotRecordOCA annot = (typeof obj2).@Config3; return a1 + self.i + b1 + obj3.foo(50) + annot.x; } }; - AnnotRecord annot = (typeof obj1).@Config2; + AnnotRecordOCA annot = (typeof obj1).@Config2; return obj1.foo(20) + annot.x; } @@ -467,7 +470,7 @@ function checkClosuresWithObjectConstrExprWithAnnotsAsArrayMember(int b1, string if obj1.k != obj3.k { self.i = 200; } - AnnotRecord annot = (typeof obj2).@Config2; + AnnotRecordOCA annot = (typeof obj2).@Config2; return b1 + a1 + self.i + b2 + intVal + annot.x; } } @@ -483,11 +486,11 @@ function testClosuresWithObjectConstrExprWithAnnots() { function testClosuresWithObjectConstrExprWithAnnotsAsFunctionDefaultParam() { assertValueEquality(60, checkClosuresWithObjectConstrExprWithAnnotsAsFunctionDefaultParam(10)); assertValueEquality(120, checkClosuresWithObjectConstrExprWithAnnotsAsFunctionDefaultParam(10, object { - int y = 10; - function foo(int c) returns int { - return self.y + c + intVal; - } - })); + int y = 10; + function foo(int c) returns int { + return self.y + c + intVal; + } + })); } function testClosuresWithObjectConstrExprWithAnnotsInAnonFunc() { @@ -508,7 +511,7 @@ function testClosuresWithObjectConstrExprWithAnnotsInReturnStmt() { int a2; function foo(int b2) returns int; } obj1 = checkClosuresWithObjectConstrExprWithAnnotsInReturnStmt(10); - AnnotRecord annot = (typeof obj1).@Config3; + AnnotRecordOCA annot = (typeof obj1).@Config3; assertValueEquality(363, obj1.foo(10) + obj1.a2 + annot.x); } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/rawtemplate/raw_template_literal_test.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/rawtemplate/raw_template_literal_test.bal index f98db266b308..2e1690a0334b 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/rawtemplate/raw_template_literal_test.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/rawtemplate/raw_template_literal_test.bal @@ -86,7 +86,7 @@ function testComplexExpressions() { assert("name: John Doe, age: 20", (checkpanic rt3.insertions[0]).toString()); } -type Template1 object { +type Template1RTLT object { *ob:RawTemplate; public (readonly & string[]) strings; public int[] insertions; @@ -96,12 +96,12 @@ function testSubtyping1() { int x = 10; int y = 20; - Template1 t = `${x} + ${y} = ${x + y}`; + Template1RTLT t = `${x} + ${y} = ${x + y}`; assert(["", " + ", " = ", ""], t.strings); assert([10, 20, 30], t.insertions); } -type Template2 object { +type Template2RTLT object { *ob:RawTemplate; public (readonly & string[]) strings; public [int, string, float] insertions; @@ -112,7 +112,7 @@ function testSubtyping2() { string s = "foo"; float f = 12.34; - Template2 t = `Using tuples: ${x}, ${s}, ${f}`; + Template2RTLT t = `Using tuples: ${x}, ${s}, ${f}`; assert(["Using tuples: ", ", ", ", ", ""], t.strings); assert(x, t.insertions[0]); assert(s, t.insertions[1]); @@ -144,14 +144,14 @@ function testSubtyping2() { const FOO = "Foo"; const BAR = "Bar"; -type FooBar FOO|BAR; +type FooBarRTLT FOO|BAR; function testSubtyping3() { int x = 10; object { *ob:RawTemplate; - public (readonly & FooBar[]) strings; + public (readonly & FooBarRTLT[]) strings; public int[] insertions; } temp1 = `Foo${x}Bar`; @@ -176,12 +176,12 @@ function testUsageWithQueryExpressions() { } } -public type Value ()|int|float|decimal|string|xml; +public type ValueRTLT ()|int|float|decimal|string|xml; -public type ParameterizedQuery object { +public type ParameterizedQueryRTLT object { *ob:RawTemplate; public (readonly & string[]) strings; - public Value[] insertions; + public ValueRTLT[] insertions; }; function testUsageWithQueryExpressions2() { @@ -191,7 +191,8 @@ function testUsageWithQueryExpressions2() { {name: "Alice3"} ]; - ParameterizedQuery[] queries = from var rec in data select `INSERT INTO People (name) values (${rec.name});`; + ParameterizedQueryRTLT[] queries = from var rec in data + select `INSERT INTO People (name) values (${rec.name});`; foreach var x in queries { assert("[\"INSERT INTO People (name) values (\",\");\"]", x.strings.toString()); @@ -199,7 +200,7 @@ function testUsageWithQueryExpressions2() { int i = 0; foreach var x in queries { - assert("[\"" + data[i]["name"]+ "\"]", x.insertions.toString()); + assert("[\"" + data[i]["name"] + "\"]", x.insertions.toString()); i += 1; } } @@ -220,21 +221,21 @@ function testUseWithAny() { assert("typedesc $rawTemplate$RawTemplate$_18", td.toString()); } -public type Template3 object { +public type Template3RTLT object { *ob:RawTemplate; public (string[2] & readonly) strings; public int[1] insertions; }; function testFixedLengthArrayFields() { - Template3 t = `Count:${1}`; + Template3RTLT t = `Count:${1}`; assert(["Count:", ""], t.strings); assert([1], t.insertions); } function testIndirectAssignmentToConcreteType() { - Template1 rt = `Count: ${10}, ${20}`; + Template1RTLT rt = `Count: ${10}, ${20}`; object { public string[] strings; @@ -249,74 +250,74 @@ function testIndirectAssignmentToConcreteType() { error err = trap rt2.insertions.push(12.34); assert("{ballerina/lang.array}InherentTypeViolation", err.message()); - assert("incompatible types: expected 'int', found 'float'", checkpanic err.detail().get("message")); + assert("incompatible types: expected 'int', found 'float'", checkpanic err.detail().get("message")); } class CompatibleObj { - public string[] strings = []; - public anydata[] insertions = []; + public string[] strings = []; + public anydata[] insertions = []; } function testModifyStringsField() { - Template1 rt = `Count: ${10}, ${20}`; + Template1RTLT rt = `Count: ${10}, ${20}`; CompatibleObj rt2 = rt; error err = trap rt2.strings.push("Invalid"); assert("{ballerina/lang.array}InvalidUpdate", err.message()); - assert("modification not allowed on readonly value", checkpanic err.detail().get("message")); + assert("modification not allowed on readonly value", checkpanic err.detail().get("message")); } function testAnyInUnion() { any|error ae = `INSERT INTO Details VALUES (${"Foo"}, ${20})`; - ob:RawTemplate rt = checkpanic ae; + ob:RawTemplate rt = checkpanic ae; assert(["INSERT INTO Details VALUES (", ", ", ")"], rt.strings); - assert("Foo", checkpanic rt.insertions[0]); - assert(20, checkpanic rt.insertions[1]); + assert("Foo", checkpanic rt.insertions[0]); + assert(20, checkpanic rt.insertions[1]); } function testAssignmentToUnion() { - Template1|string rt = `Count: ${10}, ${20}`; - Template1 t1 = rt; + Template1RTLT|string rt = `Count: ${10}, ${20}`; + Template1RTLT t1 = rt; assert(["Count: ", ", ", ""], t1.strings); assert([10, 20], t1.insertions); } -type RawTemplateType object:RawTemplate; +type RawTemplateTypeRTLT object:RawTemplate; final object:RawTemplate & readonly tmp1 = `Count: ${10}, ${20}`; -final Template1 & readonly tmp2 = `Count: ${10}, ${20}`; +final Template1RTLT & readonly tmp2 = `Count: ${10}, ${20}`; -final RawTemplateType & readonly tmp3 = `Count: ${10}, ${20}`; +final RawTemplateTypeRTLT & readonly tmp3 = `Count: ${10}, ${20}`; function testRawTemplateWithIntersectionType() returns error? { assert(["Count: ", ", ", ""], tmp1.strings); - var insertions = checkpanic tmp1.insertions; + var insertions = checkpanic tmp1.insertions; assert([10, 20], insertions); assert(["Count: ", ", ", ""], tmp2.strings); - insertions = checkpanic tmp2.insertions; + insertions = checkpanic tmp2.insertions; assert([10, 20], insertions); assert(["Count: ", ", ", ""], tmp3.strings); - insertions = checkpanic tmp3.insertions; + insertions = checkpanic tmp3.insertions; assert([10, 20], insertions); final object:RawTemplate & readonly tmp4 = `Count: ${10}, ${20}`; assert(["Count: ", ", ", ""], tmp4.strings); - insertions = checkpanic tmp4.insertions; + insertions = checkpanic tmp4.insertions; assert([10, 20], insertions); - final Template1 & readonly tmp5 = `Count: ${10}, ${20}`; + final Template1RTLT & readonly tmp5 = `Count: ${10}, ${20}`; assert(["Count: ", ", ", ""], tmp5.strings); - insertions = checkpanic tmp5.insertions; + insertions = checkpanic tmp5.insertions; assert([10, 20], insertions); - final RawTemplateType & readonly tmp6 = `Count: ${10}, ${20}`; + final RawTemplateTypeRTLT & readonly tmp6 = `Count: ${10}, ${20}`; assert(["Count: ", ", ", ""], tmp6.strings); insertions = checkpanic tmp6.insertions; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal index eb260a6c4ec9..4cdb2acc68ca 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/expressions/typecast/type-casting.bal @@ -367,10 +367,10 @@ function testMapOfCharToMapOfString() { test:assertEquals(res, {}); } -type IntOneOrTwo 1|2; +type IntOneOrTwoTC 1|2; function testFiniteTypeArrayToIntArray() { - IntOneOrTwo[] intOneOrTwoArray = [1, 2]; + IntOneOrTwoTC[] intOneOrTwoArray = [1, 2]; any anyIntOneOrTwoArray = intOneOrTwoArray; test:assertEquals( anyIntOneOrTwoArray, [1, 2]); @@ -381,10 +381,10 @@ function testFiniteTypeArrayToIntArray() { test:assertEquals( anyIntOneOrTwoArray, [1, 2]); } -type AOrBOrC "A"|"B"|"C"; +type AOrBOrCTC "A"|"B"|"C"; function testFiniteTypeToStringArray() { - AOrBOrC[] array = ["A", "C"]; + AOrBOrCTC[] array = ["A", "C"]; any anyArray = array; test:assertEquals( anyArray, ["A", "C"]); @@ -678,12 +678,12 @@ function testAnyStructToJson() returns json { return value; } -type JsonTypedesc typedesc; +type JsonTypedescTC typedesc; function testAnyNullToJson() returns json|error { anydata a = (); json value; - value = check a.cloneWithType(JsonTypedesc); + value = check a.cloneWithType(JsonTypedescTC); return value; } @@ -709,21 +709,21 @@ function testAnyNullToXml() returns xml { return value; } -type A record { +type ATC record { string x; int y; }; -type B record { +type BTC record { string x; }; -function testCompatibleStructForceCasting() returns A|error { - A a = {x: "x-valueof-a", y:4}; - B b = {x: "x-valueof-b"}; +function testCompatibleStructForceCasting() returns ATC|error { + ATC a = {x: "x-valueof-a", y:4}; + BTC b = {x: "x-valueof-b"}; b = a; - A c = check trap b; + ATC c = check trap b; //TODO Handle error @@ -731,11 +731,11 @@ function testCompatibleStructForceCasting() returns A|error { return c; } -type ATypedesc typedesc; +type ATypedescTC typedesc; -function testInCompatibleStructForceCasting() returns A|error { - B b = {x: "x-valueof-b"}; - A a = check b.cloneWithType(ATypedesc); +function testInCompatibleStructForceCasting() returns ATC|error { + BTC b = {x: "x-valueof-b"}; + ATC a = check b.cloneWithType(ATypedescTC); //TODO Handle error