From a656a36e1ca49e47fa8f16c482e57005f6754faf Mon Sep 17 00:00:00 2001 From: qiuyu Date: Fri, 17 Jan 2025 21:17:58 +0800 Subject: [PATCH 01/21] add some contents and modify structures and fix some typos Signed-off-by: qiuyu --- .../ets/doc/interop_js/1_introduction.rst | 172 ++++++-- .../plugins/ets/doc/interop_js/2_esobject.rst | 100 ----- .../interop_js/3_conversions_type_check.rst | 27 +- .../doc/interop_js/4_conversions_runtime.rst | 398 +++++------------- .../plugins/ets/doc/interop_js/index.rst | 2 - 5 files changed, 270 insertions(+), 429 deletions(-) delete mode 100644 static_core/plugins/ets/doc/interop_js/2_esobject.rst diff --git a/static_core/plugins/ets/doc/interop_js/1_introduction.rst b/static_core/plugins/ets/doc/interop_js/1_introduction.rst index b3cd32a993..b49fef94cc 100644 --- a/static_core/plugins/ets/doc/interop_js/1_introduction.rst +++ b/static_core/plugins/ets/doc/interop_js/1_introduction.rst @@ -14,70 +14,186 @@ Introduction ++++++++++++ -This document describe specification of interop between ArkTS runtime and -Typescript/Javascript, including additional compile time type checking for interop between -ArkTS and Typescript/Javascript. +Terminology explaination +------------------------ -Managed interop is part of runtime and frontend of ArkTS. It communicate -with javascript runtime via special native bridge. Here are excuted all -nessesary conversions for passed arguments. So all communication are only in -runtime. Additionally here can be typecheck for some cases at compile time. It -is just additional stage for better user experience, but it is does not affect -runtime part. ++-----------------+------------------------------------------------------------------------------------------+ +| Terminology | Explaination | ++=================+==========================================================================================+ +| ArkTS | The ArkTS with evolved ArkTS syntax and semantics | ++-----------------+------------------------------------------------------------------------------------------+ +| TS | abbreviation for Typescript | ++-----------------+------------------------------------------------------------------------------------------+ +| JS | abbreviation for Javascript | ++-----------------+------------------------------------------------------------------------------------------+ +| interop | abbreviation for interoperation | ++-----------------+------------------------------------------------------------------------------------------+ +| CTE | abbreviation for compile time error | ++-----------------+------------------------------------------------------------------------------------------+ +| RTE | abbreviation for runtime error | ++-----------------+------------------------------------------------------------------------------------------+ +| UB | abbreviation for undefined behavior | ++-----------------+------------------------------------------------------------------------------------------+ +| basic operators | property access ``.``, invocation ``()``, index access ``[]``, and instantiation ``new`` | ++-----------------+------------------------------------------------------------------------------------------+ + +Background +---------- + +With evolution of ArkTS language, ArkTS will provide more language features and some syntax and semantics also evolve. Moreover, ArkTS native compiler with complete type checking capabilities will be introduced. Althrough is not mandatory to migrate existing ArkTS and TS/JS code to Evolved ArkTS. However, for those developers who want to migrate, it is necessary to provide interoperability between ArkTS and TS/JS for better migration experiencen and for the requirement of reusing existing code assets. This document shows how ArkTS interoperates with TS/JS, which is helpful in the following scenarios: + +- migrate existing code to ArkTS + +- reuse some libraries of TS/JS code in migrated ArkTS modules + +We will elaborate interop rules in the upcoming chapters. Before that we emphasize that we basically provide these rules in the way of "white list", which means that if some scenarios are not mentioned, then they are not supported. For unsupported scenarios, there may be CTE or RTE or UB. In the future we may extend our "white list" and some unsupported scenarios will become supported, but before that unsupported scenarios should be avoided for better stability. + +Managed interop is part of runtime and frontend of ArkTS. In runtime ArkTS communicates with TS/JS via special native bridge. Additionally there can be typecheck for some cases at compile time. It is just additional stage for better user experience, but it is independent with runtime part. + +This document describes specification of interop between ArkTS and TS/JS, and additional compile time type checking for interop between ArkTS and TS/JS. Interop via 'import' and import rules ------------------------------------- + Our interop can be made via `import`, like what we have done in TS. However, we do have some rules for import directions. -- ArkTS files can import TS/JS files, +- ArkTS files can import TS/JS files, with additional restrictions: - with additional restrictions: 1. ArkTS class cannot `extends` TS/JS class 2. ArkTS class cannot `implements` TS interfaces - TS/JS files cannot import ArkTS files -Basic principles ----------------- +For now we only support the syntax ``"import {something} from 'path'"`` for interop import scenarios, and other import syntax, such as ``"import {something as alias} from 'path'"`` and ``"import defaultSomething from 'path'"`` and ``"import * as something from 'path'"``, is not supported. + +Some preliminaries about ArkTS +--------------------------------------- + +Here we list some important points for completeness. These points should be able to be implied by ArkTS language specification. + +ArkTS static semantics +====================== + +- ArkTS has static nominal type system and structural typing is forbidden. +- There is complete strict type checking during ArkTS compilation and execution. +- The layout of ArkTS objects cannot be dynamically changed. For example, it is forbidden to add/delete fields or methods of ArkTS classes and its instances. It is also forbidden to assign filed with a value whose type is different from the type of field declaration. +- There is runtime type check for implicit and explicit type conversion. + +ESObject in ArkTS +================= + +- ESObject is a special type, which is independent of Object type. +- ESObject can be used as type annotation and type parameter in generics. +- ESObject can be used to wrap data and objects from TS/JS and ArkTS. In particular, it can be used to wrap null and undefined. +- Basic operators and explicit type conversion on object of ESObject type are supported without compilation type check. And result type of basic operators on object of ESObject is still ESObject. +- Types in ArkTS can be implicitly or explicitly converted to ESObject types, but ESObject is not allowed to be implicitly converted to other types of ArkTS. +- It is not allowed to defined Object literals of ESObject type. + +Note: Abusing ESObject is strongly not recommended, because type checking for ESObject capability is weakened at compile time, which can easily leave coding errors to runtime. Also, there will be additional execution logics for operations on ESObject at runtime, resulting in worse runtime performance. + +Note: Using ESObject as type arguments in generics is not supported for now. + +Examples +******** + +.. code-block:: typescript + :linenos: -- In the ArkTS environment, when executing the ArkTS code logic and encountering an object that is incompatible with the annotated type, a runtime exception will occur. + // ArkTS code + class A { + v: number = 123 + } + function foo(x: ESObject) {} -- ArkTS objects layout cannot be dynamically modified. + let a: ESObject = new A() // OK, implicitly convert A to ESObject + a.v // OK + a[0] // no CTE, but RTE, a is not indexable + a() // no CTE, but RTE, a is not a function + new a() // no CTE, but RTE, a is not a constructor -- Type conversion (explicit or implicit) in ArkTS will cause runtime type verification, and will generate runtime exceptions if conversion is not possible in proper way. + let n1: number = a.v // CTE, cannot implicitly convert ESObject to number + let n2: number = a.v as number // OK + let n3: ESObject = a.v // OK + a.v + 1 // CTE, no '+' operation between ESObject and number + (a.v as number) + 1 // OK + + let s1: ESObject = 1 // OK, implicitly convert number to ESObject + let s2: ESObject = new A() // OK, implicitly convert A to ESObject + let s3: ESObject = 1 as ESObject // OK, explicitly convert number to ESObject + let s4: ESObject = new A() as ESObject; // OK, explicitly convert A to ESObject + + foo(1); // OK, implicitly convert number to the ESObject + foo(new A()) // OK, implicitly convert A to ESObject + + let point: ESObject = {x: 0, y: 1} // CTE, cannot create object literal of type ESObject + + foo({x: 0, y: 1}) // CTE, cannot create object literal of type ESObject + + class G { + foo(x: T) {} + } + + new G() // OK + new G() // CTE, cannot use ESObject as type arguments in generics + +- If basic operators on objects of type ESObject cannot be done properly, a runtime exception will be thrown. + +.. code-block:: typescript + :linenos: + + // ArkTS code + let x: ESObject = undefined + x[0] // RTE, x is not indexable + x() // RTE, x is not a function + x.f // RTE, cannot access property of undefined + new x() // RTE, x is not a constructor + x as string // RTE, cannot cast undefined to string + +Primitive types in ArkTS +================================= + +In ArkTS, there are the following primitive types: + +- number +- byte +- short +- int +- long +- float +- double +- bigint +- string +- boolean +- undefined +- null Principles for compilation type check ------------------------------------- - Support use TS types in ArkTS files as type annotations. +- In ArkTS, everything imported from JS has type ESObject. + - Compile-time type checking should be checked according to the rules of the file type: ArkTS files should follow the type checking rules of ArkTS, TS files should follow the type checking rules of TS. The interop part will be checked based on :ref:`Principles for compilation type mapping rules`, after type mapping to the type of the file where it is located. - When the ArkTS files are compiled into bytecode, all type annotations from TS in the ArkTS files will degenerate into ESObject. -- When the objects imported from TS/JS in the ArkTS file are finally compiled into bytecode, the types of these objects will be treated as ESObject. +- When the ArkTS files are compiled into bytecode, the types of all objects imported from TS/JS will degenerate into ESObject. .. _Principles for compilation type mapping rules: Principles for compilation type mapping rules --------------------------------------------- - - Primitive types are mapped into primitive types(e.g number -> number).(see :ref:`Typecheck conversion rules. Primitive values`) - Composed types (classes/interfaces/structs) are mapped into composed types. Moreover, nested types will be mapped into nested types.(e.g interface Y {x: X, s: string} -> interface Y {x: X, s: string}) (see :ref:`Typecheck conversion rules. Reference values`) -Principles for runtime objects mapping rules +Principles for runtime mapping rules -------------------------------------------- -- Primitive types will be mapped into primitive types (except special cases, see :ref:`Conversion rules Primitive values`) - -- ArkTS reference types will be mapped into some proxy objects in JS runtime - -- JS runtime objects will be mapped into `ESObject` in ArkTS runtime - +- Primitive types will be mapped into primitive types (except special cases, see :ref:`Conversion rules Primitive values`). -Terminology ------------ +- ArkTS reference types will be mapped into some proxy objects in TS/JS. -Throughout the docs we may often refer "CTE" by "Compile Time Error" and "RTE" by "Runtime Time Error". +- TS/JS objects will be mapped into `ESObject` in ArkTS runtime. diff --git a/static_core/plugins/ets/doc/interop_js/2_esobject.rst b/static_core/plugins/ets/doc/interop_js/2_esobject.rst deleted file mode 100644 index 7f43418d74..0000000000 --- a/static_core/plugins/ets/doc/interop_js/2_esobject.rst +++ /dev/null @@ -1,100 +0,0 @@ -.. - Copyright (c) 2025 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. - -.. _ESObject: - -++++++++++++++++++++ -ESObject in ArkTS -++++++++++++++++++++ - -- ESObject type is a special type in ArkTS. It is separate from Object type. -- ESObject type can be used in following ways without compliation type check: ``operator new``, ``operator []``, ``operator ()``, ``operator .``, ``operator as``. Moreover, the types of results of ``operator new``, ``operator []``, ``operator ()``, ``operator .`` are still ESObject and they will be called on JS-side. -- In bytecode of ArkTS, all entities imported from TS/JS will be of type ESObject. -- Values of ESObject type can be converted to and from Object type. However, implicitly converting an object of ESObject type to any other type is forbidden. -- Values of ESObject type may wrap entities from TS/JS, they also may wrap normal objects of types in ArkTS. -- ESObject can be used as type parameters in generics. -- It is not allowed to define an object literal of type ESObject. - -Examples -******** - -.. code-block:: javascript - :linenos: - - // test.js - class A { - v = 123 - } - export let a = new A() - - export function foo(v) {} - -.. code-block:: typescript - :linenos: - - // app.ets - import { a, foo } from './test' // a is of ESObject type - a.v // ok - a[index] // ok, will be called operator [] on JS-side - a() // ok, no CTE, but RTE, no operation () on JS side - new a() // no CTE, but RTE, no operation new on JS side - - let n1: number = a.v // CTE - let n2: number = a.v as number // ok - let n3: ESObject = a.v // ok - a.v + 1 // CTE - (a.v as number) + 1 // ok - - let s1: ESObject = 1; // ok, implicit conversion - let s2: ESObject = new StaticClass() // ok, implicit conversion - let s3: ESObject = 1 as ESObject; // ok, explicit conversion - let s4: ESObject = new StaticClass() as ESObject; // ok, explicit conversion - - foo(1); // ok, implicitly convert 1 to the ESObject type - foo(new StaticClass()); // ok, implicitly convert static object to the ESObject type - - let arr = new Array(); // ok, ESObject is used as a type parameter - - let point: ESObject = {x: 0, y: 1}; // CTE, cannot create object literal of type ESObject - - foo({x: 0, y: 1}); // CTE, cannot create object literal of type ESObject - -- When using ``as`` keyword if ArkTS type doesn't map to JS type then a runtime exception will be thrown. - -.. code-block:: typescript - :linenos: - - // file1.js - export x = 1; - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - import { x } from "file1"; - const valStr = x as string; // RTE, cannot cast number to string - -- When primitive type values are copied to ArkTS they become ESObject that contains primitive value. - In that case operators ``[]``, ``()``, ``.``, and ``new`` have no meaning and their usage will throw an exception. - -.. code-block:: typescript - :linenos: - - // file1.js - export x = 1; - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - import { x } from "file1"; - const val = new x(); // RTE, no operation new on JS side diff --git a/static_core/plugins/ets/doc/interop_js/3_conversions_type_check.rst b/static_core/plugins/ets/doc/interop_js/3_conversions_type_check.rst index 0517841187..9e84543eb7 100644 --- a/static_core/plugins/ets/doc/interop_js/3_conversions_type_check.rst +++ b/static_core/plugins/ets/doc/interop_js/3_conversions_type_check.rst @@ -16,9 +16,7 @@ Typecheck conversion rules ++++++++++++++++++++++++++ -Typecheck performs only for ArkTS/TS files. - -Let describe the relationships: +Typecheck performs only for ArkTS/TS files. Let us describe the relationships: 1. ArkTS to TS type conversion 2. TS to ArkTS type conversion @@ -34,23 +32,23 @@ ArkTS to TS type conversion +-------------------------+-------------------------+ | ArkTS | TS | +=========================+=========================+ -| ``number/Number`` | ``Number`` | +| ``number/Number`` | ``number`` | +-------------------------+-------------------------+ -| ``byte/Byte`` | ``Number`` | +| ``byte/Byte`` | ``number`` | +-------------------------+-------------------------+ -| ``short/Short`` | ``Number`` | +| ``short/Short`` | ``number`` | +-------------------------+-------------------------+ -| ``int/Int`` | ``Number`` | +| ``int/Int`` | ``number`` | +-------------------------+-------------------------+ -| ``long/Long`` | ``Number`` | +| ``long/Long`` | ``number`` | +-------------------------+-------------------------+ -| ``float/Float`` | ``Number`` | +| ``float/Float`` | ``number`` | +-------------------------+-------------------------+ -| ``double/Double`` | ``Number`` | +| ``double/Double`` | ``number`` | +-------------------------+-------------------------+ | ``char/Char`` | ``string`` | +-------------------------+-------------------------+ -| ``boolean/Boolean`` | ``Boolean`` | +| ``boolean/Boolean`` | ``boolean`` | +-------------------------+-------------------------+ | ``string/String`` | ``string`` | +-------------------------+-------------------------+ @@ -77,9 +75,9 @@ TS to ArkTS type conversion +--------------------------+-------------------------+ | TS | ArkTS | +==========================+=========================+ -| ``number/Number`` | ``Number`` | +| ``number/Number`` | ``number`` | +--------------------------+-------------------------+ -| ``boolean/Boolean`` | ``Boolean`` | +| ``boolean/Boolean`` | ``boolean`` | +--------------------------+-------------------------+ | ``string/String`` | ``string`` | +--------------------------+-------------------------+ @@ -103,7 +101,7 @@ TS to ArkTS type conversion +--------------------------+-------------------------+ | ``void(variable type)`` | ``undefined`` | +--------------------------+-------------------------+ -| ``void(return type)`` | ``void`` | +| ``void(return type)`` | ``void`` | +--------------------------+-------------------------+ | ``never`` | ``never`` | +--------------------------+-------------------------+ @@ -182,7 +180,6 @@ Interfaces: export class MyClass implements MyInface { data: number = 0; } - export type MyFunction = Function; .. code-block:: typescript diff --git a/static_core/plugins/ets/doc/interop_js/4_conversions_runtime.rst b/static_core/plugins/ets/doc/interop_js/4_conversions_runtime.rst index d56019c057..9818f9d12b 100644 --- a/static_core/plugins/ets/doc/interop_js/4_conversions_runtime.rst +++ b/static_core/plugins/ets/doc/interop_js/4_conversions_runtime.rst @@ -18,14 +18,14 @@ Runtime conversion rules Runtime conversion rules: Primitive values ****************************************** -Primitive type values are copied between ArkTS runtime and JS runtime by value. +Primitive type values are copied by value during interop runtime. If the value is changed in one runtime it doesn't affect another one. ArkTS to JS conversion -======================= +====================== +-------------------------+-------------------+ -| ArkTS runtime type | JS runtime type | +| ArkTS type | JS runtime type | +=========================+===================+ | ``number/Number`` | ``number`` | +-------------------------+-------------------+ @@ -51,141 +51,53 @@ ArkTS to JS conversion +-------------------------+-------------------+ | ``enum`` | ``number/string`` | +-------------------------+-------------------+ -| ``literal type string`` | ``string`` | -+-------------------------+-------------------+ | ``undefined`` | ``undefined`` | +-------------------------+-------------------+ | ``null`` | ``null`` | +-------------------------+-------------------+ -- Numeric ArkTS types map to JS ``number``. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsInt: int = 1; - export let etsDouble: double = 2.1; +- Boxed types(e.g. Number, Char, etc) map to primitive JS types. .. code-block:: javascript :linenos: // file1.js - import { etsInt, etsDouble } from "file2"; - - let jsInt = etsInt; // jsInt is 'number' and equals 1 - let jsDouble = etsDouble; // jsDouble is 'number' and equals 2.1 - -- ArkTS ``boolean`` maps to JS ``boolean``. + export function foo(x) { + console.log(typeof x) + console.log(x) + } .. code-block:: typescript :linenos: // file2.ets ArkTS - export let etsBool: boolean = true; - -.. code-block:: javascript - :linenos: - - // file1.js - import { etsBool } from "file2"; - - let jsBool = etsBool; // jsBool is 'boolean' and equals true - -- ArkTS ``string`` maps to JS ``string``. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsStr: string = "hello"; - -.. code-block:: javascript - :linenos: - - // file1.js - import { etsStr } from "file2"; - - let jsStr = etsStr; // jsStr is 'string' and equals "hello" - -- ArkTS ``bigint`` maps to JS ``bigint``. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsBigInt: bigint = 10n; - -.. code-block:: javascript - :linenos: + import { foo } from 'file1' + export let x: Number = new Number(123) + foo(x) // print 'number' and '123' - // file1.js - import { etsBigInt } from "file2"; - - let jsBigInt = etsBigInt; // jsBigInt is 'bigint' and equals 10 - -- ArkTS ``undefined`` maps to JS ``undefined``. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsUndef: undefined = undefined; +- ``enum`` conversion depends on the type of enumeration. Numeric ``enum`` converts to ``number``. String ``enum`` converts to ``string``. .. code-block:: javascript :linenos: // file1.js - import { etsUndef } from "file2"; - - let jsUndef = etsUndef; // jsUndef is 'undefined' and equals undefined - -- ArkTS ``null`` maps to JS ``null``. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsNull: null = null; - -.. code-block:: javascript - :linenos: - - // file1.js - import { etsNull } from "file2"; - - let jsNull = etsNull; // jsNull is 'object' and equals null - -- Boxed types(e.g. Number, Char, etc) map to primitive JS types. - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let x: Number = 1; // x is 'object' - -.. code-block:: javascript - :linenos: - - // file1.js JS - import { x } from "file2"; - - let a = x; // x is 'number' and equals 1 + export function foo(x) { + console.log(typeof x) + console.log(x) + } -- ``enum`` conversion depends on the type of enumeration. Numeric ``enum`` converts to ``number``. String ``enum`` converts to ``string``. .. code-block:: typescript :linenos: // file2.ets ArkTS - // numeric enum + import { foo } from 'file1' enum Direction { Up = -1, Down = 1 } - let up: Direction = Direction.Up; - let down: Direction = Direction.Down; + foo(Direction.Down) // print 'number' and '1' // string enum enum Color { @@ -193,38 +105,7 @@ ArkTS to JS conversion Red = 'red' } - let green: Color = Color.Green; - let red: Color = Color.Red; - -.. code-block:: javascript - :linenos: - - // file1.js - import { up, down, green, red } from "file2"; - - let a = up; // a is 'number' and equals -1 - let b = down; // b is 'number' and equals 1 - - let c = green; // c is 'string' and equals 'green' - let d = red; // d is 'string' and equals 'red' - -- ``literal type string`` map to JS ``string`` - -.. code-block:: typescript - :linenos: - - // file2.ets ArkTS - export let etsLiteral: "literal" = "literal"; - etsLiteral = "not literal"; // compilation error - -.. code-block:: javascript - :linenos: - - // file1.js - import { etsLiteral } from "file2"; - - let val = etsLiteral; // val is "literal" but it can be changed - val = "not literal"; // ok + foo(Color.Red) // print 'string' and 'red' JS to ArkTS conversion ======================= @@ -358,49 +239,13 @@ Value imported from JS to ArkTS, should be converted explicitly using ``as`` key // file2.ets ArkTS import { jsSymbol } from "file1"; - let val = jsSymbol; // ok, val is ESObject + let val = jsSymbol; // OK, val is ESObject Limitations =========== -Object wrapper types --------------------- - -- Object wrapper types for primitive values such as ``Null``, ``Undefined``, ``Boolean``, ``Number``, ``Bigint``, ``String``, and ``Symbol`` - can't be copied by default to ArkTS values. It need special way for creating on JS side via ``new`` keyword. Without it even in - case of capital letter it will be primitive type according JS. - -.. code-block:: typescript - :linenos: - - // file1.js - let a = new Number(123); // typeof a is "object" - let b = Number(123); // typeof a is "number" - - // file2.ets ArkTS - import { a, b } from "file1"; - let aa = a as number; // RTE, as a is a reference from JS runtime - let bb = b as number; // ok, as b is a primitive number from JS runtime - -Solutions -^^^^^^^^^ - -- Use ``valueOf`` to get primitive values from wrapper objects and copy them to ArkTS - -.. code-block:: typescript - :linenos: - - // file1.js - let a = new Number(123); // typeof a == "object" - let b = Number(123); // typeof a == "number" - - // file2.ets ArkTS - import { a, b } from "file1"; - let aa = a.valueOf() as number; // ok - let bb = b as number; // ok - Copy semantic -============= +------------- - Primitive type value is copied from JS runtime to ArkTS runtime by value so there is no connection with JS runtime after compilation and no side effects. E.g. if Prototype is changed in JS runtime it won't be changed in ArkTS runtime. @@ -435,7 +280,7 @@ Copy semantic let num = a as number; // num is just static number with val 3 Solutions -========= +^^^^^^^^^ - Instead of importing primitive types, global contex can be imported instead of them and manipulation can be done through global context @@ -479,11 +324,16 @@ Wide limitation .. code-block:: typescript :linenos: + // file1.js + export function foo(x) { + console.log(x) + } + // file2.ets ArkTS - export let a: long = Math.pow(2, 53) + 10; + import { foo } from "file1" - // file1.js - import { a } from "file2"; // this import will result in precision loss + let a: long = Math.pow(2, 53) + 10; + foo(a); // printed value will not equal Math.pow(2, 53) + 10 because of precision loss - Integer ``number`` values when converted to ArkTS may have precision loss if a value out of range of ArkTS type @@ -525,7 +375,7 @@ Solutions // file2.js import { a } from "file1"; - let num = a; // ok, bigint no precision loss + let num = a; // OK, bigint no precision loss - Using ``number`` instead of ``float`` @@ -540,7 +390,7 @@ Solutions // file2.ets ArkTS import { a } from "file1"; - let x = a as number; // ok, will be correct + let x = a as number; // OK, will be correct let y = b as float; // may lose precision, use ``number`` type instead of float .. _Conversion rules Reference values: @@ -577,32 +427,45 @@ ArkTS to JS conversion - Proxing ArkTS object. +.. code-block:: javascript + :linenos: + + // file1.js + export function foo(a) { + a.val = "222"; // OK + a.newVal = "hello"; // RTE, objects are sealed + a.val = 123; // RTE, field has another type + } + .. code-block:: typescript :linenos: // file2.ets ArkTS + import { foo } from "file1" class A { val : string = "hi"; }; - export let a = new A(); + let a = new A(); + foo(a); + +- Inheritance also will be constructed for proxy classes .. code-block:: javascript :linenos: // file1.js - import { a } from 'file2' - a.val = "222"; // ok - - Reflect.set(a, "newVal", "hello"); // runtime exception, objects are sealed - Reflect.set(a, "val", 123); // runtime exception, field has another type - -- Inheritance also will be constructed for proxy classes + export function foo(a) { + // Classes A and B will be constructed on JS side with inheritance relationships. + a.vala = "222"; // OK + a.valb = "333"; // OK + } .. code-block:: typescript :linenos: // file2.ets ArkTS + import { foo } from 'file1' class B { valb = "b"; }; @@ -612,15 +475,7 @@ ArkTS to JS conversion }; let a = new A(); - -.. code-block:: javascript - :linenos: - - // file1.js - import { a } from 'file2' - // Classes A and B will be constructed on JS side with inheritance relationships. - a.vala = "222"; // ok - a.valb = "333"; // ok + foo(a); - About proxing ArkTS ``union`` see :ref:`Features ArkTS Union` - About proxing ArkTS ``tuple`` see :ref:`Features ArkTS Tuple` @@ -634,79 +489,65 @@ Limitations - Layout of ArkTS objects can not be changed and it is root of limitations for proxy-objects +.. code-block:: javascript + :linenos: + + // file1.js + export function foo(a) { + a.val = "222"; // OK + a.newVal = "hello"; // RTE, objects are sealed + a.val = 123; // RTE, field has another type + } + .. code-block:: typescript :linenos: // file2.ets ArkTS + import { foo } from "file1" class A { val : string = "hi"; }; - export let a = new A(); - -.. code-block:: javascript - :linenos: - - // file1.js + let a = new A(); + foo(a); - import {a} from 'file2' - a.newVal = 1; // runtime exception, objects are sealed - a.val = 123; // runtime exception, field has another type - a.val = "123"; // ok Solutions ^^^^^^^^^ - All changes for static classes should be done by user on static side +.. code-block:: javascript + :linenos: + + // file1.js + export function foo(a) { + a.val = "222"; // OK + a.newVal = "hello"; // OK + a.val = 123; // OK + } + .. code-block:: typescript :linenos: // file2.ets ArkTS + import { foo } from "file1" class A { - val : number|string = 2; - newVal : number = 3; + val : string | number = "hi"; + newVal: number = 0; }; - export let a = new A(); - -.. code-block:: javascript - :linenos: - - // file1.js - - import {a} from 'file2' - a.newVal = 1; // ok - a.val = 123; // ok - a.val = "123"; // ok + let a = new A(); + foo(a); -2. JS to ArkTS conversion +JS to ArkTS conversion ============================ In JS everything that is not a primitive value is an object. We will call it a reference value and it follows the reference conversion rules described in this chapter. -We can group all reference values into the following categories. - -+----------------------------------+ -| JS reference types | -+==================================+ -| ``Object`` | -+----------------------------------+ -| ``Class`` | -+----------------------------------+ -| ``Function`` | -+----------------------------------+ -| ``Collection`` | -| | -| ``(Array, Set, Map, etc)`` | -+----------------------------------+ -| ``Other standard builtins`` | -| | -| ``(Date, RegExp, Promise, etc)`` | -+----------------------------------+ - -ESObject is used to proxy any reference values from JS. - -- Proxing JS object with ESObject. + +ESObject can used to wrap any reference values from JS. + +- Wrapping JS object with ESObject. .. code-block:: javascript :linenos: @@ -724,11 +565,11 @@ ESObject is used to proxy any reference values from JS. // file2.ets ArkTS import { a } from 'file1' - let b = a; // ok, ``b`` is ESObject - let c = a.v; // ok, ``c`` is ESObject - let d = a.v as number; // ok, ``d`` is number + let b = a; // OK, ``b`` is ESObject + let c = a.v; // OK, ``c`` is ESObject + let d = a.v as number; // OK, ``d`` is number -- Special operators: ``new``, ``.``, ``[]``, ``()`` will work properly with ESObject, if such operations available on JS side, otherwise it will generate runtime exception +- Basic operators will work properly with ESObject, if such operations available on JS side, otherwise it will generate runtime exception .. code-block:: javascript :linenos: @@ -746,12 +587,12 @@ ESObject is used to proxy any reference values from JS. // file2.ets ArkTS import { a } from 'file1' - let number1: number = a.v as number // ok - a.v = 456; // ok, will modify original JS object - a.newfield = "hi"; // ok, will modify original JS object and create new field - let missedFiled = a.missedFiled as undefined; // ok - let number2 = a["v"] as number; // ok, will return 456 - let number2 = a[1] as undefined; // ok + let number1: number = a.v as number // OK + a.v = 456; // OK, modify original JS object + a.newfield = "hi"; // OK, modify original JS object and create new field + let missedFiled = a.missedFiled as undefined; // OK + let number2 = a["v"] as number; // OK, get 456 + let number2 = a[1] as undefined; // OK - Prototype of JS object can be modified on ArkTS side and it will be applied to all instances of Class @@ -760,7 +601,6 @@ ESObject is used to proxy any reference values from JS. // file1.js export class A { - v = 123; testFunction() { return true; } @@ -786,10 +626,7 @@ ESObject is used to proxy any reference values from JS. - About proxing collections and other standard builtins see :ref:`JS Std library` and :ref:`Async and concurrency features JS`. Limitations -=========== - -Unsupported operations ----------------------- +----------- - All unsupported special operations will throw runtime exception. Or incorrect conversions. @@ -817,58 +654,51 @@ Unsupported operations a[1] as int; // RTE a["v"] as string; // RTE - -Solutions -^^^^^^^^^ - -- If you need non standard conversion, you should use conversion for static types +- ESObject which contains reference type values from JS runtime can't be cast to ArkTS object. .. code-block:: javascript :linenos: // file1.js - - class A { - v = 123 + export class A { + v = 123; } export let a = new A() - .. code-block:: typescript :linenos: // file2.ets ArkTS import { a } from 'file1' - let num = a.v as number; // ok - let str = num.toString(); // ok, now we get static string from number + let b = a as Object; // RTE. a is ESObject with reference values from JS runtime. -Cast to static object ---------------------- +Solutions +^^^^^^^^^ -- ESObject which contains reference type values from JS runtime can't be cast to ArkTS object. +- If you need non standard conversion, you should use conversion for static types .. code-block:: javascript :linenos: // file1.js - export class A { - v = 123; + + class A { + v = 123 } export let a = new A() + .. code-block:: typescript :linenos: // file2.ets ArkTS import { a } from 'file1' - let b = a as Object; // RTE. a is ESObject with reference values from JS runtime. - -Solutions -^^^^^^^^^ + let num = a.v as number; // OK + let str = num.toString(); // OK, now we get static string from number - Only primitive types can be cast to ArkTS objects. @@ -886,7 +716,7 @@ Solutions :linenos: // file2.ets ArkTS - import { a } from './file1' + import { a } from 'file1' - let b: number = a.v as number; // ok - let c: Object = a.v as Object; // ok + let b: number = a.v as number; // OK + let c: Object = a.v as Object; // OK diff --git a/static_core/plugins/ets/doc/interop_js/index.rst b/static_core/plugins/ets/doc/interop_js/index.rst index 0a12bf57e8..08de086264 100644 --- a/static_core/plugins/ets/doc/interop_js/index.rst +++ b/static_core/plugins/ets/doc/interop_js/index.rst @@ -19,11 +19,9 @@ :maxdepth: 3 /1_introduction - /2_esobject /3_conversions_type_check /4_conversions_runtime /5_js /6_ts /7_arkts /99_backlog_features_recheck - -- Gitee From 5cd95e0b936824ed0c3c0e3a1e1f34c0ae8b1c75 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Fri, 3 Jan 2025 15:46:27 +0800 Subject: [PATCH 02/21] InteropJS: add interop rules to relational operators Signed-off-by: MockMockBlack InteropJS: add interop rules to relational operators (in) Signed-off-by: MockMockBlack InteropJS: add *Description* titles to relational operators Signed-off-by: MockMockBlack InteropJS: updated interop rules arkts2.0 to js Relational operators InteropJS: updated interop rules arkts2.0 to js Relational operators Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/5_js.rst | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index b50f8f171d..1f1e12f318 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -922,15 +922,89 @@ Like other looping statements, you can use control flow statements inside statem Relational operators: ``<``, ``>``, ``<=``, ``>=`` (empty) *********************************************************** -* ``<``, ``>``, ``<=``, ``>=`` operators +Description +^^^^^^^^^^^ + +Operators ``<``, ``>``, ``<=``, ``>=`` are used to compare the order of two operands. If the condition is true, the result is ``true``; otherwise, it is ``false``. + +.. code-block:: javascript + :linenos: + + let foo = 123; + let bar = 456; + + // Expected output: true + console.log(foo <= bar); + +Interop rules +^^^^^^^^^^^^^ + +- If one of the operands is from ArkTS2.0, the operands's type converted to JS must be the primitive type. Otherwise, the runtime will throw an error. + + +.. code-block:: javascript + :linenos: + + // file1.js + export function is_greator(a, b) { + return a > b + } + +.. code-block:: typescript + :linenos: + + // file2.ets ArkTS2.0 + import { is_greator } from './file1' + + // Ok, both operands's type in JS World(converted) + // are the same primitive type(number) + + let res = is_greator(1, 2); // ok + + // Error, operands's type in JS World(converted) + // are not the same type + let res = is_greator(1, "2"); // error + + // Error, operands's type in JS World(converted) + // are not the primitive type + class Foo { + a: Number; + } + let res = is_greator(new Foo(123), new Foo(456)); // error Relational operators: ``in`` (empty) ************************************* +Description +^^^^^^^^^^^ + +``${name} in ${object}`` returns the bool value ``true`` if there is a property ``name`` in the object ``${object}`` (or in its prototype chain). +Throw an runtime error if the ``${object}`` is not an object. + +.. code-block:: javascript + :linenos: + + let foo = { bar: "bar_value"}; + + console.log("bar" in foo); // true + console.log(undefined in foo); // false + // console.log("bar" in "not a object"); // error: not an object + console.log("length" in new String("it is a object")); // true: it is an object + console.log(Symbol.iterator in new String("it is a object")) // check the iterator + + +Interop rules +^^^^^^^^^^^^^ + In to getter/setter property works as expected. So, no additional actions are required. + + + + Relational operators: ``instanceof`` (empty) ********************************************* -* ``instanceof`` operator +Description +^^^^^^^^^^^ Operator ``instanceof`` checks whether an object belongs to a certain class. In other words, object instanceof constructor checks if an object is present constructor.prototype in the prototype chain object. @@ -951,6 +1025,15 @@ Operator ``instanceof`` checks whether an object belongs to a certain class. In console.log(auto instanceof Object); // Expected output: true +Interop rules +^^^^^^^^^^^^^ + +LHS instanceof RHS +- if one and only one of the operands is from ArkTS2.0, the operator will only make sense if it's primitive type. Otherwise, return false. +- if both operands are from ArkTS2.0, the operator will make no sense. + +TODO: to be degussed. + Closure (empty) *************** -- Gitee From 3c3df4b6ab4c9fba85b31437a8109ac5f199519f Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Fri, 3 Jan 2025 15:45:52 +0800 Subject: [PATCH 03/21] InteropJS: add interop rules to JS Iterator Signed-off-by: MockMockBlack InteropJS: updated interop rules arkts2.0 to js iteration InteropJS: updated interop rules arkts2.0 to js iteration using arkts2.0's style Signed-off-by: MockMockBlack to stash Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/5_js.rst | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 1f1e12f318..6bb2dfe35c 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -919,6 +919,65 @@ Like other looping statements, you can use control flow statements inside statem * while + +Interop rules +^^^^^^^^^^^^^ + +- If try to iterate an object from ArkTS2.0 in JS world. The object should in ArkTS2.0 world must be iterable(can be used in for-of statements). Otherwise, the runtime will throw an error. + +.. code-block:: javascript + :linenos: + + // file1.js JS + export function display(iterable) { + for (let each of iterable) { + console.log(each) + } + } + +.. code-block:: typescript + :linenos: + + // file2.ets ArkTS2.0 + import { display } from './file1'; + + class Foo { + data: number[] = [1, 2, 3, 4, 5]; + + $_iterator(): FooIterator { + return new FooIterator(this); + } + } + + class FooIterator implements Iterator { + private metadata: Foo; + private index: int = 0; + + constructor(metadata: Foo) { + this.metadata = metadata; + } + + next(): IteratorResult { + + if (this.index < this.metadata.data.length) { + + return { + done: false, + value: this.metadata.data[this.index++] + }; + } else { + return { + done: true, + value: 0 + }; + } + } + } + + display(new Foo()); // ok, display will iterate over Foo object + display([1, 2, 3]); // ok, display will iterate over array + display(123); // error, 123 is not iterable + Relational operators: ``<``, ``>``, ``<=``, ``>=`` (empty) *********************************************************** -- Gitee From 755b4ea565b3bb0b7060d9ceefdbc1dbf0f0cd03 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 10:20:50 +0800 Subject: [PATCH 04/21] InteropJS: updated interop rules arkts2.0 to js Object of primitive types Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/5_js.rst | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 6bb2dfe35c..03a65d8224 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1127,21 +1127,49 @@ Object of primitive types (empty) Description ^^^^^^^^^^^ -- Null +The primitive types in JavaScript have no methods or properties. +When accessing a property or method, the primitive value is wrapped into an Object(aka auto-boxing). +And actually the method or property is called on the object, not on the primitive value. -- Undefined +.. code-block:: javascript + :linenos: + + let str = "string literal"; + + // Actually, variable str is auto-boxed into an String Object. + // Then String.toUpperCase() is called. + console.log(str.toUpperCase()); + +The converting rules are: + +- null -> Null +- undefined -> Undefined +- boolean -> Boolean +- number -> Number +- bigint -> Bigint +- string -> String +- symbol-> Symbol + +Interop rules +^^^^^^^^^^^^^ -- Boolean +- If a primitive type is passed from ArkTS2.0 to JS world, the primitive type will follow the auto-boxing rules. -- Number +.. code-block:: javascript + :linenos: -- Bigint + // file1.js + export function toUpperCase(str) { + return str.toUpperCase(); // the string will be auto-boxed into an String Object + } -- String +.. code-block:: typescript + :linenos: -- Symbol + // file2.ets ArkTS2.0 + import { toUpperCase } from './file1' - Symbol is a unique and immutable data type that can be used as an identifier for object properties. + let res = toUpperCase("string literal"); // string type in arkts 2.0 will be converted to string type in JS world The ``typeof`` Operator (empty) -- Gitee From 15d2d0f20795492041c9b88151df7da9830ec844 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 10:32:44 +0800 Subject: [PATCH 05/21] InteropJS: updated interop rules arkts2.0 to js operator typeof Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 03a65d8224..f34392d523 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1178,7 +1178,8 @@ The ``typeof`` Operator (empty) Description ^^^^^^^^^^^ -The ``typeof`` operator returns a string indicating the type of the operand's value. +The ``typeof`` operator returns a string indicating the type of the operand's value. +The rules are: +-------------------------------------------------------------------------------+-----------+ | Type | Result | @@ -1204,6 +1205,15 @@ The ``typeof`` operator returns a string indicating the type of the operand's va |Any other object | "object" | +-------------------------------------------------------------------------------+-----------+ +.. code-block:: javascript + :linenos: + + let foo = "bar"; + console.log(typeof foo); // string + +Interop rules +^^^^^^^^^^^^^ +- When the operand is from ArkTS2.0, if the operand's type converted to JS must is primitive, the operator returns the primitive's type name as above. Otherwise, the operator returns "object". Generators (empty) ****************** -- Gitee From aff34d68bc155b4ff50afdaa3bfe40ad1054b359 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 10:46:55 +0800 Subject: [PATCH 06/21] InteropJS: updated interop rules arkts2.0 to js Generators(not supportted by arkts2.0) Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index f34392d523..e4ef83d447 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1231,6 +1231,12 @@ Generators can return (``yield``) multiple values, one after another, on-demand. - ``generator.return()``: returns a value and terminates the generator - ``generator.throw()``: throws an error and terminates the generator +Interop rules +^^^^^^^^^^^^^ + +- ``Generator`` are not supported by ArkTS standard library. + + ``With`` statement (empty) ************************** -- Gitee From b7395335bf7aa0f2ad0685822c443af6721b1e2c Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 11:01:20 +0800 Subject: [PATCH 07/21] InteropJS: updated interop rules arkts2.0 to js with statement(deprecated) Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index e4ef83d447..148efdbcfd 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1246,6 +1246,13 @@ Description Use of the ``with`` statement is not recommended, as it may be the source of confusing bugs and compatibility issues, makes optimization impossible, and is forbidden in ``strict mode``. The recommended alternative is to assign the object whose properties you want to access to a temporary variable. +This feature is deprecated, using it may cause problems. + +Interop rules +^^^^^^^^^^^^^ + +- This feature is deprecated, do not use it. + The ``debugger`` statement (empty) ********************************** -- Gitee From fdc6cfcf108197b11a621da596570be9c4f3bc33 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 11:58:08 +0800 Subject: [PATCH 08/21] InteropJS: updated interop rules arkts2.0 to js debugger statement Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 148efdbcfd..64b83fff23 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1257,13 +1257,22 @@ Interop rules The ``debugger`` statement (empty) ********************************** - Description ^^^^^^^^^^^ The ``debugger`` statement invokes any available debugging functionality, such as setting a breakpoint. If no debugging functionality is available, this statement has no effect. +.. code-block:: javascript + + :linenos: + // dummy code + dubugger; // interrupt when debugging + +Interop rules +^^^^^^^^^^^^^ +- This statement has not interop with ArkTS2.0. + Proxies (empty) *************** -- Gitee From 79732c179c0c61945d2bcade6457de003e012f86 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Thu, 9 Jan 2025 12:10:56 +0800 Subject: [PATCH 09/21] InteropJS: updated interop rules arkts2.0 to js Proxy Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 64b83fff23..03a197865c 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1305,6 +1305,11 @@ You create a ``Proxy`` with two parameters: console.log(proxy2.message1); // world console.log(proxy2.message2); // world +Interop rules +^^^^^^^^^^^^^ + +- ``Proxy`` are not supported by ArkTS standard library. + The Global Object (empty) ************************* -- Gitee From 0df5d2b395d0fef71d149fc37685c330c5801fcf Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Fri, 10 Jan 2025 09:56:19 +0800 Subject: [PATCH 10/21] InteropJS: updated interop rules arkts2.0 to js The Global Object Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 03a197865c..1561202e23 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1340,6 +1340,10 @@ Other properties of the ``Global Object``: - Reflect +Interop rules +^^^^^^^^^^^^^ +- This feature has not interop with ArkTS2.0. + Reflect (empty) *************** -- Gitee From 2f1ac589da938139efb3ca24b15a3ec39b048a12 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Mon, 13 Jan 2025 09:35:25 +0800 Subject: [PATCH 11/21] InteropJS: updated interop rules arkts2.0 to js Reflect Object Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 1561202e23..ead3288558 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1367,6 +1367,10 @@ The ``Reflect`` object has a number of methods that allow developers to access a ``Reflect.get()``, ``Reflect.set()``, ``Reflect.apply()``, ``Reflect.construct()`` methods +Interop rules +^^^^^^^^^^^^^ +- For now, this feature has not be supported to interop with ArkTS2.0. If try to reflected an Proxy object from ArkTS2.0 in JS world, the runtime will throw an error. + .. _JS Std library: Symbol (empty) -- Gitee From 1377b802aa819b6cac8825831a69c2a607df6f35 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Mon, 13 Jan 2025 10:01:21 +0800 Subject: [PATCH 12/21] InteropJS: updated interop rules arkts2.0 to js Symbol Signed-off-by: MockMockBlack --- static_core/plugins/ets/doc/interop_js/5_js.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index ead3288558..0fc1203dd9 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1376,6 +1376,21 @@ Interop rules Symbol (empty) ************** +Description +^^^^^^^^^^^ + +Symbol is a primitive in JS which stand for a unique symbol(aka symbol value). + +.. code-block:: javascript + + let s = Symbol("foo"); + console.log(typeof s); // symbol + +Interop rules +^^^^^^^^^^^^^ + +- Primitive type ``symbol`` and Object ``Symbol`` are not supported by ArkTS standard library. + JS Std library ############## -- Gitee From d9dfa7a589879e79302f78c5191976894ac721cc Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Mon, 13 Jan 2025 11:13:45 +0800 Subject: [PATCH 13/21] InteropJS: updated interop rules arkts2.0 to js Array --- static_core/plugins/ets/doc/interop_js/5_js.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 0fc1203dd9..e0785483b4 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1382,7 +1382,7 @@ Description Symbol is a primitive in JS which stand for a unique symbol(aka symbol value). .. code-block:: javascript - + let s = Symbol("foo"); console.log(typeof s); // symbol @@ -1400,6 +1400,8 @@ Arrays Description ^^^^^^^^^^^ +The Array Object in JavaScript replasents a collection of some elements. The elements can be of different types. + Interop rules ^^^^^^^^^^^^^ @@ -1410,8 +1412,7 @@ Interop rules :linenos: //file1.js - let a new ; - export let a = new Array(1, 2, 3, 4, 5); + export let a = new Array(1, 2, 3, 4, 5); export let b = [1, 2, 3, 4 ,5] .. code-block:: typescript @@ -1427,6 +1428,8 @@ Interop rules a.push(6); // ok, will affect original Array b.push(6); // ok, will affect original Array + + Set (empty) *********** -- Gitee From 7152dbf03705b28edcf08c9ca346b95c552ea1d7 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Tue, 14 Jan 2025 10:14:58 +0800 Subject: [PATCH 14/21] InteropJS: updated interop rules arkts2.0 to js ArrayBuffer Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/5_js.rst | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index e0785483b4..b8b31816f6 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1428,8 +1428,6 @@ Interop rules a.push(6); // ok, will affect original Array b.push(6); // ok, will affect original Array - - Set (empty) *********** @@ -1439,6 +1437,38 @@ Map (empty) ArrayBuffer (empty) ******************* +ArrayBuffer stands for byte buffer in JavaScript. ArrayBuffer cannot be directly manipulated. Instead, it's needed to create `TypedArray` or `DataView` to write or read the buffer. + +.. code-block:: javascript + :linenos: + + // file1.js + let buf = new ArrayBuffer(128); + let bytebuf = new Uint8Array(buf); + + // manipulate bytebuf + // ... + +Interop rules +^^^^^^^^^^^^^ +- ``ArrayBuffer`` in ArkTS2.0 is an JS API-compatible object, so it can be passed through interop to ArkTS2.0. Therefore, an ArrayBuffer Object in JavaScript be casted to ab ArrayBuffer object in ArkTS2.0. + +.. code-block:: javascript + :linenos: + + //file1.js + export let buf = new ArrayBuffer(128); + +.. code-block:: typescript + :linenos: + + // file2.ets ArkTS2.0 + + import {buf} from 'file1' + + let array_buffer = buf as ArrayBuffer; // use as operator to casted it. + let int8_array = new Int8Array(buf); // consturctor(array: ArrayLike | ArrayBuffer); // casted to Int8Array if needed. + BigInt64Array (empty) ^^^^^^^^^^^^^^^^^^^^^ -- Gitee From c2cf45fe3c9b3a25ce68fd3093985d9e23bb6635 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Tue, 14 Jan 2025 11:26:41 +0800 Subject: [PATCH 15/21] InteropJS: updated interop rules arkts2.0 to js DateView Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/5_js.rst | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index b8b31816f6..3cd4f17e81 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1505,6 +1505,54 @@ Uint32Array (empty) DataView (empty) **************** +DataView is used to read and write byte buffer. + +.. code-block:: javascript + :linenos: + + // 00 00 00 00 00 00 00 00 + let buf = new ArrayBuffer(8); + let view = new DataView(buf); + + // 00 01 00 00 00 00 00 00 + view.setInt16(0, 1); + + // read as big-endian + // 00 01 00 00 00 00 00 00 + // ^~~~~~~~~~^ + // |--Int32--| High --- Low + console.log(view.getInt32(0)); + + // read as little-endian + // 00 01 00 00 00 00 00 00 + // ^~~~~~~~~~^ + // |--Int32--| Low --- High + console.log(view.getInt32(0, true)); // 256 + +Interop rules +^^^^^^^^^^^^^ + +- ``DataView`` can be passed through interop to ArkTS2.0. An DataView Object in Javascript be casted to an DataView object in ArkTS2.0. + +.. code-block:: javascript + :linenos: + + //file1.js + export let buf = new ArrayBuffer(128); + export let view = new DataView(buf); + +.. code-block:: typescript + :linenos: + + // file2.ets ArkTS2.0 + + import {view} from 'file1' + + console.log(view.getInt32(0, true) as int); // use as ESObject. + + let data_view = view as DataView; // use as operator to casted it. + console.log(data_view.getInt32(0, true)); + Date (empty) ************ -- Gitee From d094d4c2255c77608c952b4cf00ad10bbc11610a Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Tue, 14 Jan 2025 15:05:36 +0800 Subject: [PATCH 16/21] InteropJS: updated interop rules arkts2.0 to ts Symbol Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/6_ts.rst | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/6_ts.rst b/static_core/plugins/ets/doc/interop_js/6_ts.rst index cd24beb831..b4a01e69d9 100644 --- a/static_core/plugins/ets/doc/interop_js/6_ts.rst +++ b/static_core/plugins/ets/doc/interop_js/6_ts.rst @@ -510,6 +510,17 @@ https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html Symbols (empty) *************** +Description +=========== + +Symbol is a primitive date type which stand for a unique symbol(aka symbol value). + +.. code-block:: typescript + :linenos: + + let sym = Symbol(); + console.log(typeof(sym)); // symbol + https://www.typescriptlang.org/docs/handbook/symbols.html - Symbol.asyncIterator @@ -525,6 +536,24 @@ https://www.typescriptlang.org/docs/handbook/symbols.html - Symbol.toStringTag - Symbol.unscopables +Interop rules +============= + +- Primitive type ``symbol`` and Object ``Symbol`` are not supported by ArkTS standard library. Any interop with these types would causes compile time error. + +.. code-block:: typescript + :linenos: + + // file1.ts + export let sym = Symbol(); + +.. code-block:: typescript + :linenos: + + // file2.ets + import { sym } from 'file1'; + console.log(sym); // compile time error + Triple-Slash Directives (empty) ******************************* -- Gitee From ba875783a3a6abb8246ddb82ae03d694056352b9 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Tue, 14 Jan 2025 15:12:37 +0800 Subject: [PATCH 17/21] InteropJS: updated interop rules arkts2.0 to ts Narrowing Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/6_ts.rst | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/6_ts.rst b/static_core/plugins/ets/doc/interop_js/6_ts.rst index b4a01e69d9..f1668fb75d 100644 --- a/static_core/plugins/ets/doc/interop_js/6_ts.rst +++ b/static_core/plugins/ets/doc/interop_js/6_ts.rst @@ -97,8 +97,52 @@ https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#less-common-p Narrowing (empty) ***************** +Description +=========== + +Narrowing can be used to narrow the type of a variable in a conditional block. + +.. code-block:: typescript + :linenos: + + function foo(bar: number | string) { + if(typeof(bar) == "number"){ + console.log(bar.toFixed(2)); // asumeing that bar is number type + } else { + console.log(bar.charAt(0)); // asumeing that bar is string type + } + } + +Interop rules +============= + +- Narrowing is just a feature for type checking. It is safe to use it with ArkTS2.0's type. + +.. code-block:: typescript + :linenos: + + // file1.ets + export class Foo { + bar: int; + } + +.. code-block:: typescript + :linenos: + + // file2.ts + import { Foo } from 'file1'; + function foo(bar: number | Foo) { + if(typeof(bar) == "number"){ + console.log(bar.toFixed(2)); // asumeing that bar is number type + } else { + console.log(bar.bar); // asumeing that bar is Foo type + } + } + https://www.typescriptlang.org/docs/handbook/2/narrowing.html + + Function Type Expressions ************************* -- Gitee From 88e44e2a5bc2d318b1554e1b86de953dbd7a9a9f Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Tue, 14 Jan 2025 16:45:48 +0800 Subject: [PATCH 18/21] InteropJS: updated interop rules arkts2.0 to ts Function Type Expressions Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/6_ts.rst | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/static_core/plugins/ets/doc/interop_js/6_ts.rst b/static_core/plugins/ets/doc/interop_js/6_ts.rst index f1668fb75d..cf59b95be1 100644 --- a/static_core/plugins/ets/doc/interop_js/6_ts.rst +++ b/static_core/plugins/ets/doc/interop_js/6_ts.rst @@ -141,11 +141,55 @@ Interop rules https://www.typescriptlang.org/docs/handbook/2/narrowing.html - - Function Type Expressions ************************* +Description +=========== + +- A function type expression describes a function type, with it's parameters and return type. + +.. code-block:: typescript + :linenos: + + // (x: number) => number is a function type expression, + // it describes a function that takes an int and returns an int + function foo(f: (x: number) => number): number { + return f(1) + 123; + } + +Interop rules +============= + +- A function type described by a function type expression in TypeScript can be auto converted to a function type when interoping with ArkTS2.0. +- Limitation: The types of the parameters and return value of the function type expression must be able to be casted to an ArkTS2.0 type. + +.. code-block:: typescript + :linenos: + + // file1.ets + export function func_good(f: (x: number) => number): number { + return f(1) + 123; + } + + export function func_bad1(f: (x: any) => number): number { + return f(1) + 123; + } + + export function func_bad2(f: (x: symbol) => number): number { + return f(Symbol("bar")) + 123; + } + +.. code-block:: typescript + :linenos: + + // file2.ts + import { func_good, func_bad1, func_bad2 } from 'file1'; + func_good((x: number) => x); // OK, (x: number) => number is casted to (x: number) => number + func_bad1((x: number) => x); // compile time error, any cannot be casted to an ArkTS2.0 type + func_bad2((x: number) => x); // compile time error, symbol cannot be casted to an ArkTS2.0 type + + https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expressions Call Signatures (empty) -- Gitee From 9a8ea825dba851c79fcae204d2a791f61dafd487 Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Wed, 15 Jan 2025 10:05:44 +0800 Subject: [PATCH 19/21] InteropJS: updated interop rules arkts2.0 to ts Call Signatures Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/6_ts.rst | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/6_ts.rst b/static_core/plugins/ets/doc/interop_js/6_ts.rst index cf59b95be1..1b16692435 100644 --- a/static_core/plugins/ets/doc/interop_js/6_ts.rst +++ b/static_core/plugins/ets/doc/interop_js/6_ts.rst @@ -195,6 +195,64 @@ https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expr Call Signatures (empty) *********************** +Description +=========== + +- A call signature describes a callable function with properties. + +.. code-block:: typescript + :linenos: + + type LogHandler = { + name_str: string; + (content: string): void; + } + + function log(content: string, handler: LogHandler) { + console.log("use handler: {handler.name}"); + handler(content); + } + + function log_handler(content: string) { + console.log(content); + } + + log_handler.name_str = "log handler"; + log("log test", log_handler); + +Interop rules +============= + +- Call signatures are not supported by ArkTS2.0. Any interop with call signatures would causes compile time error. + +.. code-block:: typescript + :linenos: + + // file1.ets + export type LogHandler = { + name_str: string; + (content: string): void; + } + + export function log(content: string, handler: LogHandler) { + console.log("use handler: {handler.name}"); + handler(content); + } + + export function log_handler(content: string) { + console.log(content); + } + + log_handler.name_str = "log handler"; + + +.. code-block:: typescript + :linenos: + + // file2.ets + import { log, log_handler } from 'file1'; + log("log test", log_handler); // compile time error + https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures Construct Signatures (empty) -- Gitee From 1092b6c46381185ed44c54a2cd5b0f788c62f46d Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Wed, 15 Jan 2025 16:40:15 +0800 Subject: [PATCH 20/21] InteropJS: updated interop rules arkts2.0 to ts Construct Signatures Signed-off-by: MockMockBlack --- .../plugins/ets/doc/interop_js/6_ts.rst | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/static_core/plugins/ets/doc/interop_js/6_ts.rst b/static_core/plugins/ets/doc/interop_js/6_ts.rst index 1b16692435..41a5f10db9 100644 --- a/static_core/plugins/ets/doc/interop_js/6_ts.rst +++ b/static_core/plugins/ets/doc/interop_js/6_ts.rst @@ -258,11 +258,68 @@ https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures Construct Signatures (empty) **************************** +Description +=========== + +- A construct signature describes a callable function which can be call by ``new`` operator. + +.. code-block:: typescript + :linenos: + + class Foo { + bar: number = 0; + + constructor(bar: number) { + this.bar = bar; + } + } + + type Constructor = { + new (bar: number): Foo; + } + + let MyFooConstructor: Constructor = Foo; + let foo = new MyFooConstructor(123); + console.log(foo.bar); // 123 + +Interop rules +============= + +- Construct signatures are not supported by ArkTS2.0. Any interop with construct signatures would causes compile time error. + +.. code-block:: typescript + :linenos: + + // file1.ets + class Foo { + bar: number = 0; + + constructor(bar: number) { + this.bar = bar; + } + } + + type Constructor = { + new (bar: number): Foo; + } + + export let MyFooConstructor: Constructor = Foo; + +.. code-block:: typescript + :linenos: + + // file2.ets + import { MyFooConstructor } from 'file1'; + + let foo = new MyFooConstructor(123); // compile time error + https://www.typescriptlang.org/docs/handbook/2/functions.html#construct-signatures Generic Functions (empty) ************************* + + https://www.typescriptlang.org/docs/handbook/2/functions.html#construct-signatures Optional Parameters (empty) -- Gitee From 156eebe239e955a2cd0b19556e124f1f0a4dd23d Mon Sep 17 00:00:00 2001 From: MockMockBlack Date: Fri, 3 Jan 2025 15:46:45 +0800 Subject: [PATCH 21/21] InteropJS: add interop rules to closure Signed-off-by: MockMockBlack InteropJS: updated interop rules arkts2.0 to js closure --- .../plugins/ets/doc/interop_js/5_js.rst | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/static_core/plugins/ets/doc/interop_js/5_js.rst b/static_core/plugins/ets/doc/interop_js/5_js.rst index 3cd4f17e81..2b71725a76 100644 --- a/static_core/plugins/ets/doc/interop_js/5_js.rst +++ b/static_core/plugins/ets/doc/interop_js/5_js.rst @@ -1096,6 +1096,8 @@ TODO: to be degussed. Closure (empty) *************** +Closure provides access to the outer scope of a function from inside the inner function, even after the outer function has closed. + Description ^^^^^^^^^^^ @@ -1119,7 +1121,63 @@ Description // calling outer function greet('John'); // Hi John -Closure provides access to the outer scope of a function from inside the inner function, even after the outer function has closed. +Interop rules +^^^^^^^^^^^^^ + +- The closure in JS world will work as expected. So, no additional actions are required. + + +.. code-block:: javascript + :linenos: + + // js file + // handler.js + let handler = null; + + export function initHandler(foo) { + function my_handler() { + console.log("in my_handler"); + console.log(foo.bar); + } + + handler = my_handler; + } + + export function getHandler() { + if (handler === null) { + throw new Error('Handler is not set'); + } + return handler; + } + +.. code-block:: typescript + :linenos: + + // arkts 2.0 file + // init.ets + import { initHandler } from "./handler"; + + class Foo { + bar: string = ""; + } + + export function init() { + let foo = new Foo(); + foo.bar = "this is bar property"; + initHandler(foo); + } + +.. code-block:: typescript + :linenos: + + // arkts 2.0 file + import { init } from "./init"; + import { getHandler } from "./handler"; + + init(); + let handler = getHandler(); // how to handle the closure's lifetime??????? + + handler(); Object of primitive types (empty) ********************************* -- Gitee