diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index dd96ec4845dcf3744aa4c74a1cd6e57219c767f6..99c3114156d8dc993ebbe0b842ff41370b288fb7 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 26b5ec5eb32a84154b865cb5f4d00f8e8c123710..f762bac577d446be45307c4ba84f1963e52434e3 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 f27a99ee84c8117c4596b36c463012731c95b339..3b4af83ca051aec22028d135d737a053772b4f26 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 f985c5daa34632e309f42b8ac5d9cf2f2a72f1c4..116aa6c35f3cbae9c105ef0d63800b5d21f3ce79 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 a47f926c1869578bc29e6df141fceda9414b2510..f6386450d958fd04caa288f55bdc5e6a418b060c 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 b9c11d1f578f6c99f3ad2535ee27752cac595bf7..d726a6de8d13f4b86d22b38e2f2f0dd6b92016c0 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 d5ad4835b83165dbf7d93a1fdb25240f33792c11..83a5abe56b89f2fcc94bf6a1da1c7d03c90693f1 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 e58145eea59abeda53fdaaaa77d818d7f2927bbf..cf81ae1050836b07ee51a6074f951530c57552fa 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 9e859cf70701e6e2c0b011fd4759d39b790d0acb..1a4357545e55986209cff17b32ed69d3bbb30e50 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 a2339d2a107fbd6f592ec4d464f394333efc0159..21e4e6ba597a128060b3c3f58e45b62d0f8409ab 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 834d03b610a478c54b6a44ad8b84e6ea21125bb8..69305fe359c735466961df9b80098c21b19ec605 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 0000000000000000000000000000000000000000..49e884877e2a6e2340e0db35540d2ef52f1987b4 --- /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 a671048e169ccf54de126038b59209034da9c0a7..cc11ccb5b4c125d20ac9624571a7d755b9d83e8e 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 d2ae92c5b219fbd780a5e8796c6b49dc49fece68..33568e55a258ff44f067db79b4c2bc32ad2900d7 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 af134d128891ddef447c45f4d18dfb02da1e910d..f7648d6685e14cefe70cb235803460be09cbc7ae 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