diff --git a/README.md b/README.md new file mode 100755 index 0000000000000000000000000000000000000000..6f8cdb55a10cad991050127d5298fb63ec3b0362 --- /dev/null +++ b/README.md @@ -0,0 +1,165 @@ +# js_util_module Subsystems / components + +- [Introduction](#Introduction) +- [Directory](#Directory) +- [Description](#Description) + - [Interface description](#Interface description) + - [Instruction for use](#Instruction for use) + +- [Related warehouse](#Related warehouse) + +## Introduction +The interface of util is used for character Textencoder, TextDecoder and HelpFunction module.The TextEncoder represents a text encoder that accepts a string as input, encodes it in UTF-8 format, and outputs UTF-8 byte stream. The TextDecoder interface represents a text decoder. The decoder takes the byte stream as the input and outputs the Stirng string. HelpFunction is mainly used to callback and promise functions, write and output error codes, and format class strings. +## 目录 + +``` +base/compileruntime/js_util_module/ +├── Class:TextEncoder # TextEncoder class +│ ├── new TextEncoder() # create textencoder object +│ ├── encode() # encode method +│ ├── encoding # encoding property +│ └── encodeInto() # encodeInto method +├── Class:TextDecoder # TextDecoder class +│ ├── new TextDecoder() # create TextDecoder object +│ ├── decode() # decode method +│ ├── encoding # encoding property +│ ├── fatal # fatal property +│ └── ignoreBOM # ignoreBOM property +├── printf() # printf method +├── getErrorString() # getErrorString method +├── callbackWrapper() # callbackWrapper method +└── promiseWrapper() # promiseWrapper method +``` + +## Description + +### Interface description + + +| Interface name | Description | +| -------- | -------- | +| readonly encoding : string | Get the encoding format, only UTF-8 is supported. | +| encode(input : string) : Uint8Array | Input stirng string, encode and output UTF-8 byte stream. | +| encodeInto(input : string, dest : Uint8Array) : {read : number, written : number} | Enter the stirng string, dest represents the storage location after encoding, and returns an object, read represents the number of characters that have been encoded,and written represents the size of bytes occupied by the encoded characters. | +| constructor(encoding? : string, options? : {fatal? : boolean, ignoreBOM? : boolean}) | Constructor, the first parameter encoding indicates the format of decoding.The second parameter represents some attributes.Fatal in the attribute indicates whether an exception is thrown, and ignoreBOM indicates whether to ignore the bom flag. | +| readonly encoding : string | Get the set decoding format. | +| readonly fatal : boolean | Get the setting that throws the exception. | +| readonly ignoreBOM : boolean | Get whether to ignore the setting of the bom flag. | +| decode(input : ArrayBuffer | Input the data to be decoded, and solve the corresponding string character string.The first parameter input represents the data to be decoded, and the second parameter options represents a bool flag, which means that additional data will be followed. The default is false. | +| function printf(format: string, ...args: Object[]): string | The util.format() method returns a formatted string using the first argument as a printf-like format string which can contain zero or more format specifiers. | +| function getErrorString(errno: number): string | The geterrorstring () method uses a system error number as a parameter to return system error information. | +| function callbackWrapper(original: Function): (err: Object, value: Object) => void | Takes an async function (or a function that returns a Promise) and returns a function following the error-first callback style, i.e. taking an (err, value) => ... callback as the last argument. In the callback, the first argument will be the rejection reason (or null if the Promise resolved), and the second argument will be the resolved value. | +| function promiseWrapper(original: (err: Object, value: Object) => void): Object | Takes a function following the common error-first callback style, i.e. taking an (err, value) => ... callback as the last argument, and returns a version that returns promises. | + +Each specifier in printf is replaced with a converted value from the corresponding parameter. Supported specifiers are: +| Stylized character | Style requirements | +| -------- | -------- | +| %s: | String will be used to convert all values except BigInt, Object and -0. | +| %d: | Number will be used to convert all values except BigInt and Symbol. | +| %i: | parseInt(value, 10) is used for all values except BigInt and Symbol. | +| %f: | parseFloat(value) is used for all values expect Symbol. | +| %j: | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | +| %o: | Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() with options { showHidden: true, showProxy: true }. This will show the full object including non-enumerable properties and proxies. | +| %O: | Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() without options. This will show the full object not including non-enumerable properties and proxies. | +| %c: | CSS. This specifier is ignored and will skip any CSS passed in. | +| %%: | single percent sign ('%'). This does not consume an argument. | + +### Instruction for use + + +The use methods of each interface are as follows: + +1.readonly encoding() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var getEncoding = textEncoder.encoding(); +``` +2.encode() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var result = textEncoder.encode('abc'); +``` +3.encodeInto() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var obj = textEncoder.encodeInto('abc', dest); +``` +4.textDecoder() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +``` +5.readonly encoding() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var getEncoding = textDecoder.encoding(); +``` +6.readonly fatal() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var fatalStr = textDecoder.fatal(); +``` +7.readonly ignoreBOM() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var ignoreBom = textDecoder.ignoreBOM(); +``` +8.decode() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var result = textDecoder.decode(input, {stream : true}); +``` +9.printf() +``` +import util from '@ohos.util' +var format = "%%%o%%%i%s"; +var value = function aa(){}; +var value1 = 1.5; +var value2 = "qwer"; +var result = util.printf(format,value,value1,value2); +``` +10.getErrorString() +``` +import util from '@ohos.util' +var errnum = 13; +var result = util.getErrorString(errnum); +``` +11.callbackWrapper() +``` +import util from '@ohos.util' +async function promiseFn() { + return Promise.resolve('value'); +}; +var cb = util.callbackWrapper(promiseFn); +cb((err, ret) => { + expect(err).strictEqual(null); + expect(ret).strictEqual('value'); +}) +``` +12.promiseWrapper() +``` +import util from '@ohos.util' +function aysnFun(str1, str2, callback) { + if (typeof str1 === 'string' && typeof str1 === 'string') { + callback(null, str1 + str2); + } else { + callback('type err'); + } +} +let newPromiseObj = util.promiseWrapper(aysnFun)("Hello", 'World'); +newPromiseObj.then(res => { + expect(res).strictEqual('HelloWorld'); +}) +``` +## Related warehouse + +[js_util_module subsystem](https://gitee.com/OHOS_STD/js_util_module) + +[base/compileruntime/js_util_module/](base/compileruntime/js_util_module-readme.md) diff --git a/lrubuffer/BUILD.gn b/lrubuffer/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..97eae7a6ca836ab85cb684b3af98dc42010ee90f --- /dev/null +++ b/lrubuffer/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +base_output_path = get_label_info(":js_lrubuffer", "target_out_dir") +js_lrubuffer_obj_path = base_output_path + "/lrubuffer.o" + +gen_js_obj("js_lrubuffer") { + input = "//base/compileruntime/js_util_module/lrubuffer/js_lrubuffer.js" + output = js_lrubuffer_obj_path +} + +ohos_shared_library("lrubuffer") { + include_dirs = [ + "//foundation/ace/napi", + "//foundation/ace/napi/native_engine", + "//third_party/icu/icu4c/source/common", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//base/compileruntime/js_util_module/lrubuffer", + ] + + sources = [ "native_module_lrubuffer.cpp" ] + + deps = [ + ":js_lrubuffer", + "//base/compileruntime/js_util_module/lrubuffer/:js_lrubuffer", + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/icu/icu4c:static_icuuc", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + subsystem_name = "ccruntime" + part_name = "jsapi_util" + + relative_install_dir = "module" +} + +group("lrubuffer_packages") { + deps = [ ":lrubuffer" ] +} diff --git a/lrubuffer/js_lrubuffer.js b/lrubuffer/js_lrubuffer.js new file mode 100755 index 0000000000000000000000000000000000000000..a287e395c14e4565b6ba20b5331c17199fae21fc --- /dev/null +++ b/lrubuffer/js_lrubuffer.js @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; +class LruBuffer { + constructor(capacity) { + this.maxSize = 64; + this.putCount = 0; + this.createCount = 0; + this.evictionCount = 0; + this.hitCount = 0; + this.missCount = 0; + if (capacity !== undefined) { + if (capacity <= 0) { + throw new Error('data error'); + } + this.maxSize = capacity; + } + this.cache = new Map(); + } + updateCapacity(newCapacity) { + if (newCapacity <= 0) { + throw new Error('data error'); + } + else if (this.cache.size > newCapacity) { + this.changeCapacity(newCapacity); + } + this.maxSize = newCapacity; + } + get(key) { + if (key === null) { + throw new Error('key search failed'); + } + let value; + if (this.cache.has(key)) { + value = this.cache.get(key); + this.hitCount++; + this.cache.delete(key); + this.cache.set(key, value); + return value; + } + this.missCount++; + let createValue = this.createDefault(key); + if (createValue === undefined) { + return undefined; + } + else { + value = this.put(key, createValue); + this.createCount++; + if (value !== null) { + this.put(key, value); + this.afterRemoval(false, key, createValue, value); + return value; + } + return createValue; + } + } + put(key, value) { + if (key === null || value === null) { + throw new Error('key or value search failed'); + } + let former; + this.putCount++; + if (this.cache.has(key)) { + former = this.cache.get(key); + this.cache.delete(key); + this.afterRemoval(false, key, former, null); + } + else if (this.cache.size >= this.maxSize) { + this.cache.delete(this.cache.keys().next().value); + this.evictionCount++; + } + this.cache.set(key, value); + return former; + } + getCreatCount() { + return this.createCount; + } + getMissCount() { + return this.missCount; + } + getRemovalCount() { + return this.evictionCount; + } + getMatchCount() { + return this.hitCount; + } + getPutCount() { + return this.putCount; + } + capacity() { + return this.maxSize; + } + size() { + return this.cache.size; + } + clear() { + this.cache.clear(); + this.afterRemoval(false, this.cache.keys(), this.cache.values(), null); + } + isEmpty() { + let temp = false; + if (this.cache.size === 0) { + temp = true; + } + return temp; + } + contains(key) { + let flag = false; + if (this.cache.has(key)) { + flag = true; + let value; + value = this.cache.get(key); + this.cache.delete(key); + this.cache.set(key, value); + } + return flag; + } + remove(key) { + if (key === null) { + throw new Error('key search failed'); + } + else if (this.cache.has(key)) { + let former; + former = this.cache.get(key); + this.cache.delete(key); + if (key !== null) { + this.afterRemoval(false, key, former, null); + return former; + } + } + return undefined; + } + toString() { + let peek = 0; + let hitRate = 0; + peek = this.hitCount + this.missCount; + if (peek !== 0) { + hitRate = 100 * this.hitCount / peek; + } + else { + hitRate = 0; + } + let str = ''; + str = 'Lrubuffer[ maxSize = ' + this.maxSize + ', hits = ' + this.hitCount + ', misses = ' + this.missCount + + ', hitRate = ' + hitRate + '% ]'; + return str; + } + values() { + let arr = []; + for (let value of this.cache.values()) { + arr.push(value); + } + return arr; + } + keys() { + let arr = []; + for (let key of this.cache.keys()) { + arr.push(key); + } + return arr; + } + afterRemoval(isEvict, key, value, newValue) { + } + createDefault(key) { + return undefined; + } + changeCapacity(newCapacity) { + while (this.cache.size > newCapacity) { + this.cache.delete(this.cache.keys().next().value); + this.evictionCount++; + this.afterRemoval(true, this.cache.keys(), this.cache.values(), null); + } + } +} +export default { + LruBuffer: LruBuffer, +}; diff --git a/lrubuffer/native_module_lrubuffer.cpp b/lrubuffer/native_module_lrubuffer.cpp new file mode 100755 index 0000000000000000000000000000000000000000..dacc3303cab8c5f3bd9f6c4b82ee41695cbc142f --- /dev/null +++ b/lrubuffer/native_module_lrubuffer.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +static napi_value LruBufferInit(napi_env env, napi_value exports) +{ + const char *lruBufferClassName = "lrubuffer"; + napi_value lruBufferClass = nullptr; + NAPI_CALL(env, napi_define_class(env, lruBufferClassName, strlen(lruBufferClassName), nullptr, + nullptr, 0, nullptr, + &lruBufferClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("lrubuffer", lruBufferClass), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} + +// lrubuffer module define +static napi_module lrubufferModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = LruBufferInit, + .nm_modname = "lrubuffer", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__ ((constructor)) void RegisterModule() +{ + napi_module_register(&lrubufferModule); +} + +// lrubuffer JS register +extern "C" +__attribute__((visibility("default"))) void NAPI_lrubuffer_GetJSCode(const char **buf, int *buflen) +{ + extern const char _binary_js_lrubuffer_js_start[]; + extern const char _binary_js_lrubuffer_js_end[]; + if (buf != nullptr) { + *buf = _binary_js_lrubuffer_js_start; + } + if (buflen != nullptr) { + *buflen = _binary_js_lrubuffer_js_end - _binary_js_lrubuffer_js_start; + } +} \ No newline at end of file diff --git a/ohos.build b/ohos.build index e5737bd24e47b197bb6bce8f9b9cc367ff4e96dd..f53f42b886cb3716272e320a6a2022a04ab0de64 100755 --- a/ohos.build +++ b/ohos.build @@ -7,12 +7,13 @@ "phone" ], "module_list": [ - "//base/compileruntime/js_util_module/util:util_packages" + "//base/compileruntime/js_util_module/util:util_packages", + "//base/compileruntime/js_util_module/scope:scope_packages", + "//base/compileruntime/js_util_module/lrubuffer:lrubuffer_packages" ], "inner_kits": [ ], "test_list": [ - "//base/compileruntime/js_util_module/test/unittest:unittest" ] } } diff --git a/scope/BUILD.gn b/scope/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..81b858000701adc0902d743d43cfba01b0cb88a9 --- /dev/null +++ b/scope/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +base_output_path = get_label_info(":scope_js", "target_out_dir") +scope_js_obj_path = base_output_path + "/scope.o" + +gen_js_obj("scope_js") { + input = "//base/compileruntime/js_util_module/scope/scope_js.js" + output = scope_js_obj_path +} + +ohos_shared_library("scope") { + include_dirs = [ + "//foundation/ace/napi", + "//foundation/ace/napi/native_engine", + "//third_party/icu/icu4c/source/common", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//base/compileruntime/js_util_module/scope", + ] + + sources = [ "native_module_scope.cpp" ] + + deps = [ + ":scope_js", + "//base/compileruntime/js_util_module/scope/:scope_js", + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/icu/icu4c:static_icuuc", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + subsystem_name = "ccruntime" + part_name = "jsapi_util" + + relative_install_dir = "module" +} + +group("scope_packages") { + deps = [ ":scope" ] +} diff --git a/scope/native_module_scope.cpp b/scope/native_module_scope.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d1f48a6c336cd542838e33837555ad19df181554 --- /dev/null +++ b/scope/native_module_scope.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +static napi_value ScopeInit(napi_env env, napi_value exports) +{ + const char *ClassName = "scope"; + napi_value scopeClass = nullptr; + NAPI_CALL(env, napi_define_class(env, ClassName, strlen(ClassName), nullptr, + nullptr, 0, nullptr, + &scopeClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("scope", scopeClass) + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} + +// Scope module define +static napi_module scopeModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = ScopeInit, + .nm_modname = "scope", + .nm_priv = ((void*)0), + .reserved = {0}, +}; + +// Scope module register +extern "C" +__attribute__((constructor)) void RegisterModule() +{ + napi_module_register(&scopeModule); +} + +// Scope JS register +extern "C" +__attribute__((visibility("default"))) void NAPI_scope_GetJSCode(const char **buf, int *buflen) +{ + extern const char _binary_scope_js_js_start[]; + extern const char _binary_scope_js_js_end[]; + if (buf != nullptr) { + *buf = _binary_scope_js_js_start; + } + if (buflen != nullptr) { + *buflen = _binary_scope_js_js_end - _binary_scope_js_js_start; + } +} \ No newline at end of file diff --git a/scope/scope_js.js b/scope/scope_js.js new file mode 100755 index 0000000000000000000000000000000000000000..c93eec79e4932d70788547ecae6d60e85d03254c --- /dev/null +++ b/scope/scope_js.js @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Scope { + constructor(lowerObj, upperObj) { + this.lowerObj = lowerObj; + this.upperObj = upperObj; + this.checkNull(lowerObj, 'lower limit not be null'); + this.checkNull(upperObj, 'upper limit not be null'); + if (lowerObj.compareTo(upperObj)) { + throw new Error('lower limit must be less than or equal to upper limit'); + } + this._lowerLimit = lowerObj; + this._upperLimit = upperObj; + } + + getLower() { + return this._lowerLimit; + } + + getUpper() { + return this._upperLimit; + } + + contains(x) { + let resLower; + let resUpper; + this.checkNull(x, 'value must not be null'); + if (x instanceof Scope) { + resLower = x._lowerLimit.compareTo(this._lowerLimit); + resUpper = this._upperLimit.compareTo(x._upperLimit); + } else { + resLower = x.compareTo(this._lowerLimit); + resUpper = this._upperLimit.compareTo(x); + } + return resLower && resUpper; + } + + clamp(value) { + this.checkNull(value, 'value must not be null'); + if (!value.compareTo(this._lowerLimit)) { + return this._lowerLimit; + } else if (value.compareTo(this._upperLimit)) { + return this._upperLimit; + } else { + return value; + } + } + + intersect(x, y) { + let reLower; + let reUpper; + let mLower; + let mUpper; + if (y) { + this.checkNull(x, 'lower limit must not be null'); + this.checkNull(y, 'upper limit must not be null'); + reLower = this._lowerLimit.compareTo(x); + reUpper = y.compareTo(this._upperLimit); + if (reLower && reUpper) { + return this; + } else { + mLower = reLower ? this._lowerLimit : x; + mUpper = reUpper ? this._upperLimit : y; + return new Scope(mLower, mUpper); + } + } else { + this.checkNull(x, 'scope must not be null'); + reLower = this._lowerLimit.compareTo(x._lowerLimit); + reUpper = x._upperLimit.compareTo(this._upperLimit); + if (!reLower && !reUpper) { + return x; + } else if (reLower && reUpper) { + return this; + } else { + mLower = reLower ? this._lowerLimit : x._lowerLimit; + mUpper = reUpper ? this._upperLimit : x._upperLimit; + return new Scope(mLower, mUpper); + } + } + } + + expand(x, y) { + let reLower; + let reUpper; + let mLower; + let mUpper; + if (!y) { + this.checkNull(x, 'value must not be null'); + if (!(x instanceof Scope)) { + this.checkNull(x, 'value must not be null'); + return this.expand(x, x); + } + let reLower = x._lowerLimit.compareTo(this._lowerLimit); + let reUpper = this._upperLimit.compareTo(x._upperLimit); + if (reLower && reUpper) { + return this; + } else if (!reLower && !reUpper) { + return x; + } else { + let mLower = reLower ? this._lowerLimit : x._lowerLimit; + let mUpper = reUpper ? this._upperLimit : x._upperLimit; + return new Scope(mLower, mUpper); + } + } + else { + this.checkNull(x, 'lower limit must not be null'); + this.checkNull(y, 'upper limit must not be null'); + let reLower = x.compareTo(this._lowerLimit); + let reUpper = this._upperLimit.compareTo(y); + if (reLower && reUpper) { + return this; + } + let mLower = reLower ? this._lowerLimit : x; + let mUpper = reUpper ? this._upperLimit : y; + return new Scope(mLower, mUpper); + } + } + + toString() { + let strLower = this._lowerLimit.toString(); + let strUpper = this._upperLimit.toString(); + return `[${strLower}, ${strUpper}]`; + } + + checkNull(o, str) { + if (o == null) { + throw new Error(str); + } + } +} + +export default { + Scope: Scope, +}; \ No newline at end of file