From b3fd712aa5f81868d2289faffe6b3148a87c93c1 Mon Sep 17 00:00:00 2001 From: Shumilov Petr Date: Tue, 1 Aug 2023 18:04:02 +0300 Subject: [PATCH] Add first draft of Reflect design Signed-off-by: Shumilov Petr Fix code style Signed-off-by: Shumilov Petr Add Reflect and Type API design Signed-off-by: Shumilov Petr --- plugins/ets/runtime/CMakeLists.txt | 4 + plugins/ets/runtime/ets_class_linker.cpp | 16 + plugins/ets/runtime/ets_class_linker.h | 3 + .../runtime/ets_class_linker_extension.cpp | 12 + .../ets/runtime/ets_class_linker_extension.h | 20 + plugins/ets/runtime/ets_libbase_runtime.yaml | 89 ++ plugins/ets/runtime/ets_panda_file_items.h | 3 + .../ets/runtime/intrinsics/std_core_Type.cpp | 197 +++ plugins/ets/runtime/types/ets_class.h | 35 +- plugins/ets/runtime/types/ets_field.h | 22 + plugins/ets/runtime/types/ets_type.h | 4 + plugins/ets/runtime/types/ets_typeapi.h | 51 + .../ets/runtime/types/ets_typeapi_feature.h | 39 + .../ets/runtime/types/ets_typeapi_field.cpp | 29 + plugins/ets/runtime/types/ets_typeapi_field.h | 83 ++ .../ets/runtime/types/ets_typeapi_method.cpp | 29 + .../ets/runtime/types/ets_typeapi_method.h | 83 ++ .../runtime/types/ets_typeapi_parameter.cpp | 29 + .../ets/runtime/types/ets_typeapi_parameter.h | 77 + plugins/ets/stdlib/std/core/Field.ets | 28 + plugins/ets/stdlib/std/core/Method.ets | 23 + .../std/core/{Types.ets => Parameter.ets} | 14 +- plugins/ets/stdlib/std/core/Type.ets | 1289 +++++++++++++++++ 23 files changed, 2169 insertions(+), 10 deletions(-) create mode 100644 plugins/ets/runtime/intrinsics/std_core_Type.cpp create mode 100644 plugins/ets/runtime/types/ets_typeapi.h create mode 100644 plugins/ets/runtime/types/ets_typeapi_feature.h create mode 100644 plugins/ets/runtime/types/ets_typeapi_field.cpp create mode 100644 plugins/ets/runtime/types/ets_typeapi_field.h create mode 100644 plugins/ets/runtime/types/ets_typeapi_method.cpp create mode 100644 plugins/ets/runtime/types/ets_typeapi_method.h create mode 100644 plugins/ets/runtime/types/ets_typeapi_parameter.cpp create mode 100644 plugins/ets/runtime/types/ets_typeapi_parameter.h create mode 100644 plugins/ets/stdlib/std/core/Field.ets create mode 100644 plugins/ets/stdlib/std/core/Method.ets rename plugins/ets/stdlib/std/core/{Types.ets => Parameter.ets} (83%) create mode 100644 plugins/ets/stdlib/std/core/Type.ets diff --git a/plugins/ets/runtime/CMakeLists.txt b/plugins/ets/runtime/CMakeLists.txt index 2f8f9fa42..21822bcea 100644 --- a/plugins/ets/runtime/CMakeLists.txt +++ b/plugins/ets/runtime/CMakeLists.txt @@ -40,6 +40,7 @@ set(ETS_RUNTIME_SOURCES ${ETS_EXT_SOURCES}/intrinsics/std_core_gc.cpp ${ETS_EXT_SOURCES}/intrinsics/std_core_finalization_queue.cpp ${ETS_EXT_SOURCES}/intrinsics/std_core_Promise.cpp + ${ETS_EXT_SOURCES}/intrinsics/std_core_Type.cpp ${ETS_EXT_SOURCES}/intrinsics/std_math.cpp ${ETS_EXT_SOURCES}/intrinsics/escompat_JSON.cpp ${ETS_EXT_SOURCES}/intrinsics/helpers/ets_intrinsics_helpers.cpp @@ -56,6 +57,9 @@ set(ETS_RUNTIME_SOURCES ${ETS_EXT_SOURCES}/types/ets_method.cpp ${ETS_EXT_SOURCES}/types/ets_promise.cpp ${ETS_EXT_SOURCES}/types/ets_object.cpp + ${ETS_EXT_SOURCES}/types/ets_typeapi_field.cpp + ${ETS_EXT_SOURCES}/types/ets_typeapi_method.cpp + ${ETS_EXT_SOURCES}/types/ets_typeapi_parameter.cpp ${ETS_EXT_SOURCES}/ets_vm_api.cpp ${ETS_EXT_SOURCES}/lambda_utils.cpp ) diff --git a/plugins/ets/runtime/ets_class_linker.cpp b/plugins/ets/runtime/ets_class_linker.cpp index 12d7cd304..0a2880bf2 100644 --- a/plugins/ets/runtime/ets_class_linker.cpp +++ b/plugins/ets/runtime/ets_class_linker.cpp @@ -20,6 +20,7 @@ #include "plugins/ets/runtime/ets_exceptions.h" #include "plugins/ets/runtime/ets_panda_file_items.h" #include "plugins/ets/runtime/types/ets_class.h" +#include "types/ets_field.h" namespace panda::ets { @@ -91,4 +92,19 @@ EtsClass *EtsClassLinker::GetPromiseClass() return EtsClass::FromRuntimeClass(ext_->GetPromiseClass()); } +EtsClass *EtsClassLinker::GetTypeAPIFieldClass() +{ + return EtsClass::FromRuntimeClass(ext_->GetTypeAPIFieldClass()); +} + +EtsClass *EtsClassLinker::GetTypeAPIMethodClass() +{ + return EtsClass::FromRuntimeClass(ext_->GetTypeAPIMethodClass()); +} + +EtsClass *EtsClassLinker::GetTypeAPIParameterClass() +{ + return EtsClass::FromRuntimeClass(ext_->GetTypeAPIParameterClass()); +} + } // namespace panda::ets diff --git a/plugins/ets/runtime/ets_class_linker.h b/plugins/ets/runtime/ets_class_linker.h index 8b6c0f2b7..898dbfdcf 100644 --- a/plugins/ets/runtime/ets_class_linker.h +++ b/plugins/ets/runtime/ets_class_linker.h @@ -51,6 +51,9 @@ public: Method *GetMethod(const panda_file::File &pf, panda_file::File::EntityId id); Method *GetAsyncImplMethod(Method *method, EtsCoroutine *coroutine); EtsClass *GetPromiseClass(); + EtsClass *GetTypeAPIFieldClass(); + EtsClass *GetTypeAPIMethodClass(); + EtsClass *GetTypeAPIParameterClass(); EtsClassLinkerExtension *GetEtsClassLinkerExtension() { diff --git a/plugins/ets/runtime/ets_class_linker_extension.cpp b/plugins/ets/runtime/ets_class_linker_extension.cpp index 5a6e378dd..ebcf179d8 100644 --- a/plugins/ets/runtime/ets_class_linker_extension.cpp +++ b/plugins/ets/runtime/ets_class_linker_extension.cpp @@ -15,6 +15,7 @@ #include "plugins/ets/runtime/ets_class_linker_extension.h" +#include "include/method.h" #include "libpandabase/macros.h" #include "libpandabase/utils/logger.h" #include "plugins/ets/runtime/ets_annotation.h" @@ -199,6 +200,17 @@ bool EtsClassLinkerExtension::InitializeImpl(bool compressed_string_enabled) if (!CacheClass(&promise_class_, PROMISE.data())) { return false; } + + if (!CacheClass(&typeapi_field_class_, FIELD.data())) { + return false; + } + if (!CacheClass(&typeapi_method_class_, METHOD.data())) { + return false; + } + if (!CacheClass(&typeapi_parameter_class_, PARAMETER.data())) { + return false; + } + ets::EtsCoroutine::GetCurrent()->SetPromiseClass(promise_class_); Class *weak_ref_class; // Cache into local variable, no need to cache to this class diff --git a/plugins/ets/runtime/ets_class_linker_extension.h b/plugins/ets/runtime/ets_class_linker_extension.h index eeb873d7c..a2c24bf0d 100644 --- a/plugins/ets/runtime/ets_class_linker_extension.h +++ b/plugins/ets/runtime/ets_class_linker_extension.h @@ -85,6 +85,21 @@ public: return promise_class_; } + Class *GetTypeAPIFieldClass() + { + return typeapi_field_class_; + } + + Class *GetTypeAPIMethodClass() + { + return typeapi_method_class_; + } + + Class *GetTypeAPIParameterClass() + { + return typeapi_parameter_class_; + } + Class *GetBoxBooleanClass() { return box_boolean_class_; @@ -170,6 +185,11 @@ private: // Cached classes Class *promise_class_ = nullptr; + + // Cached type API classes + Class *typeapi_field_class_ = nullptr; + Class *typeapi_method_class_ = nullptr; + Class *typeapi_parameter_class_ = nullptr; }; } // namespace panda::ets diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index 19f0a472e..c84033712 100644 --- a/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -24,6 +24,15 @@ coretypes: - managed_class: Array mirror_class: panda::ets::EtsCharArray +- managed_class: std.core.Field + mirror_class: panda::ets::EtsTypeAPIField + +- managed_class: std.core.Method + mirror_class: panda::ets::EtsTypeAPIMethod + +- managed_class: std.core.Parameter + mirror_class: panda::ets::EtsTypeAPIParameter + intrinsics_namespace: panda::ets::intrinsics intrinsics: @@ -1412,3 +1421,83 @@ intrinsics: ret: escompat.RegExpExecResult args: [ std.core.String ] impl: panda::ets::intrinsics::EscompatRegExpExec + +################### +# std.core.Type # +################### + - name: StdTypeGetTypeDescriptor + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetTypeDescriptor + static: true + signature: + ret: std.core.String + args: [ std.core.Object ] + impl: panda::ets::intrinsics::TypeAPIGetTypeDescriptor + clear_flags: [ ] + + - name: StdTypeGetTypeKind + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetTypeKind + static: true + signature: + ret: i8 + args: [ std.core.String ] + impl: panda::ets::intrinsics::TypeAPIGetTypeKind + clear_flags: [ ] + + - name: StdTypeIsValueType + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIIsValueType + static: true + signature: + ret: u1 + args: [ std.core.String ] + impl: panda::ets::intrinsics::TypeAPIIsValueType + clear_flags: [ ] + + - name: StdTypeGetTypeName + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetTypeName + static: true + signature: + ret: std.core.String + args: [ std.core.String ] + impl: panda::ets::intrinsics::TypeAPIGetTypeName + clear_flags: [ ] + + - name: StdTypeGetFieldsNum + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetFieldsNum + static: true + signature: + ret: i64 + args: [ std.core.String ] + impl: panda::ets::intrinsics::TypeAPIGetFieldsNum + clear_flags: [ ] + + - name: StdTypeGetField + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetField + static: true + signature: + ret: std.core.Field + args: [ std.core.String, i64 ] + impl: panda::ets::intrinsics::TypeAPIGetField + clear_flags: [ ] + + - name: StdTypeGetArrayElementType + space: ets + class_name: std.core.ETSGLOBAL + method_name: TypeAPIGetArrayElementType + static: true + signature: + ret: std.core.String + args: [ std.core.String ] + impl: panda::ets::intrinsics::TypeAPIGetArrayElementType + clear_flags: [ ] diff --git a/plugins/ets/runtime/ets_panda_file_items.h b/plugins/ets/runtime/ets_panda_file_items.h index f198d4b85..d03f45ca8 100644 --- a/plugins/ets/runtime/ets_panda_file_items.h +++ b/plugins/ets/runtime/ets_panda_file_items.h @@ -33,6 +33,9 @@ static constexpr std::string_view PROMISE = "Lstd/c static constexpr std::string_view STRING = "Lstd/core/String;"; static constexpr std::string_view WEAK_REF = "Lstd/core/WeakRef;"; static constexpr std::string_view TYPE = "Lstd/core/Type;"; +static constexpr std::string_view FIELD = "Lstd/core/Field;"; +static constexpr std::string_view METHOD = "Lstd/core/Method;"; +static constexpr std::string_view PARAMETER = "Lstd/core/Parameter;"; // Box classes static constexpr std::string_view BOX_BOOLEAN = "Lstd/core/Boolean;"; diff --git a/plugins/ets/runtime/intrinsics/std_core_Type.cpp b/plugins/ets/runtime/intrinsics/std_core_Type.cpp new file mode 100644 index 000000000..ce6a7a186 --- /dev/null +++ b/plugins/ets/runtime/intrinsics/std_core_Type.cpp @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include +#include "include/coretypes/class.h" +#include "include/mtmanaged_thread.h" +#include "intrinsics.h" +#include "mem/mem.h" +#include "mem/vm_handle.h" +#include "plugins/ets/runtime/types/ets_object.h" +#include "plugins/ets/runtime/types/ets_string.h" +#include "plugins/ets/runtime/ets_panda_file_items.h" +#include "types/ets_class.h" +#include "types/ets_primitives.h" +#include "types/ets_typeapi.h" +#include "types/ets_typeapi_feature.h" +#include "types/ets_typeapi_field.h" + +namespace panda::ets::intrinsics { + +// General +EtsString *TypeAPIGetTypeDescriptor(EtsObject *object) +{ + return EtsString::CreateFromMUtf8(object->GetClass()->GetDescriptor()); +} + +EtsByte TypeAPIGetTypeKind(EtsString *td) +{ + auto type_desc = reinterpret_cast(td->GetDataMUtf8()); + + EtsByte kind = static_cast(EtsTypeAPIKind::NONE); + + // Is RefType? + if (*type_desc == CLASS_TYPE_PREFIX || *type_desc == ARRAY_TYPE_PREFIX) { + auto ref_type = PandaEtsVM::GetCurrent()->GetClassLinker()->GetClass(type_desc); + if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_BOOLEAN) { + kind = static_cast(EtsTypeAPIKind::BOOLEAN); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_BYTE) { + kind = static_cast(EtsTypeAPIKind::BYTE); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_CHAR) { + kind = static_cast(EtsTypeAPIKind::CHAR); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_SHORT) { + kind = static_cast(EtsTypeAPIKind::SHORT); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_INT) { + kind = static_cast(EtsTypeAPIKind::INT); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_LONG) { + kind = static_cast(EtsTypeAPIKind::LONG); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_FLOAT) { + kind = static_cast(EtsTypeAPIKind::FLOAT); + } else if (type_desc == panda::ets::panda_file_items::class_descriptors::BOX_DOUBLE) { + kind = static_cast(EtsTypeAPIKind::DOUBLE); + } else if (ref_type->IsInterface()) { + kind = static_cast(EtsTypeAPIKind::INTERFACE); + } else if (ref_type->IsArrayClass()) { + kind = static_cast(EtsTypeAPIKind::ARRAY); + } else if (ref_type->IsStringClass()) { + kind = static_cast(EtsTypeAPIKind::STRING); + } else if (ref_type->IsFunctionClass()) { + kind = static_cast(EtsTypeAPIKind::FUNCTION); + } else if (ref_type->IsUnionClass()) { + kind = static_cast(EtsTypeAPIKind::UNION); + } else if (ref_type->IsUndefined()) { // TODO(shumilov-petr): think about it + kind = static_cast(EtsTypeAPIKind::UNDEFINED); + } else { + kind = static_cast(EtsTypeAPIKind::CLASS); + } + + return kind; + } + + // Is ValueType? + auto val_type = panda::panda_file::Type::GetTypeIdBySignature(*type_desc); + switch (val_type.GetId()) { + case panda_file::Type::TypeId::VOID: + kind = static_cast(EtsTypeAPIKind::VOID); + break; + case panda_file::Type::TypeId::U1: + kind = static_cast(EtsTypeAPIKind::BOOLEAN) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::I8: + kind = static_cast(EtsTypeAPIKind::BYTE) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::U16: + kind = static_cast(EtsTypeAPIKind::CHAR) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::I16: + kind = static_cast(EtsTypeAPIKind::SHORT) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::I32: + kind = static_cast(EtsTypeAPIKind::INT) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::I64: + kind = static_cast(EtsTypeAPIKind::LONG) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::F32: + kind = static_cast(EtsTypeAPIKind::FLOAT) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + case panda_file::Type::TypeId::F64: + kind = static_cast(EtsTypeAPIKind::DOUBLE) | static_cast(ETS_TYPE_KIND_VALUE_MASK); + break; + default: + kind = static_cast(EtsTypeAPIKind::NONE); + } + return kind; +} + +EtsBoolean TypeAPIIsValueType(EtsString *td) +{ + // TODO(shumilov-petr): Add td is valid check + return static_cast(TypeAPIGetTypeKind(td)) & static_cast(ETS_TYPE_KIND_VALUE_MASK); +} + +EtsString *TypeAPIGetTypeName(EtsString *td) +{ + // TODO(shumilov-petr): Add td is valid check + return PandaEtsVM::GetCurrent() + ->GetClassLinker() + ->GetClass(reinterpret_cast(td->GetDataMUtf8())) + ->GetName(); +} + +// Features +EtsLong TypeAPIGetFieldsNum(EtsString *td) +{ + // TODO(shumilov-petr): Add td is valid check + + auto coroutine = EtsCoroutine::GetCurrent(); + [[maybe_unused]] HandleScope scope(coroutine); + + auto class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); + + return class_linker->GetClass(reinterpret_cast(td->GetDataMUtf8()))->GetFieldsNumber(); +} + +EtsTypeAPIField *TypeAPIGetField(EtsString *td, EtsLong idx) +{ + // TODO(shumilov-petr): Add td is valid check + + auto coroutine = EtsCoroutine::GetCurrent(); + [[maybe_unused]] HandleScope scope(coroutine); + + // Make the instance of Type API Field + VMHandle typeapi_field(coroutine, EtsTypeAPIField::Create(coroutine)); + + // Resolve type by td + auto obj_type = + PandaEtsVM::GetCurrent()->GetClassLinker()->GetClass(reinterpret_cast(td->GetDataMUtf8())); + + EtsField *field = obj_type->GetFieldByIndex(idx); + + // Set values + typeapi_field.GetPtr()->SetTypeDesc(field->GetTypeDescriptor()); + typeapi_field.GetPtr()->SetName(field->GetNameString()); + + // Set Access Modifier + EtsTypeAPIFeatureAccessModifier access_mod; + if (field->IsPublic()) { + access_mod = EtsTypeAPIFeatureAccessModifier::PUBLIC; + } else if (field->IsPrivate()) { + access_mod = EtsTypeAPIFeatureAccessModifier::PRIVATE; + } else { + access_mod = EtsTypeAPIFeatureAccessModifier::PROTECTED; + } + typeapi_field.GetPtr()->SetAccessMod(access_mod); + + // Set specific attributes + uint8_t attr = 0; + attr |= (field->IsStatic()) ? static_cast(EtsTypeAPIFeatureAttributes::STATIC) : 0U; + attr |= (field->IsInherited()) ? static_cast(EtsTypeAPIFeatureAttributes::INHERITED) : 0U; + attr |= (field->IsReadonly()) ? static_cast(EtsTypeAPIFeatureAttributes::READONLY) : 0U; + + typeapi_field.GetPtr()->SetAttributes(attr); + + return typeapi_field.GetPtr(); +} + +EtsString *TypeAPIGetArrayElementType(EtsString *td) +{ + // TODO(shumilov-petr): Add td is valid check + auto arr_class = + PandaEtsVM::GetCurrent()->GetClassLinker()->GetClass(reinterpret_cast(td->GetDataMUtf8())); + return EtsString::CreateFromMUtf8(arr_class->GetComponentType()->GetDescriptor()); +} + +} // namespace panda::ets::intrinsics diff --git a/plugins/ets/runtime/types/ets_class.h b/plugins/ets/runtime/types/ets_class.h index 28c8c994c..34828be0e 100644 --- a/plugins/ets/runtime/types/ets_class.h +++ b/plugins/ets/runtime/types/ets_class.h @@ -16,12 +16,14 @@ #ifndef PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_CLASS_H_ #define PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_CLASS_H_ +#include #include "libpandabase/mem/object_pointer.h" #include "runtime/class_linker_context.h" #include "runtime/include/class-inl.h" #include "runtime/include/thread.h" #include "runtime/include/class_linker.h" #include "plugins/ets/runtime/types/ets_field.h" +#include "plugins/ets/runtime/types/ets_type.h" namespace panda::ets { @@ -32,6 +34,9 @@ class EtsObject; class EtsString; class EtsArray; class EtsPromise; +class EtsTypeAPIField; +class EtsTypeAPIMethod; +class EtsTypeAPIParameter; enum class EtsType; @@ -61,6 +66,11 @@ public: return FromRuntimeClass(base); } + uint32_t GetFieldsNumber() + { + return GetRuntimeClass()->GetFields().size(); + } + uint32_t GetStaticFieldsNumber() { return GetRuntimeClass()->GetStaticFields().size(); @@ -71,6 +81,11 @@ public: return GetRuntimeClass()->GetInstanceFields().size(); } + EtsField *GetFieldByIndex(uint32_t i) + { + return reinterpret_cast(&GetRuntimeClass()->GetFields()[i]); + } + EtsField *GetFieldIDByName(const char *name, const char *sig = nullptr) { auto u8name = reinterpret_cast(name); @@ -120,9 +135,9 @@ public: return reinterpret_cast(GetRuntimeClass()->FindStaticField(pred)); } + EtsMethod *GetDirectMethod(const char *name); EtsMethod *GetDirectMethod(const uint8_t *name, const char *signature); EtsMethod *GetDirectMethod(const char *name, const char *signature); - EtsMethod *GetDirectMethod(const char *name); EtsMethod *GetMethod(const char *name); EtsMethod *GetMethod(const char *name, const char *signature); @@ -239,6 +254,24 @@ public: return GetRuntimeClass()->IsStringClass(); } + bool IsFunctionClass() const + { + // TODO(petr-shumilov): Make more clear + return !GetRuntimeClass()->IsPrimitive() && GetRuntimeClass()->GetName().rfind(FUNCTION_TYPE_PREFIX, 0) == 0; + } + + bool IsUnionClass() const + { + // TODO(petr-shumilov): Not implemented + return false; + } + + bool IsUndefined() const + { + // TODO(petr-shumilov): Not implemented + return false; + } + bool IsClassClass(); bool IsInterface() const diff --git a/plugins/ets/runtime/types/ets_field.h b/plugins/ets/runtime/types/ets_field.h index 2cd60ee7a..1878350db 100644 --- a/plugins/ets/runtime/types/ets_field.h +++ b/plugins/ets/runtime/types/ets_field.h @@ -62,6 +62,28 @@ public: return GetCoreType()->IsPublic(); } + bool IsPrivate() const + { + return GetCoreType()->IsPrivate(); + } + + bool IsProtected() const + { + return GetCoreType()->IsProtected(); + } + + bool IsReadonly() const + { + // TODO(shumilov-petr): Need to dump extra info in frontend + return false; + } + + bool IsInherited() const + { + // TODO(shumilov-petr): not implemented + return false; + } + bool IsStatic() const { return GetCoreType()->IsStatic(); diff --git a/plugins/ets/runtime/types/ets_type.h b/plugins/ets/runtime/types/ets_type.h index 6a6a0bf4f..c31584956 100644 --- a/plugins/ets/runtime/types/ets_type.h +++ b/plugins/ets/runtime/types/ets_type.h @@ -20,6 +20,10 @@ namespace panda::ets { +static constexpr char ARRAY_TYPE_PREFIX = '['; +static constexpr char CLASS_TYPE_PREFIX = 'L'; +static constexpr const char *FUNCTION_TYPE_PREFIX = "LambdaObject"; + enum class EtsType { BOOLEAN, BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, OBJECT, UNKNOWN, VOID }; inline EtsType ConvertPandaTypeToEtsType(panda_file::Type type) diff --git a/plugins/ets/runtime/types/ets_typeapi.h b/plugins/ets/runtime/types/ets_typeapi.h new file mode 100644 index 000000000..f06f90091 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef PANDA_PLUGINS_ETS_TYPEAPI_H_ +#define PANDA_PLUGINS_ETS_TYPEAPI_H_ + +#include "types/ets_primitives.h" + +namespace panda::ets { + +enum class EtsTypeAPIKind : EtsByte { + NONE = 0x0U, + VOID = 0x1U, + + CHAR = 0x2U, + BOOLEAN = 0x3U, + BYTE = 0x4U, + SHORT = 0x5U, + INT = 0x6U, + LONG = 0x7U, + FLOAT = 0x8U, + DOUBLE = 0x9U, + + CLASS = 0xAU, + STRING = 0xBU, + INTERFACE = 0xCU, + ARRAY = 0xDU, + FUNCTION = 0xEU, + UNION = 0xFU, + UNDEFINED = 0x10U, + + ENUM = 0x11U +}; + +constexpr EtsByte ETS_TYPE_KIND_VALUE_MASK = 1U << 6U; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_TYPEAPI_H_ \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_feature.h b/plugins/ets/runtime/types/ets_typeapi_feature.h new file mode 100644 index 000000000..2beef5525 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_feature.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef PANDA_PLUGINS_ETS_TYPEAPI_FEATURE_H_ +#define PANDA_PLUGINS_ETS_TYPEAPI_FEATURE_H_ + +#include "types/ets_primitives.h" + +namespace panda::ets { + +enum class EtsTypeAPIFeatureAccessModifier : EtsByte { PUBLIC = 0, PRIVATE = 1, PROTECTED = 2 }; + +// Type features' attributes "flat" representation +enum class EtsTypeAPIFeatureAttributes : EtsInt { + STATIC = 1U << 0U, // Field, Method + INHERITED = 1U << 1U, // Field, Method + READONLY = 1U << 2U, // Field + FINAL = 1U << 3U, // Method + ABSTRACT = 1U << 4U, // Method + CONSTRUCTOR = 1U << 5U, // Method + REST = 1U << 6U, // Parameter + OPTIONAL = 1U << 7U // Parameter +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_TYPEAPI_FEATURE_H_ \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_field.cpp b/plugins/ets/runtime/types/ets_typeapi_field.cpp new file mode 100644 index 000000000..57a253e69 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_field.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include "plugins/ets/runtime/types/ets_typeapi_field.h" +#include "plugins/ets/runtime/ets_coroutine.h" +#include "plugins/ets/runtime/ets_vm.h" + +namespace panda::ets { + +EtsTypeAPIField *EtsTypeAPIField::Create(EtsCoroutine *ets_coroutine) +{ + EtsClass *klass = ets_coroutine->GetPandaVM()->GetClassLinker()->GetTypeAPIFieldClass(); + EtsObject *ets_object = EtsObject::Create(ets_coroutine, klass); + return reinterpret_cast(ets_object); +} + +} // namespace panda::ets \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_field.h b/plugins/ets/runtime/types/ets_typeapi_field.h new file mode 100644 index 000000000..4128e6471 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_field.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef PANDA_PLUGINS_ETS_TYPEAPI_FIELD_H_ +#define PANDA_PLUGINS_ETS_TYPEAPI_FIELD_H_ + +#include "plugins/ets/runtime/types/ets_object.h" +#include "plugins/ets/runtime/types/ets_string.h" +#include "types/ets_primitives.h" +#include "types/ets_typeapi_feature.h" + +namespace panda::ets { + +class EtsCoroutine; + +class EtsTypeAPIField : public ObjectHeader { +public: + EtsTypeAPIField() = delete; + ~EtsTypeAPIField() = delete; + + NO_COPY_SEMANTIC(EtsTypeAPIField); + NO_MOVE_SEMANTIC(EtsTypeAPIField); + + static EtsTypeAPIField *Create(EtsCoroutine *ets_coroutine = EtsCoroutine::GetCurrent()); + + EtsObject *AsObject() + { + return EtsObject::FromCoreType(this); + } + + const EtsObject *AsObject() const + { + return EtsObject::FromCoreType(this); + } + + static EtsTypeAPIField *FromEtsObject(EtsObject *field) + { + return reinterpret_cast(field); + } + + void SetTypeDesc(const char *td) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIField, td_), + EtsString::CreateFromMUtf8(td)->AsObject()->GetCoreType()); + } + + void SetName(EtsString *name) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIField, name_), name->AsObject()->GetCoreType()); + } + + void SetAccessMod(EtsTypeAPIFeatureAccessModifier access_mod) + { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsTypeAPIField, access_mod_), access_mod); + } + + void SetAttributes(EtsInt attr) + { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsTypeAPIField, attr_), attr); + } + +private: + ObjectPointer td_; + ObjectPointer name_; + FIELD_UNUSED EtsByte access_mod_; + FIELD_UNUSED EtsInt attr_; +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_TYPEAPI_FIELD_H_ \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_method.cpp b/plugins/ets/runtime/types/ets_typeapi_method.cpp new file mode 100644 index 000000000..d549df5f0 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_method.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include "plugins/ets/runtime/types/ets_typeapi_method.h" +#include "plugins/ets/runtime/ets_coroutine.h" +#include "plugins/ets/runtime/ets_vm.h" + +namespace panda::ets { + +EtsTypeAPIMethod *EtsTypeAPIMethod::Create(EtsCoroutine *ets_coroutine) +{ + EtsClass *klass = ets_coroutine->GetPandaVM()->GetClassLinker()->GetTypeAPIMethodClass(); + EtsObject *ets_object = EtsObject::Create(ets_coroutine, klass); + return reinterpret_cast(ets_object); +} + +} // namespace panda::ets \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_method.h b/plugins/ets/runtime/types/ets_typeapi_method.h new file mode 100644 index 000000000..6fa82237a --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_method.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H_ +#define PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H_ + +#include "plugins/ets/runtime/types/ets_object.h" +#include "plugins/ets/runtime/types/ets_string.h" +#include "types/ets_primitives.h" +#include "types/ets_typeapi_feature.h" + +namespace panda::ets { + +class EtsCoroutine; + +class EtsTypeAPIMethod : public ObjectHeader { +public: + EtsTypeAPIMethod() = delete; + ~EtsTypeAPIMethod() = delete; + + NO_COPY_SEMANTIC(EtsTypeAPIMethod); + NO_MOVE_SEMANTIC(EtsTypeAPIMethod); + + static EtsTypeAPIMethod *Create(EtsCoroutine *ets_coroutine = EtsCoroutine::GetCurrent()); + + EtsObject *AsObject() + { + return EtsObject::FromCoreType(this); + } + + const EtsObject *AsObject() const + { + return EtsObject::FromCoreType(this); + } + + static EtsTypeAPIMethod *FromEtsObject(EtsObject *field) + { + return reinterpret_cast(field); + } + + void SetTypeDesc(const char *td) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIMethod, td_), + EtsString::CreateFromMUtf8(td)->AsObject()->GetCoreType()); + } + + void SetName(EtsString *name) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIMethod, name_), name->AsObject()->GetCoreType()); + } + + void SetAccessMod(EtsTypeAPIFeatureAccessModifier access_mod) + { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsTypeAPIMethod, access_mod_), access_mod); + } + + void SetAttributes(EtsInt attr) + { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsTypeAPIMethod, attr_), attr); + } + +private: + ObjectPointer td_; + ObjectPointer name_; + FIELD_UNUSED EtsByte access_mod_; + FIELD_UNUSED EtsInt attr_; +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_parameter.cpp b/plugins/ets/runtime/types/ets_typeapi_parameter.cpp new file mode 100644 index 000000000..a04d3d283 --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_parameter.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include "plugins/ets/runtime/types/ets_typeapi_parameter.h" +#include "plugins/ets/runtime/ets_coroutine.h" +#include "plugins/ets/runtime/ets_vm.h" + +namespace panda::ets { + +EtsTypeAPIParameter *EtsTypeAPIParameter::Create(EtsCoroutine *ets_coroutine) +{ + EtsClass *klass = ets_coroutine->GetPandaVM()->GetClassLinker()->GetTypeAPIParameterClass(); + EtsObject *ets_object = EtsObject::Create(ets_coroutine, klass); + return reinterpret_cast(ets_object); +} + +} // namespace panda::ets \ No newline at end of file diff --git a/plugins/ets/runtime/types/ets_typeapi_parameter.h b/plugins/ets/runtime/types/ets_typeapi_parameter.h new file mode 100644 index 000000000..d55e7a27f --- /dev/null +++ b/plugins/ets/runtime/types/ets_typeapi_parameter.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H_ +#define PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H_ + +#include "plugins/ets/runtime/types/ets_object.h" +#include "plugins/ets/runtime/types/ets_string.h" +#include "types/ets_primitives.h" +#include "types/ets_typeapi_feature.h" + +namespace panda::ets { + +class EtsCoroutine; + +class EtsTypeAPIParameter : public ObjectHeader { +public: + EtsTypeAPIParameter() = delete; + ~EtsTypeAPIParameter() = delete; + + NO_COPY_SEMANTIC(EtsTypeAPIParameter); + NO_MOVE_SEMANTIC(EtsTypeAPIParameter); + + static EtsTypeAPIParameter *Create(EtsCoroutine *ets_coroutine = EtsCoroutine::GetCurrent()); + + EtsObject *AsObject() + { + return EtsObject::FromCoreType(this); + } + + const EtsObject *AsObject() const + { + return EtsObject::FromCoreType(this); + } + + static EtsTypeAPIParameter *FromEtsObject(EtsObject *field) + { + return reinterpret_cast(field); + } + + void SetTypeDesc(const char *td) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIParameter, td_), + EtsString::CreateFromMUtf8(td)->AsObject()->GetCoreType()); + } + + void SetName(EtsString *name) + { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsTypeAPIParameter, name_), name->AsObject()->GetCoreType()); + } + + void SetAttributes(EtsInt attr) + { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsTypeAPIParameter, attr_), attr); + } + +private: + ObjectPointer td_; + ObjectPointer name_; + FIELD_UNUSED EtsInt attr_; +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_TYPEAPI_METHOD_H \ No newline at end of file diff --git a/plugins/ets/stdlib/std/core/Field.ets b/plugins/ets/stdlib/std/core/Field.ets new file mode 100644 index 000000000..3c79372fd --- /dev/null +++ b/plugins/ets/stdlib/std/core/Field.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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 std.core; + +export final class Field extends Object { + private td: string + private name: string + private accessMod: byte + private attributes: int + + + public GetType(): Type { + return Type.Resolve(this.td) + } +} \ No newline at end of file diff --git a/plugins/ets/stdlib/std/core/Method.ets b/plugins/ets/stdlib/std/core/Method.ets new file mode 100644 index 000000000..abb496041 --- /dev/null +++ b/plugins/ets/stdlib/std/core/Method.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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 std.core; + +export final class Method extends Object { + private td: string + private name: string + private accessMod: byte + private attributes: int +} \ No newline at end of file diff --git a/plugins/ets/stdlib/std/core/Types.ets b/plugins/ets/stdlib/std/core/Parameter.ets similarity index 83% rename from plugins/ets/stdlib/std/core/Types.ets rename to plugins/ets/stdlib/std/core/Parameter.ets index 44d44b7d4..aa191924a 100644 --- a/plugins/ets/stdlib/std/core/Types.ets +++ b/plugins/ets/stdlib/std/core/Parameter.ets @@ -15,12 +15,8 @@ package std.core; -final class Type { - -} - -final class Types { - // getType(o: Object): Type {} -} - -export const types = new Types(); +export final class Parameter extends Object { + private td: string + private name: string + private attributes: int +} \ No newline at end of file diff --git a/plugins/ets/stdlib/std/core/Type.ets b/plugins/ets/stdlib/std/core/Type.ets new file mode 100644 index 000000000..26062fd17 --- /dev/null +++ b/plugins/ets/stdlib/std/core/Type.ets @@ -0,0 +1,1289 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed 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 std.core; + +type TypeDesc = string + +native function TypeAPIGetTypeDescriptor(o: Object): string + +native function TypeAPIGetTypeKind(td: TypeDesc): byte + +native function TypeAPIIsValueType(td: TypeDesc): boolean + +native function TypeAPIGetTypeName(td: TypeDesc): string + +native function TypeAPIGetFieldsNum(td: TypeDesc): long + +native function TypeAPIGetField(td: TypeDesc, i: long): Field + +native function TypeAPIGetArrayElementType(td: TypeDesc): TypeDesc + +// TODO(shumilov-petr): replace to enum, enum not available now +export type TypeKind = byte + +const NoneKind: TypeKind = 0x0 +const VoidKind: TypeKind = 0x1 + +const CharKind: TypeKind = 0x2 +const BooleanKind: TypeKind = 0x3 +const ByteKind: TypeKind = 0x4 +const ShortKind: TypeKind = 0x5 +const IntKind: TypeKind = 0x6 +const LongKind: TypeKind = 0x7 +const FloatKind: TypeKind = 0x8 +const DoubleKind: TypeKind = 0x9 + +const ClassKind: TypeKind = 0xA +const StringKind: TypeKind = 0xB +const InterfaceKind: TypeKind = 0xC +const ArrayKind: TypeKind = 0xD +const FunctionKind: TypeKind = 0xE +const UnionKind: TypeKind = 0xF +const UndefinedKind: TypeKind = 0x10 + +const EnumKind: TypeKind = 0x11 + + +const TypeKindMask: TypeKind = (1 << 6) - 1 + +// TODO(shumilov-petr): replace to enum, enum not available now +const BooleanValueTD: TypeDesc = "Z" +const ByteValueTD: TypeDesc = "B" +const ShortValueTD: TypeDesc = "S" +const CharValueTD: TypeDesc = "C" +const IntValueTD: TypeDesc = "I" +const LongValueTD: TypeDesc = "J" +const FloatValueTD: TypeDesc = "F" +const DoubleValueTD: TypeDesc = "D" + +const VoidTD: TypeDesc = "V" +const UndefinedTD: TypeDesc = "UNDEF" // TODO(shumilov-petr): get td from runtime + +export abstract class Type extends Object { + protected td: TypeDesc + + public static Resolve(td: TypeDesc): Type { + let kind = TypeAPIGetTypeKind(td) & TypeKindMask + switch (kind) { + case VoidKind: + return VoidType.GetInstance() + + case CharKind: + return CharType.GetInstance(td) + case BooleanKind: + return BooleanType.GetInstance(td) + case ByteKind: + return ByteType.GetInstance(td) + case ShortKind: + return ShortType.GetInstance(td) + case IntKind: + return IntType.GetInstance(td) + case LongKind: + return LongType.GetInstance(td) + case FloatKind: + return FloatType.GetInstance(td) + case DoubleKind: + return DoubleType.GetInstance(td) + + case ClassKind: + return new ClassType(td) + case StringKind: + return StringType.GetInstance() + case InterfaceKind: + return new InterfaceType(td) + case ArrayKind: + return ArrayType.GetInstance(td) + case FunctionKind: + return new FunctionType(td) + case UnionKind: + return new UnionType(td) + case UndefinedKind: + return UndefinedType.GetInstance() + + case EnumKind: + return new EnumType(td) + default: + // TODO(shumilov-petr): unknown type, need exception + assert(false) + } + } + + public static Of(v: boolean): Type { + return BooleanType.GetInstance(BooleanValueTD) + } + + public static Of(v: char): Type { + return CharType.GetInstance(CharValueTD) + } + + public static Of(v: byte): Type { + return ByteType.GetInstance(ByteValueTD) + } + + public static Of(v: short): Type { + return ShortType.GetInstance(ShortValueTD) + } + + public static Of(v: int): Type { + return IntType.GetInstance(IntValueTD) + } + + public static Of(v: long): Type { + return LongType.GetInstance(LongValueTD) + } + + public static Of(v: float): Type { + return FloatType.GetInstance(FloatValueTD) + } + + public static Of(v: double): Type { + return DoubleType.GetInstance(DoubleValueTD) + } + + // ----- + + public static Of(v: Boolean): Type { + return BooleanType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Char): Type { + return CharType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Byte): Type { + return ByteType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Short): Type { + return ShortType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Int): Type { + return IntType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Long): Type { + return LongType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Float): Type { + return FloatType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + public static Of(v: Double): Type { + return DoubleType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + // ----- + + public static Of(v: string): Type { + return StringType.GetInstance() + } + + // ----- + + public static Of(v: boolean[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), BooleanValueTD) + } + + public static Of(v: char[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), CharValueTD) + } + + public static Of(v: byte[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), ByteValueTD) + } + + public static Of(v: short[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), ShortValueTD) + } + + public static Of(v: int[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), IntValueTD) + } + + public static Of(v: long[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), LongValueTD) + } + + public static Of(v: float[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), FloatValueTD) + } + + public static Of(v: double[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v), DoubleValueTD) + } + + // ----- + + public static Of(v: Object[]): Type { + return ArrayType.GetInstance(TypeAPIGetTypeDescriptor(v)) + } + + // ----- + + public static Of(o: Object): Type { + let td = TypeAPIGetTypeDescriptor(o) + return Type.Resolve(td) + } + + + public abstract IsPrimitive(): boolean // Or Composite + + public abstract IsReference(): boolean // Or Value + + public abstract HasName(): boolean + + public abstract GetName(): string + + public abstract GetLiteral(): string + + public override toString(): string { + if (this.HasName()) { + return this.GetName() + } + return this.GetLiteral() + } +} + +export final class UndefinedType extends Type { + private static instance: UndefinedType | null = null + + private constructor() { + this.td = UndefinedTD + } + + public static GetInstance(): UndefinedType { + if (UndefinedType.instance == null) { + UndefinedType.instance = new UndefinedType() + } + return UndefinedType.instance + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return true + } + + public override GetName(): string { + return "undefined" + } + + public override GetLiteral(): string { + return "undefined" + } + + public override equals(to: Object): boolean { + return to instanceof UndefinedType + } +} + + +export final class VoidType extends Type { + private static instance: VoidType | null = null + + private constructor() { + this.td = VoidTD + } + + public static GetInstance(): VoidType { + if (VoidType.instance == null) { + VoidType.instance = new VoidType() + } + return VoidType.instance + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return true + } + + public override GetName(): string { + return "void" + } + + public override GetLiteral(): string { + return "void" + } + + public override equals(to: Object): boolean { + return to instanceof VoidType + } +} + + +export final class CharType extends Type { + private static refInst: CharType | null = null + private static valInst: CharType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): CharType { + if (TypeAPIIsValueType(td)) { + CharType.valInst = (CharType.valInst == null) ? new CharType(td, true) : CharType.valInst + return CharType.valInst + } + CharType.refInst = (CharType.refInst == null) ? new CharType(td, false) : CharType.refInst + return CharType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "char" + } + return "Char" + } + + public override equals(to: Object): boolean { + return to instanceof CharType && this.isValue != (to as CharType).IsReference() + } +} + + +export final class BooleanType extends Type { + private static refInst: BooleanType | null = null + private static valInst: BooleanType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): BooleanType { + if (TypeAPIIsValueType(td)) { + BooleanType.valInst = (BooleanType.valInst == null) ? new BooleanType(td, true) : BooleanType.valInst + return BooleanType.valInst + } + BooleanType.refInst =(BooleanType.refInst == null) ? new BooleanType(td, false) : BooleanType.refInst + return BooleanType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "boolean" + } + return "Boolean" + } + + public override equals(to: Object): boolean { + return to instanceof BooleanType && this.isValue != (to as BooleanType).IsReference() + } +} + + +export final class ByteType extends Type { + private static refInst: ByteType | null = null + private static valInst: ByteType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): ByteType { + if (TypeAPIIsValueType(td)) { + ByteType.valInst = (ByteType.valInst == null) ? new ByteType(td, true) : ByteType.valInst + return ByteType.valInst + } + ByteType.refInst = (ByteType.refInst == null) ? new ByteType(td, false) : ByteType.refInst + return ByteType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "byte" + } + return "Byte" + } + + public override equals(to: Object): boolean { + return to instanceof ByteType && this.isValue != (to as ByteType).IsReference() + } +} + + +export final class ShortType extends Type { + private static refInst: ShortType | null = null + private static valInst: ShortType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): ShortType { + if (TypeAPIIsValueType(td)) { + ShortType.valInst = (ShortType.valInst == null) ? new ShortType(td, true) : ShortType.valInst + return ShortType.valInst + } + ShortType.refInst = (ShortType.refInst == null) ? new ShortType(td, false) : ShortType.refInst + return ShortType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "short" + } + return "Short" + } + + public override equals(to: Object): boolean { + return to instanceof ShortType && this.isValue != (to as ShortType).IsReference() + } +} + + +export final class IntType extends Type { + private static refInst: IntType | null = null + private static valInst: IntType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): IntType { + if (TypeAPIIsValueType(td)) { + IntType.valInst = (IntType.valInst == null) ? new IntType(td, true) : IntType.valInst + return IntType.valInst + } + IntType.refInst = (IntType.refInst == null) ? new IntType(td, false) : IntType.refInst + return IntType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "int" + } + return "Int" + } + + public override equals(to: Object): boolean { + return to instanceof IntType && this.isValue != (to as IntType).IsReference() + } +} + + +export final class LongType extends Type { + private static refInst: LongType | null = null + private static valInst: LongType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): LongType { + if (TypeAPIIsValueType(td)) { + LongType.valInst = (LongType.valInst == null) ? new LongType(td, true) : LongType.valInst + return LongType.valInst + } + LongType.refInst = (LongType.refInst == null) ? new LongType(td, false) : LongType.refInst + return LongType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "long" + } + return "Long" + } + + public override equals(to: Object): boolean { + return to instanceof LongType && this.isValue != (to as LongType).IsReference() + } +} + + +export final class FloatType extends Type { + private static refInst: FloatType | null = null + private static valInst: FloatType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): FloatType { + if (TypeAPIIsValueType(td)) { + FloatType.valInst = (FloatType.valInst == null) ? new FloatType(td, true) : FloatType.valInst + return FloatType.valInst + } + FloatType.refInst = (FloatType.refInst == null) ? new FloatType(td, false) : FloatType.refInst + return FloatType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "float" + } + return "Float" + } + + public override equals(to: Object): boolean { + return to instanceof FloatType && this.isValue != (to as FloatType).IsReference() + } +} + + +export final class DoubleType extends Type { + private static refInst: DoubleType | null = null + private static valInst: DoubleType | null = null + + private isValue: boolean + + private constructor(td: TypeDesc, isValue: boolean) { + this.td = td + this.isValue = isValue + } + + public static GetInstance(td: TypeDesc): DoubleType { + if (TypeAPIIsValueType(td)) { + DoubleType.valInst = (DoubleType.valInst == null) ? new DoubleType(td, true) : DoubleType.valInst + return DoubleType.valInst + } + DoubleType.refInst = (DoubleType.refInst == null) ? new DoubleType(td, false) : DoubleType.refInst + return DoubleType.refInst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return !this.isValue + } + + public override HasName(): boolean { + return !this.isValue + } + + public override GetName(): string { + if (this.isValue) { + return "" + } + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + if (this.isValue) { + return "double" + } + return "Double" + } + + public override equals(to: Object): boolean { + return to instanceof DoubleType && this.isValue != (to as DoubleType).IsReference() + } +} + + +export final class ClassType extends Type { + public constructor(td: TypeDesc) { + this.td = td + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return true + } + + public override GetName(): string { + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "class{...}" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } + + public GetBaseTypesNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetBaseType(i: long): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public GetFieldsNum(): long { + return TypeAPIGetFieldsNum(this.td) + } + + public GetField(i: long): Field { + return TypeAPIGetField(this.td, i) + } + + public GetMethodsNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetMethod(i: long): Method { + // TODO(shumilov-petr): not implemented + return null + } + + public GetConstructorsNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetConstructor(i: long): Method { + // TODO(shumilov-petr): not implemented + return null + } + + public GetTypeParametersNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetTypeParameter(i: long): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public static Create(name: string): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddBaseType(bt: Type): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddField(f: Field): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddMethod(f: Method): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddConstructor(ctor: Method): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddTypeParameter(tp: Type): ClassType { + // TODO(shumilov-petr): not implemented + return null + } + + public Make(): Object { + // TODO(shumilov-petr): not implemented + return null + } +} + + +export final class InterfaceType extends Type { + public constructor(td: TypeDesc) { + this.td = td + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return true + } + + public override GetName(): string { + return TypeAPIGetTypeName(this.td) + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "interface{...}" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } + + public GetBaseTypesNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetBaseType(i: long): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public GetFieldsNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetField(i: long): Field { + // TODO(shumilov-petr): not implemented + return null + } + + public GetMethodsNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetMethod(i: long): Method { + // TODO(shumilov-petr): not implemented + return null + } + + public GetTypeParametersNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetTypeParameter(i: long): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public static Create(name: string): InterfaceType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddBaseType(bt: Type): InterfaceType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddField(f: Field): InterfaceType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddMethod(f: Method): InterfaceType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddTypeParameter(tp: Type): ClassType { + // TODO(shumilov-petr): not implemented + return null + } +} + + +export final class ArrayType extends Type { + private elemTD: TypeDesc + + private static booleanInst: ArrayType | null = null + private static charInst: ArrayType | null = null + private static byteInst: ArrayType | null = null + private static shortInst: ArrayType | null = null + private static intInst: ArrayType | null = null + private static longInst: ArrayType | null = null + private static floatInst: ArrayType | null = null + private static doubleInst: ArrayType | null = null + + private constructor(td: TypeDesc, elemTD: TypeDesc) { + this.td = td + this.elemTD = elemTD + } + + public static GetInstance(td: TypeDesc, elemTD: TypeDesc): ArrayType { + let ek = TypeAPIGetTypeKind(elemTD) & TypeKindMask + switch (ek) { + case BooleanKind: + ArrayType.booleanInst = (ArrayType.booleanInst == null) ? new ArrayType(td, elemTD) : ArrayType.booleanInst + return ArrayType.booleanInst + case CharKind: + ArrayType.charInst = (ArrayType.charInst == null) ? new ArrayType(td, elemTD) : ArrayType.charInst + return ArrayType.charInst + case ByteKind: + ArrayType.byteInst = (ArrayType.byteInst == null) ? new ArrayType(td, elemTD) : ArrayType.byteInst + return ArrayType.byteInst + case ShortKind: + ArrayType.shortInst = (ArrayType.shortInst == null) ? new ArrayType(td, elemTD) : ArrayType.shortInst + return ArrayType.shortInst + case IntKind: + ArrayType.intInst = (ArrayType.intInst == null) ? new ArrayType(td, elemTD) : ArrayType.intInst + return ArrayType.intInst + case LongKind: + ArrayType.longInst = (ArrayType.longInst == null) ? new ArrayType(td, elemTD) : ArrayType.longInst + return ArrayType.longInst + case FloatKind: + ArrayType.floatInst = (ArrayType.floatInst == null) ? new ArrayType(td, elemTD) : ArrayType.floatInst + return ArrayType.floatInst + case DoubleKind: + ArrayType.doubleInst = (ArrayType.doubleInst == null) ? new ArrayType(td, elemTD) : ArrayType.doubleInst + return ArrayType.doubleInst + case ClassKind: + case StringKind: + case InterfaceKind: + case ArrayKind: + case FunctionKind: + case UnionKind: + return new ArrayType(td, elemTD) + default: + // TODO(shumilov-petr): need throw exception + assert(false) + } + } + + public static GetInstance(td: TypeDesc): ArrayType { + return ArrayType.GetInstance(td, TypeAPIGetArrayElementType(td)) + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return false + } + + public override GetName(): string { + return "" + } + + public override GetLiteral(): string { + return this.GetElementType().toString() + "[]" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } + + public GetElementType(): Type { + return Type.Resolve(this.elemTD) + } + + public static Create(et: Type): ArrayType { + // TODO(shumilov-petr): not implemented + return null + } + + public Make(): Object { + // TODO(shumilov-petr): not implemented + return null + } +} + + +export final class FunctionType extends Type { + private isThrowable: boolean + private isNative: boolean + private isAsync: boolean + + constructor(td: TypeDesc) { + this.td = td + // TODO(shumilov-petr): not implemented + this.isThrowable = false + this.isNative = false + this.isAsync = false + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return false + } + + public IsThrowable(): boolean { + return this.isThrowable + } + + public IsNative(): boolean { + return this.isNative + } + + public IsAsync(): boolean { + return this.isAsync + } + + public override GetName(): string { + // TODO(shumilov-petr): not implemented + return "" + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "()" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } + + public GetParametersNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetParameter(i: long): Parameter { + // TODO(shumilov-petr): not implemented + return null + } + + public GetReturnType(): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public GetTypeParametersNum(): long { + // TODO(shumilov-petr): not implemented + return 0 + } + + public GetTypeParameter(i: long): Type { + // TODO(shumilov-petr): not implemented + return null + } + + public static Create(): FunctionType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddParameter(p: Parameter): FunctionType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddReturnType(rt: Type): FunctionType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddThrows(): FunctionType { + // TODO(shumilov-petr): not implemented + return null + } + + public AddAsync(): FunctionType { + // TODO(shumilov-petr): not implemented + return null + } + + public Make(): Object { + // TODO(shumilov-petr): not implemented + return null + } +} + + +export final class StringType extends Type { + private static inst: StringType | null = null + + constructor() { + this.td = TypeAPIGetTypeDescriptor("") + } + + public static GetInstance(): StringType { + StringType.inst = (StringType.inst == null) ? new StringType() : StringType.inst + return StringType.inst + } + + public override IsPrimitive(): boolean { + return true + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return false + } + + public override GetName(): string { + // TODO(shumilov-petr): not implemented + return "" + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "string" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } +} + + +export final class EnumType extends Type { + constructor(td: TypeDesc) { + this.td = td + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return false + } + + public override HasName(): boolean { + return false + } + + public override GetName(): string { + // TODO(shumilov-petr): not implemented + return "" + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "enum {...}" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } +} + + +export final class UnionType extends Type { + constructor(td: TypeDesc) { + this.td = td + } + + public override IsPrimitive(): boolean { + return false + } + + public override IsReference(): boolean { + return true + } + + public override HasName(): boolean { + return false + } + + public override GetName(): string { + // TODO(shumilov-petr): not implemented + return "" + } + + public override GetLiteral(): string { + // TODO(shumilov-petr): not implemented + return "(... | ...)" + } + + public override equals(to: Object): boolean { + // TODO(shumilov-petr): not implemented + return false + } +} \ No newline at end of file -- Gitee