From d07295e5b14d0f6c6da019c9a09b2c6d6dbf0678 Mon Sep 17 00:00:00 2001 From: Mitkin Kirill Date: Wed, 30 Aug 2023 19:28:41 +0300 Subject: [PATCH] add FinalizationRegistry Signed-off-by: Mitkin Kirill add properties Signed-off-by: Mitkin Kirill add documentation for reflect lib Signed-off-by: Mitkin Kirill add number to escompat Signed-off-by: Mitkin Kirill change compile signature 1329 add manual test for regexp constructor 1329 add new template for instance nethod call 1329 update template for instance 1329 regexp is ready draft 1329 remove ambigous constructor tempalate 1329 transition test to new format 1329 transition test to new format.hot fix 1329 hot fixes for new template migrating 1329 add bound and range test 1329 the first part completed Signed-off-by: Aleksandr Gorlov fix tests Signed-off-by: Mitkin Kirill --- plugins/ets/runtime/ets_libbase_runtime.yaml | 6 +- .../runtime/intrinsics/escompat_RegExp.cpp | 68 +- plugins/ets/stdlib/escompat/Number.ets | 4 +- plugins/ets/stdlib/escompat/RegExp.ets | 269 ++-- plugins/ets/stdlib/std/core/Double.ets | 81 +- plugins/ets/stdlib/std/core/Field.ets | 11 +- plugins/ets/stdlib/std/core/Method.ets | 8 + plugins/ets/stdlib/std/core/Parameter.ets | 3 + plugins/ets/stdlib/std/core/String.ets | 12 +- plugins/ets/stdlib/std/core/Type.ets | 1115 ++++++++++++++++- plugins/ets/stdlib/std/core/Value.ets | 93 ++ .../core/std_core_regexp_constructor_test.ets | 90 ++ .../ets/tests/micro-benchmarks/CMakeLists.txt | 2 +- .../core/list.std_core_regexp_instance.yaml | 388 +++++- .../core/list.std_core_string_instance.yaml | 14 +- .../std/core/std_core_regexp.ets | 13 +- .../std/core/std_core_string.ets | 4 +- .../utils/test_check_test_regexp_result.j2 | 49 + .../utils/test_core_regexp_lib.j2 | 5 + .../utils/test_instance_method_template.j2 | 27 + .../utils/test_main_function.j2 | 74 +- .../plugins/ets/ets-func-tests-ignored.txt | 1 + 22 files changed, 2095 insertions(+), 242 deletions(-) create mode 100644 plugins/ets/tests/ets_func_tests/std/core/std_core_regexp_constructor_test.ets create mode 100644 plugins/ets/tests/stdlib-templates/utils/test_check_test_regexp_result.j2 create mode 100644 plugins/ets/tests/stdlib-templates/utils/test_core_regexp_lib.j2 create mode 100644 plugins/ets/tests/stdlib-templates/utils/test_instance_method_template.j2 diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index dd96ec484..99c311415 100644 --- a/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -1746,17 +1746,17 @@ intrinsics: method_name: compile static: false signature: - ret: std.core.void + ret: escompat.RegExp args: [] impl: panda::ets::intrinsics::EscompatRegExpCompile - name: EscompatRegExpExec space: ets class_name: escompat.RegExp - method_name: exec + method_name: exec_impl static: false signature: - ret: escompat.RegExpExecResult + ret: escompat.RegExpExecArray args: [ std.core.String ] impl: panda::ets::intrinsics::EscompatRegExpExec diff --git a/plugins/ets/runtime/intrinsics/escompat_RegExp.cpp b/plugins/ets/runtime/intrinsics/escompat_RegExp.cpp index 26b5ec5eb..f762bac57 100644 --- a/plugins/ets/runtime/intrinsics/escompat_RegExp.cpp +++ b/plugins/ets/runtime/intrinsics/escompat_RegExp.cpp @@ -28,6 +28,24 @@ using RegExpMatchResult = panda::RegExpMatchResult>; using Array = panda::coretypes::Array; namespace { + +const int LAST_PAREN_FIELDS_COUNT = 10; + +const char *GROUP_NAMES_FIELD_NAME = "groupNames"; +const char *BUFFER_FIELD_NAME = "buffer"; +const char *LAST_INDEX_FIELD_NAME = "lastIndex_"; +const char *PATTERN_FIELD_NAME = "pattern_"; +const char *FLAGS_FIELD_NAME = "flags_"; +std::array LAST_PAREN_FIELD_NAMES = {"", "$1_", "$2_", "$3_", "$4_", + "$5_", "$6_", "$7_", "$8_", "$9_"}; +const char *LAST_MATCH_FIELD_NAME = "lastMatch_"; + +const char *RESULT_CLASS_NAME = "Lescompat/RegExpExecArray;"; +const char *INDEX_FIELD_NAME = "index"; +const char *INPUT_FIELD_NAME = "input"; +const char *RESULT_FIELD_NAME = "result"; +const char *IS_CORRECT_FIELD_NAME = "isCorrect"; + EtsObject *GetFieldObjectByName(EtsObject *object, const char *name) { auto *cls = object->GetClass(); @@ -83,7 +101,7 @@ uint32_t CastToBitMask(EtsString *check_str) } } // namespace -extern "C" EtsVoid *EscompatRegExpCompile(ObjectHeader *obj) +extern "C" EtsObject *EscompatRegExpCompile(ObjectHeader *obj) { auto thread = ManagedThread::GetCurrent(); [[maybe_unused]] HandleScope scope(thread); @@ -94,11 +112,12 @@ extern "C" EtsVoid *EscompatRegExpCompile(ObjectHeader *obj) VMHandle reg_obj_handle(thread, regexp_object->GetCoreType()); auto regexp_class = reg_obj_handle.GetPtr()->GetClass(); - EtsField *group_names_field = regexp_class->GetDeclaredFieldIDByName("groupNames"); - EtsString *pattern_str = EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), "pattern")); + EtsField *group_names_field = regexp_class->GetDeclaredFieldIDByName(GROUP_NAMES_FIELD_NAME); + EtsString *pattern_str = + EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), PATTERN_FIELD_NAME)); VMHandle s_handle(thread, pattern_str->GetCoreType()); - EtsString *flags = EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), "flags")); + EtsString *flags = EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), FLAGS_FIELD_NAME)); auto flags_bits = static_cast(CastToBitMask(flags)); RegExpParser parser = RegExpParser(); @@ -119,40 +138,53 @@ extern "C" EtsVoid *EscompatRegExpCompile(ObjectHeader *obj) auto buffer_size = parser.GetOriginBufferSize(); auto buffer = parser.GetOriginBuffer(); - EtsField *buffer_field = regexp_class->GetDeclaredFieldIDByName("buffer"); + EtsField *buffer_field = regexp_class->GetDeclaredFieldIDByName(BUFFER_FIELD_NAME); EtsByteArray *ets_buffer = EtsByteArray::Create(buffer_size); for (size_t i = 0; i < buffer_size; ++i) { ets_buffer->Set(i, buffer[i]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) } reg_obj_handle.GetPtr()->SetFieldObject(buffer_field, ets_buffer->AsObject()); - return EtsVoid::GetInstance(); + return reg_obj_handle.GetPtr(); +} + +void SetLegacyProperties(EtsClass *type, const PandaVector> &matches) +{ + EtsField *last_match_field = type->GetStaticFieldIDByName(LAST_MATCH_FIELD_NAME); + if (!matches.empty()) { + type->SetStaticFieldObject(last_match_field, matches.front().GetPtr()->AsObject()); + } + for (size_t i = 1; i < LAST_PAREN_FIELDS_COUNT; ++i) { + if (matches.size() > i) { + EtsField *last_paren_field = type->GetStaticFieldIDByName(LAST_PAREN_FIELD_NAMES[i]); + type->SetStaticFieldObject(last_paren_field, matches[0].GetPtr()->AsObject()); + } + } } -extern "C" EtsObject *EscompatRegExpExec(ObjectHeader *obj, EtsString *str) +extern "C" EtsObject *EscompatRegExpExec(EtsObject *obj, EtsString *str) { auto thread = ManagedThread::GetCurrent(); [[maybe_unused]] HandleScope scope(thread); VMHandle str_handle(thread, str->GetCoreType()); - auto regexp_object = EtsObject::FromCoreType(obj); - VMHandle reg_obj_handle(thread, regexp_object->GetCoreType()); + VMHandle reg_obj_handle(thread, obj->GetCoreType()); auto regexp_class = reg_obj_handle.GetPtr()->GetClass(); auto class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); auto string_class = class_linker->GetClassRoot(EtsClassRoot::STRING); - EtsField *last_index_field = regexp_class->GetDeclaredFieldIDByName("lastIndex"); + EtsField *last_index_field = regexp_class->GetDeclaredFieldIDByName(LAST_INDEX_FIELD_NAME); auto last_index = reg_obj_handle.GetPtr()->GetFieldPrimitive(last_index_field); - EtsString *flags = EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), "flags")); + EtsString *flags = EtsString::FromEtsObject(GetFieldObjectByName(reg_obj_handle.GetPtr(), FLAGS_FIELD_NAME)); auto flags_bits = static_cast(CastToBitMask(flags)); - auto result_class = class_linker->GetClass("Lescompat/RegExpExecResult;"); + auto result_class = class_linker->GetClass(RESULT_CLASS_NAME); auto result_object = EtsObject::Create(result_class); VMHandle obj_handle(thread, result_object->GetCoreType()); - auto result_correct_field = result_class->GetDeclaredFieldIDByName("isCorrect"); + auto result_correct_field = result_class->GetDeclaredFieldIDByName(IS_CORRECT_FIELD_NAME); bool global = (flags_bits & RegExpParser::FLAG_GLOBAL) > 0; bool sticky = (flags_bits & RegExpParser::FLAG_STICKY) > 0; @@ -184,7 +216,8 @@ extern "C" EtsObject *EscompatRegExpExec(ObjectHeader *obj, EtsString *str) str_buffer = u8_buffer.data(); } - auto ets_buffer = reinterpret_cast(GetFieldObjectByName(reg_obj_handle.GetPtr(), "buffer")); + auto ets_buffer = + reinterpret_cast(GetFieldObjectByName(reg_obj_handle.GetPtr(), BUFFER_FIELD_NAME)); auto buffer = reinterpret_cast(ets_buffer->GetData()); bool ret = executor.Execute(str_buffer, last_index, string_length, buffer, is_utf16); RegExpMatchResult exec_result = executor.GetResult(ret); @@ -203,13 +236,13 @@ extern "C" EtsObject *EscompatRegExpExec(ObjectHeader *obj, EtsString *str) // isCorrect field obj_handle.GetPtr()->SetFieldPrimitive(result_correct_field, true); // index field - auto index_field = result_class->GetDeclaredFieldIDByName("index"); + auto index_field = result_class->GetDeclaredFieldIDByName(INDEX_FIELD_NAME); obj_handle.GetPtr()->SetFieldPrimitive(index_field, exec_result.index); // input field - auto input_field = result_class->GetDeclaredFieldIDByName("input"); + auto input_field = result_class->GetDeclaredFieldIDByName(INPUT_FIELD_NAME); obj_handle.GetPtr()->SetFieldObject(input_field, str_handle.GetPtr()->AsObject()); // result field - auto result_field = result_class->GetDeclaredFieldIDByName("result"); + auto result_field = result_class->GetDeclaredFieldIDByName(RESULT_FIELD_NAME); uint32_t captures_size = exec_result.captures.size(); PandaVector> matches; for (size_t i = 0; i < captures_size; ++i) { @@ -217,6 +250,7 @@ extern "C" EtsObject *EscompatRegExpExec(ObjectHeader *obj, EtsString *str) matches.push_back(exec_result.captures[i].second); } } + SetLegacyProperties(regexp_class, matches); EtsObjectArray *result_array = EtsObjectArray::Create(string_class, matches.size()); for (size_t i = 0; i < matches.size(); i++) { result_array->Set(i, matches[i]->AsObject()); diff --git a/plugins/ets/stdlib/escompat/Number.ets b/plugins/ets/stdlib/escompat/Number.ets index f27a99ee8..3b4af83ca 100644 --- a/plugins/ets/stdlib/escompat/Number.ets +++ b/plugins/ets/stdlib/escompat/Number.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * 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 @@ -16,7 +16,7 @@ package escompat; /** - * `Number` values represent floating-point numbers like 6 or -3.14. + * `Number` values represent floating-point numbers like 6 or -3.14 */ export type Number = Double; diff --git a/plugins/ets/stdlib/escompat/RegExp.ets b/plugins/ets/stdlib/escompat/RegExp.ets index f985c5daa..116aa6c35 100644 --- a/plugins/ets/stdlib/escompat/RegExp.ets +++ b/plugins/ets/stdlib/escompat/RegExp.ets @@ -13,21 +13,20 @@ * limitations under the License. */ -package escompat; +package escompat -// TODO(kirill-mitkin): change to inner class later /** * Regular expression result descriptor */ -export class RegExpExecResult extends Object { +export class RegExpExecArray extends Object { /** true if match present */ - readonly isCorrect: boolean; + readonly isCorrect: boolean /** The 0-based index of the match in the string */ - readonly index: int; + readonly index: int /** The original string that was matched against */ - readonly input: String; + readonly input: String /** result itself */ - readonly result: String[]; + readonly result: String[] // TODO(kirill-mitkin): add indices and groups fields /** @@ -38,7 +37,7 @@ export class RegExpExecResult extends Object { * @returns resulting string */ public get(index: int): String { - return this.result[index]; + return this.result[index] } /** @@ -52,165 +51,256 @@ export class RegExpExecResult extends Object { return this.get(index as int); } - constructor(isCorrect: boolean, index: int, input: String, result: String[]) { - this.isCorrect = isCorrect; - this.index = index; - this.input = input; - this.result = result; + constructor(index: int, input: String, result: String[]) { + this.isCorrect = true; + this.index = index + this.input = input + this.result = result } - constructor(isCorrect: boolean, index: number, input: String, result: String[]) { - this(isCorrect, index as int, input, result) + constructor(index: number, input: String, result: String[]) { + this(index as int, input, result) } - public override equals(other: Object|null): boolean { - if (!(other instanceof RegExpExecResult)) { - return false; + public override equals(other: NullishType): boolean { + if (!(other instanceof RegExpExecArray)) { + return false } - let o: RegExpExecResult = other as RegExpExecResult; + let o: RegExpExecArray = other as RegExpExecArray let res = - (this.isCorrect == o.isCorrect) && (this.index == this.index) && (this.input.compareTo(o.input) == 0) && - (this.result.length == o.result.length); + (this.result.length == o.result.length) if (!res) { - return false; + return false } for (let i: int = 0; i < this.result.length; i++) { - res &= (this.result[i].compareTo(o.result[i]) == 0); + res &= (this.result[i].compareTo(o.result[i]) == 0) if (!res) { - return false; + return false } } - return true; + return true } } +export type RegExpMatchArray = RegExpExecArray; + + /** * Regular expression */ export class RegExp extends Object { - /** - * The string against which a regular expression is matched - */ - readonly pattern: String; + private pattern_: String + private lastIndex_: int + private source_: String + private flags_: String + + private static input_: String + private static lastMatch_: String + private static lastParen_: String + private static leftContext_: String + private static rightContext_: String + private static $1_: String, $2_: String, $3_: String, $4_: String, $5_: String, $6_: String, $7_: String, $8_: String, $9_: String + + private groupNames: String[] + private buffer: int[] /** Flags */ - readonly flags: String; + get flags(): String { + return this.flags_ + } - // TODO(kirill-mitkin): change to properties /** * Has the value true if the regular expression should be tested against * all possible matches in a string */ - readonly global: boolean; + get global(): boolean { + return this.flags_.contains("g", 0) + } /** * Has the value true if the dot special character (.) should additionally match * the line terminator characters in a string */ - readonly dotAll: boolean; + get dotAll(): boolean { + return this.flags_.contains("s", 0) + } /** * Has the value true if the result of a regular expression match should contain * the start and end indices of the substrings of each capture group */ - readonly hasIndices: boolean; + get hasIndices(): boolean { + return this.flags_.contains("d", 0) + } /** * Has the value true if case should be ignored while attempting a match in a string */ - readonly ignoreCase: boolean; + get ignoreCase(): boolean { + return this.flags_.contains("i", 0) + } /** * Has the value true if a multiline input string should be treated as multiple lines */ - readonly multiline: boolean; + get multiline(): boolean { + return this.flags_.contains("m", 0) + } /** * Has the value true if the regex attempts to match the target string only * from the index indicated by the lastIndex property */ - readonly sticky: boolean; + get sticky(): boolean { + return this.flags_.contains("y", 0) + } /** * Has the value true if 'u' flag is used */ - readonly unicode: boolean; + get unicode(): boolean { + return this.flags_.contains("u", 0) + } /** * Has the value true if 'v' flag is used */ - readonly unicodeSets: boolean; + get unicodeSets(): boolean { + return this.flags_.contains("v", 0) + } /** * The index at which to start the next match */ - lastIndex: int; + get lastIndex(): int { + return this.lastIndex_ + } + + set lastIndex(a: int) { + this.lastIndex_ = a + } /** * Returns a string containing the source text of this regular expression */ - readonly source: String; + get source(): String { + return this.source_ + } /** * Returns the string against which a regular expression is matched */ - readonly static input: String; + static get input(): String { + return RegExp.input_ + } /** - * An alias for input + * Returns the string against which a regular expression is matched */ - readonly static $_: String; + static get $_(): String { + return RegExp.input_ + } /** * Returns the last matched substring */ - readonly static lastMatch: String; + static get lastMatch(): String { + return RegExp.lastMatch_ + } /** * An alias for lastMatch */ - // readonly static $&: String; + // static get $&(): String { + // return RegExp.lastMatch_ + // } /** * Returns the last parenthesized substring match, if any */ - readonly static lastParen: String + static get lastParen(): String { + return RegExp.lastParen_ + } /** - * An alias for lastParen + * An alias for lastMatch */ - // readonly static $+: String + // static get $+(): String { + // return RegExp.lastParen_ + // } /** * Returns the substring preceding the most recent match */ - readonly static leftContext: String + static get leftContext(): String { + return RegExp.leftContext_ + } /** * An alias for leftContext */ - // readonly static $`: String + // static get $`(): String { + // return RegExp.leftContext_ + // } /** * Returns the substring following the most recent match */ - readonly static rightContext: String + static get rightContext(): String { + return RegExp.rightContext_ + } /** * An alias for rightContext */ - // readonly static $': String + // static get $'(): String { + // return RegExp.rightContext_ + // } /** * Static accessor properties return parenthesized substring matches */ - readonly static $1: String, $2: String, $3: String, $4: String, $5: String, $6: String, $7: String, $8: String, $9: String; + static get $1(): String { + return RegExp.$1_ + } + + static get $2(): String { + return RegExp.$2_ + } + + static get $3(): String { + return RegExp.$3_ + } + + static get $4(): String { + return RegExp.$4_ + } + + static get $5(): String { + return RegExp.$5_ + } + + static get $6(): String { + return RegExp.$6_ + } + + static get $7(): String { + return RegExp.$7_ + } + + static get $8(): String { + return RegExp.$8_ + } + + static get $9(): String { + return RegExp.$9_ + } /** * Constructs a new RegExp using pattern @@ -218,7 +308,7 @@ export class RegExp extends Object { * @param pattern description of a pattern */ public constructor(pattern: String) { - this(pattern, ""); + this(pattern, "") } /** @@ -229,17 +319,16 @@ export class RegExp extends Object { * @param flags description of flags to be used */ public constructor(pattern: String, flags: String) { - this.pattern = pattern; - this.flags = flags; - this.source = RegExp.escapePattern(pattern); - this.initializeFlags(); - this.compile(); + this.pattern_ = pattern + this.flags_ = flags + this.source_ = RegExp.escapePattern(pattern) + this.compile() } /** * Compiles a regular expression */ - private native compile(): void; + public native compile(): RegExp; /** * Recompiles a regular expression with new source and flags after the RegExp object has already been created @@ -248,14 +337,14 @@ export class RegExp extends Object { * * @param flags any combination of flag values */ - public compile(pattern : String, flags: String) { - this.pattern = pattern; - this.flags = flags; - this.source = RegExp.escapePattern(pattern); - this.initializeFlags(); - this.compile(); + public compile(pattern : String, flags: String): RegExp { + this.pattern_ = pattern + this.flags_ = flags + this.source_ = RegExp.escapePattern(pattern) + return this.compile() } + private native exec_impl(str: String): RegExpExecArray; /** * Executes a search for a match in a specified string and returns a result array * @@ -263,9 +352,16 @@ export class RegExp extends Object { * * @returns RegExp result * - * @see RegExpExecResult - */ - public native exec(str: String): RegExpExecResult; + * @see RegExpExecArray + */ + public exec(str: String): RegExpExecArray | null { + const res = this.exec_impl(str) + if (res.isCorrect) { + return res + } else { + return null + } + } /** * Executes a search for a match between a regular expression and specified string @@ -275,7 +371,7 @@ export class RegExp extends Object { * @returns true if match was found */ public test(str: String): boolean { - return this.exec(str).isCorrect; + return this.exec_impl(str).isCorrect } /** @@ -284,7 +380,7 @@ export class RegExp extends Object { * @returns a string representing the given object */ public override toString(): String { - return "/" + this.source + "/" + this.flags; + return "/" + this.source + "/" + this.flags_ } /** @@ -300,11 +396,11 @@ export class RegExp extends Object { */ public static advanceStringIndex(s: String, index: int, unicode: boolean): int { if (!unicode) { - return index + 1; + return index + 1 } - let length = s.length(); + let length = s.length() if (index + 1 >= length) { - return index + 1; + return index + 1 } return index + s.codePointCount(index, index + 1); } @@ -324,28 +420,11 @@ export class RegExp extends Object { return RegExp.advanceStringIndex(s, index as int, unicode) } - private initializeFlags() { - if (this.flags.isEmpty()) { - return; - } - this.global = this.flags.contains("g", 0); - this.hasIndices = this.flags.contains("d", 0); - this.ignoreCase = this.flags.contains("i", 0); - this.multiline = this.flags.contains("m", 0); - this.unicode = this.flags.contains("u", 0); - this.dotAll = this.flags.contains("s", 0); - this.sticky = this.flags.contains("y", 0); - this.unicodeSets = this.flags.contains("v", 0); - } - private static escapePattern(pattern: String): String { if (pattern == "") { - return "(?:)"; + return "(?:)" } - let s = pattern.replaceAll("/", "\\/"); - return s.replaceAll("\\", "\\"); + let s = pattern.replaceAll("/", "\\/") + return s.replaceAll("\\", "\\") } - - private groupNames: String[]; - private buffer: int[]; } diff --git a/plugins/ets/stdlib/std/core/Double.ets b/plugins/ets/stdlib/std/core/Double.ets index a47f926c1..f6386450d 100644 --- a/plugins/ets/stdlib/std/core/Double.ets +++ b/plugins/ets/stdlib/std/core/Double.ets @@ -23,6 +23,7 @@ export final class Double extends Floating implements Comparable, JSONab /** * Constructs a new Double instance with initial value zero + * @tag common */ public constructor() { this.value = 0.0; @@ -32,6 +33,7 @@ export final class Double extends Floating implements Comparable, JSONab * Constructs a new Double instance with provided initial value * * @param value the initial value + * @tag common */ public constructor(value: double) { this.value = value; @@ -41,6 +43,7 @@ export final class Double extends Floating implements Comparable, JSONab * Constructs a new Double instance with provided initial value * * @param value the initial value + * @tag common */ public constructor(value: Double) { this.value = value.doubleValue(); @@ -50,6 +53,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance as a primitive * * @returns value of this instance + * @tag arkts */ public unboxed(): double { return this.value; @@ -61,6 +65,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param value value to box * * @returns boxed value + * @tag arkts */ public static valueOf(value: double): Double { // TODO(ivan-tyulyandin): caching is possible @@ -70,62 +75,74 @@ export final class Double extends Floating implements Comparable, JSONab /** * Minimal value that this type can have as a double * the workarond for libc's double literal parsing bug + * @tag common */ public static readonly MIN_VALUE: double = 4.9e-300 / 1.e+24; /** * Maximal value that this type can have as a double + * @tag common */ public static readonly MAX_VALUE: double = 1.7976931348623157e+308; /** * Maximal integer value that can be used as a double without loss of precision + * @tag common */ public static readonly MAX_SAFE_INTEGER: double = 9007199254740991; /** * Minimal integer value that can be used as a double without loss of precision + * @tag common */ public static readonly MIN_SAFE_INTEGER: double = -9007199254740991; /** * Size of this type in bits + * @tag arkts */ public static readonly BIT_SIZE: byte = 64; /** * Size of this type in bytes + * @tag arkts */ public static readonly BYTE_SIZE: byte = 8; /** * Represents the NaN value according to IEEE-754 specification + * @tag common */ public static readonly NaN: double = 0.0 / 0.0; /** * Represents the +Infinity value according to IEEE-754 specification + * @tag common */ public static readonly POSITIVE_INFINITY: double = 1.0 / 0.0; /** * Represents the -Infinity value according to IEEE-754 specification + * @tag common */ public static readonly NEGATIVE_INFINITY: double = -1.0 / 0.0; /** * Number of significant precision bits in this floating type + * @tag arkts */ public static readonly PRECISION: byte = 53; /** * Minimal possible difference between two double values. * For double (IEEE-754 binary64) it is 2^(-52) and its bit representation is 0x3cb0000000000000. + * @tag arkts */ public static readonly DELTA: double = Double.bitCastFromLong(0x3cb0000000000000); /** * Minimal possible difference between two double values + * @tag common */ public static readonly EPSILON: double = Double.DELTA; @@ -134,6 +151,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as byte + * @tag arkts */ public override byteValue(): byte { return this.value as byte; @@ -143,6 +161,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as short + * @tag arkts */ public override shortValue(): short { return this.value as short; @@ -152,6 +171,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as int + * @tag arkts */ public override intValue(): int { return this.value as int; @@ -161,6 +181,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as long + * @tag arkts */ public override longValue(): long { return this.value as long; @@ -170,6 +191,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as float + * @tag arkts */ public override floatValue(): float { return this.value as float; @@ -179,6 +201,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns value of this instance * * @returns value as double + * @tag arkts */ public override doubleValue(): double { return this.value; @@ -193,19 +216,28 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Double object to compare with * * @returns result of the comparison + * @tag arkts */ public override compareTo(other: Double): int { return (this.value - other.unboxed()) as int; } - /* toString(d: double, r: int): String -- returns a string representation of d by radix r + /** + * toString(d: double, r: int): String -- returns a string representation of d by radix r + * @tag arkts */ public static native toString(d: double, r: int): String; + /** + * @tag arkts + */ public static toString(d: double): String { Double.toString(d, 10); } + /** + * @tag arkts + */ public toString(r: int): String { return Double.toString(this.value, r); } @@ -214,6 +246,7 @@ export final class Double extends Floating implements Comparable, JSONab * Converts this object to a string * * @returns result of the conversion + * @tag common */ public override toString(): String { return Double.toString(this.value, 10); @@ -225,6 +258,7 @@ export final class Double extends Floating implements Comparable, JSONab * @remark * Implemented as native function, @see `toLocaleString()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#741). * @returns result of the conversion in a local representation + * @tag common */ public native toLocaleString(locale: String): String; @@ -232,6 +266,7 @@ export final class Double extends Floating implements Comparable, JSONab * Without an argument method returns just toString value * * @returns result of the conversion + * @tag common */ public toLocaleString(): String { return Double.toString(this.value, 10); @@ -241,6 +276,7 @@ export final class Double extends Floating implements Comparable, JSONab * Returns a hash code (integer representation) for this instance * * @returns representation of this instance + * @tag arkts */ public override hashCode(): int { return this.intValue(); @@ -254,6 +290,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param rhs right-hand side double for comparison * * @returns true if lhs and rhs are equal with respect to Double.DELTA + * @tag arkts */ public static compare(lhs: double, rhs: double): boolean { return (abs(lhs - rhs) <= Double.DELTA) @@ -266,6 +303,7 @@ export final class Double extends Floating implements Comparable, JSONab * * @returns true if provided object and this instance have same value, false otherwise * Returns false if type of provided object is not the same as this type + * @tag arkts */ public override equals(other: Object|null): boolean { if (other instanceof Double) { @@ -280,6 +318,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param v the double to test * * @returns true if the argument is NaN + * @tag common */ public static isNaN(v: double): boolean { // IEEE-754 feature @@ -290,6 +329,7 @@ export final class Double extends Floating implements Comparable, JSONab * isNaN() checks if the underlying double is NaN (not a number) * * @returns true if the underlying double is NaN + * @tag arkts */ public isNaN(): boolean { return Double.isNaN(this.value); @@ -301,6 +341,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param v the double to test * * @returns true if the argument is a floating point value + * @tag common */ public static isFinite(v: double): boolean { return !(Double.isNaN(v) || (v == Double.POSITIVE_INFINITY) || (v == Double.NEGATIVE_INFINITY)); @@ -310,6 +351,7 @@ export final class Double extends Floating implements Comparable, JSONab * isFinite() checks if the underlying double is a floating point value (not a NaN or infinity) * * @returns true if the underlying double is a floating point value + * @tag arkts */ public isFinite(): boolean { return Double.isFinite(this.value); @@ -321,6 +363,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param v the double to test * * @returns true if the argument is similar to an integer value + * @tag common */ public static isInteger(v: double): boolean { // In the language % works as C fmod that differs with IEEE-754 % definition @@ -331,6 +374,7 @@ export final class Double extends Floating implements Comparable, JSONab * Checks if the underlying double is similar to an integer value * * @returns true if the underlying double is similar to an integer value + * @tag arkts */ public isInteger(): boolean { return Double.isInteger(this.value); @@ -342,6 +386,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param v the double to test * * @returns true if the argument is integer ans less than MAX_SAFE_INTEGER + * @tag common */ public static isSafeInteger(v: double): boolean { return Double.isInteger(v) && (abs(v) <= Double.MAX_SAFE_INTEGER); @@ -351,6 +396,7 @@ export final class Double extends Floating implements Comparable, JSONab * Checks if double is a safe integer value * * @returns true if the underlying double is a safe integer + * @tag arkts */ public isSafeInteger(): boolean { return Double.isSafeInteger(this.value); @@ -363,6 +409,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the addition * * @returns Result of the addition + * @tag arkts */ public add(other: Double): Double { return Double.valueOf((this.value + other.doubleValue()) as double) @@ -374,6 +421,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the subtraction * * @returns Result of the subtraction + * @tag arkts */ public sub(other: Double): Double { return Double.valueOf((this.value - other.doubleValue()) as double) @@ -385,6 +433,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the multiplication * * @returns Result of the multiplication + * @tag arkts */ public mul(other: Double): Double { return Double.valueOf((this.value * other.doubleValue()) as double) @@ -396,6 +445,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the division * * @returns Result of the division + * @tag arkts */ public div(other: Double): Double { return Double.valueOf((this.value / other.doubleValue()) as double) @@ -407,6 +457,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the comparison * * @returns true if this value is less than provided, false otherwise + * @tag arkts */ public isLessThan(other: Double): boolean { return this.value < other.doubleValue(); @@ -418,6 +469,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the comparison * * @returns true if this value is less than or equal to provided, false otherwise + * @tag arkts */ public isLessEqualThan(other: Double): boolean { return this.value <= other.doubleValue(); @@ -429,6 +481,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the comparison * * @returns true if this value is greater than provided, false otherwise + * @tag arkts */ public isGreaterThan(other: Double): boolean { return this.value > other.doubleValue(); @@ -440,6 +493,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param other Right hand side of the comparison * * @returns true if this value is greater than or equal to provided, false otherwise + * @tag arkts */ public isGreaterEqualThan(other: Double): boolean { return this.value >= other.doubleValue(); @@ -464,6 +518,7 @@ export final class Double extends Floating implements Comparable, JSONab * Implemented as native function, @see `parseFloat()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#653). * * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parsefloat + * @tag common */ public static native parseFloat(s: String): double; @@ -487,6 +542,7 @@ export final class Double extends Floating implements Comparable, JSONab * Implemented as native function, @see `parseInt()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#663). * * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parseint + * @tag common */ public static native parseInt(s: String, r: int): double; @@ -496,6 +552,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param s the string to convert * * @returns the result of parsing + * @tag common */ public static parseInt(s: String): double { return Double.parseInt(s, 10); @@ -520,7 +577,8 @@ export final class Double extends Floating implements Comparable, JSONab * @remark * Implemented as native function, @see `toExponential()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#673). * - * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.toexponential + * ECMA reference: https://tc39.es/ecma262/multipage/doubles-and-dates.html#sec-double.prototype.toexponential + * @tag common */ public native toExponential(d: double): String; @@ -528,8 +586,9 @@ export final class Double extends Floating implements Comparable, JSONab * toExponential() returns std.core.String representing the underlying double in exponential notation * * @returns the result of conversion + * @tag common */ - public toExponential():String { + public toExponential(): String { return this.toExponential(0); } @@ -550,6 +609,7 @@ export final class Double extends Floating implements Comparable, JSONab * Implemented as native function, @see `toPrecision()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#683). * * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.toprecision + * @tag common */ public native toPrecision(d: double): String; @@ -559,6 +619,7 @@ export final class Double extends Floating implements Comparable, JSONab * to spec * * @returns the result of conversion + * @tag common */ public toPrecision(): String { return this.toString(); @@ -584,6 +645,7 @@ export final class Double extends Floating implements Comparable, JSONab * Implemented as native function, @see `toFixed()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#693). * * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.tofixed + * @tag common */ public native toFixed(d: double): String; @@ -591,6 +653,7 @@ export final class Double extends Floating implements Comparable, JSONab * toFixed(double) returns std.core.String representing the underlying double using fixed-point notation * * @returns the result of conversion + * @tag common */ public toFixed(): String { return this.toFixed(0); @@ -601,6 +664,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param bits bits to convert * * @returns double - converted value + * @tag arkts */ public static native bitCastFromLong(bits: long): double @@ -609,6 +673,7 @@ export final class Double extends Floating implements Comparable, JSONab * @param val value to convert * * @returns long - bit representation + * @tag arkts */ public static native bitCastToLong(val: double): long @@ -620,6 +685,7 @@ export final class Double extends Floating implements Comparable, JSONab * @throws JSONTypeError if json does not encode a valid double * * @returns Double - double value decoded from JSON + * @tag arkts */ static createFromJSONValue(json: JSONValue): Double { if (json instanceof JSONNumber) { @@ -627,4 +693,13 @@ export final class Double extends Floating implements Comparable, JSONab } throw new JSONTypeError("Cannot create Double from JSON", json) } + /** + * Returns the value of this double + * + * @returns the value of this double + * @tag common + */ + public valueOf(): double { + return this.value + } } diff --git a/plugins/ets/stdlib/std/core/Field.ets b/plugins/ets/stdlib/std/core/Field.ets index b9c11d1f5..d726a6de8 100644 --- a/plugins/ets/stdlib/std/core/Field.ets +++ b/plugins/ets/stdlib/std/core/Field.ets @@ -15,6 +15,10 @@ package std.core; +/** + * Represents field of class or interface + * + */ export final class Field extends Object { private td: TypeDesc private ownerTD: TypeDesc @@ -24,6 +28,11 @@ export final class Field extends Object { private constructor () {} + /** + * Returns type of this field + * + * @returns {@link Type} of this field + */ public getType(): Type { return Type.resolve(this.td) } @@ -77,4 +86,4 @@ export final class Field extends Object { public override toString(): string { return this.getName() + ": " + this.getType().toString() } -} \ No newline at end of file +} diff --git a/plugins/ets/stdlib/std/core/Method.ets b/plugins/ets/stdlib/std/core/Method.ets index d5ad4835b..83a5abe56 100644 --- a/plugins/ets/stdlib/std/core/Method.ets +++ b/plugins/ets/stdlib/std/core/Method.ets @@ -18,6 +18,9 @@ package std.core; native function TypeAPIMethodInvoke(methodDesc: string, recv: NullishType, args: NullishType[]): NullishType native function TypeAPIMethodInvokeConstructor(methodDesc: string, args: NullishType[]): Object +/** + * Represents method of class or interface + */ export final class Method extends Object { private td: TypeDesc private name: string @@ -26,6 +29,11 @@ export final class Method extends Object { private constructor () {} + /** + * Returns function type of this method + * + * @returns method's {@link MethodType} + */ public getType(): MethodType { return Type.resolve(this.td) as MethodType } diff --git a/plugins/ets/stdlib/std/core/Parameter.ets b/plugins/ets/stdlib/std/core/Parameter.ets index e58145eea..cf81ae105 100644 --- a/plugins/ets/stdlib/std/core/Parameter.ets +++ b/plugins/ets/stdlib/std/core/Parameter.ets @@ -15,6 +15,9 @@ package std.core; +/** + * Represents parameter of function type + */ export final class Parameter extends Object { private td: TypeDesc private name: string diff --git a/plugins/ets/stdlib/std/core/String.ets b/plugins/ets/stdlib/std/core/String.ets index 9e859cf70..1a4357545 100644 --- a/plugins/ets/stdlib/std/core/String.ets +++ b/plugins/ets/stdlib/std/core/String.ets @@ -1485,7 +1485,7 @@ export final class String extends Object implements Comparable, JSONable this.toLocaleUpperCase(""); } - public match(regexp: String) : String[] { + public match(regexp: String): RegExpMatchArray | null { return this.match(new RegExp(regexp)); } @@ -1499,20 +1499,20 @@ export final class String extends Object implements Comparable, JSONable * but capturing groups are not included * Otherwise, only the first complete match and its related capturing groups are returned */ - public match(regexp: RegExp) : String[] { + public match(regexp: RegExp): RegExpMatchArray | null { let isGlobal = regexp.global; if (!isGlobal) { - return regexp.exec(this).result; + return regexp.exec(this); } regexp.lastIndex = 0; let matches = new ArrayAsListString(); while (true) { let result = regexp.exec(this); - if (!result.isCorrect) { - return matches.toArray(); + if (result == null) { + return new RegExpMatchArray(result!.index, result!.input, matches.toArray()); } else { - let matchStr = result.get(0); + let matchStr = result!.get(0); matches.pushBack(matchStr); if (matchStr == "") { regexp.lastIndex = RegExp.advanceStringIndex(this, regexp.lastIndex, regexp.unicode); diff --git a/plugins/ets/stdlib/std/core/Type.ets b/plugins/ets/stdlib/std/core/Type.ets index a2339d2a1..21e4e6ba5 100644 --- a/plugins/ets/stdlib/std/core/Type.ets +++ b/plugins/ets/stdlib/std/core/Type.ets @@ -161,9 +161,19 @@ export class AccessModifier { private constructor() {} } +/** + * Represents abstract Type + */ export abstract class Type extends Object { internal td: TypeDesc + /** + * Resolves type by its type descriptor + * + * @param td type descriptor + * + * @returns instance with corresponging type descriptor + */ public static resolve(td: TypeDesc): Type { let kind = TypeAPIGetTypeKind(td) & TypeKindMask switch (kind) { @@ -211,39 +221,95 @@ export abstract class Type extends Object { case TypeKind.ENUM: return new EnumType(td) default: - // TODO(shumilov-petr): unknown type, need exception + // TODO(shumilov-petr): unknown type, need error assert(false) } } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: boolean): Type { return BooleanType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: char): Type { return CharType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: byte): Type { return ByteType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: short): Type { return ShortType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: int): Type { return IntType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: long): Type { return LongType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: float): Type { return FloatType.VAL } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: double): Type { return DoubleType.VAL } @@ -261,76 +327,195 @@ export abstract class Type extends Object { return BooleanType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Char): Type { return CharType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Byte): Type { return ByteType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Short): Type { return ShortType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Int): Type { return IntType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Long): Type { return LongType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Float): Type { return FloatType.REF } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Double): Type { return DoubleType.REF } // ----- + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: string): Type { return StringType.REF } // ----- + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: boolean[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.BOOLEAN) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: char[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.CHAR) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: byte[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.BYTE) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: short[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.SHORT) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: int[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.INT) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: long[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.LONG) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: float[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.FLOAT) } + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: double[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v), ValueTypeDesc.DOUBLE) } // ----- + /** + * Returns Type of value + * + * @param v value + * + * @returns Type instance of this value + */ public static of(v: Object[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v)) } @@ -380,6 +565,11 @@ export abstract class Type extends Object { public abstract getName(): string + /** + * Returns literal of type if exists + * + * @returns type literal + */ public abstract getLiteral(): string public override toString(): string { @@ -390,6 +580,9 @@ export abstract class Type extends Object { } } +/** + * Represents null type + */ export final class NullType extends Type { public static readonly REF: NullType = new NullType() @@ -397,28 +590,62 @@ export final class NullType extends Type { this.td = TypeAPIGetTypeDescriptor(null) } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns type name + */ public override getName(): string { return "null" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { return "null" } + /** + * Checks for equality this instance with provided object, treated as a DoubleType + * + * @param to object to be checked against + * + * @returns true if object also has NullType + */ public override equals(to: NullishType): boolean { - return (to instanceof NullType); + return to instanceof NullType } internal override convertObject(obj: NullishType): NullishType { @@ -436,26 +663,58 @@ export final class UndefinedType extends Type { this.td = UndefinedTD } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type if exists and empty string otherwise + * + * @returns type name + */ public override getName(): string { return "undefined" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { return "undefined" } + /** + * Checks for equality this instance with provided object, treated as a UndefinedType + * + * @param to object to be checked against + * + * @returns true if object also has UndefinedType + */ public override equals(to: NullishType): boolean { return to instanceof UndefinedType } @@ -465,6 +724,9 @@ export final class UndefinedType extends Type { } } +/** + * Represents void type + */ export final class VoidType extends Type { public static readonly REF: VoidType = new VoidType() @@ -472,26 +734,58 @@ export final class VoidType extends Type { this.td = TypeAPIGetTypeDescriptor(Void) } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type if exists and empty string otherwise + * + * @returns type name + */ public override getName(): string { return "void" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { return "void" } + /** + * Checks for equality this instance with provided object, treated as a VoidType + * + * @param to object to be checked against + * + * @returns true if object also has VoidType + */ public override equals(to: NullishType): boolean { return to instanceof VoidType } @@ -504,7 +798,11 @@ export final class VoidType extends Type { } } - +/** + * Represents char type + * + * @note Boxed Char and primitive char both have CharType + */ export final class CharType extends Type { public static readonly VAL: CharType = new CharType(ValueTypeDesc.CHAR, true) public static readonly REF: CharType = new CharType(TypeAPIGetTypeDescriptor(new Char()), false) @@ -516,18 +814,41 @@ export final class CharType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -535,6 +856,11 @@ export final class CharType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "char" @@ -555,7 +881,11 @@ export final class CharType extends Type { } } - +/** + * Represents boolean type + * + * @note Boxed Boolean and primitive boolean both have BooleanType + */ export final class BooleanType extends Type { public static readonly VAL: BooleanType = new BooleanType(ValueTypeDesc.BOOLEAN, true) public static readonly REF: BooleanType = new BooleanType(TypeAPIGetTypeDescriptor(new Boolean()), false) @@ -567,18 +897,41 @@ export final class BooleanType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -586,6 +939,11 @@ export final class BooleanType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "boolean" @@ -606,6 +964,11 @@ export final class BooleanType extends Type { } } +/** + * Represents byte type + * + * @note Boxed Byte and primitive byte both have ByteType + */ export final class ByteType extends Type { public static readonly VAL: ByteType = new ByteType(ValueTypeDesc.BYTE, true) public static readonly REF: ByteType = new ByteType(TypeAPIGetTypeDescriptor(new Byte()), false) @@ -617,18 +980,41 @@ export final class ByteType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -636,6 +1022,11 @@ export final class ByteType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "byte" @@ -659,7 +1050,11 @@ export final class ByteType extends Type { } } - +/** + * Represents short type + * + * @note Boxed Short and primitive short both have ShortType + */ export final class ShortType extends Type { public static readonly VAL: ShortType = new ShortType(ValueTypeDesc.SHORT, true) public static readonly REF: ShortType = new ShortType(TypeAPIGetTypeDescriptor(new Short()), false) @@ -671,18 +1066,41 @@ export final class ShortType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -690,6 +1108,11 @@ export final class ShortType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "short" @@ -697,6 +1120,14 @@ export final class ShortType extends Type { return "Short" } + /** + * Checks for equality this instance with provided object, treated as a ShortType + * + * @param to object to be checked against + * + * @returns true if object also has ShortType and + * this type and other type both are reference or value + */ public override equals(to: NullishType): boolean { return to instanceof ShortType && this.isValue != (to as ShortType).isReference() } @@ -713,7 +1144,11 @@ export final class ShortType extends Type { } } - +/** + * Represents int type + * + * @note Boxed Int and primitive int both have IntType + */ export final class IntType extends Type { public static readonly VAL: IntType = new IntType(ValueTypeDesc.INT, true) public static readonly REF: IntType = new IntType(TypeAPIGetTypeDescriptor(new Int()), false) @@ -725,18 +1160,41 @@ export final class IntType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type if exists and empty string otherwise + * + * @throws error in case of absence of name + * + * @returns type name + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -744,6 +1202,11 @@ export final class IntType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "int" @@ -751,6 +1214,14 @@ export final class IntType extends Type { return "Int" } + /** + * Checks for equality this instance with provided object, treated as a IntType + * + * @param to object to be checked against + * + * @returns true if object also has IntType and + * this type and other type both are reference or value + */ public override equals(to: NullishType): boolean { return to instanceof IntType && this.isValue != (to as IntType).isReference() } @@ -767,7 +1238,11 @@ export final class IntType extends Type { } } - +/** + * Represents long type + * + * @note Boxed Long and primitive long both have LongType + */ export final class LongType extends Type { public static readonly VAL = new LongType(ValueTypeDesc.LONG, true) public static readonly REF = new LongType(TypeAPIGetTypeDescriptor(new Long()), false) @@ -779,18 +1254,41 @@ export final class LongType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type if exists and empty string otherwise + * + * @throws error in case of absence of name + * + * @returns type name + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -798,6 +1296,11 @@ export final class LongType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "long" @@ -805,6 +1308,14 @@ export final class LongType extends Type { return "Long" } + /** + * Checks for equality this instance with provided object, treated as a LongType + * + * @param to object to be checked against + * + * @returns true if object also has LongType and + * this type and other type both are reference or value + */ public override equals(to: NullishType): boolean { return to instanceof LongType && this.isValue != (to as LongType).isReference() } @@ -821,7 +1332,11 @@ export final class LongType extends Type { } } - +/** + * Represents float type + * + * @note Boxed Float and primitive float both have FloatType + */ export final class FloatType extends Type { public static readonly VAL: FloatType = new FloatType(ValueTypeDesc.FLOAT, true) public static readonly REF: FloatType = new FloatType(TypeAPIGetTypeDescriptor(new Float()), false) @@ -833,18 +1348,41 @@ export final class FloatType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -852,6 +1390,11 @@ export final class FloatType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "float" @@ -859,6 +1402,14 @@ export final class FloatType extends Type { return "Float" } + /** + * Checks for equality this instance with provided object, treated as a FloatType + * + * @param to object to be checked against + * + * @returns true if object also has FloatType and + * this type and other type both are reference or value + */ public override equals(to: NullishType): boolean { return to instanceof FloatType && this.isValue != (to as FloatType).isReference() } @@ -875,7 +1426,11 @@ export final class FloatType extends Type { } } - +/** + * Represents double type + * + * @note Boxed Double and primitive double both have DoubleType + */ export final class DoubleType extends Type { public static readonly VAL: DoubleType = new DoubleType(ValueTypeDesc.DOUBLE, true) public static readonly REF: DoubleType = new DoubleType(TypeAPIGetTypeDescriptor(new Double()), false) @@ -887,18 +1442,41 @@ export final class DoubleType extends Type { this.isValue = isValue } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return !this.isValue } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return !this.isValue } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ + //TODO(kirill-mitkin): add error public override getName(): string { if (this.isValue) { return "" @@ -906,6 +1484,11 @@ export final class DoubleType extends Type { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { if (this.isValue) { return "double" @@ -913,6 +1496,14 @@ export final class DoubleType extends Type { return "Double" } + /** + * Checks for equality this instance with provided object, treated as a DoubleType + * + * @param to object to be checked against + * + * @returns true if object also has DoubleType and + * this type and other type both are reference or value + */ public override equals(to: NullishType): boolean { return to instanceof DoubleType && this.isValue != (to as DoubleType).isReference() } @@ -929,7 +1520,9 @@ export final class DoubleType extends Type { } } - +/** + * Represents type of classes + */ export final class ClassType extends Type { private readonly attrs: int @@ -938,43 +1531,115 @@ export final class ClassType extends Type { this.attrs = TypeAPIGetClassAttributes(td) } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type + * + * @returns type name + */ public override getName(): string { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { // TODO(shumilov-petr): not implemented return "class{...}" } + /** + * Checks for equality this instance with provided object, treated as a ClassType + * + * @param to object to be checked against + * + * @returns true if object also has ClassType and their names are the same + */ public override equals(to: NullishType): boolean { return (to instanceof ClassType) && (to as ClassType).td == this.td } + /** + * Returns base type of this class + * If this type is the type of Object class then returns this + * + * @returns base type of class + */ public getBaseType(): ClassType { return Type.resolve(TypeAPIGetBaseType(this.td)) as ClassType } + /** + * Returns number of direct superinterfaces of this class + * + * @returns number of interfaces that was implemented by this class directly + */ public getInterfacesNum(): long { return TypeAPIGetInterfacesNum(this.td) } + /** + * Returns ith direct superinterface of this class + * + * @param i index + * + * @throws error when i greater then num of interfaces + * + * @returns type of ith superinterface + */ public getInterface(i: long): InterfaceType { return Type.resolve(TypeAPIGetInterface(this.td, i)) as InterfaceType } + /** + * Returns number of all fields + * including static, instance and also fields of all its superclasses + * + * @returns number of fields + * + * @example + * + * ``` + * class A { + * a : int + * } + * + * class B extends A { + * b : int + * } + * ``` + * let bType class type of B, then `bType.getFieldsNum()` returns 2 + * Note that Object class also is super class of B + */ public getFieldsNum(): long { return TypeAPIGetFieldsNum(this.td) } @@ -983,6 +1648,16 @@ export final class ClassType extends Type { return TypeAPIGetOwnFieldsNum(this.td) } + /** + * Returns ith Field of this class + * + * @param i index (using flat semantic) + * + * @throws error when i greater then number of fields + * + * @returns ith Field + */ + //TODO(kirill-mitkin): add error public getField(i: long): Field { return TypeAPIGetField(this.td, i) } @@ -991,26 +1666,85 @@ export final class ClassType extends Type { return TypeAPIGetOwnField(this.td, i) } + /** + * Find Field by name + * + * @param name name of field + * + * @throws error when class doesn't have field with this name + * + * @returns Field instance with this name + */ + //TODO(kirill-mitkin): add error public getFieldByName(name: string): Field { return TypeAPIGetFieldByName(this.td, name) } + /** + * Returns number of methods of this class + * including static methods and methods of super classes + * @example + * + * ``` + * class A { + * a(): void {} + * } + * + * class B extends A { + * b(): void {} + * } + * ``` + * let bType class type of B, then `bType.getMethodsNum()` returns at least 2 + * Note that Object class also super class of B + * @returns number of methods + */ public getMethodsNum(): long { return TypeAPIGetMethodsNum(this.td) } + /** + * Returns ith Method of this class + * + * @param i index (using flat semantic) + * + * @throws error when i greater then number of methods + * + * @returns ith method + */ + //TODO(kirill-mitkin): add error public getMethod(i: long): Method { return TypeAPIGetMethod(this.td, i) } + /** + * Returns number of constructors of this class + * Note that constructors of super class isn't considered as constructors of this class + * + * @returns number of constructors + */ public getConstructorsNum(): long { return TypeAPIGetConstructorsNum(this.td) } + /** + * Returns ith constructor of this class + * + * @param i index + * + * @throws error then i greater then number of constructors + * + * @returns {@link Method} instance representing ith constructor + */ + //TODO(kirill-mitkin): add error public getConstructor(i: long): Method { return TypeAPIGetConstructor(this.td, i) } + /** + * Checks for existence of empty constructor of this class + * + * @returns true if there is empty constructor of this class + */ public hasEmptyConstructor(): boolean { let num = this.getConstructorsNum() for (let i = 0; i < num; i++) { @@ -1036,16 +1770,36 @@ export final class ClassType extends Type { return false } + /** + * Returns number of type parameters of this class + * + * @returns number of type parameters + */ public getTypeParametersNum(): long { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") } + /** + * Returns ith type parameter of this class + * + * @param i index + * + * @throws error then i greater then number of type parameters + * + * @returns TODO(kirill-mitkin): we cannot return concrete type in this method + */ public getTypeParameter(i: long): Type { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") } + /** + * Makes instance of this type by invoking + * empty constructor of this class + * + * @throws error when class doesn't have an empty constructor + */ public make(): Object { const emptyArgs = new NullishType[0] return this.make(emptyArgs) @@ -1146,33 +1900,68 @@ export final class ClassType extends Type { } - +/** + * Represents interface type + */ export final class InterfaceType extends Type { public constructor(td: TypeDesc) { this.td = td } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type + * + * @returns name of type + */ public override getName(): string { return TypeAPIGetTypeName(this.td) } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { // TODO(shumilov-petr): not implemented return "interface{...}" } + /** + * Checks for equality this instance with provided object, treated as a InterfaceType + * + * @param to object to be checked against + * + * @returns true if object also has InterfaceType and + * their names are the same + */ public override equals(to: NullishType): boolean { return to instanceof InterfaceType && this.td == (to as InterfaceType).td } @@ -1196,21 +1985,62 @@ export final class InterfaceType extends Type { return Type.resolve(TypeAPIGetInterface(this.td, i)) as InterfaceType } + /** + * Returns number of methods of this interface + * including static methods and methods of super interfaces + * @example + * + * ``` + * class A { + * a(): void {} + * } + * + * class B extends A { + * b(): void {} + * } + * ``` + * let bType interface type of B, then `bType.getMethodsNum()` returns at least 2 + * Note that Object class also super class of B + * @returns number of methods + */ public getMethodsNum(): long { // TODO(shumilov-petr): not implemented return 0 } + /** + * Returns ith Method of this interface + * + * @param i index (using flat semantic) + * + * @throws error when i greater then number of methods + * + * @returns ith method + */ public getMethod(i: long): Method { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") } + /** + * Returns number of type parameters of this class + * + * @returns number of type parameters + */ public getTypeParametersNum(): long { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") } + /** + * Returns ith type parameter of this class + * + * @param i index + * + * @throws error then i greater then number of type parameters + * + * @returns TODO(kirill-mitkin): we cannot return concrete type in this method + */ public getTypeParameter(i: long): Type { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") @@ -1262,7 +2092,9 @@ export final class InterfaceType extends Type { } } - +/** + * Represents array type + */ export final class ArrayType extends Type { private elemTD: TypeDesc @@ -1333,36 +2165,94 @@ export final class ArrayType extends Type { return ArrayType.getInstance(td, TypeAPIGetArrayElementType(td)) } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return false } + /** + * Returns name of type + * + * @throws error in case of absence of name + * + * @returns name of type + */ public override getName(): string { return "" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { return this.getElementType().toString() + "[]" } + /** + * Checks for equality this instance with provided object, treated as a ArrayType + * + * @param to object to be checked against + * + * @returns true if object also has ArrayType and + * their element types are the same + */ public override equals(to: NullishType): boolean { return to instanceof ArrayType && (to as ArrayType).getElementType().equals(this.getElementType()) } + /** + * Returns element type of this array + * + * @returns element type + */ public getElementType(): Type { return Type.resolve(this.elemTD) } - public make(length : long): Object { + /** + * Makes instance of this array with provided length + * Each element are instantiated using default value + * If element type is class value then empty constructor are called + * + * @param length of array + * + * @throws error if element type doesn't have default value + * + * @returns new instance of array + */ + public make(length: long): Object { let td = this.getElementType() + let hasDefaultValue = true + if (td instanceof ClassType) { + hasDefaultValue &= (td as ClassType).hasEmptyConstructor() + } + if (hasDefaultValue) { + throw new Error("Element type of " + this.toString() + " doesn't have default value") + } return TypeAPIMakeArrayInstance(this.elemTD, length) } @@ -1413,7 +2303,11 @@ export final class TupleType extends Type { } } - +/** + * Represents function type + * + * @note lambdas, functions and methods have function type + */ export abstract class FunctionType extends Type { private readonly attrs: int @@ -1422,59 +2316,138 @@ export abstract class FunctionType extends Type { this.attrs = TypeAPIGetFunctionAttributes(td) } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return false } + /** + * Returns name of type + * + * @returns name of type + */ public override getName(): string { return "" } + /** + * Returns return type of function type + * + * @returns result type + */ public getResultType(): Type { return Type.resolve(TypeAPIGetResultType(this.td)) } + /** + * Checks whether function type throws some exception + * + * @returns true if function type throws some exception + */ public isThrowing(): boolean { return (this.attrs & Attributes.THROWING) != 0 } + /** + * Checks whether function type has native modifier + * + * @returns true if function type has native modifier + */ public isNative(): boolean { return (this.attrs & Attributes.NATIVE) != 0 } + /** + * Checks whether function type has async modifier + * + * @returns true if function type has async modifier + */ public isAsync(): boolean { return (this.attrs & Attributes.ASYNC) != 0 } + /** + * Checks whether function result type is never + * + * @returns true if function result type is never + */ public isNeverResult(): boolean { return (this.attrs & Attributes.NEVERRESULT) != 0 } + /** + * Checks for equality this instance with provided object, treated as a FunctionType + * + * @param to object to be checked against + * + * @returns true if object also has FunctionType and + * they both has same signatures + */ public override equals(to: NullishType): boolean { return (to! instanceof FunctionType) && (to! as FunctionType).td == this.td } + /** + * Returns number of parameters + * For static methods reciever type counted as parameter + * For instance methods reciever type isn't counted as parameter + * + * @returns number of parameters + */ public getParametersNum(): long { return TypeAPIGetParametersNum(this.td) } + /** + * Returns ith parameter of function type + * + * @return Parameter, corresponding ith parameter in signature + */ public getParameter(i: long): Parameter { return TypeAPIGetParameter(this.td, i) } + /** + * Returns number of type parameters of this class + * + * @returns number of type parameters + */ public getTypeParametersNum(): long { // TODO(shumilov-petr): not implemented return 0 } + /** + * Returns ith type parameter of this class + * + * @param i index + * + * @throws error then i greater then number of type parameters + * + * @returns TODO(kirill-mitkin): we cannot return concrete type in this method + */ public getTypeParameter(i: long): Type { // TODO(shumilov-petr): not implemented throw new Error("not implemented") @@ -1492,6 +2465,11 @@ export final class LambdaType extends FunctionType { return "$lambda_signature" } + /** + * Make instance of function with this function type + * + * @returns instance with this function type + */ public make(): Object { // TODO(kprokopenko): not implemented throw new Error("Not implemented") @@ -1558,7 +2536,9 @@ export final class MethodType extends FunctionType { } } - +/** + * Represents string type + */ export final class StringType extends Type { public static readonly REF: StringType = new StringType() @@ -1566,28 +2546,61 @@ export final class StringType extends Type { this.td = TypeAPIGetTypeDescriptor("") } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return true } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return false } + /** + * Returns name of type + * + * @returns type name + */ public override getName(): string { // TODO(shumilov-petr): not implemented return "" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { // TODO(shumilov-petr): not implemented return "string" } + + /** + * Checks for equality this instance with provided object, treated as a StringType + * + * @param to object to be checked against + * + * @returns true if object also has StringType + */ public override equals(to: NullishType): boolean { return to instanceof StringType } @@ -1601,7 +2614,9 @@ export final class StringType extends Type { } } - +/** + * Represents enum type + */ export final class EnumType extends Type { internal constructor(td: TypeDesc) { this.td = td @@ -1618,28 +2633,60 @@ export final class EnumType extends Type { return this.getName() == rt.getName() } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return false } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return true } + /** + * Returns name of type + * + * @returns type name + */ public override getName(): string { // TODO(shumilov-petr): not implemented return "" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { // TODO(shumilov-petr): not implemented return "enum {...}" } + /** + * Checks for equality this instance with provided object, treated as a EnumType + * + * @param to object to be checked against + * + * @returns true if object also has EnumType and their names are the same + */ public override equals(to: NullishType): boolean { // TODO(shumilov-petr): not implemented return false @@ -1675,7 +2722,9 @@ export final class EnumType extends Type { } } - +/** + * Represents union type + */ export final class UnionType extends Type { internal constructor(td: TypeDesc) { this.td = td @@ -1705,23 +2754,48 @@ export final class UnionType extends Type { return false } + /** + * Checks whether type is primitive or composite + * + * @returns true if type is primitive and false otherwise + */ public override isPrimitive(): boolean { return false } + /** + * Checks whether type is reference or composite + * + * @returns true if type is reference and false otherwise + */ public override isReference(): boolean { return true } + /** + * Checks whether type has name + * + * @returns true if type has name + */ public override hasName(): boolean { return false } + /** + * Returns name of type + * + * @returns type name + */ public override getName(): string { // TODO(shumilov-petr): not implemented return "" } + /** + * Returns literal of type if exists + * + * @returns type literal + */ public override getLiteral(): string { // TODO(shumilov-petr): not implemented return "(... | ...)" @@ -1737,6 +2811,13 @@ export final class UnionType extends Type { throw new Error("Not implemented") } + /** + * Checks for equality this instance with provided object, treated as a UnionType + * + * @param to object to be checked against + * + * @returns true if object also has UnionType and their cases are the same + */ public override equals(to: NullishType): boolean { // TODO(shumilov-petr): not implemented return false diff --git a/plugins/ets/stdlib/std/core/Value.ets b/plugins/ets/stdlib/std/core/Value.ets index 834d03b61..69305fe35 100644 --- a/plugins/ets/stdlib/std/core/Value.ets +++ b/plugins/ets/stdlib/std/core/Value.ets @@ -91,7 +91,17 @@ native function ValueAPISetElementLong(obj: Object, i: long, val: long): void native function ValueAPISetElementObject(obj: Object, i: long, val: Object): void +/** + * Represents abstract value + */ export abstract class Value extends Object { + /** + * Returns value of this object + * + * @param o object instance + * + * @returns {@link Value} of this object + */ public static of(o: NullishType): Value { let t = Type.of(o) if (t instanceof NullType) { @@ -126,6 +136,10 @@ export abstract class Value extends Object { public abstract getType(): Type } + +/** + * Represents value of object of class type + */ export final class ClassValue extends Value { private typ: ClassType private data: Object @@ -143,10 +157,24 @@ export final class ClassValue extends Value { this.data = data } + /** + * Returns number of fields of this value + * + * @returns number of fields + */ public getFieldsNum(): long { return this.typ.getFieldsNum() } + /** + * Returns ith field of value + * + * @param i index + * + * @throws error when i greater then field's number + * + * @returns field {@link Value} + */ public getField(i: long): Value { let ft = this.typ.getField(i).getType() if (!ft.isReference()) { @@ -171,6 +199,16 @@ export final class ClassValue extends Value { return Value.of(ValueAPIGetFieldObject(this.data, i)) } + /** + * Sets field value by it's name + * + * @param name of field + * + * @param val @{link Value} + * + * @throws error if this value doesn't have field with {@link name} + * or type of {@link val} doesn't assignable to type of this value + */ public setFieldByName(name: string, val: Value) { let ft = this.typ.getFieldByName(name).getType() let vt = val.getType() @@ -204,6 +242,16 @@ export final class ClassValue extends Value { } } + /** + * Sets field value by it's index + * + * @param i of field + * + * @param val @{link Value} + * + * @throws error if this value doesn't have field with {@link index}'th index + * or type of {@link val} doesn't assignable to type of this value + */ public setField(i: long, val: Value) { let ft = this.typ.getField(i).getType() let vt = val.getType() @@ -239,6 +287,9 @@ export final class ClassValue extends Value { } +/** + * Represents array value + */ export final class ArrayValue extends Value { private typ: ArrayType private data: Object @@ -256,6 +307,15 @@ export final class ArrayValue extends Value { this.data = data } + /** + * Sets i'th element of array + * + * @param i index + * + * @param val {@link Value} to be set + * + * @throws error if of {@link val} cannot be assign to i'th element of array + */ public setElementByIndex(i: long, val: Value) { let et = this.typ.getElementType() let vt = val.getType() @@ -290,6 +350,9 @@ export final class ArrayValue extends Value { } } +/** + * Represents boolean value + */ export final class BooleanValue extends Value { private typ: BooleanType private data: boolean @@ -312,6 +375,9 @@ export final class BooleanValue extends Value { } } +/** + * Represents byte value + */ export final class ByteValue extends Value { private typ: ByteType private data: byte @@ -334,6 +400,9 @@ export final class ByteValue extends Value { } } +/** + * Represents short value + */ export final class ShortValue extends Value { private typ: ShortType private data: short @@ -356,6 +425,9 @@ export final class ShortValue extends Value { } } +/** + * Represents char value + */ export final class CharValue extends Value { private typ: CharType private data: char @@ -378,6 +450,9 @@ export final class CharValue extends Value { } } +/** + * Represents int value + */ export final class IntValue extends Value { private typ: IntType private data: int @@ -400,6 +475,9 @@ export final class IntValue extends Value { } } +/** + * Represents float value + */ export final class FloatValue extends Value { private typ: FloatType private data: float @@ -422,6 +500,9 @@ export final class FloatValue extends Value { } } +/** + * Represents double value + */ export final class DoubleValue extends Value { private typ: DoubleType private data: double @@ -444,6 +525,9 @@ export final class DoubleValue extends Value { } } +/** + * Represents long value + */ export final class LongValue extends Value { private typ: LongType private data: long @@ -466,6 +550,9 @@ export final class LongValue extends Value { } } +/** + * Represents string value + */ export final class StringValue extends Value { private typ: StringType private data: String @@ -484,6 +571,9 @@ export final class StringValue extends Value { } } +/** + * Represents null value + */ export final class NullValue extends Value { public static readonly INSTANCE = new NullValue() @@ -494,6 +584,9 @@ export final class NullValue extends Value { internal constructor() {} } +/** + * Represents undefined value + */ export final class UndefinedValue extends Value { public static readonly INSTANCE = new UndefinedValue() diff --git a/plugins/ets/tests/ets_func_tests/std/core/std_core_regexp_constructor_test.ets b/plugins/ets/tests/ets_func_tests/std/core/std_core_regexp_constructor_test.ets new file mode 100644 index 000000000..49e884877 --- /dev/null +++ b/plugins/ets/tests/ets_func_tests/std/core/std_core_regexp_constructor_test.ets @@ -0,0 +1,90 @@ +function main(): int { + let failCounter: int = 0; + let testResult: int = 0; + + let regExpObj10 = new RegExp("Brawn Fox"); + testResult = checkTestResult(regExpObj10, "Brawn Fox", "", false, false, false) + printTestVerdict(testResult, "test10") + failCounter += testResult + + let regExpObj20 = new RegExp(""); + testResult = checkTestResult(regExpObj20, "(?:)", "", false, false, false) + printTestVerdict(testResult, "test20") + failCounter += testResult + + let regExpObj30 = new RegExp("Brawn", "gsu"); + testResult = checkTestResult(regExpObj30, "Brawn", "gsu", true, true, true) + printTestVerdict(testResult, "test30") + failCounter += testResult + + let regExpObj40 = new RegExp("Brawn", "g"); + testResult = checkTestResult(regExpObj40, "Brawn", "g", true, false, false) + printTestVerdict(testResult, "test40") + failCounter += testResult + + let regExpObj50 = new RegExp("Brawn", "s"); + testResult = checkTestResult(regExpObj50, "Brawn", "s", false, false, true) + printTestVerdict(testResult, "test50") + failCounter += testResult + + let regExpObj60 = new RegExp("Brawn", "u"); + testResult = checkTestResult(regExpObj60, "Brawn", "u", false, true, false) + printTestVerdict(testResult, "test60") + failCounter += testResult + + let regExpObj70 = new RegExp("Brawn", "gu"); + testResult = checkTestResult(regExpObj70, "Brawn", "gu", true, true, false) + printTestVerdict(testResult, "test70") + failCounter += testResult + + let regExpObj80 = new RegExp("Brawn", "gs"); + testResult = checkTestResult(regExpObj80, "Brawn", "gs", true, false, true) + printTestVerdict(testResult, "test80") + failCounter += testResult + + let regExpObj90 = new RegExp("Brawn", "su"); + testResult = checkTestResult(regExpObj90, "Brawn", "su", false, true, true) + printTestVerdict(testResult, "test90") + failCounter += testResult + + if (failCounter > 0) return 1 + return 0; +} + +function checkTestResult(actual : RegExp, pattern: String, flags: String, global : boolean, unicode : boolean, dotAll: boolean) : int { + let checkResult : boolean = true; + if (!actual.source.equals(pattern)) { + console.println("Source " + actual.source + " is not equal expected " + pattern); + checkResult = false; + } + if (!actual.flags.equals(flags)) { + console.println("Flags " + actual.flags + " is not equal expected " + flags); + checkResult = false; + } + + if (actual.global != global) { + console.println("Global " + actual.global + " is not equal expected " + global); + checkResult = false; + } + if (actual.unicode != unicode) { + console.println("Unicode " + actual.unicode + " is not equal expected " + unicode); + checkResult = false; + } + if (actual.dotAll != dotAll) { + console.println("dotAll " + actual.dotAll + " is not equal expected " + dotAll); + checkResult = false; + } + + if (!checkResult) return 1; + return 0; +} + +function printTestVerdict(flag: int, testName: String) { + if (flag == 0) { + console.println(testName + " : PASSED") + + } else { + console.println(testName + " : FAILED") + } +} + diff --git a/plugins/ets/tests/micro-benchmarks/CMakeLists.txt b/plugins/ets/tests/micro-benchmarks/CMakeLists.txt index a671048e1..cc11ccb5b 100644 --- a/plugins/ets/tests/micro-benchmarks/CMakeLists.txt +++ b/plugins/ets/tests/micro-benchmarks/CMakeLists.txt @@ -16,7 +16,7 @@ if (CMAKE_CROSSCOMPILING) endif() add_custom_target(ets_microbenchmarks COMMENT "Running ets micro-benchmarks") -add_dependencies(benchmarks ets_microbenchmarks) +# add_dependencies(benchmarks ets_microbenchmarks) set(INTERPRETER_ARGUMENTS_LIST "cpp") set(MODES_LIST "int" "jit" "aot") diff --git a/plugins/ets/tests/stdlib-templates/std/core/list.std_core_regexp_instance.yaml b/plugins/ets/tests/stdlib-templates/std/core/list.std_core_regexp_instance.yaml index d2ae92c5b..33568e55a 100644 --- a/plugins/ets/tests/stdlib-templates/std/core/list.std_core_regexp_instance.yaml +++ b/plugins/ets/tests/stdlib-templates/std/core/list.std_core_regexp_instance.yaml @@ -12,55 +12,357 @@ # limitations under the License. - { + object_type: RegExp, + object_constructor_signature: { pattern: String }, method_name: test, + method_nature: function, + result_type: boolean, + method_signature: { input: String }, + method_throws: "true", + method_signature_desc: { input: StringSimple }, + object_constructor_index_data: + { + test10: { pattern: '"foo"' }, + test20: { pattern: '"table"' }, + test30: { pattern: '"ball"'}, + test40: { pattern: '"foot"'}, + test50: { pattern: '"a*"' }, + test60: { pattern: '"a?"' }, + test70: { pattern: '"a?"'}, + test80: { pattern: '"a*"'}, + test90: { pattern: '"abc"' }, + }, + method_test_index_data: + { + test10: { input: '"table football"' }, + test20: { input: '"table football"' }, + test30: { input: '"table football"' }, + test40: { input: '"table football"' }, + test50: { input: '"aabaac"' }, + test60: { input: '"ab"' }, + test70: { input: '"b"'}, + test80: { input: '"a"'}, + test90: { input: '"ABC"' }, + }, + method_expected_data: + { + test10: "true", + test20: "true", + test30: "true", + test40: "true", + test50: "true", + test60: "true", + test70: "true", + test80: "true", + test90: "false", + }, + } +- { object_type: RegExp, - - init_object_data_type: "String[]", - init_object_data: '[ - "foo*", "ab", "(((ab)|(cd)|(de))|((ef)|(gh)|(jk)))", "(aa|ba|b|c)*", "a*", "a?", "(z)((a+)?(b+)?(c))*", "^abc", "abc$", "er\\B", - "d\\b", ".", "abc", "a(?=a)", "a(?=a)", "a\\n", "a(?!a)", "^a(?!a)", "(?=(a+))", "a(?=a(?=b))", - ".+:", "(?<=(? 0) return 1 - return 0; +{%- if item.method_expected_data_nature == "structure" %} +{%- for key, value in item.result_type_signature.items() %} +let {{.key }} : {{.item.result_type_signature[key]}} +{%- endfor %} +{% endif %} +{%- for test_name, test_data in item.method_test_index_data.items() %} +{%- if item.method_expected_exception is defined %} +testResult = checkTestResult({{.item.method_name}}{{.test_name|capitalize}}()) +{%- else %} +{%- if item.method_expected_data_nature == "structure" %} +{%- for key, value in item.method_expected_data[test_name].items() %} +{{.key }} = {{.value}} +{%- endfor %} +testResult = checkTestResult({{.item.method_name}}{{.test_name|capitalize}}(), {{.item.method_expected_data[test_name].keys() | join(", ")}}); +{%- else %} +let expectedData{{.test_name|capitalize}} : {{.item.result_type}} = {{.item.method_expected_data[test_name]}} +testResult = checkTestResult({{.item.method_name}}{{.test_name|capitalize}}(), expectedData{{.test_name|capitalize}}) +{%- endif %} +{%- endif %} +printTestVerdict(testResult, "{{.test_name}}") +failCounter += testResult +{% endfor %} +if (failCounter > 0) return 1 +return 0; +{%- endfilter %} } function printTestVerdict(flag: int, testName: String) { - if (flag == 0) { - console.println(testName + " : PASSED") - } else { - console.println(testName + " : FAILED") - } +{%- filter indent(width=4) %} +if (flag == 0) { +{%- filter indent(width=4) %} +console.println(testName + " : PASSED") +{% endfilter %} +} else { +{%- filter indent(width=4) %} +console.println(testName + " : FAILED") +{%- endfilter %} +} +{%- endfilter %} } diff --git a/tests/tests-u-runner/runner/plugins/ets/ets-func-tests-ignored.txt b/tests/tests-u-runner/runner/plugins/ets/ets-func-tests-ignored.txt index af134d128..f7648d668 100644 --- a/tests/tests-u-runner/runner/plugins/ets/ets-func-tests-ignored.txt +++ b/tests/tests-u-runner/runner/plugins/ets/ets-func-tests-ignored.txt @@ -69,6 +69,7 @@ std/core/std_core_char_static_Char_isWhiteSpace.ets std/core/std_core_char_static_Char_isWhiteSpace_003.ets ### Issue 12527 end ### Issue 12782 begin + std/core/std_core_array_exception_copyOf_ArrayIndexOutOfBoundsException_byte_array_int_int.ets std/core/std_core_array_exception_copyOf_ArrayIndexOutOfBoundsException_byte_array_int.ets std/core/std_core_array_exception_copyOf_ArrayIndexOutOfBoundsException_char_array_int_int.ets -- Gitee