diff --git a/.gitee/CODEOWNERS b/.gitee/CODEOWNERS
index d0600cc8da97ce8b5adc2b75ad51a0eb4af605cd..3a02023a8ad054ecc5e0c515c62fb4325bb4b093 100755
--- a/.gitee/CODEOWNERS
+++ b/.gitee/CODEOWNERS
@@ -26,6 +26,9 @@ compiler/test/ut/ @lixingchi1
compiler/test/utForPartialUpdate/ @lixingchi1
compiler/test/utForValidate/ @lixingchi1
compiler/test/transform_ut/ @lixingchi1
+koala-wrapper/native/src/bridges.cc @keerecles
+koala-wrapper/native/src/common.cc @keerecles
+koala-wrapper/native/src/generated/bridges.cc @keerecles
# Code owners for ArkCompiler ace_ets2bundle
diff --git a/BUILD.gn b/BUILD.gn
index 9dd538cb9bdd6f1725ca6e3644a5dbd0e6ec7cce..34b850cf7e93405686b8353d63e4b8ae6902ce80 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -14,12 +14,9 @@
import("//build/ohos.gni")
import("//build/ohos/ace/ace.gni")
import("//build/ohos_var.gni")
+import("//build/templates/bpf/ohos_bpf_config.gni")
import("//foundation/arkui/ace_engine/ace_config.gni")
-if (sdk_build_public) {
- import("//out/sdk-public/public_interface/sdk-js/interface_config.gni")
-} else {
- import("//interface/sdk-js/interface_config.gni")
-}
+import("//interface/sdk-js/interface_config.gni")
ets_loader_lib_dir =
get_label_info(":build_ets_loader_library", "target_out_dir") + "/lib"
@@ -38,13 +35,20 @@ ets_sysResource = get_label_info(":build_ets_sysResource", "target_out_dir") +
"/sysResource.js"
ets_loader_kit_configs_dir = get_label_info(":build_ets_loader_library",
"target_out_dir") + "/kit_configs"
+ets_component_dep = "//interface/sdk-js:ets_component"
+ets_component_out_dir = get_label_info(ets_component_dep, "target_out_dir")
action("build_ets_loader_library") {
deps = [
":components",
":form_components",
- ":install_arkguard_tsc",
+ ":install_arkguard_tsc_declgen",
":server",
+ "//interface/sdk-js:ohos_declaration_ets",
+ "//interface/sdk-js:ets_component",
+ "//interface/sdk-js:bundle_kits",
+ "//interface/sdk-js:bundle_arkts",
+ "//interface/sdk-js:ets_internal_api",
]
script = "build_ets_loader_library.py"
depfile = "$target_gen_dir/$target_name.d"
@@ -63,19 +67,10 @@ action("build_ets_loader_library") {
} else {
_ace_config_dir = "//prebuilts/ace-toolkit/ets-loader/compiler"
}
- _declarations_file_dir = "//interface/sdk-js/api/@internal/component/ets"
- _kit_configs_file_dir = "//interface/sdk-js/kits"
- _kit_apis_file_dir = "//interface/sdk-js/api"
- _arkts_apis_file_dir = "//interface/sdk-js/arkts"
- isPublic = "false"
- if (sdk_build_public) {
- _declarations_file_dir =
- "//out/sdk-public/public_interface/sdk-js/api/@internal/component/ets"
- _kit_configs_file_dir = "//out/sdk-public/public_interface/sdk-js/kits"
- _kit_apis_file_dir = "//out/sdk-public/public_interface/sdk-js/api"
- _arkts_apis_file_dir = "//out/sdk-public/public_interface/sdk-js/arkts"
- isPublic = "true"
- }
+ _declarations_file_dir = ets_component_out_dir + "/${sdk_type}/ets_component"
+ _kit_configs_file_dir = ets_component_out_dir + "/${sdk_type}/bundle_kits"
+ _kit_apis_file_dir = root_out_dir + "/ohos_declaration/${sdk_type}/ohos_declaration_ets"
+ _arkts_apis_file_dir = ets_component_out_dir + "/${sdk_type}/bundle_arkts"
_babel_js = _ace_config_dir + "/node_modules/@babel/cli/bin/babel.js"
_babel_config_js = _ace_config_dir + "/babel.config.js"
@@ -139,7 +134,7 @@ action("build_ets_loader_library") {
"--arkts-apis-file-dir",
rebase_path(_arkts_apis_file_dir, root_build_dir),
"--build-public-sdk",
- isPublic,
+ "${sdk_build_public}",
]
}
@@ -179,7 +174,7 @@ ets_loader_sources = [
ohos_copy("ets_loader") {
deps = [
":build_ets_loader_library",
- ":install_arkguard_tsc",
+ ":install_arkguard_tsc_declgen",
]
sources = ets_loader_sources
deps += [ ":build_ets_sysResource" ]
@@ -266,7 +261,7 @@ ohos_copy("ets_loader_declaration") {
ohos_copy("ets_loader_ark") {
deps = [
":build_ets_loader_library",
- ":install_arkguard_tsc",
+ ":install_arkguard_tsc_declgen",
]
sources = ets_loader_sources
deps += [ ":build_ets_sysResource" ]
@@ -329,20 +324,15 @@ ohos_copy("ets_loader_ark_codegen") {
}
ohos_copy("ohos_declaration_ets_ark") {
- deps = []
- if (sdk_build_public) {
- deps += [ "//out/sdk-public/public_interface/sdk-js:ohos_declaration_ets" ]
- } else {
- deps += [ "//interface/sdk-js:ohos_declaration_ets" ]
- }
+ deps = [ "//interface/sdk-js:ohos_declaration_ets" ]
- sources = [ root_out_dir + "/ohos_declaration/ohos_declaration_ets" ]
+ sources =
+ [ root_out_dir + "/ohos_declaration/${sdk_type}/ohos_declaration_ets" ]
outputs = [ target_out_dir + "/../api" ]
}
-ohos_copy("ets_loader_ark_hap") {
- sources = common_api_src
+group("ets_loader_ark_hap") {
deps = [
":ets_loader_ark",
":ets_loader_ark_codegen",
@@ -353,25 +343,27 @@ ohos_copy("ets_loader_ark_hap") {
":ets_loader_ark_server",
":ohos_declaration_ets_ark",
]
- outputs = [ target_out_dir + "/../../developtools/api/{{source_file_part}}" ]
- module_install_name = ""
}
typescript_dir = get_label_info("//third_party/typescript:build_typescript",
"target_out_dir")
-action("install_arkguard_tsc") {
+action("install_arkguard_tsc_declgen") {
+ static_core = "//arkcompiler/runtime_core/static_core"
deps = [
+ "${static_core}/plugins/ets/tools/declgen_ts2sts:build_declgen",
"//arkcompiler/ets_frontend/arkguard:build_arkguard",
"//third_party/typescript:build_typescript",
]
- script = "install_arkguard_tsc.py"
+ script = "install_arkguard_tsc_declgen.py"
args = [
rebase_path("${typescript_dir}/ohos-typescript-4.9.5-r4.tgz"),
rebase_path(
"${root_out_dir}/obj/arkcompiler/ets_frontend/arkguard/arkguard-1.1.3.tgz"),
rebase_path("//developtools/ace_ets2bundle/compiler"),
current_os,
+ rebase_path(
+ "${root_out_dir}/obj/arkcompiler/runtime_core/static_core/plugins/ets/tools/declgen_ts2sts/panda-declgen-1.0.0.tgz"),
]
outputs = [ "${target_out_dir}/${target_name}.stamp" ]
}
diff --git a/OAT.xml b/OAT.xml
index 3aaf1c1b76a0a76e796bdc2539766f3ea2cca931..eb7f62ab17b4eebd0baa65e29f65ef32859a0351 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -26,6 +26,7 @@
+
diff --git a/arkui-plugins/.gitignore b/arkui-plugins/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..98f9b3e907e12eb5eaac00e962654cb76f9091a0
--- /dev/null
+++ b/arkui-plugins/.gitignore
@@ -0,0 +1,19 @@
+node_modules/
+**/*/node_modules/
+
+**/*/dist/
+**/*/build/
+dist/
+build/
+lib/
+
+*.tgz
+
+package-lock.json
+/**/*/package-lock.json
+
+coverage/
+**/*/generated
+**/*/report
+
+test/demo/localtest/build_config.json
diff --git a/arkui-plugins/.prettierrc b/arkui-plugins/.prettierrc
new file mode 100644
index 0000000000000000000000000000000000000000..e9e9c6fdb49bbeff983dca7cf4474097cf81de5d
--- /dev/null
+++ b/arkui-plugins/.prettierrc
@@ -0,0 +1,8 @@
+{
+ "semi": true,
+ "singleQuote": true,
+ "tabWidth": 4,
+ "trailingComma": "es5",
+ "bracketSpacing": true,
+ "printWidth": 120
+}
\ No newline at end of file
diff --git a/arkui-plugins/BUILD.gn b/arkui-plugins/BUILD.gn
new file mode 100755
index 0000000000000000000000000000000000000000..707355e1d2cf1ab6080c64b7799320b8f742e4c9
--- /dev/null
+++ b/arkui-plugins/BUILD.gn
@@ -0,0 +1,69 @@
+# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build/ohos.gni")
+import("//build/config/components/ets_frontend/ets2abc_config.gni")
+
+npm_path = "//prebuilts/build-tools/common/nodejs/current/bin/npm"
+
+action("gen_ui_plugins") {
+ script = "build_ui_plugins.py"
+ args = [
+ "--source_path",
+ rebase_path(get_path_info(".", "abspath")),
+ "--output_path",
+ rebase_path("$target_gen_dir"),
+ "--npm",
+ rebase_path(npm_path),
+ "--current_os",
+ "$current_os",
+ "--root_out_dir",
+ rebase_path(root_out_dir),
+ ]
+ outputs = [ "$target_gen_dir" ]
+}
+
+action("build_ets_sysResource") {
+ deps = [":gen_ui_plugins"]
+ script = "//developtools/ace_ets2bundle/generateSysResource.py"
+ ets_sysResource = "$target_gen_dir" + "/lib/ui-plugins/sysResource.js"
+ outputs = [ ets_sysResource ]
+
+ _id_defined_json = "//base/global/system_resources/systemres/main/resources/base/element/id_defined.json"
+ inputs = [ _id_defined_json ]
+
+ args = [
+ "--input-json",
+ rebase_path(_id_defined_json, root_build_dir),
+ "--output-js",
+ rebase_path(ets_sysResource, root_build_dir),
+ ]
+}
+
+ohos_copy("ui_plugin") {
+ deps = [":gen_ui_plugins", ":build_ets_sysResource" ]
+ sources = [ rebase_path("$target_gen_dir") ]
+ outputs = [ target_out_dir + "/$target_name" ]
+ module_source_dir = target_out_dir + "/$target_name"
+ module_install_name = ""
+ subsystem_name = "developtools"
+ part_name = "ace_ets2bundle"
+}
+
+ohos_copy("ohos_ets_ui_plugins") {
+ deps = [ ":gen_ui_plugins", ":build_ets_sysResource" ]
+ sources = [ rebase_path("$target_gen_dir") ]
+ outputs = [ ohos_ets_ui_plugins_path ]
+ subsystem_name = "developtools"
+ part_name = "ace_ets2bundle"
+}
\ No newline at end of file
diff --git a/arkui-plugins/babel.config.js b/arkui-plugins/babel.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe3d51b87c5dafb9ae733659c30a7984fd289d48
--- /dev/null
+++ b/arkui-plugins/babel.config.js
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+module.exports = function(api) {
+ api.cache(true);
+
+ const presets = ['@babel/typescript'];
+ const plugins = [
+ '@babel/plugin-transform-modules-commonjs',
+ '@babel/plugin-proposal-class-properties',
+ [
+ '@babel/plugin-transform-arrow-functions',
+ {
+ spec: true
+ }
+ ],
+ './custom-import-plugin'
+ ];
+ const ignore = [
+ '**/test/**',
+ '**/node_modules/**',
+ 'jest-test.config.ts'
+ ];
+
+ return {
+ presets,
+ plugins,
+ ignore
+ };
+};
diff --git a/arkui-plugins/build_ui_plugins.py b/arkui-plugins/build_ui_plugins.py
new file mode 100755
index 0000000000000000000000000000000000000000..6ae5d669e05bb65f03fa3825e81dd7da2ac49eff
--- /dev/null
+++ b/arkui-plugins/build_ui_plugins.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# 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.
+
+import argparse
+import os
+import shutil
+import subprocess
+import sys
+import tarfile
+
+
+def copy_files(source_path, dest_path, is_file=False):
+ try:
+ if is_file:
+ os.makedirs(os.path.dirname(dest_path), exist_ok=True)
+ shutil.copy(source_path, dest_path)
+ else:
+ shutil.copytree(source_path, dest_path, dirs_exist_ok=True,
+ symlinks=True)
+ except Exception as err:
+ raise Exception("Copy files failed. Error: " + str(err)) from err
+
+
+def run_cmd(cmd, execution_path=None):
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=execution_path)
+ stdout, stderr = proc.communicate(timeout=1000)
+ if proc.returncode != 0:
+ raise Exception(stderr.decode())
+
+
+def build(options):
+ build_cmd = [options.npm, 'run', 'compile:plugins']
+ run_cmd(build_cmd, options.source_path)
+
+
+def copy_output(options):
+ run_cmd(['rm', '-rf', options.output_path])
+ copy_files(os.path.join(options.source_path, 'lib'),
+ os.path.join(options.output_path, 'lib'))
+
+ copy_files(os.path.join(options.source_path, '../compiler/components'),
+ os.path.join(options.output_path, 'lib/components'))
+
+ copy_files(os.path.join(options.source_path, 'package.json'),
+ os.path.join(options.output_path, 'package.json'), True)
+
+
+def parse_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--npm', help='path to a npm exetuable')
+ parser.add_argument('--source_path', help='path to build system source')
+ parser.add_argument('--output_path', help='path to output')
+ parser.add_argument('--root_out_dir', help='path to root out')
+ parser.add_argument('--current_os', help='current_os')
+
+ options = parser.parse_args()
+ return options
+
+
+def main():
+ options = parse_args()
+
+ build(options)
+ copy_output(options)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
\ No newline at end of file
diff --git a/arkui-plugins/collectors/memo-collectors/factory.ts b/arkui-plugins/collectors/memo-collectors/factory.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e1d6e17454c127feec7599709a30a131149aec9a
--- /dev/null
+++ b/arkui-plugins/collectors/memo-collectors/factory.ts
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import {
+ addMemoAnnotation,
+ collectMemoFromCallExpression,
+ findCanAddMemoFromArrowFunction,
+ findCanAddMemoFromClassProperty,
+ findCanAddMemoFromMethod,
+ findCanAddMemoFromParameter,
+ findCanAddMemoFromProperty,
+ findCanAddMemoFromTypeAlias,
+} from './utils';
+
+export function findAndCollectMemoableNode(node: arkts.AstNode): arkts.AstNode {
+ const type = arkts.nodeType(node);
+ if (collectByType.has(type)) {
+ return collectByType.get(type)!(node);
+ }
+ return node;
+}
+
+export class factory {
+ static findAndCollectMemoableProperty(node: arkts.Property): arkts.Property {
+ if (findCanAddMemoFromProperty(node)) {
+ addMemoAnnotation(node.value! as arkts.ArrowFunctionExpression);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableClassProperty(node: arkts.ClassProperty): arkts.ClassProperty {
+ if (findCanAddMemoFromClassProperty(node)) {
+ addMemoAnnotation(node);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableTypeAlias(node: arkts.TSTypeAliasDeclaration): arkts.TSTypeAliasDeclaration {
+ if (findCanAddMemoFromTypeAlias(node)) {
+ addMemoAnnotation(node);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableParameter(node: arkts.ETSParameterExpression): arkts.ETSParameterExpression {
+ if (findCanAddMemoFromParameter(node)) {
+ addMemoAnnotation(node);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableMethod(node: arkts.MethodDefinition): arkts.MethodDefinition {
+ if (findCanAddMemoFromMethod(node)) {
+ addMemoAnnotation(node.scriptFunction);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableArrowFunction(node: arkts.ArrowFunctionExpression): arkts.ArrowFunctionExpression {
+ if (findCanAddMemoFromArrowFunction(node)) {
+ addMemoAnnotation(node.scriptFunction);
+ }
+ return node;
+ }
+
+ static findAndCollectMemoableCallExpression(node: arkts.CallExpression): arkts.CallExpression {
+ collectMemoFromCallExpression(node);
+ return node;
+ }
+}
+
+type CollectFactoryFn = (node: any) => arkts.AstNode;
+
+const collectByType = new Map([
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_PROPERTY, factory.findAndCollectMemoableProperty],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, factory.findAndCollectMemoableClassProperty],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_ALIAS_DECLARATION, factory.findAndCollectMemoableTypeAlias],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, factory.findAndCollectMemoableParameter],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, factory.findAndCollectMemoableMethod],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, factory.findAndCollectMemoableArrowFunction],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, factory.findAndCollectMemoableCallExpression],
+]);
diff --git a/arkui-plugins/collectors/memo-collectors/function-collector.ts b/arkui-plugins/collectors/memo-collectors/function-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a2751741f69e1484bdebada2f62f07056ec40d31
--- /dev/null
+++ b/arkui-plugins/collectors/memo-collectors/function-collector.ts
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor } from '../../common/abstract-visitor';
+import {
+ checkIsMemoFromMemoableInfo,
+ collectMemoableInfoInFunctionReturnType,
+ collectMemoableInfoInScriptFunction,
+ collectMemoableInfoInVariableDeclarator,
+ collectMemoableInfoMapInFunctionParams,
+ collectMemoScriptFunctionBody,
+ findIdentifierFromCallee,
+ getDeclResolveAlias,
+ MemoableInfo,
+} from './utils';
+
+export class MemoFunctionCollector extends AbstractVisitor {
+ private returnMemoableInfo: MemoableInfo | undefined;
+ private paramMemoableInfoMap: Map | undefined;
+ private _disableCollectReturn: boolean = false;
+ private _shouldCollectReturn: boolean = true;
+
+ private get shouldCollectReturn(): boolean {
+ if (this._disableCollectReturn) {
+ return false;
+ }
+ return this._shouldCollectReturn;
+ }
+
+ private set shouldCollectReturn(newValue: boolean) {
+ if (this._disableCollectReturn) {
+ return;
+ }
+ this._shouldCollectReturn = newValue;
+ }
+
+ private disableCollectReturnBeforeCallback(callbackFn: () => void): void {
+ const tempValue = this.shouldCollectReturn;
+ this.shouldCollectReturn = false;
+ callbackFn();
+ this.shouldCollectReturn = tempValue;
+ }
+
+ private collectMemoAstNode(node: arkts.AstNode, info: MemoableInfo): void {
+ if (checkIsMemoFromMemoableInfo(info, false)) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ }
+
+ private collectCallWithDeclaredPeerInParamMap(node: arkts.CallExpression, peer: arkts.AstNode['peer']): void {
+ const memoableInfo = this.paramMemoableInfoMap!.get(peer)!;
+ if (checkIsMemoFromMemoableInfo(memoableInfo, true)) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ }
+
+ private collectCallWithDeclaredIdInVariableDeclarator(
+ node: arkts.CallExpression,
+ declarator: arkts.VariableDeclarator
+ ): void {
+ const shouldCollect =
+ arkts.NodeCache.getInstance().has(declarator) ||
+ (!!declarator.initializer && arkts.NodeCache.getInstance().has(declarator.initializer));
+ if (shouldCollect) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ }
+
+ private visitVariableDeclarator(node: arkts.VariableDeclarator): arkts.AstNode {
+ let memoableInfo: MemoableInfo;
+ if (this.paramMemoableInfoMap?.has(node.name.peer)) {
+ memoableInfo = this.paramMemoableInfoMap.get(node.name.peer)!;
+ } else {
+ memoableInfo = collectMemoableInfoInVariableDeclarator(node);
+ }
+ this.collectMemoAstNode(node, memoableInfo);
+ if (!node.initializer) {
+ return node;
+ }
+ if (arkts.isArrowFunctionExpression(node.initializer)) {
+ const localInfo = collectMemoableInfoInScriptFunction(node.initializer.scriptFunction);
+ const shouldCollectParameter =
+ (localInfo.hasBuilder || localInfo.hasMemo) && !localInfo.hasMemoEntry && !localInfo.hasMemoIntrinsic;
+ const shouldCollectReturn =
+ localInfo.hasBuilder || localInfo.hasMemo || memoableInfo.hasBuilder || memoableInfo.hasMemo;
+ const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(node.initializer.scriptFunction);
+ const [paramMemoableInfoMap, gensymCount] = collectMemoableInfoMapInFunctionParams(
+ node.initializer.scriptFunction,
+ shouldCollectParameter
+ );
+ if (
+ !!node.initializer.scriptFunction.body &&
+ arkts.isBlockStatement(node.initializer.scriptFunction.body)
+ ) {
+ collectMemoScriptFunctionBody(
+ node.initializer.scriptFunction.body,
+ returnMemoableInfo,
+ paramMemoableInfoMap,
+ gensymCount,
+ !shouldCollectReturn
+ );
+ }
+ return node;
+ }
+ this.shouldCollectReturn = !!memoableInfo.hasMemo || !!memoableInfo.hasBuilder;
+ this.visitor(node.initializer);
+ return node;
+ }
+
+ private visitCallExpression(node: arkts.CallExpression): arkts.AstNode {
+ if (arkts.NodeCache.getInstance().has(node)) {
+ this.disableCollectReturnBeforeCallback(() => {
+ this.visitEachChild(node);
+ });
+ return node;
+ }
+ const expr = findIdentifierFromCallee(node.expression);
+ const decl = (expr && getDeclResolveAlias(expr)) ?? node.expression;
+ if (!decl) {
+ this.disableCollectReturnBeforeCallback(() => {
+ this.visitEachChild(node);
+ });
+ return node;
+ }
+ if (arkts.NodeCache.getInstance().has(decl)) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ if (this.paramMemoableInfoMap?.has(decl.peer)) {
+ this.collectCallWithDeclaredPeerInParamMap(node, decl.peer);
+ } else if (arkts.isEtsParameterExpression(decl) && this.paramMemoableInfoMap?.has(decl.identifier.peer)) {
+ this.collectCallWithDeclaredPeerInParamMap(node, decl.identifier.peer);
+ } else if (arkts.isIdentifier(decl) && !!decl.parent && arkts.isVariableDeclarator(decl.parent)) {
+ this.collectCallWithDeclaredIdInVariableDeclarator(node, decl.parent);
+ }
+ this.disableCollectReturnBeforeCallback(() => {
+ this.visitEachChild(node);
+ });
+ return node;
+ }
+
+ private visitIdentifier(node: arkts.Identifier): arkts.AstNode {
+ const decl = getDeclResolveAlias(node);
+ if (!decl) {
+ return node;
+ }
+ if (this.paramMemoableInfoMap?.has(decl.peer)) {
+ arkts.NodeCache.getInstance().collect(node);
+ } else if (arkts.isEtsParameterExpression(decl) && this.paramMemoableInfoMap?.has(decl.identifier.peer)) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ return node;
+ }
+
+ private visitReturnStatement(node: arkts.ReturnStatement): arkts.AstNode {
+ if (!!this.returnMemoableInfo && !!node.argument && arkts.isArrowFunctionExpression(node.argument)) {
+ this.collectMemoAstNode(node.argument, this.returnMemoableInfo);
+ }
+ arkts.NodeCache.getInstance().collect(node);
+ this.visitEachChild(node);
+ return node;
+ }
+
+ registerReturnInfo(info: MemoableInfo): this {
+ this.returnMemoableInfo = info;
+ return this;
+ }
+
+ registerParamInfoMap(infoMap: Map): this {
+ this.paramMemoableInfoMap = infoMap;
+ return this;
+ }
+
+ disableCollectReturn(): this {
+ this._disableCollectReturn = true;
+ return this;
+ }
+
+ enableCollectReturn(): this {
+ this._disableCollectReturn = false;
+ return this;
+ }
+
+ reset(): void {
+ this.returnMemoableInfo = undefined;
+ this.paramMemoableInfoMap = undefined;
+ this._shouldCollectReturn = true;
+ this._disableCollectReturn = false;
+ }
+
+ visitor(node: arkts.AstNode): arkts.AstNode {
+ if (arkts.isVariableDeclarator(node)) {
+ return this.visitVariableDeclarator(node);
+ }
+ if (arkts.isCallExpression(node)) {
+ return this.visitCallExpression(node);
+ }
+ if (!!this.paramMemoableInfoMap && arkts.isIdentifier(node)) {
+ return this.visitIdentifier(node);
+ }
+ if (arkts.isReturnStatement(node) && this.shouldCollectReturn) {
+ return this.visitReturnStatement(node);
+ }
+ if (
+ arkts.isArrowFunctionExpression(node) &&
+ !arkts.NodeCache.getInstance().has(node) &&
+ !arkts.NodeCache.getInstance().has(node.scriptFunction)
+ ) {
+ this.shouldCollectReturn = false;
+ }
+ return this.visitEachChild(node);
+ }
+}
diff --git a/arkui-plugins/collectors/memo-collectors/memo-visitor.ts b/arkui-plugins/collectors/memo-collectors/memo-visitor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..233288748cbc9a087514119c0bedda40679fb7d3
--- /dev/null
+++ b/arkui-plugins/collectors/memo-collectors/memo-visitor.ts
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor } from '../../common/abstract-visitor';
+import { findAndCollectMemoableNode } from './factory';
+
+export class MemoVisitor extends AbstractVisitor {
+ visitor(node: arkts.AstNode): arkts.AstNode {
+ const newNode = this.visitEachChild(node);
+ findAndCollectMemoableNode(newNode);
+ return newNode;
+ }
+}
diff --git a/arkui-plugins/collectors/memo-collectors/utils.ts b/arkui-plugins/collectors/memo-collectors/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1fe12a46dd257bc80b6eeb2725499b52d8b25a9a
--- /dev/null
+++ b/arkui-plugins/collectors/memo-collectors/utils.ts
@@ -0,0 +1,842 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { annotation, forEachArgWithParam, isDecoratorAnnotation } from '../../common/arkts-utils';
+import { ImportCollector } from '../../common/import-collector';
+import { DecoratorNames, GenSymPrefix, MEMO_IMPORT_SOURCE_NAME } from '../../common/predefines';
+import { MemoFunctionCollector } from './function-collector';
+
+export enum MemoNames {
+ MEMO = 'memo',
+ MEMO_SKIP = 'memo_skip',
+ MEMO_INTRINSIC = 'memo_intrinsic',
+ MEMO_ENTRY = 'memo_entry',
+}
+
+export type MemoAstNode =
+ | arkts.ScriptFunction
+ | arkts.ETSParameterExpression
+ | arkts.ClassProperty
+ | arkts.TSTypeAliasDeclaration
+ | arkts.ETSFunctionType
+ | arkts.ArrowFunctionExpression
+ | arkts.ETSUnionType
+ | arkts.VariableDeclaration;
+
+interface MemoableAnnotationInfo {
+ hasMemo?: boolean;
+ hasMemoSkip?: boolean;
+ hasMemoIntrinsic?: boolean;
+ hasMemoEntry?: boolean;
+ hasBuilder?: boolean;
+ hasBuilderParam?: boolean;
+}
+
+export type MemoableInfo = MemoableAnnotationInfo & {
+ hasProperType?: boolean;
+};
+
+export function isMemoAnnotation(node: arkts.AnnotationUsage, memoName: MemoNames): boolean {
+ return node.expr !== undefined && arkts.isIdentifier(node.expr) && node.expr.name === memoName;
+}
+
+export function hasMemoAnnotation(node: T): boolean {
+ return node.annotations.some((it) => isMemoAnnotation(it, MemoNames.MEMO));
+}
+
+export function addMemoAnnotation(node: T, memoName: MemoNames = MemoNames.MEMO): T {
+ collectMemoAnnotationSource(memoName);
+ if (arkts.isETSUnionType(node)) {
+ return arkts.factory.updateUnionType(
+ node,
+ node.types.map((type) => {
+ if (arkts.isETSFunctionType(type)) {
+ return addMemoAnnotation(type, memoName);
+ }
+ return type;
+ })
+ ) as T;
+ }
+ const newAnnotations: arkts.AnnotationUsage[] = [
+ ...node.annotations.filter((it) => !isMemoAnnotation(it, memoName)),
+ annotation(memoName),
+ ];
+ collectMemoAnnotationImport(memoName);
+ if (arkts.isEtsParameterExpression(node)) {
+ node.annotations = newAnnotations;
+ arkts.NodeCache.getInstance().collect(node);
+ return node;
+ }
+ const newNode = node.setAnnotations(newAnnotations) as T;
+ arkts.NodeCache.getInstance().collect(newNode);
+ return newNode;
+}
+
+export function hasMemoableAnnotation(node: T): MemoableAnnotationInfo {
+ let hasBuilder: boolean = false;
+ let hasBuilderParam: boolean = false;
+ let hasMemo: boolean = false;
+ let hasMemoSkip: boolean = false;
+ let hasMemoIntrinsic: boolean = false;
+ let hasMemoEntry: boolean = false;
+ node.annotations.forEach((it) => {
+ hasBuilder ||= isDecoratorAnnotation(it, DecoratorNames.BUILDER);
+ hasBuilderParam ||= isDecoratorAnnotation(it, DecoratorNames.BUILDER_PARAM);
+ hasMemo ||= isMemoAnnotation(it, MemoNames.MEMO);
+ hasMemoSkip ||= isMemoAnnotation(it, MemoNames.MEMO_SKIP);
+ hasMemoIntrinsic ||= isMemoAnnotation(it, MemoNames.MEMO_INTRINSIC);
+ hasMemoEntry ||= isMemoAnnotation(it, MemoNames.MEMO_ENTRY);
+ });
+ return {
+ ...(hasMemo ? { hasMemo } : {}),
+ ...(hasMemoSkip ? { hasMemoSkip } : {}),
+ ...(hasMemoIntrinsic ? { hasMemoIntrinsic } : {}),
+ ...(hasMemoEntry ? { hasMemoEntry } : {}),
+ ...(hasBuilder ? { hasBuilder } : {}),
+ ...(hasBuilderParam ? { hasBuilderParam } : {}),
+ };
+}
+
+export function collectMemoAnnotationImport(memoName: MemoNames = MemoNames.MEMO): void {
+ ImportCollector.getInstance().collectImport(memoName);
+}
+
+export function collectMemoAnnotationSource(memoName: MemoNames = MemoNames.MEMO): void {
+ ImportCollector.getInstance().collectSource(memoName, MEMO_IMPORT_SOURCE_NAME);
+}
+
+export function collectMemoableInfoInUnionType(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isETSUnionType(node)) {
+ return currInfo;
+ }
+ node.types.forEach((t) => {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInTypeReference(t),
+ ...collectMemoableInfoInFunctionType(t),
+ ...collectMemoableInfoInUnionType(t),
+ };
+ });
+ currInfo = { ...currInfo, ...hasMemoableAnnotation(node) };
+ return currInfo;
+}
+
+export function collectMemoableInfoInTypeReference(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isETSTypeReference(node) || !node.part || !arkts.isETSTypeReferencePart(node.part)) {
+ return currInfo;
+ }
+ const expr = node.part.name;
+ let decl: arkts.AstNode | undefined;
+ if (!expr || !(decl = arkts.getDecl(expr))) {
+ return currInfo;
+ }
+ return {
+ ...currInfo,
+ ...collectMemoableInfoInTypeAlias(decl),
+ };
+}
+
+export function collectMemoableInfoInFunctionType(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isETSFunctionType(node)) {
+ return currInfo;
+ }
+ currInfo.hasProperType = true;
+ currInfo = { ...currInfo, ...hasMemoableAnnotation(node) };
+ return currInfo;
+}
+
+export function collectMemoableInfoInTypeAlias(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isTSTypeAliasDeclaration(node)) {
+ return currInfo;
+ }
+ currInfo = {
+ ...currInfo,
+ ...hasMemoableAnnotation(node),
+ };
+ if (!!node.typeAnnotation) {
+ return {
+ ...currInfo,
+ ...collectMemoableInfoInType(node.typeAnnotation),
+ };
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInParameter(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isEtsParameterExpression(node)) {
+ return currInfo;
+ }
+ currInfo = {
+ ...currInfo,
+ ...hasMemoableAnnotation(node),
+ };
+ if (!!node.type) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInType(node.type),
+ };
+ }
+ if (!!node.initializer) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInArrowFunction(node.initializer),
+ };
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInVariableDeclarator(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isVariableDeclarator(node)) {
+ return currInfo;
+ }
+ if (!!node.name.typeAnnotation) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInType(node.name.typeAnnotation),
+ };
+ }
+ if (!!node.initializer && arkts.isArrowFunctionExpression(node.initializer)) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInArrowFunction(node.initializer),
+ };
+ }
+ if (!!node.parent && arkts.isVariableDeclaration(node.parent)) {
+ currInfo = {
+ ...currInfo,
+ ...hasMemoableAnnotation(node.parent),
+ };
+ }
+ const decl = arkts.getDecl(node.name);
+ if (!decl) {
+ return currInfo;
+ }
+ if (arkts.isMethodDefinition(decl)) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInScriptFunction(decl.scriptFunction),
+ };
+ } else if (arkts.isClassProperty(decl)) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInClassProperty(decl),
+ };
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInProperty(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ const property = node as arkts.Property;
+ const hasProperType = !!property.value && arkts.isArrowFunctionExpression(property.value);
+ return { ...currInfo, hasMemo: true, hasProperType };
+ }
+ if (!arkts.isProperty(node) || !node.key || !arkts.isIdentifier(node.key)) {
+ return currInfo;
+ }
+ const decl = arkts.getDecl(node.key);
+ if (!decl || !arkts.isMethodDefinition(decl)) {
+ return currInfo;
+ }
+ const hasReceiver = decl.scriptFunction.hasReceiver;
+ const isSetter = decl.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET;
+ const isGetter = decl.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET;
+ let newInfo: MemoableInfo = {};
+ if (isSetter && decl.scriptFunction.params.length > 0) {
+ if (hasReceiver && decl.scriptFunction.params.length === 2) {
+ newInfo = collectMemoableInfoInParameter(decl.scriptFunction.params.at(1)!);
+ } else {
+ newInfo = collectMemoableInfoInParameter(decl.scriptFunction.params.at(0)!);
+ }
+ } else if (isGetter) {
+ newInfo = collectMemoableInfoInFunctionReturnType(decl.scriptFunction);
+ }
+ currInfo = { ...currInfo, ...collectMemoableInfoInScriptFunction(decl.scriptFunction), ...newInfo };
+ currInfo.hasProperType = false;
+ if (!!node.value && arkts.isArrowFunctionExpression(node.value)) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInScriptFunction(node.value.scriptFunction),
+ };
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInClassProperty(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isClassProperty(node)) {
+ return currInfo;
+ }
+ currInfo = { ...currInfo, ...hasMemoableAnnotation(node) };
+ if (!!node.typeAnnotation) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInType(node.typeAnnotation),
+ };
+ }
+ if (!!node.value) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInArrowFunction(node.value),
+ };
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInArrowFunction(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isArrowFunctionExpression(node)) {
+ return currInfo;
+ }
+ currInfo.hasProperType = true;
+ currInfo = { ...currInfo, ...hasMemoableAnnotation(node) };
+ if (!!node.scriptFunction) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInScriptFunction(node.scriptFunction),
+ };
+ }
+ if (!!node.parent && arkts.isAssignmentExpression(node.parent) && !!node.parent.left) {
+ const expr = arkts.isMemberExpression(node.parent.left) ? node.parent.left.property : node.parent.left;
+ const decl = arkts.getDecl(expr);
+ if (!decl) {
+ return currInfo;
+ }
+ if (arkts.isClassProperty(decl)) {
+ currInfo = {
+ ...currInfo,
+ ...collectMemoableInfoInClassProperty(decl),
+ };
+ }
+ }
+ return currInfo;
+}
+
+export function collectMemoableInfoInScriptFunction(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return { ...currInfo, hasMemo: true, hasProperType: true };
+ }
+ if (!arkts.isScriptFunction(node)) {
+ return currInfo;
+ }
+ currInfo.hasProperType = true;
+ currInfo = { ...currInfo, ...hasMemoableAnnotation(node) };
+ return currInfo;
+}
+
+export function collectMemoableInfoInMethod(node: arkts.MethodDefinition): MemoableInfo {
+ const hasReceiver = node.scriptFunction.hasReceiver;
+ const isSetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET;
+ const isGetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET;
+ let info: MemoableInfo = {};
+ if (isSetter && node.scriptFunction.params.length > 0) {
+ if (hasReceiver && node.scriptFunction.params.length === 2) {
+ info = collectMemoableInfoInParameter(node.scriptFunction.params.at(1)!);
+ } else {
+ info = collectMemoableInfoInParameter(node.scriptFunction.params.at(0)!);
+ }
+ } else if (isGetter) {
+ info = collectMemoableInfoInFunctionReturnType(node.scriptFunction);
+ }
+ return collectMemoableInfoInScriptFunction(node.scriptFunction, info);
+}
+
+export function collectMemoableInfoInType(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo {
+ let currInfo = info ?? {};
+ return {
+ ...currInfo,
+ ...collectMemoableInfoInFunctionType(node),
+ ...collectMemoableInfoInUnionType(node),
+ ...collectMemoableInfoInTypeReference(node),
+ };
+}
+
+export function collectMemoableInfoInFunctionReturnType(node: arkts.ScriptFunction): MemoableInfo {
+ if (!!node.returnTypeAnnotation) {
+ let memoableInfo: MemoableInfo;
+ if (arkts.NodeCache.getInstance().has(node.returnTypeAnnotation)) {
+ memoableInfo = { hasMemo: true, hasProperType: true };
+ } else {
+ memoableInfo = collectMemoableInfoInType(node.returnTypeAnnotation);
+ }
+ if ((memoableInfo.hasMemo || memoableInfo.hasBuilder) && memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(node.returnTypeAnnotation);
+ }
+ return memoableInfo;
+ }
+ return {};
+}
+
+export function collectGensymDeclarator(declarator: arkts.VariableDeclarator, info: MemoableInfo): void {
+ if (!info.hasMemo && !info.hasBuilder) {
+ return;
+ }
+ arkts.NodeCache.getInstance().collect(declarator);
+ const initializer = declarator.initializer;
+ if (!initializer || !arkts.isConditionalExpression(initializer)) {
+ return;
+ }
+ const alternate = initializer.alternate;
+ if (!alternate) {
+ return;
+ }
+ let arrowFunc: arkts.ArrowFunctionExpression | undefined;
+ if (arkts.isTSAsExpression(alternate) && !!alternate.expr && arkts.isArrowFunctionExpression(alternate.expr)) {
+ arrowFunc = alternate.expr;
+ } else if (arkts.isArrowFunctionExpression(alternate)) {
+ arrowFunc = alternate;
+ }
+ if (!!arrowFunc) {
+ const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(arrowFunc.scriptFunction);
+ const [paramMemoableInfoMap, gensymCount] = collectMemoableInfoMapInFunctionParams(arrowFunc.scriptFunction);
+ if (!!arrowFunc.scriptFunction.body && arkts.isBlockStatement(arrowFunc.scriptFunction.body)) {
+ collectMemoScriptFunctionBody(
+ arrowFunc.scriptFunction.body,
+ returnMemoableInfo,
+ paramMemoableInfoMap,
+ gensymCount
+ );
+ }
+ }
+}
+
+export function collectMemoableInfoMapInFunctionParams(
+ node: arkts.ScriptFunction,
+ shouldCollectParameter: boolean = true
+): [Map, number] {
+ const hasReceiver = node.hasReceiver;
+ const paramMap: Map = new Map();
+ let gensymCount: number = 0;
+ node.params.slice(hasReceiver ? 1 : 0).forEach((p) => {
+ const info = collectMemoableInfoInFunctionParam(node, p, gensymCount, shouldCollectParameter);
+ gensymCount = info.gensymCount;
+ info.peers.forEach((peer) => paramMap.set(peer, info.memoableInfo));
+ });
+ return [paramMap, gensymCount];
+}
+
+interface FunctionParamCollectInfo {
+ peers: arkts.AstNode['peer'][];
+ gensymCount: number;
+ memoableInfo: MemoableInfo;
+}
+
+function collectMemoableInfoInFunctionParam(
+ node: arkts.ScriptFunction,
+ param: arkts.Expression,
+ gensymCount: number,
+ shouldCollectParameter: boolean = true
+): FunctionParamCollectInfo {
+ const peers: arkts.AstNode['peer'][] = [];
+ let memoableInfo: MemoableInfo;
+ const _param = param as arkts.ETSParameterExpression;
+ if (arkts.NodeCache.getInstance().has(_param)) {
+ const metadata = arkts.NodeCache.getInstance().get(_param)!.metadata ?? {};
+ const { hasMemoSkip } = metadata;
+ memoableInfo = { hasMemo: true, hasMemoSkip, hasProperType: true };
+ } else {
+ memoableInfo = collectMemoableInfoInParameter(_param);
+ }
+ if (_param.identifier.name.startsWith(GenSymPrefix.INTRINSIC) && !!node.body && arkts.isBlockStatement(node.body)) {
+ const declaration = node.body.statements.at(gensymCount);
+ if (!!declaration && arkts.isVariableDeclaration(declaration) && declaration.declarators.length > 0) {
+ const declarator = declaration.declarators[0];
+ collectGensymDeclarator(declarator, memoableInfo);
+ if (!memoableInfo.hasMemoSkip && shouldCollectParameter) {
+ peers.push(declarator.name.peer);
+ }
+ gensymCount++;
+ }
+ }
+ if (checkIsMemoFromMemoableInfo(memoableInfo)) {
+ arkts.NodeCache.getInstance().collect(_param, { hasMemoSkip: memoableInfo.hasMemoSkip });
+ }
+ if (!memoableInfo.hasMemoSkip && shouldCollectParameter) {
+ peers.push(_param.identifier.peer);
+ }
+ return { peers, memoableInfo, gensymCount };
+}
+
+/**
+ * Collect `@memo` annotated `arkts.TypeNode` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.TypeNode` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromTypeAnnotation(
+ typeAnnotation: arkts.AstNode | undefined
+): typeAnnotation is arkts.ETSFunctionType {
+ if (!typeAnnotation) {
+ return false;
+ }
+ const memoableInfo = collectMemoableInfoInType(typeAnnotation);
+ if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(typeAnnotation);
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.Property` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.Property` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromProperty(property: arkts.AstNode): property is arkts.Property {
+ const memoableInfo = collectMemoableInfoInProperty(property);
+ if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(property);
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.ClassProperty` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.ClassProperty` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromClassProperty(property: arkts.AstNode): property is arkts.ClassProperty {
+ const memoableInfo = collectMemoableInfoInClassProperty(property);
+ if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(property);
+ }
+ return (
+ (!!memoableInfo.hasBuilder || !!memoableInfo.hasBuilderParam) &&
+ !memoableInfo.hasMemo &&
+ !!memoableInfo.hasProperType
+ );
+}
+
+/**
+ * Collect `@memo` annotated `arkts.ETSParameterExpression` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.ETSParameterExpression` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromParameter(param: arkts.AstNode | undefined): param is arkts.ETSParameterExpression {
+ if (!param) {
+ return false;
+ }
+ const memoableInfo = collectMemoableInfoInParameter(param);
+ if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(param, { hasMemoSkip: memoableInfo.hasMemoSkip });
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.ArrowFunctionExpression` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.ArrowFunctionExpression` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromArrowFunction(node: arkts.AstNode): node is arkts.ArrowFunctionExpression {
+ if (!arkts.isArrowFunctionExpression(node)) {
+ return false;
+ }
+ const memoableInfo = collectMemoableInfoInArrowFunction(node);
+ const { hasMemoEntry, hasMemoIntrinsic } = memoableInfo;
+ const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(node.scriptFunction);
+ const [paramMemoableInfoMap, gensymCount] = collectMemoableInfoMapInFunctionParams(
+ node.scriptFunction,
+ !hasMemoEntry && !hasMemoIntrinsic
+ );
+ const isMemoReturnType = checkIsMemoFromMemoableInfo(returnMemoableInfo);
+ if (isMemoReturnType) {
+ arkts.NodeCache.getInstance().collect(node.scriptFunction.returnTypeAnnotation!);
+ }
+ const isMemo = checkIsMemoFromMemoableInfo(memoableInfo);
+ if (isMemo && !arkts.NodeCache.getInstance().has(node)) {
+ arkts.NodeCache.getInstance().collect(node, { hasMemoEntry, hasMemoIntrinsic });
+ if (!!node.scriptFunction.body && arkts.isBlockStatement(node.scriptFunction.body)) {
+ const disableCollectReturn = hasMemoEntry || hasMemoIntrinsic;
+ collectMemoScriptFunctionBody(
+ node.scriptFunction.body,
+ returnMemoableInfo,
+ paramMemoableInfoMap,
+ gensymCount,
+ disableCollectReturn
+ );
+ }
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.TSTypeAliasDeclaration` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.TSTypeAliasDeclaration` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromTypeAlias(node: arkts.AstNode): node is arkts.TSTypeAliasDeclaration {
+ const memoableInfo = collectMemoableInfoInTypeAlias(node);
+ if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) {
+ arkts.NodeCache.getInstance().collect(node);
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.MethodDefinition` node. And find whether it can be `@memo` annotated.
+ *
+ * @param node `arkts.MethodDefinition` node.
+ * @returns true if it is not `@memo` annotated but can add `@memo` to it.
+ */
+export function findCanAddMemoFromMethod(node: arkts.AstNode): node is arkts.MethodDefinition {
+ if (!arkts.isMethodDefinition(node)) {
+ return false;
+ }
+ const memoableInfo = collectMemoableInfoInMethod(node);
+ const { hasMemoEntry, hasMemoIntrinsic } = memoableInfo;
+ const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(node.scriptFunction);
+ const [paramMemoableInfoMap, gensymCount] = collectMemoableInfoMapInFunctionParams(
+ node.scriptFunction,
+ !hasMemoEntry && !hasMemoIntrinsic
+ );
+ const isMemo = checkIsMemoFromMemoableInfo(memoableInfo);
+ const isMemoReturnType = checkIsMemoFromMemoableInfo(returnMemoableInfo);
+ if (isMemoReturnType) {
+ arkts.NodeCache.getInstance().collect(node.scriptFunction.returnTypeAnnotation!);
+ }
+ if (isMemo && !arkts.NodeCache.getInstance().has(node)) {
+ const metadata = collectMetadataInMethod(node);
+ arkts.NodeCache.getInstance().collect(node, {
+ ...metadata,
+ hasMemoEntry,
+ hasMemoIntrinsic,
+ });
+ if (!!node.scriptFunction.body && arkts.isBlockStatement(node.scriptFunction.body)) {
+ const disableCollectReturn = hasMemoEntry || hasMemoIntrinsic;
+ collectMemoScriptFunctionBody(
+ node.scriptFunction.body,
+ returnMemoableInfo,
+ paramMemoableInfoMap,
+ gensymCount,
+ disableCollectReturn
+ );
+ }
+ }
+ return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType;
+}
+
+/**
+ * Collect `@memo` annotated `arkts.CallExpression` node from corresponding declared method,
+ * as well as collect each `@memo` annotated argument from corresponding declared method parameter.
+ *
+ * @param node `arkts.CallExpression` node.
+ */
+export function collectMemoFromCallExpression(node: arkts.CallExpression): void {
+ if (arkts.NodeCache.getInstance().has(node)) {
+ return;
+ }
+ const expr = findIdentifierFromCallee(node.expression);
+ const decl = (expr && getDeclResolveAlias(expr)) ?? node.expression;
+ if (!decl) {
+ return;
+ }
+ let isCollected: boolean = false;
+ if (arkts.NodeCache.getInstance().has(decl)) {
+ arkts.NodeCache.getInstance().collect(node);
+ isCollected = true;
+ }
+ if (arkts.isMethodDefinition(decl)) {
+ isCollected = collectCallWithDeclaredMethod(node, decl);
+ } else if (arkts.isClassProperty(decl)) {
+ isCollected = collectCallWithDeclaredClassProperty(node, decl);
+ }
+ if (isCollected && arkts.isTSAsExpression(node.expression) && node.expression.typeAnnotation) {
+ arkts.NodeCache.getInstance().collect(node.expression.typeAnnotation);
+ }
+}
+
+export function collectCallWithDeclaredClassProperty(node: arkts.CallExpression, decl: arkts.ClassProperty): boolean {
+ if (arkts.NodeCache.getInstance().has(decl)) {
+ arkts.NodeCache.getInstance().collect(node);
+ return true;
+ }
+ const memoableInfo = collectMemoableInfoInClassProperty(decl);
+ if (checkIsMemoFromMemoableInfo(memoableInfo, false) || memoableInfo.hasBuilder || memoableInfo.hasBuilderParam) {
+ arkts.NodeCache.getInstance().collect(node);
+ return true;
+ }
+ return false;
+}
+
+export function collectCallWithDeclaredMethod(node: arkts.CallExpression, decl: arkts.MethodDefinition): boolean {
+ const hasReceiver = decl.scriptFunction.hasReceiver;
+ const params = decl.scriptFunction.params;
+ const args = node.arguments;
+ const hasRestParameter = decl.scriptFunction.hasRestParameter;
+ const isTrailingCall = node.isTrailingCall;
+ const options = { hasRestParameter, isTrailingCall };
+ forEachArgWithParam(args, params, collectCallArgsWithMethodParams, options);
+ if (arkts.NodeCache.getInstance().has(decl)) {
+ const { hasMemoEntry, hasMemoIntrinsic } = arkts.NodeCache.getInstance().get(decl)!.metadata ?? {};
+ arkts.NodeCache.getInstance().collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic });
+ return true;
+ } else {
+ const memoableInfo = collectMemoableInfoInScriptFunction(decl.scriptFunction);
+ if (checkIsMemoFromMemoableInfo(memoableInfo, true)) {
+ const { hasMemoEntry, hasMemoIntrinsic } = memoableInfo;
+ arkts.NodeCache.getInstance().collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic });
+ return true;
+ }
+ }
+ return false;
+}
+
+export function collectCallArgsWithMethodParams(arg: arkts.Expression | undefined, param: arkts.Expression): void {
+ if (!arg) {
+ return;
+ }
+ let info: MemoableInfo;
+ if (arkts.NodeCache.getInstance().has(param)) {
+ info = { hasMemo: true, hasProperType: true };
+ } else {
+ info = collectMemoableInfoInParameter(param);
+ }
+ if (checkIsMemoFromMemoableInfo(info) && arkts.isArrowFunctionExpression(arg)) {
+ arkts.NodeCache.getInstance().collect(arg);
+ const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(arg.scriptFunction);
+ const [paramMemoableInfoMap, gensymCount] = collectMemoableInfoMapInFunctionParams(arg.scriptFunction);
+ if (!!arg.scriptFunction.body && arkts.isBlockStatement(arg.scriptFunction.body)) {
+ collectMemoScriptFunctionBody(
+ arg.scriptFunction.body,
+ returnMemoableInfo,
+ paramMemoableInfoMap,
+ gensymCount
+ );
+ }
+ }
+}
+
+export function findIdentifierFromCallee(callee: arkts.AstNode | undefined): arkts.Identifier | undefined {
+ if (!callee) {
+ return undefined;
+ }
+ if (arkts.isIdentifier(callee)) {
+ return callee;
+ }
+ if (arkts.isMemberExpression(callee)) {
+ return findIdentifierFromCallee(callee.property);
+ }
+ if (arkts.isTSAsExpression(callee)) {
+ return findIdentifierFromCallee(callee.expr);
+ }
+ if (arkts.isTSNonNullExpression(callee)) {
+ return findIdentifierFromCallee(callee.expr);
+ }
+ return undefined;
+}
+
+export function collectMemoScriptFunctionBody(
+ body: arkts.BlockStatement,
+ returnMemoableInfo: MemoableInfo,
+ paramMemoableInfoMap: Map,
+ gensymCount: number,
+ disableCollectReturn?: boolean
+): void {
+ const collector = new MemoFunctionCollector();
+ body.statements.forEach((st, index) => {
+ if (index < gensymCount) {
+ return;
+ }
+ if (disableCollectReturn) {
+ collector.disableCollectReturn();
+ }
+ collector.registerReturnInfo(returnMemoableInfo).registerParamInfoMap(paramMemoableInfoMap).visitor(st);
+ collector.reset();
+ });
+}
+
+export function collectMetadataInMethod(node: arkts.MethodDefinition): arkts.AstNodeCacheValue['metadata'] {
+ const callName = node.name.name;
+ const hasReceiver = node.scriptFunction.hasReceiver;
+ const isSetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET;
+ const isGetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET;
+ return { callName, hasReceiver, isSetter, isGetter };
+}
+
+export function checkIsMemoFromMemoableInfo(info: MemoableInfo, ignoreType: boolean = false): boolean {
+ return (
+ (!!info.hasMemo || !!info.hasMemoIntrinsic || !!info.hasMemoEntry || !!info.hasBuilder) &&
+ (ignoreType || !!info.hasProperType)
+ );
+}
+
+export function getDeclResolveAlias(node: arkts.AstNode): arkts.AstNode | undefined {
+ const decl = arkts.getDecl(node);
+ if (!!decl && !!decl.parent && arkts.isIdentifier(decl) && arkts.isVariableDeclarator(decl.parent)) {
+ if (!!decl.parent.initializer && arkts.isIdentifier(decl.parent.initializer)) {
+ return getDeclResolveAlias(decl.parent.initializer);
+ }
+ if (!!decl.parent.initializer && arkts.isMemberExpression(decl.parent.initializer)) {
+ return getDeclResolveAlias(decl.parent.initializer.property);
+ }
+ }
+ return decl;
+}
+
+export function parametersBlockHasReceiver(params: readonly arkts.Expression[]): boolean {
+ return params.length > 0 && arkts.isEtsParameterExpression(params[0]) && isThisParam(params[0]);
+}
+
+export function parametrizedNodeHasReceiver(node: arkts.ScriptFunction | arkts.ETSFunctionType | undefined): boolean {
+ if (node === undefined) {
+ return false;
+ }
+ return parametersBlockHasReceiver(node.params);
+}
+
+function isThisParam(node: arkts.Expression | undefined): boolean {
+ if (node === undefined || !arkts.isEtsParameterExpression(node)) {
+ return false;
+ }
+ return node.identifier?.isReceiver ?? false;
+}
diff --git a/arkui-plugins/common/abstract-visitor.ts b/arkui-plugins/common/abstract-visitor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2c7a307da160e41671fa8d0aca5586a38d30ef8e
--- /dev/null
+++ b/arkui-plugins/common/abstract-visitor.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+export interface VisitorOptions {
+ isExternal?: boolean;
+ externalSourceName?: string;
+ program?: arkts.Program;
+}
+
+export abstract class AbstractVisitor implements VisitorOptions {
+ public isExternal: boolean;
+ public externalSourceName?: string;
+ public program?: arkts.Program;
+
+ constructor(options?: VisitorOptions) {
+ this.isExternal = options?.isExternal ?? false;
+ this.externalSourceName = options?.externalSourceName;
+ this.program = options?.program;
+ }
+
+ indentation = 0;
+
+ withIndentation(exec: () => T) {
+ this.indentation++;
+ const result = exec();
+ this.indentation--;
+ return result;
+ }
+
+ abstract visitor(node: arkts.AstNode): arkts.AstNode;
+
+ reset(): void {
+ this.indentation = 0;
+ }
+
+ visitEachChild(node: arkts.AstNode): arkts.AstNode {
+ return this.withIndentation(() => arkts.visitEachChild(node, (it) => this.visitor(it)));
+ }
+}
diff --git a/arkui-plugins/common/arkts-utils.ts b/arkui-plugins/common/arkts-utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..59016f2fd2f84d36b1bdb5df737e15e5f30c3004
--- /dev/null
+++ b/arkui-plugins/common/arkts-utils.ts
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { DeclarationCollector } from './declaration-collector';
+import { ARKUI_IMPORT_PREFIX_NAMES, DecoratorNames } from './predefines';
+
+
+/**
+ * create and insert `import { as } from ` to the top of script's statements.
+ */
+export function createAndInsertImportDeclaration(
+ source: arkts.StringLiteral,
+ imported: arkts.Identifier,
+ local: arkts.Identifier,
+ importKind: arkts.Es2pandaImportKinds,
+ program: arkts.Program
+): void {
+ const importDecl: arkts.ETSImportDeclaration = arkts.factory.createImportDeclaration(
+ source,
+ [arkts.factory.createImportSpecifier(imported, local)],
+ importKind,
+ program,
+ arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE
+ );
+ arkts.importDeclarationInsert(importDecl, program);
+ return;
+}
+
+export function annotation(name: string): arkts.AnnotationUsage {
+ const ident: arkts.Identifier = arkts.factory.createIdentifier(name).setAnnotationUsage();
+ const annotation: arkts.AnnotationUsage = arkts.factory.createAnnotationUsage(ident);
+
+ annotation.modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_ANNOTATION_USAGE;
+ ident.parent = annotation;
+
+ return annotation;
+}
+
+export function isAnnotation(node: arkts.AnnotationUsage, annoName: string) {
+ return node.expr !== undefined && arkts.isIdentifier(node.expr) && node.expr.name === annoName;
+}
+
+export function isDecoratorAnnotation(
+ anno: arkts.AnnotationUsage,
+ decoratorName: DecoratorNames,
+ ignoreDecl?: boolean
+): boolean {
+ if (!(!!anno.expr && arkts.isIdentifier(anno.expr) && anno.expr.name === decoratorName)) {
+ return false;
+ }
+ if (!ignoreDecl) {
+ const decl = arkts.getDecl(anno.expr);
+ if (!decl) {
+ return false;
+ }
+ const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName;
+ if (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName)) {
+ return false;
+ }
+ DeclarationCollector.getInstance().collect(decl);
+ }
+ return true;
+}
+
+export function removeAnnotationByName(
+ annotations: readonly arkts.AnnotationUsage[],
+ annoName: string
+): arkts.AnnotationUsage[] {
+ return annotations.filter((it) => !isAnnotation(it, annoName));
+}
+
+export function expectName(node: arkts.AstNode | undefined): string {
+ if (!node) {
+ throw new Error('Expected an identifier, got empty node');
+ }
+ if (!arkts.isIdentifier(node)) {
+ throw new Error('Expected an identifier, got: ' + arkts.nodeType(node).toString());
+ }
+ return node.name;
+}
+
+export function mangle(value: string): string {
+ return `__${value}`;
+}
+
+export function backingField(originalName: string): string {
+ return mangle(`backing_${originalName}`);
+}
+
+export function filterDefined(value: (T | undefined)[]): T[] {
+ return value.filter((it: T | undefined): it is T => it != undefined);
+}
+
+export function collect(...value: (ReadonlyArray | T | undefined)[]): T[] {
+ const empty: (T | undefined)[] = [];
+ return filterDefined(empty.concat(...value));
+}
+
+export function matchPrefix(prefixCollection: (string | RegExp)[], name: string): boolean {
+ for (const prefix of prefixCollection) {
+ let regex: RegExp;
+
+ if (typeof prefix === 'string') {
+ regex = new RegExp('^' + prefix);
+ } else {
+ regex = new RegExp('^' + prefix.source);
+ }
+
+ if (regex.test(name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+export function moveToFront(arr: T[], idx: number): T[] {
+ if (idx < 0 || idx >= arr.length) {
+ throw new Error(`Index ${idx} is out of bounds for array of length ${arr.length}`);
+ }
+
+ const copy = [...arr];
+ const [item] = copy.splice(idx, 1);
+ return [item, ...copy];
+}
+
+/**
+ * Performs the specified action for each argument in a `arkts.CallExpression`'s arguments array
+ * paired with corresponding parameter from the function declaration node.
+ *
+ * @param args An arguments array from a `arkts.CallExpression` node.
+ * @param params A parameters array from a function declaration node.
+ * @param callbackFn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
+ * @param options Additional options field that accepts special conditions of calls and function, used for pairing arguments with parameters.
+ */
+export function forEachArgWithParam(
+ args: readonly arkts.Expression[],
+ params: readonly arkts.Expression[],
+ callbackFn: (arg: arkts.Expression | undefined, param: arkts.Expression, index?: number) => void,
+ options?: { isTrailingCall?: boolean; hasReceiver?: boolean; hasRestParameter?: boolean }
+): void {
+ const argLen: number = args.length;
+ const paramLen: number = params.length;
+ if (argLen === 0 || paramLen === 0) {
+ return;
+ }
+ const hasRestParam: boolean = !!options?.hasRestParameter;
+ const isTrailingCall: boolean = !!options?.isTrailingCall;
+ const maxLen = hasRestParam ? argLen : paramLen;
+ let index: number = 0;
+ while (index < maxLen - 1) {
+ const param = params.at(index) ?? params.at(paramLen - 1)!;
+ const argument = isTrailingCall && index >= argLen - 1 ? undefined : args.at(index);
+ callbackFn(argument, param, index);
+ index++;
+ }
+ const lastParam = params.at(paramLen - 1)!;
+ const lastIndex = isTrailingCall ? argLen - 1 : maxLen - 1;
+ const lastArg = args.at(lastIndex);
+ callbackFn(lastArg, lastParam, maxLen - 1);
+}
diff --git a/arkui-plugins/common/debug.ts b/arkui-plugins/common/debug.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4675725602d7f27589789677fa841ae3ad924ca7
--- /dev/null
+++ b/arkui-plugins/common/debug.ts
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+import * as fs from 'fs';
+import * as path from 'path';
+import * as arkts from '@koalaui/libarkts';
+
+const isDebugLog: boolean = false;
+const isDebugDump: boolean = false;
+const isPerformance: boolean = false;
+const enableMemoryTracker: boolean = false;
+arkts.Performance.getInstance().skip(!isPerformance);
+arkts.Performance.getInstance().enableMemoryTracker(enableMemoryTracker);
+export function getEnumName(enumType: any, value: number): string | undefined {
+ return enumType[value];
+}
+
+function mkDir(filePath: string): void {
+ const parent = path.join(filePath, '..');
+ if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) {
+ mkDir(parent);
+ }
+ fs.mkdirSync(filePath);
+}
+
+export function debugDump(
+ content: string,
+ fileName: string,
+ isInit: boolean,
+ cachePath: string | undefined,
+ programFileName: string
+): void {
+ if (!isDebugDump) return;
+ const currentDirectory = process.cwd();
+ const modifiedFileName = programFileName.replaceAll('.', '_');
+ const outputDir: string = cachePath
+ ? path.resolve(currentDirectory, cachePath, modifiedFileName)
+ : path.resolve(currentDirectory, 'dist', 'cache', modifiedFileName);
+ const filePath: string = path.resolve(outputDir, fileName);
+ if (!fs.existsSync(outputDir)) {
+ mkDir(outputDir);
+ }
+ try {
+ if (!isInit && fs.existsSync(filePath)) {
+ const existingContent = fs.readFileSync(filePath, 'utf8');
+ const newContent =
+ existingContent && !existingContent.endsWith('\n')
+ ? existingContent + '\n' + content
+ : existingContent + content;
+ fs.writeFileSync(filePath, newContent, 'utf8');
+ } else {
+ fs.writeFileSync(filePath, content, 'utf8');
+ }
+ } catch (error) {
+ console.error('文件操作失败:', error);
+ }
+}
+
+export function debugLog(message?: any, ...optionalParams: any[]): void {
+ if (!isDebugLog) return;
+ console.log(message, ...optionalParams);
+}
+
+export function getDumpFileName(state: number, prefix: string, index: number | undefined, suffix: string): string {
+ return `${state}_${prefix}_${index ?? ''}_${suffix}.sts`;
+}
diff --git a/arkui-plugins/common/declaration-collector.ts b/arkui-plugins/common/declaration-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d65f0d40da094bc237037b592d7b699e322c77bd
--- /dev/null
+++ b/arkui-plugins/common/declaration-collector.ts
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+import * as arkts from '@koalaui/libarkts';
+import { IMPORT_SOURCE_MAP_V2, INTERMEDIATE_IMPORT_SOURCE } from './predefines';
+import { ImportCollector } from './import-collector';
+
+export class DeclarationCollector {
+ private fromExternalSourceNameMap: Map;
+ private fromExternalSourceNodePeerMap: Map;
+ static instance: DeclarationCollector;
+
+ private constructor() {
+ this.fromExternalSourceNameMap = new Map();
+ this.fromExternalSourceNodePeerMap = new Map();
+ }
+
+ static getInstance(): DeclarationCollector {
+ if (!this.instance) {
+ this.instance = new DeclarationCollector();
+ }
+ return this.instance;
+ }
+
+ private collectIntermediateImportSource(symbol: string, declSourceName: string): void {
+ let sourceName: string;
+ if (IMPORT_SOURCE_MAP_V2.has(symbol)) {
+ sourceName = IMPORT_SOURCE_MAP_V2.get(symbol)!;
+ } else {
+ sourceName = declSourceName;
+ }
+ ImportCollector.getInstance().collectSource(symbol, sourceName);
+ }
+
+ collect(decl: arkts.AstNode | undefined): void {
+ if (!decl) {
+ return;
+ }
+ let declName: string | undefined;
+ if (arkts.isAnnotationDeclaration(decl) && !!decl.expr && arkts.isIdentifier(decl.expr)) {
+ declName = decl.expr.name;
+ } else if (arkts.isMethodDefinition(decl)) {
+ declName = decl.name.name;
+ } else if (arkts.isIdentifier(decl)) {
+ declName = decl.name;
+ } else if (arkts.isClassProperty(decl) && !!decl.key && arkts.isIdentifier(decl.key)) {
+ declName = decl.key.name;
+ } else if (arkts.isEtsParameterExpression(decl)) {
+ declName = decl.identifier.name;
+ }
+ if (!declName) {
+ return;
+ }
+ let sourceName: string = arkts.getProgramFromAstNode(decl).moduleName;
+ this.fromExternalSourceNameMap.set(declName, sourceName);
+ this.fromExternalSourceNodePeerMap.set(decl.peer, sourceName);
+
+ INTERMEDIATE_IMPORT_SOURCE.get(declName)?.forEach((symbol) => {
+ this.collectIntermediateImportSource(symbol, sourceName);
+ });
+ }
+
+ findExternalSourceFromName(declName: string): string | undefined {
+ return this.fromExternalSourceNameMap.get(declName);
+ }
+
+ findExternalSourceFromNode(decl: arkts.AstNode): string | undefined {
+ return this.fromExternalSourceNodePeerMap.get(decl.peer);
+ }
+
+ reset(): void {
+ this.fromExternalSourceNameMap.clear();
+ this.fromExternalSourceNodePeerMap.clear();
+ }
+}
diff --git a/arkui-plugins/common/etsglobal-remover.ts b/arkui-plugins/common/etsglobal-remover.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3d9711799c01b776e626fea84429fae186a05e3b
--- /dev/null
+++ b/arkui-plugins/common/etsglobal-remover.ts
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor } from './abstract-visitor';
+
+const ETSGLOBAL = 'ETSGLOBAL';
+
+export class EtsglobalRemover extends AbstractVisitor {
+ visitor(node: arkts.AstNode): arkts.AstNode {
+ if (arkts.isEtsScript(node)) {
+ const keep = node.statements.filter((it) => {
+ return !(arkts.isClassDeclaration(it) && it.definition?.ident?.name == ETSGLOBAL);
+ });
+ return arkts.factory.updateEtsScript(node, keep);
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/common/gensym-generator.ts b/arkui-plugins/common/gensym-generator.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6e05f109d44c8bbc69932857b18e4583b9fb0f2b
--- /dev/null
+++ b/arkui-plugins/common/gensym-generator.ts
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+import { getCommonPath } from '../path';
+const common = require(getCommonPath());
+const UniqueId = common.UniqueId;
+
+export class GenSymGenerator {
+ // Global for the whole program.
+ private static callCount: number = 0;
+ static instance: GenSymGenerator;
+
+ // Set `stable` to true if you want to have more predictable values.
+ // For example for tests.
+ // Don't use it in production!
+ private constructor(public stableForTests: boolean = false) {
+ if (stableForTests) GenSymGenerator.callCount = 0;
+ }
+
+ static getInstance(stableForTests: boolean = false): GenSymGenerator {
+ if (!this.instance) {
+ this.instance = new GenSymGenerator(stableForTests);
+ }
+
+ return this.instance;
+ }
+
+ sha1Id(callName: string): string {
+ const uniqId = new UniqueId();
+ uniqId.addString('gensym uniqid');
+ uniqId.addString(callName);
+ uniqId.addI32(GenSymGenerator.callCount++);
+ return uniqId.compute().substring(0, 7);
+ }
+
+ stringId(callName: string): string {
+ return `${GenSymGenerator.callCount++}_${callName}_id`;
+ }
+
+ id(callName: string = ''): string {
+ const positionId = this.stableForTests ? this.stringId(callName) : this.sha1Id(callName);
+
+ const coreceToStr = parseInt(positionId, 16).toString();
+
+ // compiler use gensym%%_ but % is illegal before after-check phase
+ return `gensym___${coreceToStr}`;
+ }
+}
diff --git a/arkui-plugins/common/import-collector.ts b/arkui-plugins/common/import-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..935b339af29f87951a69cc85508b64f1fa83e810
--- /dev/null
+++ b/arkui-plugins/common/import-collector.ts
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { createAndInsertImportDeclaration } from './arkts-utils';
+
+interface ImportInfo {
+ imported: string;
+ local: string;
+ source: string;
+ kind: arkts.Es2pandaImportKinds;
+}
+
+function insertImport(importInfo: ImportInfo, program?: arkts.Program): void {
+ const source: arkts.StringLiteral = arkts.factory.create1StringLiteral(importInfo.source);
+ const imported: arkts.Identifier = arkts.factory.createIdentifier(importInfo.imported);
+ const local: arkts.Identifier = arkts.factory.createIdentifier(importInfo.local);
+ // Insert this import at the top of the script's statements.
+ if (!program) {
+ throw Error('Failed to insert import: Transformer has no program');
+ }
+ createAndInsertImportDeclaration(source, imported, local, importInfo.kind, program);
+}
+
+export class ImportCollector {
+ public importInfos: ImportInfo[];
+ public localMap: Map;
+ public sourceMap: Map;
+ private static instance: ImportCollector;
+
+ /** this set is used for keeping the import sentence unique */
+ private imported: Set;
+
+ private constructor() {
+ this.importInfos = [];
+ this.imported = new Set();
+ this.localMap = new Map();
+ this.sourceMap = new Map();
+ }
+
+ static getInstance(): ImportCollector {
+ if (!this.instance) {
+ this.instance = new ImportCollector();
+ }
+ return this.instance;
+ }
+
+ reset(): void {
+ this.importInfos = [];
+ this.imported.clear();
+ this.localMap.clear();
+ this.sourceMap.clear();
+ }
+
+ collectSource(imported: string, source: string): void {
+ if (!this.sourceMap.has(imported)) {
+ this.sourceMap.set(imported, source);
+ }
+ }
+
+ collectImport(
+ imported: string,
+ local?: string,
+ kind: arkts.Es2pandaImportKinds = arkts.Es2pandaImportKinds.IMPORT_KINDS_TYPE
+ ): void {
+ if (!this.sourceMap.has(imported)) {
+ throw new Error(`ImportCollector: import ${imported}'s source haven't been collected yet.`);
+ }
+ if (this.imported.has(imported)) {
+ return;
+ }
+ const source: string = this.sourceMap.get(imported)!;
+ const _local: string = local ?? imported;
+ this.importInfos.push({
+ source,
+ imported,
+ local: _local,
+ kind,
+ });
+ this.localMap.set(imported, _local);
+ this.imported.add(imported);
+ }
+
+ getLocal(imported: string): string | undefined {
+ return this.localMap.get(imported);
+ }
+
+ insertCurrentImports(program?: arkts.Program): void {
+ this.importInfos.forEach((importInfo) => {
+ insertImport(importInfo, program);
+ });
+ }
+}
diff --git a/arkui-plugins/common/log-collector.ts b/arkui-plugins/common/log-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5fa9ed7af815dca0e10d9c5bc469f3477762227d
--- /dev/null
+++ b/arkui-plugins/common/log-collector.ts
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { LogType } from './predefines';
+
+interface LogInfo {
+ type: LogType;
+ message: string;
+ node: arkts.AstNode;
+ code: string;
+}
+
+export function generateDiagnosticKind(logItem: LogInfo): arkts.DiagnosticKind {
+ return arkts.DiagnosticKind.create(
+ `${logItem.code}: ${logItem.message}`,
+ logItem.type === LogType.ERROR
+ ? arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_ERROR
+ : arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_WARNING
+ );
+}
+
+export class LogCollector {
+ public logInfos: LogInfo[];
+ private static instance: LogCollector;
+ private ignoreError: boolean;
+
+ private constructor() {
+ this.logInfos = [];
+ this.ignoreError = false;
+ }
+
+ static getInstance(): LogCollector {
+ if (!this.instance) {
+ this.instance = new LogCollector();
+ }
+ return this.instance;
+ }
+
+ reset(): void {
+ this.logInfos = [];
+ this.ignoreError = false;
+ }
+
+ collectLogInfo(logItem: LogInfo): void {
+ this.logInfos.push(logItem);
+ }
+
+ emitLogInfo(): void {
+ if (this.ignoreError) {
+ return;
+ }
+ this.logInfos.forEach((logItem: LogInfo) => {
+ arkts.Diagnostic.logDiagnostic(generateDiagnosticKind(logItem), arkts.getStartPosition(logItem.node));
+ });
+ }
+
+ shouldIgnoreError(ignoreError: boolean | undefined): void {
+ if (!!ignoreError) {
+ this.ignoreError = true;
+ }
+ }
+}
diff --git a/arkui-plugins/common/plugin-context.ts b/arkui-plugins/common/plugin-context.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f661350a0fbf5d86de9efddb843f24c66dac55a1
--- /dev/null
+++ b/arkui-plugins/common/plugin-context.ts
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+// This is the same plugin-context in the build-system.
+export class PluginContext {
+ private ast: arkts.EtsScript | undefined;
+ private program: arkts.Program | undefined;
+ private projectConfig: ProjectConfig | undefined;
+ private contextPtr: number | undefined;
+ private codingFilePath: string | undefined;
+
+ constructor() {
+ this.ast = undefined;
+ this.program = undefined;
+ this.projectConfig = undefined;
+ this.contextPtr = undefined;
+ this.codingFilePath = undefined;
+ }
+
+ /**
+ * @deprecated
+ */
+ public setArkTSAst(ast: arkts.EtsScript): void {
+ this.ast = ast;
+ }
+
+ /**
+ * @deprecated
+ */
+ public getArkTSAst(): arkts.EtsScript | undefined {
+ return this.ast;
+ }
+
+ /**
+ * @deprecated
+ */
+ public setArkTSProgram(program: arkts.Program): void {
+ this.program = program;
+ }
+
+ /**
+ * @deprecated
+ */
+ public getArkTSProgram(): arkts.Program | undefined {
+ return this.program;
+ }
+
+ public setProjectConfig(projectConfig: ProjectConfig): void {
+ this.projectConfig = projectConfig;
+ }
+
+ public getProjectConfig(): ProjectConfig | undefined {
+ return this.projectConfig;
+ }
+
+ public setContextPtr(ptr: number): void {
+ this.contextPtr = ptr;
+ }
+
+ public getContextPtr(): number | undefined {
+ return this.contextPtr;
+ }
+
+ public setCodingFilePath(codingFilePath: string): void {
+ this.codingFilePath = codingFilePath;
+ }
+
+ public getCodingFilePath(): string | undefined {
+ return this.codingFilePath;
+ }
+
+ public isCoding(): boolean {
+ return this.codingFilePath !== undefined;
+ }
+}
+
+export interface DependentModuleConfig {
+ packageName: string;
+ moduleName: string;
+ moduleType: string;
+ modulePath: string;
+ sourceRoots: string[];
+ entryFile: string;
+ language: string;
+ declFilesPath?: string;
+ dependencies?: string[];
+}
+
+export interface ProjectConfig {
+ bundleName: string;
+ moduleName: string;
+ cachePath: string;
+ dependentModuleList: DependentModuleConfig[];
+ appResource: string;
+ rawFileResource: string;
+ buildLoaderJson: string;
+ hspResourcesMap: boolean;
+ compileHar: boolean;
+ byteCodeHar: boolean;
+ uiTransformOptimization: boolean;
+ resetBundleName: boolean;
+ allowEmptyBundleName: boolean;
+ moduleType: string;
+ moduleRootPath: string;
+ aceModuleJsonPath: string;
+ ignoreError: boolean;
+ projectPath: string,
+ projectRootPath: string,
+ integratedHsp: boolean
+ frameworkMode?: string;
+}
+
+export type PluginHandlerFunction = () => void;
+
+export type PluginHandlerObject = {
+ order: 'pre' | 'post' | undefined;
+ handler: PluginHandlerFunction;
+};
+
+export type PluginHandler = PluginHandlerFunction | PluginHandlerObject;
+
+export interface Plugins {
+ name: string;
+ afterNew?: PluginHandler;
+ parsed?: PluginHandler;
+ scopeInited?: PluginHandler;
+ checked?: PluginHandler;
+ lowered?: PluginHandler;
+ asmGenerated?: PluginHandler;
+ binGenerated?: PluginHandler;
+ clean?: PluginHandler;
+}
+
+export type PluginState = keyof Omit;
+
+export type PluginExecutor = {
+ name: string;
+ handler: PluginHandlerFunction;
+};
diff --git a/arkui-plugins/common/predefines.ts b/arkui-plugins/common/predefines.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6101ba6ba069db34d6b53dd255254f66717e51ad
--- /dev/null
+++ b/arkui-plugins/common/predefines.ts
@@ -0,0 +1,304 @@
+/*
+ * 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.
+ */
+
+export const EXTERNAL_SOURCE_PREFIX_NAMES: (string | RegExp)[] = [
+ 'std',
+ 'escompat',
+ 'security',
+ 'application',
+ 'permissions',
+ 'bundleManager',
+ 'commonEvent',
+ /@arkts\..*/,
+ /@ohos\.(?!arkui).*/,
+ /@system\..*/,
+ /ability\..*/,
+];
+
+export const EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK: (string | RegExp)[] = [
+ 'std',
+ 'escompat',
+ /@arkts\..*/
+];
+
+export const ARKUI_IMPORT_PREFIX_NAMES: (string | RegExp)[] = [/arkui\..*/, /@ohos\..*/, /@kit\..*/];
+
+export const MEMO_IMPORT_SOURCE_NAME: string = 'arkui.stateManagement.runtime';
+export const CUSTOM_COMPONENT_IMPORT_SOURCE_NAME: string = 'arkui.component.customComponent';
+export const CUSTOM_DIALOG_CONTROLLER_SOURCE_NAME: string = 'arkui.component.customDialogController';
+export const ENTRY_POINT_IMPORT_SOURCE_NAME: string = 'arkui.UserView';
+export const ARKUI_COMPONENT_COMMON_SOURCE_NAME: string = 'arkui.component.common';
+export const ARKUI_FOREACH_SOURCE_NAME: string = 'arkui.component.forEach';
+
+export enum ModuleType {
+ HAR = 'har',
+ ENTRY = 'entry',
+ FEATURE = 'feature',
+ SHARED = 'shared',
+}
+
+export enum DefaultConfiguration {
+ HAR_DEFAULT_MODULE_NAME = '__harDefaultModuleName__',
+ HAR_DEFAULT_BUNDLE_NAME = '__harDefaultBundleName__',
+ DYNAMIC_MODULE_NAME = '__MODULE_NAME__',
+ DYNAMIC_BUNDLE_NAME = '__BUNDLE_NAME__',
+}
+
+export enum LogType {
+ ERROR = 'ERROR',
+ WARN = 'WARN',
+}
+
+export enum Dollars {
+ DOLLAR_RESOURCE = '$r',
+ DOLLAR_RAWFILE = '$rawfile',
+ DOLLAR_DOLLAR = '$$',
+ TRANSFORM_DOLLAR_RESOURCE = '_r',
+ TRANSFORM_DOLLAR_RAWFILE = '_rawfile',
+}
+
+export enum BindableDecl {
+ BINDABLE = 'Bindable',
+}
+
+export enum StructDecoratorNames {
+ ENTRY = 'Entry',
+ COMPONENT = 'Component',
+ COMPONENT_V2 = 'ComponentV2',
+ RESUABLE = 'Reusable',
+ RESUABLE_V2 = 'ReusableV2',
+ CUSTOM_LAYOUT = 'CustomLayout',
+ CUSTOMDIALOG = 'CustomDialog',
+}
+
+export enum EntryWrapperNames {
+ ENTRY_FUNC = 'entry',
+ WRAPPER_CLASS_NAME = '__EntryWrapper',
+ ENTRY_STORAGE_LOCAL_STORAGE_PROPERTY_NAME = '_entry_local_storage_',
+ ENTRY_POINT_CLASS_NAME = 'EntryPoint',
+ REGISTER_NAMED_ROUTER = 'RegisterNamedRouter',
+ ROUTER_NAME = 'routerName',
+ INSTANCE = 'instance',
+ PARAM = 'param'
+}
+
+export enum EntryParamNames {
+ ENTRY_STORAGE = 'storage',
+ ENTRY_USE_SHARED_STORAGE = 'useSharedStorage',
+ ENTRY_ROUTE_NAME = 'routeName'
+}
+
+export enum InnerComponentNames {
+ FOR_EACH = 'ForEach',
+}
+
+export enum DecoratorNames {
+ STATE = 'State',
+ STORAGE_LINK = 'StorageLink',
+ STORAGE_PROP = 'StorageProp',
+ LINK = 'Link',
+ PROP = 'Prop',
+ PROVIDE = 'Provide',
+ CONSUME = 'Consume',
+ OBJECT_LINK = 'ObjectLink',
+ OBSERVED = 'Observed',
+ WATCH = 'Watch',
+ BUILDER_PARAM = 'BuilderParam',
+ BUILDER = 'Builder',
+ CUSTOM_DIALOG = 'CustomDialog',
+ LOCAL_STORAGE_PROP = 'LocalStorageProp',
+ LOCAL_STORAGE_LINK = 'LocalStorageLink',
+ REUSABLE = 'Reusable',
+ TRACK = 'Track',
+ JSONSTRINGIFYIGNORE = 'JSONStringifyIgnore',
+ JSONRENAME = 'JSONRename',
+ ANIMATABLE_EXTEND = 'AnimatableExtend',
+ PROP_REF = 'PropRef',
+ LOCAL = 'Local',
+ LOCAL_STORAGE_PROP_REF = 'LocalStoragePropRef',
+ STORAGE_PROP_REF = 'StoragePropRef',
+}
+
+export enum DecoratorIntrinsicNames {
+ LINK = '__Link_intrinsic',
+}
+
+export enum StateManagementTypes {
+ STATE_MANAGEMENT_FACTORY = 'STATE_MGMT_FACTORY',
+ STATE_DECORATED = 'IStateDecoratedVariable',
+ LINK_DECORATED = 'ILinkDecoratedVariable',
+ LINK_SOURCE_TYPE = 'LinkSourceType',
+ STORAGE_LINK_DECORATED = 'IStorageLinkDecoratedVariable',
+ STORAGE_PROP_REF_DECORATED = 'IStoragePropRefDecoratedVariable',
+ LOCAL_STORAGE_LINK_DECORATED = 'ILocalStorageLinkDecoratedVariable',
+ PROP_DECORATED = 'IPropDecoratedVariable',
+ SYNCED_PROPERTY = 'SyncedProperty',
+ PROVIDE_DECORATED = 'IProvideDecoratedVariable',
+ CONSUME_DECORATED = 'IConsumeDecoratedVariable',
+ OBJECT_LINK_DECORATED = 'IObjectLinkDecoratedVariable',
+ PROP_REF_DECORATED = 'IPropRefDecoratedVariable',
+ LOCAL_DECORATED = 'ILocalDecoratedVariable',
+ LOCAL_STORAGE_PROP_REF_DECORATED = 'ILocalStoragePropRefDecoratedVariable',
+ MUTABLE_STATE_META = 'IMutableStateMeta',
+ OBSERVED_OBJECT = 'IObservedObject',
+ WATCH_ID_TYPE = 'WatchIdType',
+ RENDER_ID_TYPE = 'RenderIdType',
+ OBSERVE = 'OBSERVE',
+ META = '__meta',
+ SUBSCRIBED_WATCHES = 'ISubscribedWatches',
+ STORAGE_LINK_STATE = 'StorageLinkState',
+ OBSERVABLE_PROXY = 'observableProxy',
+ PROP_STATE = 'propState',
+ UPDATE = 'update',
+ MAKE_STATE = 'makeState',
+ MAKE_LINK = 'makeLink',
+ MAKE_PROP = 'makeProp',
+ MAKE_PROP_REF = 'makePropRef',
+ MAKE_LOCAL = 'makeLocal',
+ MAKE_STORAGE_PROP_REF = 'makeStoragePropRef',
+ MAKE_LOCAL_STORAGE_PROP_REF = 'makeLocalStoragePropRef',
+ MAKE_STORAGE_LINK = 'makeStorageLink',
+ MAKE_LOCAL_STORAGE_LINK = 'makeLocalStorageLink',
+ MAKE_PROVIDE = 'makeProvide',
+ MAKE_CONSUME = 'makeConsume',
+ MAKE_OBJECT_LINK = 'makeObjectLink',
+ MAKE_SUBSCRIBED_WATCHES = 'makeSubscribedWatches',
+ MAKE_MUTABLESTATE_META = 'makeMutableStateMeta',
+}
+
+export enum AnimationNames {
+ ANIMATABLE_ARITHMETIC = 'AnimatableArithmetic',
+ CREATE_OR_SET_ANIMATABLEPROPERTY = '__createOrSetAnimatableProperty',
+ ANIMATION = 'animation',
+ ANIMATION_START = 'animationStart',
+ ANIMATION_STOP = 'animationStop',
+}
+
+export enum NavigationNames {
+ NAVINTERFACE = 'NavInterface',
+ BUNDLE_NAME = 'bundleName',
+ MODULE_NAME = 'moduleName',
+ PAGE_PATH = 'pagePath',
+ PAGE_FULL_PATH = 'pageFullPath',
+ INTEGRATED_HSP = 'integratedHsp',
+}
+
+export const RESOURCE_TYPE: Record = {
+ color: 10001,
+ float: 10002,
+ string: 10003,
+ plural: 10004,
+ boolean: 10005,
+ intarray: 10006,
+ integer: 10007,
+ pattern: 10008,
+ strarray: 10009,
+ media: 20000,
+ rawfile: 30000,
+ symbol: 40000,
+};
+
+export const DECORATOR_TYPE_MAP = new Map([
+ [DecoratorNames.STATE, StateManagementTypes.STATE_DECORATED],
+ [DecoratorNames.LINK, StateManagementTypes.LINK_SOURCE_TYPE],
+ [DecoratorNames.PROP, StateManagementTypes.PROP_DECORATED],
+ [DecoratorNames.PROP_REF, StateManagementTypes.PROP_REF_DECORATED],
+ [DecoratorNames.STORAGE_LINK, StateManagementTypes.STORAGE_LINK_DECORATED],
+ [DecoratorNames.STORAGE_PROP, StateManagementTypes.STORAGE_PROP_REF_DECORATED],
+ [DecoratorNames.STORAGE_PROP_REF, StateManagementTypes.STORAGE_PROP_REF_DECORATED],
+ [DecoratorNames.LOCAL_STORAGE_PROP_REF, StateManagementTypes.LOCAL_STORAGE_PROP_REF_DECORATED],
+ [DecoratorNames.LOCAL_STORAGE_PROP, StateManagementTypes.SYNCED_PROPERTY],
+ [DecoratorNames.LOCAL_STORAGE_LINK, StateManagementTypes.LOCAL_STORAGE_LINK_DECORATED],
+ [DecoratorNames.OBJECT_LINK, StateManagementTypes.OBJECT_LINK_DECORATED],
+ [DecoratorNames.PROVIDE, StateManagementTypes.PROVIDE_DECORATED],
+ [DecoratorNames.CONSUME, StateManagementTypes.CONSUME_DECORATED],
+ [DecoratorNames.LOCAL, StateManagementTypes.LOCAL_DECORATED],
+]);
+
+export const INTERMEDIATE_IMPORT_SOURCE: Map = new Map([
+ [Dollars.DOLLAR_RESOURCE, [Dollars.TRANSFORM_DOLLAR_RESOURCE]],
+ [Dollars.DOLLAR_RAWFILE, [Dollars.TRANSFORM_DOLLAR_RAWFILE]],
+ [Dollars.DOLLAR_DOLLAR, [BindableDecl.BINDABLE]],
+ [DecoratorNames.STATE, [StateManagementTypes.STATE_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.LINK, [StateManagementTypes.LINK_DECORATED, StateManagementTypes.LINK_SOURCE_TYPE, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.PROP, [StateManagementTypes.PROP_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.PROP_REF, [StateManagementTypes.PROP_REF_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.PROVIDE, [StateManagementTypes.PROVIDE_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.CONSUME, [StateManagementTypes.CONSUME_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.STORAGE_PROP, [StateManagementTypes.STORAGE_PROP_REF_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.STORAGE_PROP_REF, [StateManagementTypes.STORAGE_PROP_REF_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.LOCAL_STORAGE_PROP_REF, [StateManagementTypes.LOCAL_STORAGE_PROP_REF_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.STORAGE_LINK, [StateManagementTypes.STORAGE_LINK_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.OBJECT_LINK, [StateManagementTypes.OBJECT_LINK_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.LOCAL_STORAGE_LINK, [StateManagementTypes.LOCAL_STORAGE_LINK_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [DecoratorNames.LOCAL, [StateManagementTypes.LOCAL_DECORATED, StateManagementTypes.STATE_MANAGEMENT_FACTORY]],
+ [
+ DecoratorNames.LOCAL_STORAGE_PROP,
+ [
+ StateManagementTypes.STORAGE_LINK_STATE,
+ StateManagementTypes.SYNCED_PROPERTY,
+ StateManagementTypes.OBSERVABLE_PROXY,
+ StateManagementTypes.PROP_STATE,
+ ],
+ ],
+ [
+ DecoratorNames.OBSERVED,
+ [
+ StateManagementTypes.MUTABLE_STATE_META,
+ StateManagementTypes.OBSERVED_OBJECT,
+ StateManagementTypes.WATCH_ID_TYPE,
+ StateManagementTypes.RENDER_ID_TYPE,
+ StateManagementTypes.OBSERVE,
+ StateManagementTypes.SUBSCRIBED_WATCHES,
+ StateManagementTypes.STATE_MANAGEMENT_FACTORY
+ ],
+ ],
+ [
+ DecoratorNames.TRACK,
+ [
+ StateManagementTypes.MUTABLE_STATE_META,
+ StateManagementTypes.OBSERVED_OBJECT,
+ StateManagementTypes.WATCH_ID_TYPE,
+ StateManagementTypes.RENDER_ID_TYPE,
+ StateManagementTypes.OBSERVE,
+ StateManagementTypes.SUBSCRIBED_WATCHES,
+ StateManagementTypes.STATE_MANAGEMENT_FACTORY
+ ],
+ ],
+ [DecoratorNames.ANIMATABLE_EXTEND, [AnimationNames.ANIMATABLE_ARITHMETIC]]
+]);
+
+/**
+ * @deprecated
+ */
+export const IMPORT_SOURCE_MAP_V2: Map = new Map([
+ [Dollars.TRANSFORM_DOLLAR_RESOURCE, 'arkui.component.resources'],
+ [Dollars.TRANSFORM_DOLLAR_RAWFILE, 'arkui.component.resources'],
+ [StateManagementTypes.SYNCED_PROPERTY, 'arkui.stateManagement.runtime'],
+ [StateManagementTypes.STORAGE_LINK_STATE, 'arkui.stateManagement.runtime'],
+ [StateManagementTypes.OBSERVABLE_PROXY, 'arkui.stateManagement.runtime'],
+ [StateManagementTypes.PROP_STATE, 'arkui.stateManagement.runtime'],
+ [AnimationNames.ANIMATABLE_ARITHMETIC, 'arkui.component.common']
+]);
+
+export enum GetSetTypes {
+ GET = 'get',
+ SET = 'set',
+}
+
+export enum GenSymPrefix {
+ INTRINSIC = 'gensym%%',
+ UI = 'gensym__'
+}
\ No newline at end of file
diff --git a/arkui-plugins/common/print-visitor.ts b/arkui-plugins/common/print-visitor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9f69e250d952ad572047cdc90874c9d95eadd992
--- /dev/null
+++ b/arkui-plugins/common/print-visitor.ts
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor } from '../common/abstract-visitor';
+
+export class PrintVisitor extends AbstractVisitor {
+ private result = '';
+
+ private printNode(node: arkts.AstNode) {
+ return `${' '.repeat(4 * this.indentation) + node.constructor.name} ${this.nameIfIdentifier(node)}`;
+ }
+
+ private nameIfIdentifier(node: arkts.AstNode): string {
+ return arkts.isIdentifier(node) ? `'${node.name}'` : '';
+ }
+
+ visitor(node: arkts.AstNode): arkts.AstNode {
+ console.log(this.printNode(node));
+ return this.visitEachChild(node);
+ }
+}
diff --git a/arkui-plugins/common/program-visitor.ts b/arkui-plugins/common/program-visitor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..55ac1aad41e3b936d0d1faeeb5d037b98db90c66
--- /dev/null
+++ b/arkui-plugins/common/program-visitor.ts
@@ -0,0 +1,303 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor, VisitorOptions } from './abstract-visitor';
+import { matchPrefix } from './arkts-utils';
+import { debugDump, getDumpFileName } from './debug';
+import { InteroperAbilityNames } from '../ui-plugins/interop/predefines';
+import { PluginContext } from './plugin-context';
+import { LegacyTransformer } from '../ui-plugins/interop/legacy-transformer';
+import { ComponentTransformer } from '../ui-plugins/component-transformer';
+
+export interface ProgramVisitorOptions extends VisitorOptions {
+ pluginName: string;
+ state: arkts.Es2pandaContextState;
+ visitors: AbstractVisitor[];
+ skipPrefixNames: (string | RegExp)[];
+ hooks?: ProgramHooks;
+ pluginContext?: PluginContext;
+}
+
+export interface ProgramHookConfig {
+ visitors: AbstractVisitor[];
+ resetAfter?: arkts.Es2pandaContextState;
+}
+
+export type ProgramHookLifeCycle = Partial>;
+
+export interface ProgramHooks {
+ external?: ProgramHookLifeCycle;
+ source?: ProgramHookLifeCycle;
+}
+
+function flattenVisitorsInHooks(
+ programHooks?: ProgramHooks,
+ resetAfterValue?: arkts.Es2pandaContextState
+): AbstractVisitor[] {
+ if (!programHooks) return [];
+ const flatMapInHook = (config: ProgramHookConfig): AbstractVisitor[] => {
+ if (!resetAfterValue) return [];
+ if (!config.resetAfter || resetAfterValue !== config.resetAfter) return [];
+ return config.visitors;
+ };
+ return [
+ ...Object.values(programHooks.external || {}).flatMap(flatMapInHook),
+ ...Object.values(programHooks.source || {}).flatMap(flatMapInHook),
+ ];
+}
+
+export interface StructMap {
+ [key: string]: string;
+}
+
+export class ProgramVisitor extends AbstractVisitor {
+ private readonly pluginName: string;
+ private readonly state: arkts.Es2pandaContextState;
+ private readonly visitors: AbstractVisitor[];
+ private readonly skipPrefixNames: (string | RegExp)[];
+ private readonly hooks?: ProgramHooks;
+ private filenames: Map;
+ private pluginContext?: PluginContext;
+ private legacyModuleList: string[] = [];
+ private legacyStructMap: Map;
+
+ constructor(options: ProgramVisitorOptions) {
+ super(options);
+ this.pluginName = options.pluginName;
+ this.state = options.state;
+ this.visitors = options.visitors;
+ this.skipPrefixNames = options.skipPrefixNames ?? [];
+ this.hooks = options.hooks;
+ this.filenames = new Map();
+ this.pluginContext = options.pluginContext;
+ this.legacyModuleList = [];
+ this.legacyStructMap = new Map();
+ }
+
+ reset(): void {
+ super.reset();
+ this.filenames = new Map();
+ this.legacyStructMap = new Map();
+ this.legacyModuleList = [];
+ }
+
+ private getLegacyModule(): void {
+ const moduleList = this.pluginContext?.getProjectConfig()?.dependentModuleList;
+ if (moduleList === undefined) {
+ return;
+ }
+ for (const module of moduleList) {
+ const language = module.language;
+ const moduleName = module.moduleName;
+ if (language !== InteroperAbilityNames.ARKTS_1_1) {
+ continue;
+ }
+ if (!this.legacyStructMap.has(moduleName)) {
+ this.legacyStructMap.set(moduleName, {});
+ this.legacyModuleList.push(moduleName);
+ }
+ }
+ }
+
+ private dumpExternalSource(
+ script: arkts.AstNode,
+ name: string,
+ cachePath: string | undefined,
+ prefixName: string,
+ extensionName: string
+ ): void {
+ debugDump(
+ script.dumpSrc(),
+ getDumpFileName(this.state, prefixName, undefined, name),
+ true,
+ cachePath,
+ extensionName
+ );
+ }
+
+ private visitLegacyInExternalSource(currProgram: arkts.Program, name: string): void {
+ if (this.state === arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED) {
+ const structList = this.visitorLegacy(currProgram.astNode, currProgram, name);
+ const moduleName = name.split('/')[0];
+ const structMap = this.legacyStructMap.get(moduleName)!;
+ for (const struct of structList) {
+ structMap[struct] = name;
+ }
+ }
+ }
+
+ private visitNonLegacyInExternalSource(
+ program: arkts.Program,
+ currProgram: arkts.Program,
+ name: string,
+ cachePath?: string
+ ): void {
+ const extensionName: string = program.fileNameWithExtension;
+ this.dumpExternalSource(currProgram.astNode, name, cachePath, 'ORI', extensionName);
+ const script = this.visitor(currProgram.astNode, currProgram, name);
+ if (script) {
+ this.dumpExternalSource(script, name, cachePath, this.pluginName, extensionName);
+ }
+ }
+
+ private visitNextProgramInQueue(
+ queue: arkts.Program[],
+ visited: Set,
+ externalSource: arkts.ExternalSource
+ ): void {
+ const nextProgramArr: arkts.Program[] = externalSource.programs ?? [];
+ for (const nextProgram of nextProgramArr) {
+ this.filenames.set(nextProgram.peer, externalSource.getName());
+ if (!visited.has(nextProgram.peer)) {
+ queue.push(nextProgram);
+ }
+ }
+ }
+
+ private visitExternalSources(
+ program: arkts.Program,
+ programQueue: arkts.Program[]
+ ): void {
+ const visited = new Set();
+ const queue: arkts.Program[] = programQueue;
+ this.getLegacyModule();
+ while (queue.length > 0) {
+ const currProgram = queue.shift()!;
+ if (visited.has(currProgram.peer) || currProgram.isASTLowered()) {
+ continue;
+ }
+ if (currProgram.peer !== program.peer) {
+ const name: string = this.filenames.get(currProgram.peer)!;
+ const cachePath: string | undefined = this.pluginContext?.getProjectConfig()?.cachePath;
+ if (this.legacyModuleList && matchPrefix(this.legacyModuleList, name)) {
+ this.visitLegacyInExternalSource(currProgram, name);
+ } else {
+ this.visitNonLegacyInExternalSource(program, currProgram, name, cachePath);
+ }
+ }
+ visited.add(currProgram.peer);
+ for (const externalSource of currProgram.externalSources) {
+ if (matchPrefix(this.skipPrefixNames, externalSource.getName())) {
+ continue;
+ }
+ this.visitNextProgramInQueue(queue, visited, externalSource);
+ }
+ }
+ }
+
+ programVisitor(program: arkts.Program): arkts.Program {
+ this.visitExternalSources(program, [program]);
+
+ let programScript = program.astNode;
+ programScript = this.visitor(programScript, program, this.externalSourceName);
+
+ const visitorsToReset = flattenVisitorsInHooks(this.hooks, this.state);
+ visitorsToReset.forEach((visitor) => visitor.reset());
+
+ return program;
+ }
+
+ private preVisitor(
+ hook: ProgramHookLifeCycle | undefined,
+ node: arkts.AstNode,
+ program?: arkts.Program,
+ externalSourceName?: string
+ ): void {
+ let script: arkts.EtsScript = node as arkts.EtsScript;
+ const preVisitors = hook?.pre?.visitors ?? [];
+ for (const transformer of preVisitors) {
+ this.visitTransformer(transformer, script, externalSourceName, program);
+ if (!this.hooks?.external?.pre?.resetAfter) {
+ transformer.reset();
+ }
+ }
+ }
+
+ private postVisitor(
+ hook: ProgramHookLifeCycle | undefined,
+ node: arkts.AstNode,
+ program?: arkts.Program,
+ externalSourceName?: string
+ ): void {
+ let script: arkts.EtsScript = node as arkts.EtsScript;
+ const postVisitors = hook?.post?.visitors ?? [];
+ for (const transformer of postVisitors) {
+ this.visitTransformer(transformer, script, externalSourceName, program);
+ if (!this.hooks?.external?.pre?.resetAfter) {
+ transformer.reset();
+ }
+ }
+ }
+
+ visitor(node: arkts.AstNode, program?: arkts.Program, externalSourceName?: string): arkts.EtsScript {
+ let hook: ProgramHookLifeCycle | undefined;
+
+ let script: arkts.EtsScript = node as arkts.EtsScript;
+ let count: number = 0;
+ const isExternal: boolean = !!externalSourceName;
+
+ // pre-run visitors
+ hook = isExternal ? this.hooks?.external : this.hooks?.source;
+ this.preVisitor(hook, node, program, externalSourceName);
+
+ for (const transformer of this.visitors) {
+ if (this.legacyStructMap.size > 0 && transformer instanceof ComponentTransformer) {
+ transformer.registerMap(this.legacyStructMap);
+ }
+ this.visitTransformer(transformer, script, externalSourceName, program);
+ transformer.reset();
+ arkts.setAllParents(script);
+ if (!transformer.isExternal) {
+ debugDump(
+ script.dumpSrc(),
+ getDumpFileName(this.state, this.pluginName, count, transformer.constructor.name),
+ true,
+ this.pluginContext?.getProjectConfig()?.cachePath,
+ program!.fileNameWithExtension
+ );
+ count += 1;
+ }
+ }
+
+ // post-run visitors
+ hook = isExternal ? this.hooks?.external : this.hooks?.source;
+ this.postVisitor(hook, node, program, externalSourceName);
+ return script;
+ }
+
+ private visitorLegacy(node: arkts.AstNode, program?: arkts.Program, externalSourceName?: string): string[] {
+ const transformer = new LegacyTransformer();
+ transformer.isExternal = !!externalSourceName;
+ transformer.externalSourceName = externalSourceName;
+ transformer.program = program;
+ transformer.visitor(node);
+ const structList = transformer.getList();
+ return structList;
+ }
+
+ private visitTransformer(
+ transformer: AbstractVisitor,
+ script: arkts.EtsScript,
+ externalSourceName?: string,
+ program?: arkts.Program
+ ): arkts.EtsScript {
+ transformer.isExternal = !!externalSourceName;
+ transformer.externalSourceName = externalSourceName;
+ transformer.program = program;
+ const newScript = transformer.visitor(script) as arkts.EtsScript;
+ return newScript;
+ }
+}
diff --git a/arkui-plugins/common/safe-types.ts b/arkui-plugins/common/safe-types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..899ef0c39b3dccec8dbbbe1fb68d6243a009dcc2
--- /dev/null
+++ b/arkui-plugins/common/safe-types.ts
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+export type PartialExcept = Partial & Pick;
+
+type PartialArray = T extends readonly any[] | any[] ? T | undefined : T;
+type PartialAstNode = T extends arkts.AstNode ? T | undefined : T;
+type PartialObject = T extends object ? { [P in keyof T]?: T[P] } : T;
+type PartialPrimitive = T;
+
+export type PartialNested = {
+ [P in keyof T]?: T[P] extends readonly any[] | any[]
+ ? PartialArray
+ : T[P] extends arkts.AstNode
+ ? PartialAstNode
+ : T[P] extends object
+ ? PartialObject
+ : PartialPrimitive;
+};
+
+type NestedKey = {
+ [P in keyof T]: P extends K ? T[P] : T[P] extends object ? NestedKey : T[P];
+ };
+
+export type PickNested = {
+ [P in keyof T]: P extends K ? T[P] : T[P] extends object ? NestedKey : T[P];
+};
+
+export type PartialNestedExcept = PartialNested> & PickNested;
\ No newline at end of file
diff --git a/arkui-plugins/custom-import-plugin.js b/arkui-plugins/custom-import-plugin.js
new file mode 100644
index 0000000000000000000000000000000000000000..84b8a6bd5847b908683c89111b4447e2b3ac87b3
--- /dev/null
+++ b/arkui-plugins/custom-import-plugin.js
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+const path = require('path');
+
+module.exports = function (babel) {
+ const { types: t } = babel;
+
+ return {
+ name: 'custom-import-plugin',
+ visitor: {
+ ImportDeclaration(pathNode) {
+ const sourceValue = pathNode.node.source.value;
+ if (sourceValue === '@koalaui/libarkts' && pathNode.node.specifiers.length === 1 && t.isImportNamespaceSpecifier(pathNode.node.specifiers[0])) {
+ const currentFileDir = path.dirname(pathNode.hub.file.opts.filename);
+ const configDir = process.cwd();
+ const relativePath = path.relative(currentFileDir, configDir);
+ const importPath = relativePath ? path.join(relativePath, 'path') : './path';
+
+ const newImport = t.importDeclaration(
+ [t.importSpecifier(t.identifier('getArktsPath'), t.identifier('getArktsPath'))],
+ t.stringLiteral(importPath)
+ );
+
+ const requireCall = t.callExpression(t.identifier('require'), [t.callExpression(t.identifier('getArktsPath'), [])]);
+ const arkts = t.variableDeclaration('const', [
+ t.variableDeclarator(t.identifier('arkts'), requireCall)
+ ]);
+
+ pathNode.replaceWithMultiple([newImport, arkts]);
+ }
+ }
+ }
+ };
+};
\ No newline at end of file
diff --git a/arkui-plugins/interop-plugins/arkuiImportList.ts b/arkui-plugins/interop-plugins/arkuiImportList.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ddc19b2bd98bf3d005f43c654945be7fbc640c2f
--- /dev/null
+++ b/arkui-plugins/interop-plugins/arkuiImportList.ts
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+export const ARKUI_DECLARE_LIST: Set = new Set([
+ 'AbilityComponent',
+ 'AlphabetIndexer',
+ 'AnalogClock',
+ 'Animator',
+ 'Badge',
+ 'Blank',
+ 'Button',
+ 'Calendar',
+ 'CalendarPicker',
+ 'Camera',
+ 'Canvas',
+ 'Checkbox',
+ 'CheckboxGroup',
+ 'Circle',
+ 'ColorPicker',
+ 'ColorPickerDialog',
+ 'Column',
+ 'ColumnSplit',
+ 'ContentSlot',
+ 'Counter',
+ 'DataPanel',
+ 'DatePicker',
+ 'Divider',
+ 'EffectComponent',
+ 'Ellipse',
+ 'EmbeddedComponent',
+ 'Flex',
+ 'FolderStack',
+ 'FormComponent',
+ 'FormLink',
+ 'Gauge',
+ 'GeometryView',
+ 'Grid',
+ 'GridItem',
+ 'GridContainer',
+ 'Hyperlink',
+ 'Image',
+ 'ImageAnimator',
+ 'Line',
+ 'LinearIndicator',
+ 'List',
+ 'ListItem',
+ 'ListItemGroup',
+ 'LoadingProgress',
+ 'Marquee',
+ 'MediaCachedImage',
+ 'Menu',
+ 'MenuItem',
+ 'MenuItemGroup',
+ 'MovingPhotoView',
+ 'NavDestination',
+ 'NavRouter',
+ 'Navigation',
+ 'Navigator',
+ 'NodeContainer',
+ 'Option',
+ 'PageTransitionEnter',
+ 'PageTransitionExit',
+ 'Panel',
+ 'Particle',
+ 'Path',
+ 'PatternLock',
+ 'Piece',
+ 'PlatformView',
+ 'PluginComponent',
+ 'Polygon',
+ 'Polyline',
+ 'Progress',
+ 'QRCode',
+ 'Radio',
+ 'Rating',
+ 'Rect',
+ 'Refresh',
+ 'RelativeContainer',
+ 'RemoteWindow',
+ 'RootScene',
+ 'Row',
+ 'RowSplit',
+ 'RichText',
+ 'Screen',
+ 'Scroll',
+ 'ScrollBar',
+ 'Search',
+ 'Section',
+ 'Select',
+ 'Shape',
+ 'Sheet',
+ 'SideBarContainer',
+ 'Slider',
+ 'Span',
+ 'Stack',
+ 'Stepper',
+ 'StepperItem',
+ 'Swiper',
+ 'SymbolGlyph',
+ 'SymbolSpan',
+ 'TabContent',
+ 'Tabs',
+ 'Text',
+ 'TextPicker',
+ 'TextClock',
+ 'TextArea',
+ 'TextInput',
+ 'TextTimer',
+ 'TimePicker',
+ 'Toggle',
+ 'Video',
+ 'Web',
+ 'WindowScene',
+ 'WithTheme',
+ 'XComponent',
+ 'GridRow',
+ 'GridCol',
+ 'WaterFlow',
+ 'FlowItem',
+ 'ImageSpan',
+ 'LocationButton',
+ 'PasteButton',
+ 'SaveButton',
+ 'UIExtensionComponent',
+ 'IsolatedComponent',
+ 'RichEditor',
+ 'Component3D',
+ 'ContainerSpan',
+ 'Require',
+ 'BuilderParam',
+ 'Local',
+ 'Param',
+ 'Once',
+ 'Event',
+ 'State',
+ 'Track',
+ 'Trace',
+ 'Prop',
+ 'Link',
+ 'ObjectLink',
+ 'Provide',
+ 'Provider',
+ 'Consume',
+ 'Consumer',
+ 'StorageProp',
+ 'StorageLink',
+ 'Watch',
+ 'LocalStorageLink',
+ 'LocalStorageProp',
+ 'Component',
+ 'ComponentV2',
+ 'Entry',
+ 'Observed',
+ 'ObservedV2',
+ 'Preview',
+ 'CustomDialog',
+ 'Reusable',
+ 'Computed',
+ 'Builder',
+ 'LocalBuilder',
+ 'Styles',
+ 'Extend',
+ 'AnimatableExtend'
+]);
\ No newline at end of file
diff --git a/arkui-plugins/interop-plugins/decl_transformer.ts b/arkui-plugins/interop-plugins/decl_transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58d5a6a6dcad76f8c71bb8cdd6aa3ea2aafcdade
--- /dev/null
+++ b/arkui-plugins/interop-plugins/decl_transformer.ts
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+import { AbstractVisitor } from '../common/abstract-visitor';
+import { ARKUI_DECLARE_LIST } from './arkuiImportList';
+import { debugLog } from '../common/debug';
+
+export class DeclTransformer extends AbstractVisitor {
+ constructor(private options?: interop.DeclTransformerOptions) {
+ super();
+ }
+
+ processComponent(node: arkts.StructDeclaration): arkts.ClassDeclaration {
+ const className = node.definition?.ident?.name;
+ if (!className) {
+ throw 'Non Empty className expected for Component';
+ }
+
+ let newDec: arkts.ClassDeclaration = arkts.factory.createClassDeclaration(node.definition);
+
+ const newDefinition = arkts.factory.updateClassDefinition(
+ newDec.definition!,
+ newDec.definition?.ident,
+ undefined,
+ undefined,
+ newDec.definition?.implements!,
+ undefined,
+ undefined,
+ node.definition?.body,
+ newDec.definition?.modifiers!,
+ arkts.classDefinitionFlags(newDec.definition!) | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE
+ );
+
+ arkts.factory.updateClassDeclaration(newDec, newDefinition);
+ newDec.modifiers = node.modifiers;
+ return newDec;
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ let astNode: arkts.AstNode = beforeChildren;
+ if (arkts.isEtsScript(astNode)) {
+ astNode = this.transformImportDecl(astNode);
+ }
+ const node = this.visitEachChild(astNode);
+ if (arkts.isStructDeclaration(node)) {
+ debugLog(`DeclTransformer:before:flag:${arkts.classDefinitionIsFromStructConst(node.definition!)}`);
+ arkts.classDefinitionSetFromStructModifier(node.definition!);
+ let newnode = this.processComponent(node);
+ debugLog(`DeclTransformer:after:flag:${arkts.classDefinitionIsFromStructConst(newnode.definition!)}`);
+ return newnode;
+ } else if (arkts.isETSImportDeclaration(astNode)) {
+ return this.updateImportDeclaration(astNode);
+ } else if (arkts.isMethodDefinition(astNode)) {
+ if (astNode.name?.name === 'build' ) {
+ return this.transformMethodDefinition(astNode);
+ }
+ return astNode;
+ }
+ return node;
+ }
+
+ transformImportDecl(astNode: arkts.AstNode):arkts.AstNode {
+ if (!arkts.isEtsScript(astNode)) {
+ return astNode;
+ }
+ let statements = astNode.statements.filter(node => this.isImportDeclarationNeedFilter(node));
+ return arkts.factory.updateEtsScript(astNode, statements);
+ }
+
+ transformMethodDefinition(node: arkts.MethodDefinition): arkts.AstNode {
+ const func: arkts.ScriptFunction = node.scriptFunction;
+ const isFunctionCall: boolean = false;
+ const typeNode: arkts.TypeNode | undefined = node.scriptFunction?.returnTypeAnnotation;
+ const updateFunc = arkts.factory.updateScriptFunction(
+ func,
+ !!func.body && arkts.isBlockStatement(func.body)
+ ? arkts.factory.updateBlock(
+ func.body,
+ func.body.statements.filter((st) => false)
+ )
+ : undefined,
+ arkts.FunctionSignature.createFunctionSignature(func.typeParams, func.params, func.returnTypeAnnotation, false),
+ func?.flags,
+ func?.modifiers
+ );
+
+ return arkts.factory.updateMethodDefinition(
+ node,
+ node.kind,
+ arkts.factory.updateIdentifier(
+ node.name,
+ node.name?.name
+ ),
+ updateFunc,
+ node.modifiers,
+ false
+ );
+ }
+
+ isImportDeclarationNeedFilter(astNode: arkts.AstNode):boolean {
+ if (!arkts.isETSImportDeclaration(astNode)) {
+ return true;
+ }
+ return astNode?.source?.str !== '@global.arkui';
+ }
+
+ updateImportDeclaration(astNode: arkts.AstNode):arkts.AstNode {
+ if (!arkts.isETSImportDeclaration(astNode) || astNode?.source?.str !== '@ohos.arkui.component') {
+ return astNode;
+ }
+ astNode.specifiers.forEach((element) => {
+ if (arkts.isImportSpecifier(element)) {
+ if (ARKUI_DECLARE_LIST.has(element.imported?.name as string)) {
+ arkts.ImportSpecifierSetRemovable(element);
+ }
+ }
+ });
+ return astNode;
+ }
+}
diff --git a/arkui-plugins/interop-plugins/emit_transformer.ts b/arkui-plugins/interop-plugins/emit_transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d68dfbc2fb39522b05e6c352a0bc55af8d30e35c
--- /dev/null
+++ b/arkui-plugins/interop-plugins/emit_transformer.ts
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+import { AbstractVisitor } from '../common/abstract-visitor';
+
+import { debugLog } from '../common/debug';
+
+export class EmitTransformer extends AbstractVisitor {
+ constructor(private options?: interop.EmitTransformerOptions) {
+ super();
+ }
+
+ processComponent(node: arkts.ClassDeclaration): arkts.ClassDeclaration {
+ const className = node.definition?.ident?.name;
+ if (!className) {
+ throw 'Non Empty className expected for Component';
+ }
+
+ const newDefinition = arkts.factory.updateClassDefinition(
+ node.definition,
+ node.definition?.ident,
+ undefined,
+ undefined,
+ node.definition?.implements,
+ undefined,
+ undefined,
+ node.definition?.body,
+ node.definition?.modifiers,
+ arkts.classDefinitionFlags(node.definition) | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE
+ );
+
+ let newDec: arkts.ClassDeclaration = arkts.factory.updateClassDeclaration(node, newDefinition);
+
+ debugLog(`DeclTransformer:checked:struct_ast:${newDefinition.dumpJson()}`);
+ newDec.modifiers = node.modifiers;
+ return newDec;
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ const node = this.visitEachChild(beforeChildren);
+ if (arkts.isClassDeclaration(node) && arkts.classDefinitionIsFromStructConst(node.definition!)) {
+ return this.processComponent(node);
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/interop-plugins/index.ts b/arkui-plugins/interop-plugins/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..21c971ce0e3f65a6109399b782c0ea1b39998240
--- /dev/null
+++ b/arkui-plugins/interop-plugins/index.ts
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+
+import { DeclTransformer } from './decl_transformer';
+import { EmitTransformer } from './emit_transformer';
+
+import { ProgramVisitor } from '../common/program-visitor';
+import { EXTERNAL_SOURCE_PREFIX_NAMES } from '../common/predefines';
+import { debugLog } from '../common/debug';
+import { PluginContext, Plugins } from 'common/plugin-context';
+
+export function interopTransform():Plugins {
+ return {
+ name: 'interop-plugin',
+ parsed: parsedTransform,
+ checked: checkedTransform,
+ clean() {
+ arkts.arktsGlobal.clearContext();
+ },
+ };
+}
+
+function parsedTransform(this: PluginContext): arkts.EtsScript | undefined {
+ let script: arkts.EtsScript | undefined;
+ debugLog('interopTransform:parsed');
+ const contextPtr = arkts.arktsGlobal.compilerContext?.peer ?? this.getContextPtr();
+ if (!!contextPtr) {
+ let program = arkts.getOrUpdateGlobalContext(contextPtr).program;
+ script = program.astNode;
+
+ if (script) {
+ const declTransformer = new DeclTransformer({
+ arkui: '@koalaui.arkts-arkui.StructParse' as interop.TransfromerName
+ });
+
+ const programVisitor = new ProgramVisitor({
+ pluginName: interopTransform().name,
+ state: arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED,
+ visitors: [declTransformer],
+ skipPrefixNames: EXTERNAL_SOURCE_PREFIX_NAMES,
+ pluginContext: this as unknown as PluginContext
+ });
+
+ program = programVisitor.programVisitor(program);
+ script = program.astNode;
+ this.setArkTSAst(script);
+ debugLog('interopTransform:parsed exit');
+ return script;
+ }
+ }
+ debugLog('interopTransform: parsed exit with no transform');
+ return script;
+}
+
+function checkedTransform(this: PluginContext): arkts.EtsScript | undefined {
+ let script: arkts.EtsScript | undefined;
+ debugLog('interopTransform:checked');
+ const contextPtr = arkts.arktsGlobal.compilerContext?.peer ?? this.getContextPtr();
+ if (!!contextPtr) {
+ let program = arkts.getOrUpdateGlobalContext(contextPtr).program;
+ script = program.astNode;
+ if (script) {
+ const emitTransformer = new EmitTransformer({
+ arkui: '@koalaui.arkts-arkui.EmitBase' as interop.TransfromerName
+ });
+
+ const programVisitor = new ProgramVisitor({
+ pluginName: interopTransform().name,
+ state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED,
+ visitors: [emitTransformer],
+ skipPrefixNames: EXTERNAL_SOURCE_PREFIX_NAMES,
+ pluginContext: this as unknown as PluginContext
+ });
+
+ program = programVisitor.programVisitor(program);
+ script = program.astNode;
+ arkts.recheckSubtree(script);
+ this.setArkTSAst(script);
+ debugLog('interopTransform:checked exit');
+ return script;
+ }
+ }
+ debugLog('interopTransform:checked exit with no transform');
+ return script;
+}
diff --git a/arkui-plugins/interop-plugins/types.ts b/arkui-plugins/interop-plugins/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..49b257dc5d1cfa4d3a57fa45ea9813487c11c525
--- /dev/null
+++ b/arkui-plugins/interop-plugins/types.ts
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+namespace interop {
+ export type NativePointer = number;
+
+ export interface PluginContext {
+ setArkTSAst(ast: Node): void;
+ getArkTSAst(): Node | undefined;
+ setArkTSProgram(program: Node): void;
+ getArkTSProgram(): Node | undefined;
+ setProjectConfig(projectConfig: Node): void;
+ getProjectConfig(): Node | undefined;
+ }
+
+ export interface ArktsObject {
+ readonly peer: NativePointer;
+ }
+
+ export interface Node extends ArktsObject {
+ get originalPeer(): NativePointer;
+ set originalPeer(peer: NativePointer);
+ dumpJson(): string;
+ dumpSrc(): string;
+ }
+
+ export interface EtsScript extends Node {}
+
+ export interface Plugin {
+ name: string;
+ parsed?(context: PluginContext): EtsScript | undefined;
+ checked?(context: PluginContext): EtsScript | undefined;
+ }
+
+ export type TransfromerName = string & { __TransfromerNameBrand: any };
+
+ export interface EmitTransformerOptions {
+ arkui: TransfromerName;
+ }
+
+ export interface DeclTransformerOptions {
+ arkui: TransfromerName;
+ }
+}
diff --git a/arkui-plugins/jest-test.config.js b/arkui-plugins/jest-test.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..cbca1f13e2e3c5cf964642ba71a4c025e339e706
--- /dev/null
+++ b/arkui-plugins/jest-test.config.js
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+const path = require('path');
+
+const rootPath = path.resolve(__dirname, '../../../');
+const sdkPath = path.resolve(rootPath, './out/sdk/ohos-sdk/linux/ets/ets1.2');
+const pandaSdkPath = path.resolve(sdkPath, './build-tools/ets2panda');
+const apiPath = path.resolve(sdkPath, './api');
+const kitPath = path.resolve(sdkPath, './kits');
+
+module.exports = {
+ testEnvironment: 'node',
+ transform: {
+ '^.+\\.ts$': ['ts-jest'],
+ },
+ testRegex: './test/ut/.+\\.test\\.ts$',
+ moduleFileExtensions: ['ts', 'js', 'json', 'node'],
+ coverageDirectory: './test/report',
+ collectCoverageFrom: [
+ 'collectors/**',
+ 'common/**',
+ 'memo-plugins/**',
+ 'ui-plugins/**'
+ ],
+ coveragePathIgnorePatterns: [
+ 'common/debug.ts',
+ 'common/etsglobal-remover.ts',
+ 'common/print-visitor.ts',
+ 'common/plugin-context.ts',
+ 'memo-plugins/index.ts',
+ 'memo-plugins/import-transformer.ts',
+ 'memo-plugins/memo-transformer.ts',
+ 'ui-plugins/index.ts',
+ 'ui-plugins/printer-transformer.ts',
+ 'ui-plugins/builder-lambda-translators/builder-lambda-transformer.ts',
+ 'ui-plugins/entry-translators/entry-transformer.ts',
+ 'ui-plugins/struct-translators/struct-transformer.ts',
+ ],
+ verbose: true,
+ globals: {
+ SDK_PATH: sdkPath,
+ PANDA_SDK_PATH: pandaSdkPath,
+ API_PATH: apiPath,
+ KIT_PATH: kitPath,
+ },
+};
diff --git a/arkui-plugins/memo-plugins/function-transformer.ts b/arkui-plugins/memo-plugins/function-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4f2c55f1f4c572c8cabfa2ede178bc0d0cc1018d
--- /dev/null
+++ b/arkui-plugins/memo-plugins/function-transformer.ts
@@ -0,0 +1,740 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { factory } from './memo-factory';
+import { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor';
+import {
+ MemoInfo,
+ PositionalIdTracker,
+ ReturnTypeInfo,
+ buildReturnTypeInfo,
+ castArrowFunctionExpression,
+ castIdentifier,
+ castOverloadsToMethods,
+ castParameters,
+ findMemoFromTypeAnnotation,
+ findThisAttribute,
+ getDeclResolveAlias,
+ hasMemoAnnotation,
+ hasMemoEntryAnnotation,
+ hasMemoIntrinsicAnnotation,
+ hasMemoStableAnnotation,
+ isDeclaredMethodWithMemoParams,
+ isFunctionProperty,
+ isMemoArrowFunction,
+ isMemoClassProperty,
+ isMemoDeclaredClassProperty,
+ isMemoDeclaredIdentifier,
+ isMemoDeclaredMethod,
+ isMemoETSParameterExpression,
+ isMemoMethodDefinition,
+ isMemoProperty,
+ isMemoTSTypeAliasDeclaration,
+ isMemoThisAttribute,
+ isMemoVariableDeclarator,
+ isStandaloneArrowFunction,
+ isThisAttributeAssignment,
+ removeMemoAnnotation,
+ parametrizedNodeHasReceiver,
+} from './utils';
+import { ParameterTransformer } from './parameter-transformer';
+import { ReturnTransformer } from './return-transformer';
+import { SignatureTransformer } from './signature-transformer';
+import { moveToFront } from '../common/arkts-utils';
+import { InternalsTransformer } from './internal-transformer';
+import { CachedMetadata, rewriteByType } from './memo-cache-factory';
+
+interface ScopeInfo extends MemoInfo {
+ regardAsSameScope?: boolean;
+}
+
+export interface FunctionTransformerOptions extends VisitorOptions {
+ positionalIdTracker: PositionalIdTracker;
+ parameterTransformer: ParameterTransformer;
+ returnTransformer: ReturnTransformer;
+ signatureTransformer: SignatureTransformer;
+ internalsTransformer?: InternalsTransformer;
+ useCache?: boolean;
+}
+
+export class FunctionTransformer extends AbstractVisitor {
+ private readonly positionalIdTracker: PositionalIdTracker;
+ private readonly parameterTransformer: ParameterTransformer;
+ private readonly returnTransformer: ReturnTransformer;
+ private readonly signatureTransformer: SignatureTransformer;
+ private readonly internalsTransformer?: InternalsTransformer;
+ private readonly useCache: boolean;
+
+ /* Tracking whether should import `__memo_context_type` and `__memo_id_type` */
+ private modified = false;
+
+ constructor(options: FunctionTransformerOptions) {
+ super(options);
+ this.positionalIdTracker = options.positionalIdTracker;
+ this.parameterTransformer = options.parameterTransformer;
+ this.returnTransformer = options.returnTransformer;
+ this.signatureTransformer = options.signatureTransformer;
+ this.internalsTransformer = options.internalsTransformer;
+ this.useCache = !!options.useCache;
+ }
+
+ private scopes: ScopeInfo[] = [];
+ private stable: number = 0;
+
+ reset() {
+ super.reset();
+ this.scopes = [];
+ this.stable = 0;
+ this.modified = false;
+ this.parameterTransformer.reset();
+ this.returnTransformer.reset();
+ this.signatureTransformer.reset();
+ }
+
+ private enterMethod(node: arkts.MethodDefinition): void {
+ const name = node.name.name;
+ const isMemo = isMemoMethodDefinition(node);
+ this.scopes.push({ name, isMemo });
+ }
+
+ private enterClassPropety(node: arkts.ClassProperty): void {
+ const name = castIdentifier(node.key).name;
+ const isMemo = isMemoClassProperty(node);
+ this.scopes.push({ name, isMemo });
+ }
+
+ private enterStandaloneArrowFunction(node: arkts.ArrowFunctionExpression): void {
+ const name = undefined;
+ const isMemo = isMemoArrowFunction(node);
+ this.scopes.push({ name, isMemo });
+ }
+
+ private enterTSTypeAliasDeclaration(node: arkts.TSTypeAliasDeclaration): void {
+ const name = castIdentifier(node.id).name;
+ const isMemo = isMemoTSTypeAliasDeclaration(node);
+ this.scopes.push({ name, isMemo });
+ }
+
+ private enterVariableDeclarator(node: arkts.VariableDeclarator): void {
+ const name = node.name.name;
+ const isMemo = isMemoVariableDeclarator(node);
+ this.scopes.push({ name, isMemo, regardAsSameScope: !!node.initializer });
+ }
+
+ private enterTSAsExpression(node: arkts.TSAsExpression): void {
+ const isMemo = findMemoFromTypeAnnotation(node.typeAnnotation);
+ this.scopes.push({ isMemo });
+ }
+
+ private enterFunctionProperty(node: arkts.Property): void {
+ const name = castIdentifier(node.key).name;
+ const isMemo = isMemoProperty(node, castArrowFunctionExpression(node.value));
+ this.scopes.push({ name, isMemo });
+ }
+
+ private enterThisAttributeAssignment(node: arkts.AssignmentExpression): void {
+ const thisAttribute = findThisAttribute(node.left!)!;
+ const name = thisAttribute.name;
+ const isMemo = isMemoThisAttribute(thisAttribute, castArrowFunctionExpression(node.right));
+ this.scopes.push({ name, isMemo });
+ }
+
+ enter(node: arkts.AstNode): this {
+ if (arkts.isMethodDefinition(node)) {
+ this.enterMethod(node);
+ }
+ if (arkts.isClassProperty(node) && !!node.key && arkts.isIdentifier(node.key)) {
+ this.enterClassPropety(node);
+ }
+ if (isStandaloneArrowFunction(node)) {
+ this.enterStandaloneArrowFunction(node);
+ }
+ if (arkts.isTSTypeAliasDeclaration(node) && !!node.id && !!node.typeAnnotation) {
+ this.enterTSTypeAliasDeclaration(node);
+ }
+ if (arkts.isVariableDeclarator(node)) {
+ this.enterVariableDeclarator(node);
+ }
+ if (arkts.isTSAsExpression(node) && !!node.expr && arkts.isArrowFunctionExpression(node.expr)) {
+ this.enterTSAsExpression(node);
+ }
+ if (isFunctionProperty(node)) {
+ this.enterFunctionProperty(node);
+ }
+ if (isThisAttributeAssignment(node) && !!node.right && arkts.isArrowFunctionExpression(node.right)) {
+ this.enterThisAttributeAssignment(node);
+ }
+ if (arkts.isClassDefinition(node)) {
+ if (hasMemoStableAnnotation(node)) {
+ this.stable++;
+ }
+ }
+ return this;
+ }
+
+ exit(node: arkts.AstNode) {
+ if (arkts.isMethodDefinition(node)) {
+ this.scopes.pop();
+ }
+ if (arkts.isClassDefinition(node)) {
+ if (hasMemoStableAnnotation(node)) {
+ this.stable--;
+ }
+ }
+ return this;
+ }
+
+ enterAnonymousScope(node: arkts.ScriptFunction) {
+ const name = undefined;
+ const isMemo = hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node);
+ this.scopes.push({ name, isMemo });
+ return this;
+ }
+
+ exitAnonymousScope() {
+ this.scopes.pop();
+ return this;
+ }
+
+ checkMemoCallInMethod(decl: arkts.MethodDefinition) {
+ const scope = this.scopes[this.scopes.length - 1];
+ if (scope?.regardAsSameScope === false && scope?.isMemo === false) {
+ if (scope.name) {
+ console.error(`Attempt to call @memo-method ${decl.name.name} from non-@memo-method ${scope.name}`);
+ throw 'Invalid @memo usage';
+ } else {
+ console.error(`Attempt to call @memo-method ${decl.name.name} from anonymous non-@memo-method`);
+ throw 'Invalid @memo usage';
+ }
+ }
+ return this;
+ }
+
+ checkMemoCallInFunction() {
+ const scope = this.scopes[this.scopes.length - 1];
+ if (scope?.regardAsSameScope === false && scope?.isMemo === false) {
+ console.error(`Attempt to call @memo-function`);
+ throw 'Invalid @memo usage';
+ }
+ return this;
+ }
+
+ updateInternalsInScriptFunction(scriptFunction: arkts.ScriptFunction): arkts.ScriptFunction {
+ if (!scriptFunction.body || !arkts.isBlockStatement(scriptFunction.body) || !this.internalsTransformer) {
+ return scriptFunction;
+ }
+ const afterInternalsTransformer = this.internalsTransformer.visitor(
+ scriptFunction.body
+ ) as arkts.BlockStatement;
+ return arkts.factory.updateScriptFunction(
+ scriptFunction,
+ afterInternalsTransformer,
+ arkts.factory.createFunctionSignature(
+ scriptFunction.typeParams,
+ scriptFunction.params,
+ scriptFunction.returnTypeAnnotation,
+ scriptFunction.hasReceiver
+ ),
+ scriptFunction.flags,
+ scriptFunction.modifiers
+ );
+ }
+
+ updateScriptFunction(scriptFunction: arkts.ScriptFunction, name: string = ''): arkts.ScriptFunction {
+ if (!scriptFunction.body || !arkts.isBlockStatement(scriptFunction.body)) {
+ return scriptFunction;
+ }
+ if (this.parameterTransformer.isTracked(scriptFunction.body)) {
+ return this.updateInternalsInScriptFunction(scriptFunction);
+ }
+ if (hasMemoIntrinsicAnnotation(scriptFunction) || hasMemoEntryAnnotation(scriptFunction)) {
+ return this.updateInternalsInScriptFunction(scriptFunction);
+ }
+ const returnType = scriptFunction.returnTypeAnnotation;
+ const isStableThis = this.stable > 0 && returnType !== undefined && arkts.isTSThisType(returnType);
+ const returnTypeInfo: ReturnTypeInfo = buildReturnTypeInfo(
+ returnType,
+ findMemoFromTypeAnnotation(returnType),
+ isStableThis
+ );
+ const [body, parameterIdentifiers, memoParametersDeclaration, syntheticReturnStatement] =
+ factory.updateFunctionBody(
+ scriptFunction.body,
+ castParameters(scriptFunction.params),
+ returnTypeInfo,
+ this.positionalIdTracker.id(name)
+ );
+ const afterParameterTransformer = this.parameterTransformer
+ .withParameters(parameterIdentifiers)
+ .skip(memoParametersDeclaration)
+ .visitor(body);
+ const afterReturnTransformer = this.returnTransformer
+ .skip(syntheticReturnStatement)
+ .registerReturnTypeInfo(returnTypeInfo)
+ .rewriteThis(this.stable > 0)
+ .visitor(afterParameterTransformer);
+ const updateScriptFunction = factory.updateScriptFunctionWithMemoParameters(
+ scriptFunction,
+ afterReturnTransformer,
+ returnTypeInfo.node
+ );
+ this.modified = true;
+ this.parameterTransformer.track(updateScriptFunction.body);
+ return this.updateInternalsInScriptFunction(updateScriptFunction);
+ }
+
+ private updateMethodDefinition(node: arkts.MethodDefinition): arkts.MethodDefinition {
+ let updateMethod: arkts.MethodDefinition;
+ const that = this;
+ const updateOverloads = node.overloads?.map((overload) => that.visitor(overload)) ?? undefined;
+ const isMemo =
+ hasMemoAnnotation(node.scriptFunction) ||
+ hasMemoIntrinsicAnnotation(node.scriptFunction) ||
+ hasMemoEntryAnnotation(node.scriptFunction);
+ if (isMemo && node.scriptFunction.body) {
+ const hasIntrinsic = hasMemoIntrinsicAnnotation(node.scriptFunction);
+ updateMethod = arkts.factory.updateMethodDefinition(
+ node,
+ node.kind,
+ node.name,
+ this.signatureTransformer.visitor(
+ removeMemoAnnotation(this.updateScriptFunction(node.scriptFunction, node.name.name)),
+ hasIntrinsic
+ ),
+ node.modifiers,
+ false
+ );
+ } else {
+ updateMethod = arkts.factory.updateMethodDefinition(
+ node,
+ node.kind,
+ node.name,
+ this.signatureTransformer.visitor(node.scriptFunction),
+ node.modifiers,
+ false
+ );
+ }
+ if (!!updateOverloads) {
+ updateMethod.setOverloads(castOverloadsToMethods(updateOverloads));
+ }
+ this.modified ||= this.signatureTransformer.modified;
+ return updateMethod;
+ }
+
+ private updateDeclaredMethodMemoCall(
+ node: arkts.CallExpression,
+ decl: arkts.MethodDefinition,
+ ignoreSelf: boolean = false
+ ): arkts.CallExpression {
+ let updatedArguments: arkts.AstNode[] = node.arguments.map((it, index) => {
+ const param = decl.scriptFunction.params.at(index);
+ if (!param || !arkts.isEtsParameterExpression(param)) {
+ return it;
+ }
+ if (isMemoETSParameterExpression(param) && arkts.isArrowFunctionExpression(it)) {
+ this.enterAnonymousScope(it.scriptFunction);
+ const res = this.updateScriptFunction(it.scriptFunction);
+ this.exitAnonymousScope();
+ this.modified = true;
+ return arkts.factory.updateArrowFunction(it, res);
+ }
+ return it;
+ });
+ if (!ignoreSelf) {
+ this.checkMemoCallInMethod(decl);
+ updatedArguments = [
+ ...factory.createHiddenArguments(this.positionalIdTracker.id(decl.name.name)),
+ ...updatedArguments,
+ ];
+ }
+ const isMemo =
+ hasMemoAnnotation(decl.scriptFunction) ||
+ hasMemoIntrinsicAnnotation(decl.scriptFunction) ||
+ hasMemoEntryAnnotation(decl.scriptFunction);
+ if (parametrizedNodeHasReceiver(decl.scriptFunction) && isMemo) {
+ updatedArguments = moveToFront(updatedArguments, 2);
+ }
+ this.modified = true;
+ return arkts.factory.updateCallExpression(node, node.expression, node.typeArguments, updatedArguments);
+ }
+
+ private updateDeclaredCallWithName(node: arkts.CallExpression, name: string): arkts.CallExpression {
+ this.modified = true;
+ return factory.insertHiddenArgumentsToCall(node, this.positionalIdTracker.id(name));
+ }
+
+ private updateAnonymousCallWithMemoParams(node: arkts.CallExpression): arkts.CallExpression {
+ let newExpression: arkts.AstNode = node.expression;
+ if (isStandaloneArrowFunction(node.expression)) {
+ newExpression = arkts.factory.updateArrowFunction(
+ node.expression,
+ this.signatureTransformer.visitor(node.expression.scriptFunction)
+ );
+ }
+ const that = this;
+ const updatedArguments: arkts.AstNode[] = node.arguments.map((it) => {
+ if (arkts.isArrowFunctionExpression(it) && isMemoArrowFunction(it)) {
+ that.enterAnonymousScope(it.scriptFunction);
+ const res = that.updateScriptFunction(it.scriptFunction);
+ that.exitAnonymousScope();
+ that.modified = true;
+ return arkts.factory.updateArrowFunction(it, res);
+ }
+ return it;
+ });
+ this.modified ||= this.signatureTransformer.modified;
+ return arkts.factory.updateCallExpression(node, newExpression, node.typeArguments, updatedArguments);
+ }
+
+ private updateAnonymousMemoCall(
+ node: arkts.CallExpression,
+ expression: arkts.ArrowFunctionExpression
+ ): arkts.CallExpression {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === expression.scriptFunction.id?.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return this.updateAnonymousCallWithMemoParams(node);
+ }
+ this.checkMemoCallInFunction();
+
+ this.enterAnonymousScope(expression.scriptFunction);
+ const res = this.updateScriptFunction(expression.scriptFunction, expression.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+
+ const newNode = this.updateAnonymousCallWithMemoParams(node);
+ this.modified = true;
+ return arkts.factory.updateCallExpression(
+ node,
+ arkts.factory.updateArrowFunction(expression, res),
+ newNode.typeArguments,
+ [...factory.createHiddenArguments(this.positionalIdTracker.id()), ...newNode.arguments]
+ );
+ }
+
+ private updateCallExpressionWithNoDecl(node: arkts.CallExpression): arkts.CallExpression {
+ if (isStandaloneArrowFunction(node.expression)) {
+ return this.updateAnonymousMemoCall(node, node.expression);
+ }
+ return this.updateAnonymousCallWithMemoParams(node);
+ }
+
+ private updateCallExpression(node: arkts.CallExpression): arkts.CallExpression {
+ const expr = node.expression;
+ const decl = getDeclResolveAlias(expr);
+ if (!decl) {
+ return this.updateCallExpressionWithNoDecl(node);
+ }
+ if (arkts.isMethodDefinition(decl) && isMemoDeclaredMethod(decl)) {
+ return this.updateDeclaredMethodMemoCall(node, decl);
+ }
+ if (arkts.isMethodDefinition(decl) && isDeclaredMethodWithMemoParams(decl)) {
+ return this.updateDeclaredMethodMemoCall(node, decl, true);
+ }
+ if (arkts.isIdentifier(decl) && isMemoDeclaredIdentifier(decl)) {
+ return this.updateDeclaredCallWithName(node, decl.name);
+ }
+ if (
+ arkts.isClassProperty(decl) &&
+ isMemoDeclaredClassProperty(decl) &&
+ !!decl.key &&
+ arkts.isIdentifier(decl.key)
+ ) {
+ return this.updateDeclaredCallWithName(node, decl.key.name);
+ }
+ if (arkts.isEtsParameterExpression(decl) && isMemoETSParameterExpression(decl)) {
+ return this.updateDeclaredCallWithName(node, decl.identifier.name);
+ }
+ return this.updateCallExpressionWithNoDecl(node);
+ }
+
+ private updateClassProperty(node: arkts.ClassProperty, key: arkts.Identifier): arkts.ClassProperty {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === key.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return node;
+ }
+
+ let res: arkts.ScriptFunction | undefined;
+ if (!!node.value && arkts.isArrowFunctionExpression(node.value)) {
+ this.enterAnonymousScope(node.value.scriptFunction);
+ res = this.updateScriptFunction(node.value.scriptFunction, key.name);
+ this.exitAnonymousScope();
+ }
+
+ let typeAnnotation: arkts.TypeNode | undefined;
+ if (!!node.typeAnnotation && !(typeAnnotation = factory.updateMemoTypeAnnotation(node.typeAnnotation))) {
+ console.error(`ETSFunctionType or ETSUnionType expected for @memo-property ${key.name}`);
+ throw 'Invalid @memo usage';
+ }
+
+ this.modified = true;
+ return arkts.factory.updateClassProperty(
+ node,
+ node.key,
+ res ? arkts.factory.updateArrowFunction(castArrowFunctionExpression(node.value), res) : undefined,
+ typeAnnotation,
+ node.modifiers,
+ node.isComputed
+ );
+ }
+
+ private updateTSTypeAliasDeclaration(node: arkts.TSTypeAliasDeclaration): arkts.TSTypeAliasDeclaration {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === node.id?.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ if (!!node.typeAnnotation) {
+ const newNode = arkts.factory.updateTSTypeAliasDeclaration(
+ node,
+ node.id,
+ node.typeParams,
+ this.signatureTransformer.visitor(node.typeAnnotation)
+ );
+ this.modified ||= this.signatureTransformer.modified;
+ return newNode;
+ }
+ return node;
+ }
+
+ let typeAnnotation: arkts.TypeNode | undefined;
+ if (!(typeAnnotation = factory.updateMemoTypeAnnotation(node.typeAnnotation))) {
+ console.error(`ETSFunctionType or ETSUnionType expected for @memo-type ${node.id!.name}`);
+ throw 'Invalid @memo usage';
+ }
+
+ this.modified = true;
+ return arkts.factory.updateTSTypeAliasDeclaration(node, node.id, node.typeParams, typeAnnotation);
+ }
+
+ private updateStandaloneArrowFunction(node: arkts.ArrowFunctionExpression): arkts.ArrowFunctionExpression {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === node.scriptFunction.id?.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return arkts.factory.updateArrowFunction(node, this.signatureTransformer.visitor(node.scriptFunction));
+ }
+
+ this.enterAnonymousScope(node.scriptFunction);
+ const res = this.updateScriptFunction(node.scriptFunction, node.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+
+ this.modified = true;
+ return arkts.factory.updateArrowFunction(node, this.signatureTransformer.visitor(res));
+ }
+
+ private updateVariableDeclarator(node: arkts.VariableDeclarator): arkts.VariableDeclarator {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === node.name.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ if (!!node.initializer && arkts.isArrowFunctionExpression(node.initializer)) {
+ return arkts.factory.updateVariableDeclarator(
+ node,
+ node.flag,
+ node.name,
+ arkts.factory.updateArrowFunction(
+ node.initializer,
+ this.signatureTransformer.visitor(node.initializer.scriptFunction)
+ )
+ );
+ }
+ return node;
+ }
+
+ let typeAnnotation: arkts.TypeNode | undefined;
+ if (
+ !!node.name.typeAnnotation &&
+ !(typeAnnotation = factory.updateMemoTypeAnnotation(node.name.typeAnnotation))
+ ) {
+ console.error(`ETSFunctionType or ETSUnionType expected for @memo-variable-type ${node.name.name}`);
+ throw 'Invalid @memo usage';
+ }
+
+ let initializer: arkts.AstNode | undefined = node.initializer;
+ if (!!initializer && arkts.isArrowFunctionExpression(initializer)) {
+ this.enterAnonymousScope(initializer.scriptFunction);
+ const res = this.updateScriptFunction(initializer.scriptFunction, initializer.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+ initializer = arkts.factory.updateArrowFunction(initializer, res);
+ }
+
+ this.modified = true;
+ return arkts.factory.updateVariableDeclarator(
+ node,
+ node.flag,
+ arkts.factory.updateIdentifier(node.name, node.name.name, typeAnnotation),
+ initializer
+ );
+ }
+
+ private updateTSAsExpression(
+ node: arkts.TSAsExpression,
+ expr: arkts.ArrowFunctionExpression
+ ): arkts.TSAsExpression {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return node;
+ }
+
+ this.enterAnonymousScope(expr.scriptFunction);
+ const res = this.updateScriptFunction(expr.scriptFunction, expr.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+
+ let typeAnnotation: arkts.TypeNode | undefined;
+ if (!(typeAnnotation = factory.updateMemoTypeAnnotation(node.typeAnnotation))) {
+ console.error(`ETSFunctionType or ETSUnionType expected for @memo-as-type`);
+ throw 'Invalid @memo usage';
+ }
+
+ this.modified = true;
+ return arkts.factory.updateTSAsExpression(
+ node,
+ arkts.factory.updateArrowFunction(expr, res),
+ typeAnnotation,
+ node.isConst
+ );
+ }
+
+ private updateProperty(
+ node: arkts.Property,
+ key: arkts.Identifier,
+ value: arkts.ArrowFunctionExpression
+ ): arkts.Property {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === key.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return node;
+ }
+
+ this.enterAnonymousScope(value.scriptFunction);
+ const res = this.updateScriptFunction(value.scriptFunction, value.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+
+ this.modified = true;
+ return arkts.factory.updateProperty(node, key, arkts.factory.updateArrowFunction(value, res));
+ }
+
+ private updateThisAttributeAssignment(
+ node: arkts.AssignmentExpression,
+ thisAttribute: arkts.Identifier,
+ right: arkts.ArrowFunctionExpression
+ ): arkts.AssignmentExpression {
+ const scope = this.scopes[this.scopes.length - 1];
+ const isValidScope = !!scope && scope.name === thisAttribute.name;
+ if (!isValidScope) {
+ return node;
+ }
+ this.exitAnonymousScope();
+ if (!scope.isMemo) {
+ return node;
+ }
+
+ this.enterAnonymousScope(right.scriptFunction);
+ const res = this.updateScriptFunction(right.scriptFunction, right.scriptFunction.id?.name);
+ this.exitAnonymousScope();
+
+ this.modified = true;
+ return arkts.factory.updateAssignmentExpression(
+ node,
+ node.left!,
+ node.operatorType,
+ arkts.factory.updateArrowFunction(right, res)
+ );
+ }
+
+ private visitorWithCache(beforeChildren: arkts.AstNode): arkts.AstNode {
+ const node = this.visitEachChild(beforeChildren);
+ if (arkts.NodeCache.getInstance().has(node)) {
+ const value = arkts.NodeCache.getInstance().get(node)!;
+ if (rewriteByType.has(value.type)) {
+ this.modified = true;
+ const metadata: CachedMetadata = { ...value.metadata, internalsTransformer: this.internalsTransformer };
+ return rewriteByType.get(value.type)!(node, metadata);
+ }
+ }
+ if (arkts.isEtsScript(node) && this.modified) {
+ factory.createContextTypesImportDeclaration(this.program);
+ }
+ return node;
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ if (this.useCache) {
+ return this.visitorWithCache(beforeChildren);
+ }
+ this.enter(beforeChildren);
+ const node = this.visitEachChild(beforeChildren);
+ this.exit(beforeChildren);
+ if (arkts.isMethodDefinition(node)) {
+ return this.updateMethodDefinition(node);
+ }
+ if (arkts.isCallExpression(node)) {
+ return this.updateCallExpression(node);
+ }
+ if (arkts.isClassProperty(node) && !!node.key && arkts.isIdentifier(node.key)) {
+ return this.updateClassProperty(node, node.key);
+ }
+ if (arkts.isTSTypeAliasDeclaration(node)) {
+ return this.updateTSTypeAliasDeclaration(node);
+ }
+ if (isStandaloneArrowFunction(node)) {
+ return this.updateStandaloneArrowFunction(node);
+ }
+ if (arkts.isVariableDeclarator(node)) {
+ return this.updateVariableDeclarator(node);
+ }
+ if (arkts.isTSAsExpression(node) && node.expr && arkts.isArrowFunctionExpression(node.expr)) {
+ return this.updateTSAsExpression(node, node.expr);
+ }
+ if (isFunctionProperty(node)) {
+ return this.updateProperty(node, castIdentifier(node.key), castArrowFunctionExpression(node.value));
+ }
+ if (isThisAttributeAssignment(node) && !!node.right && arkts.isArrowFunctionExpression(node.right)) {
+ const thisAttribute = findThisAttribute(node.left!)!;
+ return this.updateThisAttributeAssignment(node, thisAttribute, node.right);
+ }
+ if (arkts.isEtsScript(node) && this.modified) {
+ factory.createContextTypesImportDeclaration(this.program);
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/import-transformer.ts b/arkui-plugins/memo-plugins/import-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac8adfaf0c7966288dbb5a8e5f86d63980a6fdd5
--- /dev/null
+++ b/arkui-plugins/memo-plugins/import-transformer.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { AbstractVisitor } from '../common/abstract-visitor';
+import { factory } from './memo-factory';
+
+export class ImportTransformer extends AbstractVisitor {
+ visitor(node: arkts.AstNode): arkts.AstNode {
+ if (node instanceof arkts.EtsScript) {
+ factory.createContextTypesImportDeclaration(arkts.arktsGlobal.compilerContext?.program);
+ return arkts.factory.updateEtsScript(node, node.statements);
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/index.ts b/arkui-plugins/memo-plugins/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5c19bc8414083b125b060e9fa01acd1f62e8bbf6
--- /dev/null
+++ b/arkui-plugins/memo-plugins/index.ts
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { Plugins, PluginContext } from '../common/plugin-context';
+import { FunctionTransformer } from './function-transformer';
+import { PositionalIdTracker } from './utils';
+import { ReturnTransformer } from './return-transformer';
+import { ParameterTransformer } from './parameter-transformer';
+import { ProgramVisitor } from '../common/program-visitor';
+import { EXTERNAL_SOURCE_PREFIX_NAMES, EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK } from '../common/predefines';
+import { debugDump, debugLog, getDumpFileName } from '../common/debug';
+import { SignatureTransformer } from './signature-transformer';
+import { InternalsTransformer } from './internal-transformer';
+
+export function unmemoizeTransform(): Plugins {
+ return {
+ name: 'memo-plugin',
+ checked: checkedTransform,
+ clean() {
+ arkts.arktsGlobal.clearContext();
+ },
+ };
+}
+
+function checkedTransform(this: PluginContext): arkts.EtsScript | undefined {
+ console.log('[MEMO PLUGIN] AFTER CHECKED ENTER');
+ arkts.Performance.getInstance().memoryTrackerReset();
+ arkts.Performance.getInstance().startMemRecord('Node:UIPlugin:Memo-AfterCheck');
+ const contextPtr = this.getContextPtr() ?? arkts.arktsGlobal.compilerContext?.peer;
+ if (!!contextPtr) {
+ let program = arkts.getOrUpdateGlobalContext(contextPtr).program;
+ let script = program.astNode;
+ debugLog('[BEFORE MEMO SCRIPT] script: ', script.dumpSrc());
+ const cachePath: string | undefined = this.getProjectConfig()?.cachePath;
+ const isFrameworkMode = !!this.getProjectConfig()?.frameworkMode;
+ const canSkipPhases = !isFrameworkMode && program.canSkipPhases();
+ debugDump(
+ script.dumpSrc(),
+ getDumpFileName(0, 'SRC', 5, 'MEMO_AfterCheck_Begin'),
+ true,
+ cachePath,
+ program.fileNameWithExtension
+ );
+ arkts.Performance.getInstance().createEvent('memo-checked');
+ program = checkedProgramVisit(program, this, canSkipPhases, isFrameworkMode);
+ script = program.astNode;
+ arkts.Performance.getInstance().stopEvent('memo-checked', true);
+ debugLog('[AFTER MEMO SCRIPT] script: ', script.dumpSrc());
+ debugDump(
+ script.dumpSrc(),
+ getDumpFileName(0, 'SRC', 6, 'MEMO_AfterCheck_End'),
+ true,
+ cachePath,
+ program.fileNameWithExtension
+ );
+
+ arkts.Performance.getInstance().memoryTrackerGetDelta('UIPlugin:Memo-AfterCheck');
+ arkts.Performance.getInstance().memoryTrackerReset();
+ arkts.Performance.getInstance().stopMemRecord('Node:UIPlugin:Memo-AfterCheck');
+ arkts.Performance.getInstance().startMemRecord('Node:ArkTS:Recheck');
+ arkts.Performance.getInstance().createEvent('memo-recheck');
+ arkts.recheckSubtree(script);
+ arkts.Performance.getInstance().stopEvent('memo-recheck', true);
+ this.setArkTSAst(script);
+ arkts.Performance.getInstance().memoryTrackerGetDelta('ArkTS:Recheck');
+ arkts.Performance.getInstance().stopMemRecord('Node:ArkTS:Recheck');
+ arkts.Performance.getInstance().memoryTrackerPrintCurrent('UIPlugin:End');
+ console.log('[MEMO PLUGIN] AFTER CHECKED EXIT');
+ return script;
+ }
+ console.log('[MEMO PLUGIN] AFTER CHECKED EXIT WITH NO TRANSFORM');
+ return undefined;
+}
+
+function checkedProgramVisit(
+ program: arkts.Program,
+ pluginContext: PluginContext,
+ canSkipPhases: boolean = false,
+ isFrameworkMode: boolean = false
+): arkts.Program {
+ if (canSkipPhases) {
+ debugLog('[SKIP PHASE] phase: memo-checked, moduleName: ', program.moduleName);
+ } else {
+ debugLog('[CANT SKIP PHASE] phase: memo-checked, moduleName: ', program.moduleName);
+ const positionalIdTracker = new PositionalIdTracker(arkts.getFileName(), false);
+ const parameterTransformer = new ParameterTransformer({ positionalIdTracker });
+ const returnTransformer = new ReturnTransformer();
+ const signatureTransformer = new SignatureTransformer();
+ let internalsTransformer: InternalsTransformer | undefined;
+ if (isFrameworkMode) {
+ internalsTransformer = new InternalsTransformer({ positionalIdTracker });
+ }
+ const functionTransformer = new FunctionTransformer({
+ positionalIdTracker,
+ parameterTransformer,
+ returnTransformer,
+ signatureTransformer,
+ internalsTransformer,
+ useCache: arkts.NodeCache.getInstance().isCollected(),
+ });
+ const skipPrefixNames = isFrameworkMode
+ ? EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK
+ : EXTERNAL_SOURCE_PREFIX_NAMES;
+ const programVisitor = new ProgramVisitor({
+ pluginName: unmemoizeTransform.name,
+ state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED,
+ visitors: [functionTransformer],
+ skipPrefixNames,
+ pluginContext,
+ });
+ program = programVisitor.programVisitor(program);
+ arkts.NodeCache.getInstance().clear();
+ }
+ return program;
+}
diff --git a/arkui-plugins/memo-plugins/internal-transformer.ts b/arkui-plugins/memo-plugins/internal-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3541fb7c37fb8db20c34eb7171c37ed3cad20044
--- /dev/null
+++ b/arkui-plugins/memo-plugins/internal-transformer.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { RuntimeNames, PositionalIdTracker } from './utils';
+import { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor';
+
+export interface InternalsTransformerOptions extends VisitorOptions {
+ positionalIdTracker: PositionalIdTracker;
+}
+
+export class InternalsTransformer extends AbstractVisitor {
+ private readonly positionalIdTracker: PositionalIdTracker;
+
+ constructor(options: InternalsTransformerOptions) {
+ super(options);
+ this.positionalIdTracker = options.positionalIdTracker;
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ const node = this.visitEachChild(beforeChildren);
+ if (arkts.isCallExpression(node)) {
+ if (arkts.isIdentifier(node.expression)) {
+ if (node.expression.name === RuntimeNames.__CONTEXT) {
+ return arkts.factory.createIdentifier(RuntimeNames.CONTEXT, undefined);
+ }
+ if (node.expression.name === RuntimeNames.__ID) {
+ return arkts.factory.createIdentifier(RuntimeNames.ID, undefined);
+ }
+ if (node.expression.name === RuntimeNames.__KEY) {
+ return this.positionalIdTracker.id(RuntimeNames.__KEY);
+ }
+ }
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/memo-cache-factory.ts b/arkui-plugins/memo-plugins/memo-cache-factory.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e8151cb3145fdd770f9410d1df012ba44f2cd6a5
--- /dev/null
+++ b/arkui-plugins/memo-plugins/memo-cache-factory.ts
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { factory } from './memo-factory';
+import {
+ filterMemoSkipParams,
+ findLocalReturnTypeFromTypeAnnotation,
+ findUnmemoizedScopeInFunctionBody,
+ fixGensymParams,
+ getFunctionParamsBeforeUnmemoized,
+ isVoidType,
+ mayAddLastReturn,
+ parametrizedNodeHasReceiver,
+ ParamInfo,
+ PositionalIdTracker,
+} from './utils';
+import { InternalsTransformer } from './internal-transformer';
+import { GenSymPrefix } from '../common/predefines';
+
+export interface CachedMetadata extends arkts.AstNodeCacheValueMetadata {
+ internalsTransformer?: InternalsTransformer;
+}
+
+export class RewriteFactory {
+ static rewriteUnionType(node: arkts.ETSUnionType, metadata?: CachedMetadata): arkts.ETSUnionType {
+ return arkts.factory.updateUnionType(
+ node,
+ node.types.map((t) => {
+ if (arkts.isETSFunctionType(t)) {
+ return RewriteFactory.rewriteFunctionType(t, metadata);
+ }
+ if (arkts.isETSUnionType(t)) {
+ return RewriteFactory.rewriteUnionType(t, metadata);
+ }
+ return t;
+ })
+ );
+ }
+
+ static rewriteFunctionType(node: arkts.ETSFunctionType, metadata?: CachedMetadata): arkts.ETSFunctionType {
+ const hasReceiver = metadata?.hasReceiver ?? parametrizedNodeHasReceiver(node);
+ return factory.updateFunctionTypeWithMemoParameters(node, hasReceiver);
+ }
+
+ /**
+ * @internal
+ */
+ static rewriteType(node: arkts.TypeNode | undefined, metadata?: CachedMetadata): arkts.TypeNode | undefined {
+ let newNodeType = node;
+ if (!!newNodeType && arkts.isETSFunctionType(newNodeType)) {
+ newNodeType = RewriteFactory.rewriteFunctionType(newNodeType, metadata);
+ } else if (!!newNodeType && arkts.isETSUnionType(newNodeType)) {
+ newNodeType = RewriteFactory.rewriteUnionType(newNodeType, metadata);
+ }
+ return newNodeType;
+ }
+
+ static rewriteTypeAlias(
+ node: arkts.TSTypeAliasDeclaration,
+ metadata?: CachedMetadata
+ ): arkts.TSTypeAliasDeclaration {
+ if (!node.typeAnnotation) {
+ return node;
+ }
+ const newNodeType = RewriteFactory.rewriteType(node.typeAnnotation);
+ return arkts.factory.updateTSTypeAliasDeclaration(node, node.id, node.typeParams, newNodeType);
+ }
+
+ static rewriteParameter(
+ node: arkts.ETSParameterExpression,
+ metadata?: CachedMetadata
+ ): arkts.ETSParameterExpression {
+ if (!node.type && !node.initializer) {
+ return node;
+ }
+ node.type = RewriteFactory.rewriteType(node.type as arkts.TypeNode);
+ return arkts.factory.updateParameterDeclaration(node, node.identifier, node.initializer);
+ }
+
+ static rewriteProperty(node: arkts.Property, metadata?: CachedMetadata): arkts.Property {
+ if (!node.value || !arkts.isArrowFunctionExpression(node.value)) {
+ return node;
+ }
+ return arkts.factory.updateProperty(node, node.key, RewriteFactory.rewriteArrowFunction(node.value, metadata));
+ }
+
+ static rewriteClassProperty(node: arkts.ClassProperty, metadata?: CachedMetadata): arkts.ClassProperty {
+ const newType = !!node.typeAnnotation ? RewriteFactory.rewriteType(node.typeAnnotation) : undefined;
+ const newValue =
+ !!node.value && arkts.isArrowFunctionExpression(node.value)
+ ? RewriteFactory.rewriteArrowFunction(node.value, metadata)
+ : node.value;
+ return arkts.factory.updateClassProperty(node, node.key, newValue, newType, node.modifiers, node.isComputed);
+ }
+
+ static rewriteArrowFunction(
+ node: arkts.ArrowFunctionExpression,
+ metadata?: arkts.AstNodeCacheValueMetadata,
+ expectReturn?: arkts.TypeNode
+ ): arkts.ArrowFunctionExpression {
+ return arkts.factory.updateArrowFunction(
+ node,
+ RewriteFactory.rewriteScriptFunction(node.scriptFunction, metadata, expectReturn)
+ );
+ }
+
+ /**
+ * @internal
+ */
+ static rewriteScriptFunctionBody(
+ node: arkts.ScriptFunction,
+ body: arkts.BlockStatement,
+ positionalIdTracker: PositionalIdTracker,
+ callName?: string,
+ hasReceiver?: boolean,
+ expectReturn?: arkts.TypeNode
+ ): arkts.BlockStatement {
+ const _hasReceiver = hasReceiver ?? node.hasReceiver;
+ const _callName = callName ?? node.id?.name;
+ const parameters = getFunctionParamsBeforeUnmemoized(node.params, _hasReceiver);
+ const filteredParameters = filterMemoSkipParams(parameters);
+ const declaredParams: ParamInfo[] = filteredParameters.map((p) => {
+ const param = p as arkts.ETSParameterExpression;
+ return { ident: param.identifier, param };
+ });
+ const _gensymCount = fixGensymParams(declaredParams, body);
+ if (findUnmemoizedScopeInFunctionBody(body, _gensymCount)) {
+ return body;
+ }
+ const returnType =
+ node.returnTypeAnnotation ??
+ expectReturn ??
+ arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID);
+ const _isVoidReturn = isVoidType(returnType);
+ const scopeDeclaration = factory.createScopeDeclaration(
+ returnType,
+ positionalIdTracker.id(_callName),
+ declaredParams.length
+ );
+ const memoParametersDeclaration = node.params.length
+ ? factory.createMemoParameterDeclaration(declaredParams.map((p) => p.ident.name))
+ : undefined;
+ const syntheticReturnStatement = factory.createSyntheticReturnStatement(false);
+ const unchangedCheck = factory.createIfStatementWithSyntheticReturnStatement(
+ syntheticReturnStatement,
+ _isVoidReturn
+ );
+ const lastReturn = mayAddLastReturn(body)
+ ? factory.createWrappedReturnStatement(factory.createRecacheCall(), _isVoidReturn)
+ : undefined;
+ return arkts.factory.updateBlock(body, [
+ ...body.statements.slice(0, _gensymCount),
+ scopeDeclaration,
+ ...(!!memoParametersDeclaration ? [memoParametersDeclaration] : []),
+ unchangedCheck,
+ ...body.statements.slice(_gensymCount),
+ ...(!!lastReturn ? [lastReturn] : []),
+ ]);
+ }
+
+ static rewriteScriptFunction(
+ node: arkts.ScriptFunction,
+ metadata?: CachedMetadata,
+ expectReturn?: arkts.TypeNode
+ ): arkts.ScriptFunction {
+ const _callName = metadata?.callName;
+ const _hasReceiver = metadata?.hasReceiver ?? node.hasReceiver;
+ const _isSetter = !!metadata?.isSetter;
+ const _isGetter = !!metadata?.isGetter;
+ const _hasMemoEntry = !!metadata?.hasMemoEntry;
+ const _hasMemoIntrinsic = !!metadata?.hasMemoIntrinsic;
+ const _internalsTransformer = metadata?.internalsTransformer;
+ const _isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE);
+ const newParams: readonly arkts.Expression[] = prepareRewriteScriptFunctionParameters(
+ node,
+ _isSetter,
+ _isGetter,
+ _hasReceiver
+ );
+ const newReturnType: arkts.TypeNode | undefined = prepareRewriteScriptFunctionReturnType(
+ node,
+ _isGetter,
+ _hasReceiver
+ );
+ const newBody: arkts.AstNode | undefined = prepareRewriteScriptFunctionBody(
+ node,
+ expectReturn,
+ _internalsTransformer,
+ _isDecl,
+ _hasMemoEntry,
+ _hasMemoIntrinsic,
+ _callName,
+ _hasReceiver,
+ _isGetter,
+ _isSetter
+ );
+ return arkts.factory.updateScriptFunction(
+ node,
+ newBody,
+ arkts.factory.createFunctionSignature(node.typeParams, newParams, newReturnType, _hasReceiver),
+ node.flags,
+ node.modifiers
+ );
+ }
+
+ static rewriteMethodDefinition(node: arkts.MethodDefinition, metadata?: CachedMetadata): arkts.MethodDefinition {
+ const isSetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET;
+ const isGetter = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET;
+ if (node.overloads.length > 0) {
+ node.setOverloads(node.overloads.map((o) => RewriteFactory.rewriteMethodDefinition(o, metadata)));
+ }
+ return arkts.factory.updateMethodDefinition(
+ node,
+ node.kind,
+ node.name,
+ RewriteFactory.rewriteScriptFunction(node.scriptFunction, {
+ callName: node.name.name,
+ ...metadata,
+ isSetter,
+ isGetter,
+ }),
+ node.modifiers,
+ false
+ );
+ }
+
+ static rewriteCallExpression(node: arkts.CallExpression, metadata?: CachedMetadata): arkts.CallExpression {
+ const _hasMemoEntry = !!metadata?.hasMemoEntry;
+ if (_hasMemoEntry) {
+ return node;
+ }
+ const _hasReceiver = metadata?.hasReceiver;
+ let _callName: string | undefined = metadata?.callName;
+ if (!!_callName && arkts.isIdentifier(node.expression)) {
+ _callName = node.expression.name;
+ } else if (
+ !!_callName &&
+ arkts.isMemberExpression(node.expression) &&
+ arkts.isIdentifier(node.expression.property)
+ ) {
+ _callName = node.expression.property.name;
+ }
+ return factory.insertHiddenArgumentsToCall(
+ node,
+ PositionalIdTracker.getInstance(arkts.getFileName()).id(_callName),
+ _hasReceiver
+ );
+ }
+
+ static rewriteIdentifier(
+ node: arkts.Identifier,
+ metadata?: CachedMetadata
+ ): arkts.Identifier | arkts.MemberExpression {
+ if (!node.name.startsWith(GenSymPrefix.INTRINSIC) && !node.name.startsWith(GenSymPrefix.UI)) {
+ return factory.createMemoParameterAccess(node.name);
+ }
+ return node;
+ }
+
+ static rewriteReturnStatement(
+ node: arkts.ReturnStatement,
+ metadata?: CachedMetadata
+ ): arkts.ReturnStatement | arkts.BlockStatement {
+ return factory.createWrappedReturnStatement(factory.createRecacheCall(node.argument), !node.argument);
+ }
+
+ static rewriteVariableDeclarator(
+ node: arkts.VariableDeclarator,
+ metadata?: CachedMetadata
+ ): arkts.VariableDeclarator {
+ const expectReturnType = findLocalReturnTypeFromTypeAnnotation(node.name.typeAnnotation);
+ const variableType = RewriteFactory.rewriteType(node.name.typeAnnotation);
+ let initializer = node.initializer;
+ if (!!initializer && arkts.isConditionalExpression(initializer) && !!initializer.alternate) {
+ let alternate = initializer.alternate;
+ if (arkts.isTSAsExpression(alternate)) {
+ alternate = arkts.factory.updateTSAsExpression(
+ alternate,
+ !!alternate.expr && arkts.isArrowFunctionExpression(alternate.expr)
+ ? RewriteFactory.rewriteArrowFunction(alternate.expr, metadata, expectReturnType)
+ : alternate.expr,
+ RewriteFactory.rewriteType(alternate.typeAnnotation),
+ alternate.isConst
+ );
+ } else if (arkts.isArrowFunctionExpression(alternate)) {
+ alternate = RewriteFactory.rewriteArrowFunction(alternate, metadata, expectReturnType);
+ }
+ initializer = arkts.factory.updateConditionalExpression(
+ initializer,
+ initializer.test,
+ initializer.consequent,
+ alternate
+ );
+ } else if (!!initializer && arkts.isArrowFunctionExpression(initializer)) {
+ initializer = RewriteFactory.rewriteArrowFunction(initializer, metadata, expectReturnType);
+ }
+ return arkts.factory.updateVariableDeclarator(
+ node,
+ node.flag,
+ arkts.factory.updateIdentifier(node.name, node.name.name, variableType),
+ initializer
+ );
+ }
+}
+
+function prepareRewriteScriptFunctionParameters(
+ node: arkts.ScriptFunction,
+ isSetter?: boolean,
+ isGetter?: boolean,
+ hasReceiver?: boolean
+): readonly arkts.Expression[] {
+ let newParams: readonly arkts.Expression[] = node.params;
+ if (!isSetter && !isGetter) {
+ newParams = factory.createHiddenParameterIfNotAdded(node.params, node.hasReceiver);
+ } else if (isSetter && node.params.length > 0) {
+ if (hasReceiver && node.params.length === 2) {
+ newParams = [
+ node.params.at(0)!,
+ RewriteFactory.rewriteParameter(node.params.at(1)! as arkts.ETSParameterExpression),
+ ];
+ } else {
+ newParams = [RewriteFactory.rewriteParameter(node.params.at(0)! as arkts.ETSParameterExpression)];
+ }
+ }
+ return newParams;
+}
+
+function prepareRewriteScriptFunctionReturnType(
+ node: arkts.ScriptFunction,
+ isGetter?: boolean,
+ hasReceiver?: boolean
+): arkts.TypeNode | undefined {
+ let newReturnType: arkts.TypeNode | undefined = node.returnTypeAnnotation;
+ if (!!node.returnTypeAnnotation && isGetter) {
+ newReturnType = RewriteFactory.rewriteType(node.returnTypeAnnotation, { hasReceiver });
+ }
+ return newReturnType;
+}
+
+function prepareRewriteScriptFunctionBody(
+ node: arkts.ScriptFunction,
+ expectReturn?: arkts.TypeNode,
+ internalsTransformer?: InternalsTransformer,
+ isDecl?: boolean,
+ hasMemoEntry?: boolean,
+ hasMemoIntrinsic?: boolean,
+ callName?: string,
+ hasReceiver?: boolean,
+ isGetter?: boolean,
+ isSetter?: boolean,
+): arkts.AstNode | undefined {
+ if (isGetter || isSetter || isDecl || !node.body || !arkts.isBlockStatement(node.body)) {
+ return node.body;
+ }
+
+ let newBody: arkts.AstNode | undefined;
+ const positionalIdTracker = PositionalIdTracker.getInstance(arkts.getFileName());
+ newBody = internalsTransformer?.visitor(node.body) ?? node.body;
+ if (!hasMemoEntry && !hasMemoIntrinsic) {
+ newBody = RewriteFactory.rewriteScriptFunctionBody(
+ node,
+ newBody as arkts.BlockStatement,
+ positionalIdTracker,
+ callName,
+ hasReceiver,
+ expectReturn
+ );
+ }
+ return newBody;
+}
+
+export const rewriteByType = new Map arkts.AstNode>([
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_UNION_TYPE, RewriteFactory.rewriteUnionType],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_FUNCTION_TYPE, RewriteFactory.rewriteFunctionType],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_ALIAS_DECLARATION, RewriteFactory.rewriteTypeAlias],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, RewriteFactory.rewriteParameter],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, RewriteFactory.rewriteClassProperty],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, RewriteFactory.rewriteArrowFunction],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION, RewriteFactory.rewriteScriptFunction],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, RewriteFactory.rewriteMethodDefinition],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, RewriteFactory.rewriteCallExpression],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER, RewriteFactory.rewriteIdentifier],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_RETURN_STATEMENT, RewriteFactory.rewriteReturnStatement],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATOR, RewriteFactory.rewriteVariableDeclarator],
+ [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_PROPERTY, RewriteFactory.rewriteProperty],
+]);
diff --git a/arkui-plugins/memo-plugins/memo-factory.ts b/arkui-plugins/memo-plugins/memo-factory.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a9d43b59139aff263e3a3bf363c33cefdb560704
--- /dev/null
+++ b/arkui-plugins/memo-plugins/memo-factory.ts
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import {
+ fixGensymParams,
+ buildeParamInfos,
+ isUnmemoizedInFunctionParams,
+ mayAddLastReturn,
+ ParamInfo,
+ ReturnTypeInfo,
+ RuntimeNames,
+ parametrizedNodeHasReceiver,
+} from './utils';
+import { moveToFront } from '../common/arkts-utils';
+
+export class factory {
+ // Importing
+ static createContextTypeImportSpecifier(): arkts.ImportSpecifier {
+ return arkts.factory.createImportSpecifier(
+ arkts.factory.createIdentifier(RuntimeNames.CONTEXT_TYPE),
+ arkts.factory.createIdentifier(RuntimeNames.CONTEXT_TYPE)
+ );
+ }
+ static createIdTypeImportSpecifier(): arkts.ImportSpecifier {
+ return arkts.factory.createImportSpecifier(
+ arkts.factory.createIdentifier(RuntimeNames.ID_TYPE),
+ arkts.factory.createIdentifier(RuntimeNames.ID_TYPE)
+ );
+ }
+ static createContextTypesImportDeclaration(program?: arkts.Program): void {
+ const source: arkts.StringLiteral = arkts.factory.createStringLiteral(RuntimeNames.MEMO_IMPORT_NAME);
+ const importDecl: arkts.ETSImportDeclaration = arkts.factory.createImportDeclaration(
+ source,
+ [factory.createContextTypeImportSpecifier(), factory.createIdTypeImportSpecifier()],
+ arkts.Es2pandaImportKinds.IMPORT_KINDS_TYPE,
+ program!,
+ arkts.Es2pandaImportFlags.IMPORT_FLAGS_NONE
+ );
+ // Insert this import at the top of the script's statements.
+ if (!program) {
+ throw Error('Failed to insert import: Transformer has no program');
+ }
+ arkts.importDeclarationInsert(importDecl, program);
+ return;
+ }
+
+ // Parameters
+ static createContextParameter(): arkts.ETSParameterExpression {
+ return arkts.factory.createParameterDeclaration(
+ arkts.factory.createIdentifier(
+ RuntimeNames.CONTEXT,
+ arkts.factory.createTypeReference(
+ arkts.factory.createTypeReferencePart(arkts.factory.createIdentifier(RuntimeNames.CONTEXT_TYPE))
+ )
+ ),
+ undefined
+ );
+ }
+ static createIdParameter(): arkts.ETSParameterExpression {
+ return arkts.factory.createParameterDeclaration(
+ arkts.factory.createIdentifier(
+ RuntimeNames.ID,
+ arkts.factory.createTypeReference(
+ arkts.factory.createTypeReferencePart(arkts.factory.createIdentifier(RuntimeNames.ID_TYPE))
+ )
+ ),
+ undefined
+ );
+ }
+ static createHiddenParameters(): arkts.ETSParameterExpression[] {
+ return [factory.createContextParameter(), factory.createIdParameter()];
+ }
+ static createHiddenParameterIfNotAdded(
+ params: readonly arkts.Expression[],
+ hasReceiver: boolean = false
+ ): readonly arkts.Expression[] {
+ const _params = params ?? [];
+ if (isUnmemoizedInFunctionParams(_params)) {
+ return _params;
+ }
+ let newParams: arkts.Expression[] = [...factory.createHiddenParameters(), ..._params];
+ if (hasReceiver) {
+ newParams = moveToFront(newParams, 2);
+ }
+ return newParams;
+ }
+ static updateFunctionTypeWithMemoParameters(
+ type: arkts.ETSFunctionType,
+ hasReceiver: boolean = false
+ ): arkts.ETSFunctionType {
+ return arkts.factory.updateFunctionType(
+ type,
+ arkts.factory.createFunctionSignature(
+ undefined,
+ factory.createHiddenParameterIfNotAdded(type.params, hasReceiver),
+ type.returnType,
+ false
+ ),
+ arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW
+ );
+ }
+ static updateScriptFunctionWithMemoParameters(
+ func: arkts.ScriptFunction,
+ newBody?: arkts.AstNode | undefined,
+ returnType?: arkts.TypeNode | undefined
+ ): arkts.ScriptFunction {
+ return arkts.factory.updateScriptFunction(
+ func,
+ newBody ?? func.body,
+ arkts.factory.createFunctionSignature(
+ func.typeParams,
+ factory.createHiddenParameterIfNotAdded(func.params, parametrizedNodeHasReceiver(func)),
+ returnType ?? func.returnTypeAnnotation,
+ func.hasReceiver
+ ),
+ func.flags,
+ func.modifiers
+ );
+ }
+
+ // Arguments
+ static createContextArgument(): arkts.AstNode {
+ return arkts.factory.createIdentifier(RuntimeNames.CONTEXT);
+ }
+ static createIdArgument(hash: arkts.NumberLiteral | arkts.StringLiteral): arkts.AstNode {
+ return arkts.factory.createBinaryExpression(
+ arkts.factory.createIdentifier(RuntimeNames.ID),
+ hash,
+ arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_PLUS
+ );
+ }
+ static createHiddenArguments(hash: arkts.NumberLiteral | arkts.StringLiteral): arkts.AstNode[] {
+ return [factory.createContextArgument(), factory.createIdArgument(hash)];
+ }
+
+ // Memo parameters
+ static createMemoParameterIdentifier(name: string): arkts.Identifier {
+ if (name === RuntimeNames.EQUAL_T) {
+ return arkts.factory.createIdentifier(`${RuntimeNames.PARAMETER}_${RuntimeNames.THIS}`, undefined);
+ }
+ return arkts.factory.createIdentifier(`${RuntimeNames.PARAMETER}_${name}`);
+ }
+ static createMemoParameterDeclarator(id: number, name: string): arkts.VariableDeclarator {
+ const originalIdent =
+ name === RuntimeNames.THIS || name === RuntimeNames.EQUAL_T
+ ? arkts.factory.createThisExpression()
+ : arkts.factory.createIdentifier(name, undefined);
+ return arkts.factory.createVariableDeclarator(
+ arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_CONST,
+ factory.createMemoParameterIdentifier(name),
+ arkts.factory.createCallExpression(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_PARAMETER_STATE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
+ false,
+ false
+ ),
+ undefined,
+ [arkts.factory.createNumericLiteral(id), originalIdent]
+ )
+ );
+ }
+ static createMemoParameterDeclaration(parameters: string[]): arkts.VariableDeclaration {
+ return arkts.factory.createVariableDeclaration(
+ arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE,
+ arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_CONST,
+ parameters.map((name, id) => {
+ return factory.createMemoParameterDeclarator(id, name);
+ })
+ );
+ }
+ static createMemoParameterAccess(name: string): arkts.MemberExpression {
+ return arkts.factory.createMemberExpression(
+ factory.createMemoParameterIdentifier(name),
+ arkts.factory.createIdentifier(RuntimeNames.VALUE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER,
+ false,
+ false
+ );
+ }
+ static createMemoParameterAccessCall(name: string, passArgs?: arkts.AstNode[]): arkts.CallExpression {
+ const updatedArgs = passArgs ? passArgs : [];
+ return arkts.factory.createCallExpression(
+ arkts.factory.createMemberExpression(
+ factory.createMemoParameterIdentifier(name),
+ arkts.factory.createIdentifier(RuntimeNames.VALUE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_GETTER,
+ false,
+ false
+ ),
+ undefined,
+ [...updatedArgs]
+ );
+ }
+
+ // Recache
+ static createScopeDeclaration(
+ returnTypeAnnotation: arkts.TypeNode | undefined,
+ hash: arkts.NumberLiteral | arkts.StringLiteral,
+ cnt: number
+ ): arkts.VariableDeclaration {
+ return arkts.factory.createVariableDeclaration(
+ 0,
+ arkts.Es2pandaVariableDeclarationKind.VARIABLE_DECLARATION_KIND_CONST,
+ [
+ arkts.factory.createVariableDeclarator(
+ arkts.Es2pandaVariableDeclaratorFlag.VARIABLE_DECLARATOR_FLAG_CONST,
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createCallExpression(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.CONTEXT),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_SCOPE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
+ false,
+ false
+ ),
+ returnTypeAnnotation
+ ? [returnTypeAnnotation]
+ : [arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID)],
+ [factory.createIdArgument(hash), arkts.factory.createNumericLiteral(cnt)]
+ )
+ ),
+ ]
+ );
+ }
+ static createRecacheCall(arg?: arkts.AstNode): arkts.CallExpression {
+ return arkts.factory.createCallExpression(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE_NEW),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
+ false,
+ false
+ ),
+ undefined,
+ arg ? [arg] : undefined
+ );
+ }
+ static createReturnThis(): arkts.BlockStatement {
+ return arkts.factory.createBlock([
+ arkts.factory.createExpressionStatement(factory.createRecacheCall()),
+ arkts.factory.createReturnStatement(arkts.factory.createThisExpression()),
+ ]);
+ }
+ static createSyntheticReturnStatement(stableThis: boolean): arkts.ReturnStatement | arkts.BlockStatement {
+ if (!stableThis) {
+ return arkts.factory.createReturnStatement(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE,
+ false,
+ false
+ )
+ );
+ }
+ return arkts.factory.createBlock([
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE,
+ false,
+ false
+ ),
+ arkts.factory.createReturnStatement(arkts.factory.createThisExpression()),
+ ]);
+ }
+ static createIfStatementWithSyntheticReturnStatement(
+ syntheticReturnStatement: arkts.ReturnStatement | arkts.BlockStatement,
+ isVoidValue: boolean
+ ): arkts.IfStatement {
+ let returnStatement = syntheticReturnStatement;
+ if (isVoidValue && arkts.isReturnStatement(syntheticReturnStatement)) {
+ returnStatement = arkts.factory.createBlock([
+ arkts.factory.createExpressionStatement(syntheticReturnStatement.argument!),
+ arkts.factory.createReturnStatement(),
+ ]);
+ }
+ return arkts.factory.createIfStatement(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.SCOPE),
+ arkts.factory.createIdentifier(RuntimeNames.INTERNAL_VALUE_OK),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_NONE,
+ false,
+ false
+ ),
+ returnStatement
+ );
+ }
+ static createWrappedReturnStatement(
+ argument: arkts.Expression,
+ isReturnVoid: boolean
+ ): arkts.ReturnStatement | arkts.BlockStatement {
+ if (!isReturnVoid) {
+ return arkts.factory.createReturnStatement(argument);
+ }
+ return arkts.factory.createBlock([
+ arkts.factory.createExpressionStatement(argument),
+ arkts.factory.createReturnStatement(),
+ ]);
+ }
+
+ // Compute
+ static createLambdaWrapper(node: arkts.Expression): arkts.ArrowFunctionExpression {
+ return arkts.factory.createArrowFunction(
+ arkts.factory.createScriptFunction(
+ arkts.factory.createBlock([arkts.factory.createReturnStatement(node)]),
+ arkts.factory.createFunctionSignature(undefined, [], undefined, false),
+ arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW,
+ arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_NONE
+ )
+ );
+ }
+ static createComputeExpression(
+ hash: arkts.NumberLiteral | arkts.StringLiteral,
+ node: arkts.Expression
+ ): arkts.CallExpression {
+ return arkts.factory.createCallExpression(
+ arkts.factory.createMemberExpression(
+ arkts.factory.createIdentifier(RuntimeNames.CONTEXT),
+ arkts.factory.createIdentifier(RuntimeNames.COMPUTE),
+ arkts.Es2pandaMemberExpressionKind.MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS,
+ false,
+ false
+ ),
+ undefined,
+ [factory.createIdArgument(hash), factory.createLambdaWrapper(node)]
+ );
+ }
+
+ static updateFunctionBody(
+ node: arkts.BlockStatement,
+ parameters: arkts.ETSParameterExpression[],
+ returnTypeInfo: ReturnTypeInfo,
+ hash: arkts.NumberLiteral | arkts.StringLiteral
+ ): [
+ arkts.BlockStatement,
+ ParamInfo[],
+ arkts.VariableDeclaration | undefined,
+ arkts.ReturnStatement | arkts.BlockStatement | undefined
+ ] {
+ const paramInfos = buildeParamInfos(parameters);
+ const gensymParamsCount = fixGensymParams(paramInfos, node);
+ const parameterNames = paramInfos.map((it) => it.ident.name);
+ const scopeDeclaration = factory.createScopeDeclaration(returnTypeInfo.node, hash, parameterNames.length);
+ const memoParametersDeclaration = parameterNames.length
+ ? factory.createMemoParameterDeclaration(parameterNames)
+ : undefined;
+ const syntheticReturnStatement = factory.createSyntheticReturnStatement(!!returnTypeInfo.isStableThis);
+ const isVoidValue = !!returnTypeInfo.isVoid;
+ const unchangedCheck = factory.createIfStatementWithSyntheticReturnStatement(
+ syntheticReturnStatement,
+ isVoidValue
+ );
+ return [
+ arkts.factory.updateBlock(node, [
+ ...node.statements.slice(0, gensymParamsCount),
+ scopeDeclaration,
+ ...(memoParametersDeclaration ? [memoParametersDeclaration] : []),
+ unchangedCheck,
+ ...node.statements.slice(gensymParamsCount),
+ ...(mayAddLastReturn(node) ? [arkts.factory.createReturnStatement()] : []),
+ ]),
+ paramInfos,
+ memoParametersDeclaration,
+ syntheticReturnStatement,
+ ];
+ }
+
+ static updateMemoTypeAnnotation(typeAnnotation: arkts.AstNode | undefined): arkts.TypeNode | undefined {
+ if (!typeAnnotation || !arkts.isTypeNode(typeAnnotation)) {
+ return undefined;
+ }
+
+ if (arkts.isETSFunctionType(typeAnnotation)) {
+ return factory.updateFunctionTypeWithMemoParameters(typeAnnotation);
+ } else if (arkts.isETSUnionType(typeAnnotation)) {
+ return arkts.factory.updateUnionType(
+ typeAnnotation,
+ typeAnnotation.types.map((it) => {
+ if (arkts.isETSFunctionType(it)) {
+ return factory.updateFunctionTypeWithMemoParameters(it);
+ }
+ return it;
+ })
+ );
+ }
+ return typeAnnotation;
+ }
+
+ static insertHiddenArgumentsToCall(
+ node: arkts.CallExpression,
+ hash: arkts.NumberLiteral | arkts.StringLiteral,
+ hasReceiver?: boolean
+ ): arkts.CallExpression {
+ let updatedArguments = [...factory.createHiddenArguments(hash), ...node.arguments];
+ if (!!hasReceiver) {
+ updatedArguments = moveToFront(updatedArguments, 2);
+ }
+ return arkts.factory.updateCallExpression(node, node.expression, node.typeArguments, updatedArguments);
+ }
+}
diff --git a/arkui-plugins/memo-plugins/memo-transformer.ts b/arkui-plugins/memo-plugins/memo-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..430148fc230277aa308876ed0f3b0ad16e67a63f
--- /dev/null
+++ b/arkui-plugins/memo-plugins/memo-transformer.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { FunctionTransformer } from './function-transformer';
+import { PositionalIdTracker } from './utils';
+import { factory } from './memo-factory';
+import { ReturnTransformer } from './return-transformer';
+import { ParameterTransformer } from './parameter-transformer';
+import { EtsglobalRemover } from '../common/etsglobal-remover';
+import { SignatureTransformer } from './signature-transformer';
+
+export interface TransformerOptions {
+ trace?: boolean;
+ removeEtsglobal?: boolean;
+}
+
+export default function memoTransformer(userPluginOptions?: TransformerOptions) {
+ return (node0: arkts.EtsScript) => {
+ const node = (
+ userPluginOptions?.removeEtsglobal ? new EtsglobalRemover().visitor(node0) : node0
+ ) as arkts.EtsScript;
+ const positionalIdTracker = new PositionalIdTracker(arkts.getFileName(), false);
+ const parameterTransformer = new ParameterTransformer({
+ positionalIdTracker,
+ });
+ const returnTransformer = new ReturnTransformer();
+ const signatureTransformer = new SignatureTransformer();
+ const functionTransformer = new FunctionTransformer({
+ positionalIdTracker,
+ parameterTransformer,
+ returnTransformer,
+ signatureTransformer,
+ });
+ factory.createContextTypesImportDeclaration(arkts.arktsGlobal.compilerContext?.program);
+ return functionTransformer.visitor(arkts.factory.updateEtsScript(node, node.statements));
+ };
+}
diff --git a/arkui-plugins/memo-plugins/parameter-transformer.ts b/arkui-plugins/memo-plugins/parameter-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8aef0822cd3d5292081474db178b415b6a50a612
--- /dev/null
+++ b/arkui-plugins/memo-plugins/parameter-transformer.ts
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+import * as arkts from '@koalaui/libarkts';
+
+import { factory } from './memo-factory';
+import { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor';
+import {
+ buildReturnTypeInfo,
+ castParameters,
+ findReturnTypeFromTypeAnnotation,
+ isMemoETSParameterExpression,
+ isMemoParametersDeclaration,
+ isUnmemoizedInFunctionParams,
+ MemoInfo,
+ ParamInfo,
+ PositionalIdTracker,
+ ReturnTypeInfo,
+ RuntimeNames,
+} from './utils';
+import { ReturnTransformer } from './return-transformer';
+
+export interface ParameterTransformerOptions extends VisitorOptions {
+ positionalIdTracker: PositionalIdTracker;
+}
+
+interface RewriteMemoInfo extends MemoInfo {
+ rewritePeer: number;
+}
+
+export class ParameterTransformer extends AbstractVisitor {
+ private rewriteIdentifiers?: Map arkts.MemberExpression | arkts.Identifier>;
+ private rewriteCalls?: Map arkts.CallExpression>;
+ private rewriteMemoInfos?: Map;
+ private rewriteThis?: boolean;
+ private skipNode?: arkts.VariableDeclaration;
+ private visited: Set;
+
+ private positionalIdTracker: PositionalIdTracker;
+
+ constructor(options: ParameterTransformerOptions) {
+ super(options);
+ this.positionalIdTracker = options.positionalIdTracker;
+ this.visited = new Set();
+ }
+
+ reset(): void {
+ super.reset();
+ this.rewriteIdentifiers = undefined;
+ this.rewriteCalls = undefined;
+ this.rewriteMemoInfos = undefined;
+ this.skipNode = undefined;
+ this.visited.clear();
+ }
+
+ withThis(flag: boolean): ParameterTransformer {
+ this.rewriteThis = flag;
+ return this;
+ }
+
+ withParameters(parameters: ParamInfo[]): ParameterTransformer {
+ this.rewriteCalls = new Map(
+ parameters
+ .filter(
+ (it) =>
+ it.param.type && (arkts.isETSFunctionType(it.param.type) || arkts.isETSUnionType(it.param.type))
+ )
+ .map((it) => {
+ return [
+ it.param.identifier.name.startsWith(RuntimeNames.GENSYM)
+ ? it.ident.originalPeer
+ : it.param.originalPeer,
+ (passArgs: arkts.Expression[]): arkts.CallExpression => {
+ return factory.createMemoParameterAccessCall(it.ident.name, passArgs);
+ },
+ ];
+ })
+ );
+ this.rewriteIdentifiers = new Map(
+ parameters.map((it) => {
+ return [
+ it.param.identifier.name.startsWith(RuntimeNames.GENSYM)
+ ? it.ident.originalPeer
+ : it.param.originalPeer,
+ (): arkts.MemberExpression => {
+ return factory.createMemoParameterAccess(it.ident.name);
+ },
+ ];
+ })
+ );
+ this.rewriteMemoInfos = new Map(
+ parameters.map((it) => {
+ return [
+ it.param.identifier.name.startsWith(RuntimeNames.GENSYM)
+ ? it.ident.originalPeer
+ : it.param.originalPeer,
+ {
+ name: it.param.identifier.name,
+ rewritePeer: it.param.identifier.originalPeer,
+ isMemo: isMemoETSParameterExpression(it.param),
+ },
+ ];
+ })
+ );
+ return this;
+ }
+
+ skip(memoParametersDeclaration?: arkts.VariableDeclaration): ParameterTransformer {
+ this.skipNode = memoParametersDeclaration;
+ return this;
+ }
+
+ track(node: arkts.AstNode | undefined): void {
+ if (!!node?.peer) {
+ this.visited.add(node.peer);
+ }
+ }
+
+ isTracked(node: arkts.AstNode | undefined): boolean {
+ return !!node?.peer && this.visited.has(node.peer);
+ }
+
+ private updateArrowFunctionFromVariableDeclareInit(
+ initializer: arkts.ArrowFunctionExpression,
+ returnType: arkts.TypeNode | undefined
+ ): arkts.ArrowFunctionExpression {
+ const scriptFunction = initializer.scriptFunction;
+ if (!scriptFunction.body || !arkts.isBlockStatement(scriptFunction.body)) {
+ return initializer;
+ }
+ if (isUnmemoizedInFunctionParams(scriptFunction.params)) {
+ return initializer;
+ }
+ const returnTypeInfo: ReturnTypeInfo = buildReturnTypeInfo(
+ returnType ?? scriptFunction.returnTypeAnnotation,
+ true
+ );
+ const [body, parameterIdentifiers, memoParametersDeclaration, syntheticReturnStatement] =
+ factory.updateFunctionBody(
+ scriptFunction.body,
+ castParameters(scriptFunction.params),
+ returnTypeInfo,
+ this.positionalIdTracker.id()
+ );
+ const paramaterTransformer = new ParameterTransformer({
+ positionalIdTracker: this.positionalIdTracker,
+ });
+ const returnTransformer = new ReturnTransformer();
+ const afterParameterTransformer = paramaterTransformer
+ .withParameters(parameterIdentifiers)
+ .skip(memoParametersDeclaration)
+ .visitor(body);
+ const afterReturnTransformer = returnTransformer
+ .skip(syntheticReturnStatement)
+ .registerReturnTypeInfo(returnTypeInfo)
+ .visitor(afterParameterTransformer);
+ const updateScriptFunction = factory.updateScriptFunctionWithMemoParameters(
+ scriptFunction,
+ afterReturnTransformer,
+ returnTypeInfo.node
+ );
+ paramaterTransformer.reset();
+ returnTransformer.reset();
+ this.track(updateScriptFunction.body);
+ return arkts.factory.updateArrowFunction(initializer, updateScriptFunction);
+ }
+
+ private updateVariableDeclareInit(
+ initializer: T | undefined,
+ returnType: arkts.TypeNode | undefined
+ ): T | undefined {
+ if (!initializer) {
+ return undefined;
+ }
+ if (arkts.isConditionalExpression(initializer)) {
+ return arkts.factory.updateConditionalExpression(
+ initializer,
+ initializer.test,
+ this.updateVariableDeclareInit(initializer.consequent, returnType),
+ this.updateVariableDeclareInit(initializer.alternate, returnType)
+ ) as unknown as T;
+ }
+ if (arkts.isTSAsExpression(initializer)) {
+ return arkts.factory.updateTSAsExpression(
+ initializer,
+ this.updateVariableDeclareInit(initializer.expr, returnType),
+ factory.updateMemoTypeAnnotation(initializer.typeAnnotation),
+ initializer.isConst
+ ) as unknown as T;
+ }
+ if (arkts.isArrowFunctionExpression(initializer)) {
+ return this.updateArrowFunctionFromVariableDeclareInit(initializer, returnType) as unknown as T;
+ }
+ return initializer;
+ }
+
+ private updateParamReDeclare(node: arkts.VariableDeclarator, memoInfo: RewriteMemoInfo): arkts.VariableDeclarator {
+ const shouldUpdate: boolean = node.name.name !== memoInfo.name && memoInfo.isMemo;
+ if (!shouldUpdate) {
+ return node;
+ }
+ const decl = arkts.getPeerDecl(memoInfo.rewritePeer);
+ if (!decl || !arkts.isEtsParameterExpression(decl)) {
+ return node;
+ }
+
+ let typeAnnotation: arkts.TypeNode | undefined;
+ if (
+ !!node.name.typeAnnotation &&
+ !(typeAnnotation = factory.updateMemoTypeAnnotation(node.name.typeAnnotation))
+ ) {
+ console.error(`ETSFunctionType or ETSUnionType expected for @memo-variable-type ${node.name.name}`);
+ throw 'Invalid @memo usage';
+ }
+
+ const returnType = findReturnTypeFromTypeAnnotation(decl.type);
+ return arkts.factory.updateVariableDeclarator(
+ node,
+ node.flag,
+ arkts.factory.updateIdentifier(node.name, node.name.name, typeAnnotation),
+ this.updateVariableDeclareInit(node.initializer, returnType)
+ );
+ }
+
+ private updateVariableReDeclarationFromParam(node: arkts.VariableDeclaration): arkts.VariableDeclaration {
+ const that = this;
+ return arkts.factory.updateVariableDeclaration(
+ node,
+ node.modifiers,
+ node.declarationKind,
+ node.declarators.map((declarator) => {
+ if (that.rewriteMemoInfos?.has(declarator.name.originalPeer)) {
+ const memoInfo = that.rewriteMemoInfos.get(declarator.name.originalPeer)!;
+ return that.updateParamReDeclare(declarator, memoInfo);
+ }
+ if (!!declarator.initializer && arkts.isIdentifier(declarator.initializer)) {
+ const decl = arkts.getPeerDecl(declarator.initializer.originalPeer);
+ if (decl && that.rewriteIdentifiers?.has(decl.peer)) {
+ return arkts.factory.updateVariableDeclarator(
+ declarator,
+ declarator.flag,
+ declarator.name,
+ that.rewriteIdentifiers.get(decl.peer)!()
+ );
+ }
+ }
+ return declarator;
+ })
+ );
+ }
+
+ private updateCallReDeclare(
+ node: arkts.CallExpression,
+ oriName: arkts.Identifier,
+ memoInfo: RewriteMemoInfo
+ ): arkts.CallExpression {
+ const shouldUpdate: boolean = oriName.name !== memoInfo.name && memoInfo.isMemo;
+ if (!shouldUpdate) {
+ return node;
+ }
+ return factory.insertHiddenArgumentsToCall(node, this.positionalIdTracker.id(oriName.name));
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ // TODO: temporary checking skip nodes by comparison with expected skip nodes
+ // Should be fixed when update procedure implemented properly
+ if (/* beforeChildren === this.skipNode */ isMemoParametersDeclaration(beforeChildren)) {
+ return beforeChildren;
+ }
+ if (arkts.isVariableDeclaration(beforeChildren)) {
+ return this.updateVariableReDeclarationFromParam(beforeChildren);
+ }
+ if (arkts.isCallExpression(beforeChildren) && arkts.isIdentifier(beforeChildren.expression)) {
+ const decl = arkts.getPeerDecl(beforeChildren.expression.originalPeer);
+ if (decl && this.rewriteCalls?.has(decl.peer)) {
+ const updateCall = this.rewriteCalls.get(decl.peer)!(
+ beforeChildren.arguments.map((it) => this.visitor(it) as arkts.Expression)
+ );
+ if (this.rewriteMemoInfos?.has(decl.peer)) {
+ const memoInfo = this.rewriteMemoInfos.get(decl.peer)!;
+ return this.updateCallReDeclare(updateCall, beforeChildren.expression, memoInfo);
+ }
+ return updateCall;
+ }
+ }
+ const node = this.visitEachChild(beforeChildren);
+ if (arkts.isIdentifier(node)) {
+ const decl = arkts.getPeerDecl(node.originalPeer);
+ if (decl && this.rewriteIdentifiers?.has(decl.peer)) {
+ return this.rewriteIdentifiers.get(decl.peer)!();
+ }
+ }
+ if (arkts.isThisExpression(node) && this.rewriteThis) {
+ return factory.createMemoParameterAccess(RuntimeNames.THIS);
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/return-transformer.ts b/arkui-plugins/memo-plugins/return-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c2c0fac2e6033aca90d5fce9060020b0286a4ebb
--- /dev/null
+++ b/arkui-plugins/memo-plugins/return-transformer.ts
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { factory } from './memo-factory';
+import { AbstractVisitor } from '../common/abstract-visitor';
+import { isSyntheticReturnStatement, ReturnTypeInfo } from './utils';
+
+export class ReturnTransformer extends AbstractVisitor {
+ private skipNode?: arkts.ReturnStatement | arkts.BlockStatement;
+ private stableThis: boolean = false;
+ private returnTypeInfo: ReturnTypeInfo | undefined;
+
+ reset() {
+ super.reset();
+ this.skipNode = undefined;
+ this.stableThis = false;
+ this.returnTypeInfo = undefined;
+ }
+
+ skip(syntheticReturnStatement?: arkts.ReturnStatement | arkts.BlockStatement): ReturnTransformer {
+ this.skipNode = syntheticReturnStatement;
+ return this;
+ }
+
+ rewriteThis(stableThis: boolean): ReturnTransformer {
+ this.stableThis = stableThis;
+ return this;
+ }
+
+ registerReturnTypeInfo(returnTypeInfo: ReturnTypeInfo): ReturnTransformer {
+ this.returnTypeInfo = returnTypeInfo;
+ return this;
+ }
+
+ visitor(beforeChildren: arkts.AstNode): arkts.AstNode {
+ // TODO: temporary checking skip nodes by comparison with expected skip nodes
+ // Should be fixed when update procedure implemented properly
+ if (/* beforeChildren === this.skipNode */ isSyntheticReturnStatement(beforeChildren)) {
+ return beforeChildren;
+ }
+ if (arkts.isScriptFunction(beforeChildren)) {
+ return beforeChildren;
+ }
+ const node = this.visitEachChild(beforeChildren);
+ if (arkts.isReturnStatement(node)) {
+ if (this.stableThis && node.argument && arkts.isThisExpression(node.argument)) {
+ return factory.createReturnThis();
+ }
+ if (node.argument === undefined) {
+ return arkts.factory.createBlock([
+ arkts.factory.createExpressionStatement(factory.createRecacheCall()),
+ node,
+ ]);
+ }
+
+ let argument = node.argument;
+ if (
+ !!this.returnTypeInfo?.node &&
+ this.returnTypeInfo.isMemo &&
+ arkts.isArrowFunctionExpression(argument)
+ ) {
+ argument = arkts.factory.updateArrowFunction(
+ argument,
+ factory.updateScriptFunctionWithMemoParameters(argument.scriptFunction)
+ );
+ }
+
+ return arkts.factory.updateReturnStatement(node, factory.createRecacheCall(argument));
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/signature-transformer.ts b/arkui-plugins/memo-plugins/signature-transformer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7fa8a62d37b9500e7e334a9cf66ee816279e993
--- /dev/null
+++ b/arkui-plugins/memo-plugins/signature-transformer.ts
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+
+import * as arkts from '@koalaui/libarkts';
+import { factory } from './memo-factory';
+import {
+ hasMemoAnnotation,
+ hasMemoIntrinsicAnnotation,
+ parametrizedNodeHasReceiver,
+ isMemoTSTypeAliasDeclaration,
+} from './utils';
+import { AbstractVisitor } from '../common/abstract-visitor';
+
+function isScriptFunctionFromGetter(node: arkts.ScriptFunction): boolean {
+ return (
+ !!node.parent &&
+ !!node.parent.parent &&
+ arkts.isFunctionExpression(node.parent) &&
+ arkts.isMethodDefinition(node.parent.parent) &&
+ node.parent.parent.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET
+ );
+}
+
+function isScriptFunctionFromSetter(node: arkts.ScriptFunction): boolean {
+ return (
+ !!node.parent &&
+ !!node.parent.parent &&
+ arkts.isFunctionExpression(node.parent) &&
+ arkts.isMethodDefinition(node.parent.parent) &&
+ node.parent.parent.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET
+ );
+}
+
+export class SignatureTransformer extends AbstractVisitor {
+ /* Tracking whether should import `__memo_context_type` and `__memo_id_type` */
+ public modified = false;
+
+ reset(): void {
+ super.reset();
+ this.modified = false;
+ }
+
+ visitor(node: T, applyMemo: boolean = false): T {
+ if (arkts.isScriptFunction(node)) {
+ const memo = hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node) || applyMemo;
+ if (memo) {
+ this.modified = true;
+ }
+ const isFromGetter = isScriptFunctionFromGetter(node);
+ const isFromSetter = isScriptFunctionFromSetter(node);
+ const shouldAddMemoParam = memo && !isFromGetter && !isFromSetter;
+ const shouldApplyMemoToParamExpr = memo && isFromSetter;
+ const shouldApplyMemoToReturnType = memo && isFromGetter;
+ const newParams = node.params.map((it) => this.visitor(it, shouldApplyMemoToParamExpr));
+ return arkts.factory.updateScriptFunction(
+ node,
+ node.body,
+ arkts.factory.createFunctionSignature(
+ node.typeParams,
+ shouldAddMemoParam
+ ? factory.createHiddenParameterIfNotAdded(newParams, parametrizedNodeHasReceiver(node))
+ : newParams,
+ node.returnTypeAnnotation
+ ? this.visitor(node.returnTypeAnnotation, shouldApplyMemoToReturnType)
+ : memo
+ ? arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID)
+ : undefined,
+ node.hasReceiver
+ ),
+ node.flags,
+ node.modifiers
+ ) as any as T;
+ }
+ if (arkts.isEtsParameterExpression(node)) {
+ const memo = hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node) || applyMemo;
+ if (!node.type) {
+ if (memo) {
+ console.error(`@memo parameter ${node.identifier.name} without type annotatation`);
+ throw 'Invalid @memo usage';
+ }
+ return node;
+ }
+ node.type = this.visitor(node.type, memo);
+ return node as any as T;
+ }
+ if (arkts.isETSFunctionType(node)) {
+ const memo = hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node) || applyMemo;
+ if (memo) {
+ this.modified = true;
+ }
+ const newParams = node.params.map((it) => this.visitor(it));
+ return arkts.factory.updateFunctionType(
+ node,
+ arkts.factory.createFunctionSignature(
+ undefined,
+ memo ? factory.createHiddenParameterIfNotAdded(newParams) : newParams,
+ this.visitor(node.returnType!),
+ false
+ ),
+ arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_ARROW
+ ) as any as T;
+ }
+ if (arkts.isETSUnionType(node)) {
+ return arkts.factory.updateUnionType(
+ node,
+ node.types.map((it) => this.visitor(it, applyMemo))
+ ) as any as T;
+ }
+ if (arkts.isETSUndefinedType(node)) {
+ return node as any as T;
+ }
+ if (arkts.isETSTypeReference(node) && applyMemo) {
+ if (!node.part || !node.part.name) {
+ console.error(`@memo parameter has no type reference`);
+ throw 'Invalid @memo usage';
+ }
+ const expr = node.part.name;
+ const decl = arkts.getDecl(expr);
+ if (!decl || !arkts.isTSTypeAliasDeclaration(decl)) {
+ console.error(`@memo parameter's type has not been declared`);
+ throw 'Invalid @memo usage';
+ }
+ const memoDecl = isMemoTSTypeAliasDeclaration(decl);
+ if (memoDecl) {
+ return node as any as T;
+ }
+ console.error(`@memo parameter type reference has no @memo type declaration`);
+ throw 'Invalid @memo usage';
+ }
+ if (applyMemo) {
+ console.error(`@memo parameter's signature has invalid type`);
+ throw 'Invalid @memo usage';
+ }
+ return node;
+ }
+}
diff --git a/arkui-plugins/memo-plugins/utils.ts b/arkui-plugins/memo-plugins/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e3b415e7fa2216438caddbf64d73efd2ed1455d7
--- /dev/null
+++ b/arkui-plugins/memo-plugins/utils.ts
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+import * as arkts from '@koalaui/libarkts';
+import { getCommonPath } from '../path';
+const common = require(getCommonPath());
+const UniqueId = common.UniqueId;
+
+export enum RuntimeNames {
+ __CONTEXT = '__context',
+ __ID = '__id',
+ __KEY = '__key',
+ ANNOTATION_BUILDER = 'Builder',
+ ANNOTATION = 'memo',
+ ANNOTATION_ENTRY = 'memo_entry',
+ ANNOTATION_INTRINSIC = 'memo_intrinsic',
+ ANNOTATION_STABLE = 'memo_stable',
+ ANNOTATION_SKIP = 'memo_skip',
+ COMPUTE = 'compute',
+ CONTEXT = '__memo_context',
+ CONTEXT_TYPE = '__memo_context_type',
+ MEMO_IMPORT_NAME = 'arkui.stateManagement.runtime',
+ GENSYM = 'gensym%%_',
+ ID = '__memo_id',
+ ID_TYPE = '__memo_id_type',
+ INTERNAL_PARAMETER_STATE = 'param',
+ INTERNAL_SCOPE = 'scope',
+ INTERNAL_VALUE = 'cached',
+ INTERNAL_VALUE_NEW = 'recache',
+ INTERNAL_VALUE_OK = 'unchanged',
+ PARAMETER = '__memo_parameter',
+ SCOPE = '__memo_scope',
+ THIS = 'this',
+ VALUE = 'value',
+ EQUAL_T = '=t',
+}
+
+export interface ReturnTypeInfo {
+ node: arkts.TypeNode | undefined;
+ isMemo?: boolean;
+ isVoid?: boolean;
+ isStableThis?: boolean;
+}
+
+export interface ParamInfo {
+ ident: arkts.Identifier;
+ param: arkts.ETSParameterExpression;
+}
+
+export interface MemoInfo {
+ name?: string;
+ isMemo: boolean;
+}
+
+function baseName(path: string): string {
+ return path.replace(/^.*\/(.*)$/, '$1');
+}
+
+export class PositionalIdTracker {
+ // Global for the whole program.
+ static callCount: number = 0;
+
+ private static instance: PositionalIdTracker;
+
+ static getInstance(fileName: string): PositionalIdTracker {
+ if (!this.instance) {
+ this.instance = new PositionalIdTracker(fileName);
+ }
+ return this.instance;
+ }
+
+ // Set `stable` to true if you want to have more predictable values.
+ // For example for tests.
+ // Don't use it in production!
+ constructor(public filename: string, public stableForTests: boolean = false) {
+ if (stableForTests) PositionalIdTracker.callCount = 0;
+ }
+
+ sha1Id(callName: string, fileName: string): string {
+ const uniqId = new UniqueId();
+ uniqId.addString('memo call uniqid');
+ uniqId.addString(fileName);
+ uniqId.addString(callName);
+ uniqId.addI32(PositionalIdTracker.callCount++);
+ return uniqId.compute().substring(0, 7);
+ }
+
+ stringId(callName: string, fileName: string): string {
+ return `${PositionalIdTracker.callCount++}_${callName}_id_DIRNAME/${fileName}`;
+ }
+
+ id(callName: string = ''): arkts.NumberLiteral | arkts.StringLiteral {
+ const fileName = this.stableForTests ? baseName(this.filename) : this.filename;
+
+ const positionId = this.stableForTests ? this.stringId(callName, fileName) : this.sha1Id(callName, fileName);
+
+ return this.stableForTests
+ ? arkts.factory.createStringLiteral(positionId)
+ : arkts.factory.createNumericLiteral(parseInt(positionId, 16));
+ }
+}
+
+export function isMemoAnnotation(node: arkts.AnnotationUsage, memoName: RuntimeNames): boolean {
+ return node.expr !== undefined && arkts.isIdentifier(node.expr) && node.expr.name === memoName;
+}
+
+export type MemoAstNode =
+ | arkts.ScriptFunction
+ | arkts.ETSParameterExpression
+ | arkts.ClassProperty
+ | arkts.TSTypeAliasDeclaration
+ | arkts.ETSFunctionType
+ | arkts.ArrowFunctionExpression
+ | arkts.ETSTypeReference
+ | arkts.VariableDeclaration;
+
+export function hasMemoAnnotation(node: T): boolean {
+ return node.annotations.some(
+ (it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION) || isMemoAnnotation(it, RuntimeNames.ANNOTATION_BUILDER)
+ );
+}
+
+export function hasMemoIntrinsicAnnotation(node: T): boolean {
+ return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION_INTRINSIC));
+}
+
+export function hasMemoEntryAnnotation(node: T): boolean {
+ return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION_ENTRY));
+}
+
+export function hasMemoStableAnnotation(node: arkts.ClassDefinition): boolean {
+ return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION_STABLE));
+}
+
+export function hasMemoSkipAnnotation(node: arkts.ETSParameterExpression): boolean {
+ return node.annotations.some((it) => isMemoAnnotation(it, RuntimeNames.ANNOTATION_SKIP));
+}
+
+export function removeMemoAnnotation(node: T): T {
+ const newAnnotations: arkts.AnnotationUsage[] = node.annotations.filter(
+ (it) => !isMemoAnnotation(it, RuntimeNames.ANNOTATION) && !isMemoAnnotation(it, RuntimeNames.ANNOTATION_STABLE)
+ );
+ if (arkts.isEtsParameterExpression(node)) {
+ node.annotations = newAnnotations;
+ return node;
+ }
+ return node.setAnnotations(newAnnotations) as T;
+}
+
+/**
+ * TODO:
+ * @deprecated
+ */
+export function isSyntheticReturnStatement(node: arkts.AstNode): boolean {
+ return isIfStatementWithSyntheticReturn(node) || isSimpleSyntheticReturn(node) || isSyntheticReturnInBlock(node);
+}
+
+function isIfStatementWithSyntheticReturn(node: arkts.AstNode): boolean {
+ return (
+ arkts.isIfStatement(node) &&
+ !!node.test &&
+ arkts.isMemberExpression(node.test) &&
+ arkts.isIdentifier(node.test.object) &&
+ node.test.object.name === RuntimeNames.SCOPE &&
+ arkts.isIdentifier(node.test.property) &&
+ node.test.property.name === RuntimeNames.INTERNAL_VALUE_OK &&
+ (arkts.isBlockStatement(node.consequent) || arkts.isReturnStatement(node.consequent))
+ );
+}
+
+function isSimpleSyntheticReturn(node: arkts.AstNode): boolean {
+ return (
+ arkts.isReturnStatement(node) &&
+ !!node.argument &&
+ arkts.isMemberExpression(node.argument) &&
+ arkts.isIdentifier(node.argument.object) &&
+ node.argument.object.name === RuntimeNames.SCOPE &&
+ arkts.isIdentifier(node.argument.property) &&
+ node.argument.property.name === RuntimeNames.INTERNAL_VALUE
+ );
+}
+
+function isSyntheticReturnInBlock(node: arkts.AstNode): boolean {
+ if (!arkts.isBlockStatement(node) || node.statements.length !== 2) {
+ return false;
+ }
+ if (!arkts.isReturnStatement(node.statements[1])) {
+ return false;
+ }
+ const isReturnThis: boolean = !!node.statements[1].argument && arkts.isThisExpression(node.statements[1].argument);
+ const isReturnVoid: boolean = node.statements[1].argument === undefined;
+
+ return (
+ arkts.isMemberExpression(node.statements[0]) &&
+ arkts.isIdentifier(node.statements[0].object) &&
+ node.statements[0].object.name === RuntimeNames.SCOPE &&
+ arkts.isIdentifier(node.statements[0].property) &&
+ node.statements[0].property.name === RuntimeNames.INTERNAL_VALUE &&
+ (isReturnThis || isReturnVoid)
+ );
+}
+
+/**
+ * TODO:
+ * @deprecated
+ */
+export function isMemoParametersDeclaration(node: arkts.AstNode): boolean {
+ return (
+ arkts.isVariableDeclaration(node) &&
+ node.declarators.every((it) => it.name.name.startsWith(RuntimeNames.PARAMETER))
+ );
+}
+
+/**
+ * TODO: change this to TypeNodeGetType to check void type
+ */
+export function isVoidType(typeNode: arkts.TypeNode | undefined): boolean {
+ return typeNode?.dumpSrc() === 'void';
+}
+
+/**
+ * es2panda API is weird here
+ *
+ * @deprecated
+ */
+export function castParameters(params: readonly arkts.Expression[]): arkts.ETSParameterExpression[] {
+ return params as arkts.ETSParameterExpression[];
+}
+
+/**
+ * es2panda API is weird here
+ *
+ * @deprecated
+ */
+export function castFunctionExpression(value: arkts.Expression | undefined): arkts.FunctionExpression {
+ return value as unknown as arkts.FunctionExpression;
+}
+
+/**
+ * es2panda API is weird here
+ *
+ * @deprecated
+ */
+export function castArrowFunctionExpression(value: arkts.Expression | undefined): arkts.ArrowFunctionExpression {
+ return value as unknown as arkts.ArrowFunctionExpression;
+}
+
+/**
+ * es2panda API is weird here
+ *
+ * @deprecated
+ */
+export function castIdentifier(value: arkts.AstNode | undefined): arkts.Identifier {
+ return value as unknown as arkts.Identifier;
+}
+
+/**
+ * es2panda API is weird here
+ *
+ * @deprecated
+ */
+export function castOverloadsToMethods(overloads: arkts.AstNode[]): readonly arkts.MethodDefinition[] {
+ return overloads as unknown as readonly arkts.MethodDefinition[];
+}
+
+export function isStandaloneArrowFunction(node: arkts.AstNode): node is arkts.ArrowFunctionExpression {
+ if (!arkts.isArrowFunctionExpression(node)) return false;
+
+ // handling anonymous arrow function call
+ if (!!node.parent && arkts.isCallExpression(node.parent) && node.parent.expression.peer === node.peer) {
+ return true;
+ }
+
+ return (
+ !!node.parent &&
+ !arkts.isVariableDeclarator(node.parent) &&
+ !arkts.isClassProperty(node.parent) &&
+ !(arkts.isCallExpression(node.parent) && node.parent.expression)
+ );
+}
+
+export function isFunctionProperty(node: arkts.AstNode): node is arkts.Property {
+ return (
+ arkts.isProperty(node) &&
+ !!node.key &&
+ arkts.isIdentifier(node.key) &&
+ !!node.value &&
+ arkts.isArrowFunctionExpression(node.value)
+ );
+}
+
+export function isThisAttributeAssignment(node: arkts.AstNode): node is arkts.AssignmentExpression {
+ if (!arkts.isAssignmentExpression(node)) {
+ return false;
+ }
+ if (!node.left || !node.right) {
+ return false;
+ }
+ const isAssignOperator = node.operatorType === arkts.Es2pandaTokenType.TOKEN_TYPE_PUNCTUATOR_SUBSTITUTION;
+ const isThisAttribute =
+ arkts.isMemberExpression(node.left) &&
+ arkts.isThisExpression(node.left.object) &&
+ arkts.isIdentifier(node.left.property);
+ return isAssignOperator && isThisAttribute;
+}
+
+export function findThisAttribute(node: arkts.AstNode): arkts.Identifier | undefined {
+ if (!arkts.isMemberExpression(node) || !arkts.isIdentifier(node.property)) {
+ return undefined;
+ }
+ return node.property;
+}
+
+export function isMemoThisAttribute(node: arkts.Identifier, value: arkts.ArrowFunctionExpression): boolean {
+ let isMemo: boolean = isMemoArrowFunction(value);
+ if (isMemo) {
+ return true;
+ }
+ const decl: arkts.AstNode | undefined = getDeclResolveAlias(node);
+ if (!decl) {
+ return false;
+ }
+ if (arkts.isClassProperty(decl)) {
+ isMemo ||= isMemoClassProperty(decl);
+ } else if (arkts.isMethodDefinition(decl)) {
+ isMemo ||= isMemoDeclaredMethod(decl);
+ }
+ return isMemo;
+}
+
+export function isMemoClassProperty(node: arkts.ClassProperty): boolean {
+ let isMemo = findMemoFromTypeAnnotation(node.typeAnnotation);
+ if (node.value) {
+ isMemo ||=
+ arkts.isArrowFunctionExpression(node.value) &&
+ (hasMemoAnnotation(node.value) || hasMemoIntrinsicAnnotation(node.value));
+ }
+ isMemo ||= hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node);
+ return isMemo;
+}
+
+export function isMemoMethodDefinition(node: arkts.MethodDefinition): boolean {
+ return (
+ hasMemoAnnotation(node.scriptFunction) ||
+ hasMemoIntrinsicAnnotation(node.scriptFunction) ||
+ hasMemoEntryAnnotation(node.scriptFunction)
+ );
+}
+
+export function isMemoArrowFunction(node: arkts.ArrowFunctionExpression): boolean {
+ return hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node);
+}
+
+export function isMemoTSTypeAliasDeclaration(node: arkts.TSTypeAliasDeclaration): boolean {
+ let isMemo = findMemoFromTypeAnnotation(node.typeAnnotation);
+ isMemo ||= hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node);
+ return isMemo;
+}
+
+export function isMemoETSParameterExpression(param: arkts.ETSParameterExpression): boolean {
+ const type = param.identifier.typeAnnotation;
+ if (!type) {
+ return false;
+ }
+ let isMemo: boolean = hasMemoAnnotation(param) || hasMemoIntrinsicAnnotation(param);
+ isMemo ||= findMemoFromTypeAnnotation(type);
+ let decl: arkts.AstNode | undefined;
+ if (
+ arkts.isETSTypeReference(type) &&
+ !!type.part &&
+ !!type.part.name &&
+ !!(decl = getDeclResolveAlias(type.part.name))
+ ) {
+ if (arkts.isTSTypeAliasDeclaration(decl)) {
+ isMemo ||= hasMemoAnnotation(decl) || hasMemoIntrinsicAnnotation(decl);
+ isMemo ||= findMemoFromTypeAnnotation(decl.typeAnnotation);
+ return isMemo;
+ }
+ }
+ return isMemo;
+}
+
+export function isMemoVariableDeclaration(node: arkts.VariableDeclaration): boolean {
+ return hasMemoAnnotation(node) || hasMemoIntrinsicAnnotation(node);
+}
+
+export function isMemoVariableDeclarator(node: arkts.VariableDeclarator): boolean {
+ let isMemo: boolean = false;
+ if (!!node.name.typeAnnotation) {
+ isMemo ||= findMemoFromTypeAnnotation(node.name.typeAnnotation);
+ }
+ if (!!node.initializer && arkts.isArrowFunctionExpression(node.initializer)) {
+ isMemo ||= isMemoArrowFunction(node.initializer);
+ }
+ if (!!node.parent && arkts.isVariableDeclaration(node.parent)) {
+ isMemo ||= isMemoVariableDeclaration(node.parent);
+ }
+ return isMemo;
+}
+
+export function isMemoProperty(node: arkts.Property, value: arkts.ArrowFunctionExpression): boolean {
+ let isMemo: boolean = isMemoArrowFunction(value);
+ if (isMemo) {
+ return true;
+ }
+ let decl: arkts.AstNode | undefined;
+ if (!node.key || !(decl = getDeclResolveAlias(node.key))) {
+ return false;
+ }
+ if (arkts.isMethodDefinition(decl)) {
+ isMemo ||= isMemoDeclaredMethod(decl);
+ }
+ return isMemo;
+}
+
+export function isMemoDeclaredMethod(decl: arkts.MethodDefinition): boolean {
+ if (
+ decl.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET &&
+ findMemoFromTypeAnnotation(decl.scriptFunction.returnTypeAnnotation)
+ ) {
+ return true;
+ }
+ return !hasMemoEntryAnnotation(decl.scriptFunction) && isMemoMethodDefinition(decl);
+}
+
+export function isDeclaredMethodWithMemoParams(decl: arkts.MethodDefinition): boolean {
+ if (decl.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET) {
+ return false;
+ }
+ return decl.scriptFunction.params.some((param) => {
+ return arkts.isEtsParameterExpression(param) && isMemoETSParameterExpression(param);
+ });
+}
+
+export function isMemoDeclaredIdentifier(decl: arkts.Identifier): boolean {
+ if (findMemoFromTypeAnnotation(decl.typeAnnotation)) {
+ return true;
+ }
+ if (!!decl.parent && arkts.isVariableDeclarator(decl.parent)) {
+ return isMemoVariableDeclarator(decl.parent);
+ }
+ return false;
+}
+
+export function isMemoDeclaredClassProperty(decl: arkts.ClassProperty): boolean {
+ return isMemoClassProperty(decl);
+}
+
+export function findMemoFromTypeAnnotation(typeAnnotation: arkts.AstNode | undefined): boolean {
+ if (!typeAnnotation) {
+ return false;
+ }
+ if (arkts.isETSTypeReference(typeAnnotation) && !!typeAnnotation.part && !!typeAnnotation.part.name) {
+ let decl: arkts.AstNode | undefined = arkts.getDecl(typeAnnotation.part.name);
+ if (!decl || !arkts.isTSTypeAliasDeclaration(decl)) {
+ return false;
+ }
+ let isMemo: boolean = hasMemoAnnotation(decl) || hasMemoIntrinsicAnnotation(decl);
+ if (!isMemo && !!decl.typeAnnotation) {
+ isMemo = findMemoFromTypeAnnotation(decl.typeAnnotation);
+ }
+ return isMemo;
+ } else if (arkts.isETSFunctionType(typeAnnotation)) {
+ return hasMemoAnnotation(typeAnnotation) || hasMemoIntrinsicAnnotation(typeAnnotation);
+ } else if (arkts.isETSUnionType(typeAnnotation)) {
+ return typeAnnotation.types.some(
+ (type) => arkts.isETSFunctionType(type) && (hasMemoAnnotation(type) || hasMemoIntrinsicAnnotation(type))
+ );
+ }
+ return false;
+}
+
+export function findReturnTypeFromTypeAnnotation(
+ typeAnnotation: arkts.AstNode | undefined
+): arkts.TypeNode | undefined {
+ if (!typeAnnotation) {
+ return undefined;
+ }
+ if (arkts.isETSTypeReference(typeAnnotation) && !!typeAnnotation.part && !!typeAnnotation.part.name) {
+ let decl: arkts.AstNode | undefined = arkts.getDecl(typeAnnotation.part.name);
+ if (!!decl && arkts.isTSTypeAliasDeclaration(decl)) {
+ return findReturnTypeFromTypeAnnotation(decl.typeAnnotation);
+ }
+ return undefined;
+ }
+ if (arkts.isETSFunctionType(typeAnnotation)) {
+ return typeAnnotation.returnType;
+ }
+ if (arkts.isETSUnionType(typeAnnotation)) {
+ return typeAnnotation.types.find((type) => arkts.isETSFunctionType(type))?.returnType;
+ }
+ return undefined;
+}
+
+export function findLocalReturnTypeFromTypeAnnotation(
+ typeAnnotation: arkts.AstNode | undefined
+): arkts.TypeNode | undefined {
+ if (!typeAnnotation) {
+ return undefined;
+ }
+ if (arkts.isETSFunctionType(typeAnnotation)) {
+ return typeAnnotation.returnType;
+ }
+ if (arkts.isETSUnionType(typeAnnotation)) {
+ return typeAnnotation.types.find((type) => arkts.isETSFunctionType(type))?.returnType;
+ }
+ return undefined;
+}
+
+export function getDeclResolveAlias(node: arkts.AstNode): arkts.AstNode | undefined {
+ const decl = arkts.getDecl(node);
+ if (!!decl && !!decl.parent && arkts.isIdentifier(decl) && arkts.isVariableDeclarator(decl.parent)) {
+ if (!!decl.parent.initializer && arkts.isIdentifier(decl.parent.initializer)) {
+ return getDeclResolveAlias(decl.parent.initializer);
+ }
+ if (!!decl.parent.initializer && arkts.isMemberExpression(decl.parent.initializer)) {
+ return getDeclResolveAlias(decl.parent.initializer.property);
+ }
+ }
+ return decl;
+}
+
+export function mayAddLastReturn(node: arkts.BlockStatement): boolean {
+ if (node.statements.length === 0) {
+ return true;
+ }
+ const lastStatement = node.statements[node.statements.length - 1];
+ if (arkts.isBlockStatement(lastStatement)) {
+ return mayAddLastReturn(lastStatement);
+ }
+ if (arkts.isReturnStatement(lastStatement) || arkts.isThrowStatement(lastStatement)) {
+ return false;
+ }
+ return true;
+}
+
+export function fixGensymParams(params: ParamInfo[], body: arkts.BlockStatement): number {
+ let gensymParamsCount = 0;
+ for (let i = 0; i < params.length; i++) {
+ if (params[i].ident.name.startsWith(RuntimeNames.GENSYM)) {
+ if (gensymParamsCount >= body.statements.length) {
+ throw new Error(`Expected ${params[i].ident.name} replacement to original parameter`);
+ }
+ const declaration = body.statements[gensymParamsCount];
+ if (!arkts.isVariableDeclaration(declaration)) {
+ throw new Error(`Expected ${params[i].ident.name} replacement to original parameter`);
+ }
+ if (!arkts.isIdentifier(declaration.declarators[0].name)) {
+ throw new Error(`Expected ${params[i].ident.name} replacement to original parameter`);
+ }
+ params[i].ident = declaration.declarators[0].name;
+ gensymParamsCount++;
+ }
+ }
+ return gensymParamsCount;
+}
+
+export function isMemoContextParamAdded(param: arkts.Expression): boolean {
+ return arkts.isEtsParameterExpression(param) && param.identifier.name === RuntimeNames.CONTEXT;
+}
+
+export function isMemoIdParamAdded(param: arkts.Expression): boolean {
+ return arkts.isEtsParameterExpression(param) && param.identifier.name === RuntimeNames.ID;
+}
+
+export function isUnmemoizedInFunctionParams(params?: readonly arkts.Expression[], hasReceiver?: boolean): boolean {
+ const _params = params ?? [];
+ const startIndex = hasReceiver ? 1 : 0;
+ const isContextAdded = !!_params.at(startIndex) && isMemoContextParamAdded(_params.at(startIndex)!);
+ const isIdAdded = !!_params.at(startIndex + 1) && isMemoIdParamAdded(_params.at(startIndex + 1)!);
+ return isContextAdded && isIdAdded;
+}
+
+export function getFunctionParamsBeforeUnmemoized(
+ params?: readonly arkts.Expression[],
+ hasReceiver?: boolean
+): readonly arkts.Expression[] {
+ const _params = params ?? [];
+ if (isUnmemoizedInFunctionParams(_params, hasReceiver)) {
+ if (!!hasReceiver) {
+ return [_params.at(0)!, ..._params.slice(3)];
+ }
+ return _params.slice(2);
+ }
+ return _params;
+}
+
+export function findUnmemoizedScopeInFunctionBody(body: arkts.BlockStatement, gensymCount: number = 0): boolean {
+ const startIndex = gensymCount;
+ if (body.statements.length < startIndex + 1) {
+ return false;
+ }
+ const statement = body.statements.at(startIndex)!;
+ if (!arkts.isVariableDeclaration(statement)) {
+ return false;
+ }
+ const declarator = statement.declarators.at(0)!;
+ return declarator.name.name === RuntimeNames.SCOPE;
+}
+
+export function buildReturnTypeInfo(
+ returnType: arkts.TypeNode | undefined,
+ isMemo?: boolean,
+ isStableThis?: boolean
+): ReturnTypeInfo {
+ const newReturnType = !!returnType
+ ? returnType.clone()
+ : arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID);
+ return {
+ node: newReturnType,
+ isMemo,
+ isVoid: isVoidType(newReturnType),
+ isStableThis,
+ };
+}
+
+export function buildeParamInfos(parameters: readonly arkts.ETSParameterExpression[]): ParamInfo[] {
+ return [
+ ...parameters
+ .filter((it) => !hasMemoSkipAnnotation(it))
+ .map((it) => {
+ return { ident: it.identifier, param: it };
+ }),
+ ];
+}
+
+export function parametersBlockHasReceiver(params: readonly arkts.Expression[]): boolean {
+ return params.length > 0 && arkts.isEtsParameterExpression(params[0]) && isThisParam(params[0]);
+}
+
+export function parametrizedNodeHasReceiver(node: arkts.ScriptFunction | arkts.ETSFunctionType | undefined): boolean {
+ if (node === undefined) {
+ return false;
+ }
+ return parametersBlockHasReceiver(node.params);
+}
+
+function isThisParam(node: arkts.Expression | undefined): boolean {
+ if (node === undefined || !arkts.isEtsParameterExpression(node)) {
+ return false;
+ }
+ return node.identifier?.isReceiver ?? false;
+}
+
+export function filterMemoSkipParams(params: readonly arkts.Expression[]): readonly arkts.Expression[] {
+ return params.filter((p) => !hasMemoSkipAnnotation(p as arkts.ETSParameterExpression));
+}
diff --git a/arkui-plugins/npm_preinstall.sh b/arkui-plugins/npm_preinstall.sh
new file mode 100755
index 0000000000000000000000000000000000000000..478471ab0ddcfcec949a6753fc1dfd15dda9394b
--- /dev/null
+++ b/arkui-plugins/npm_preinstall.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# coding: utf-8
+# 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.
+
+if [ "$1" == "--init" ]; then
+ cd ../koala-wrapper
+ npm install
+ npm run compile
+ npm link
+
+ cd ../ts_wrapper
+ npm install
+ npm run compile
+ npm link
+
+ cd ../arkui-plugins
+ mkdir node_modules
+ npm link @koalaui/libarkts
+fi
\ No newline at end of file
diff --git a/arkui-plugins/package.json b/arkui-plugins/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..929c12377e1d5259d15b24c986a6e41ff93b5e70
--- /dev/null
+++ b/arkui-plugins/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "arkui-plugin",
+ "version": "1.0.0",
+ "description": "",
+ "private": true,
+ "workspaces": [
+ "./test"
+ ],
+ "scripts": {
+ "local:install": "chmod 777 ./npm_preinstall.sh && ./npm_preinstall.sh --init",
+ "compile:plugins": "./node_modules/.bin/babel . --out-dir lib --extensions .ts",
+ "compile:clean": "rm -rf lib",
+ "clean:test": "rm -rf dist && rm -rf coverage",
+ "prepare:test": "cp -rf $INIT_CWD/../../../out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/koala-wrapper/build/native/ ../koala-wrapper/build/",
+ "test": "npm run clean:test && npm run prepare:test && LD_LIBRARY_PATH=$INIT_CWD/../../../out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/ets2panda/lib jest --coverage --logHeapUsage --config ./jest-test.config.js --maxWorkers=50% --silent",
+ "test:gdb": "LD_LIBRARY_PATH=$INIT_CWD/../../../out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/ets2panda/lib gdb --args node ./node_modules/.bin/jest --config ./jest-test.config.js",
+ "compile": "npm run compile:clean && npm run compile:plugins && cp -rf ./lib $INIT_CWD/../../../../out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/ui-plugins/"
+ },
+ "devDependencies": {
+ "@babel/cli": "7.20.7",
+ "@babel/core": "7.20.12",
+ "@babel/plugin-proposal-class-properties": "7.18.6",
+ "@babel/preset-env": "7.20.2",
+ "@babel/preset-typescript": "7.18.6",
+ "@babel/runtime": "7.20.13",
+ "@types/jest": "^29.5.14",
+ "@types/node": "^22.13.9",
+ "jest": "^29.7.0",
+ "ts-jest": "^29.2.0",
+ "ts-node": "^10.9.0",
+ "typescript": "^5.0.0"
+ },
+ "dependencies": {
+ "@koalaui/libarkts": "../koala-wrapper"
+ }
+}
diff --git a/arkui-plugins/path.ts b/arkui-plugins/path.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a8646fcbf9f1a0b882082eca9843bd5441c171d9
--- /dev/null
+++ b/arkui-plugins/path.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022-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.
+ */
+import { error } from 'console';
+import * as path from 'path';
+
+const UI_PLUGINS = 'ui-plugins';
+const ARKUI_PLUGINS = 'arkui-plugins';
+
+function findMatchingFile(currentPath: string, targetFileName1: string, targetFileName2: string): string | null {
+ let current = currentPath;
+ while (true) {
+ // 获取当前路径的文件名
+ const baseName = path.basename(current);
+ if (baseName === targetFileName1 || baseName === targetFileName2) {
+ return path.dirname(current);
+ }
+
+ const parentPath = path.dirname(current);
+ if (parentPath === current) {
+ break;
+ }
+ current = parentPath;
+ }
+ throw new Error('ui-plugins not found.');
+}
+
+function findRootDir() {
+ const plugins = findMatchingFile(__dirname, UI_PLUGINS, ARKUI_PLUGINS);
+ if (plugins === null) {
+ throw 'error';
+ }
+ return plugins;
+}
+
+export function getArktsPath() {
+ return path.join(findRootDir(), 'koala-wrapper', './build/lib/arkts-api/index.js');
+}
+
+export function getInteropPath() {
+ return path.join(findRootDir(), 'koala-wrapper/koalaui/interop', './dist/lib/src/interop/index.js');
+}
+
+export function getCommonPath() {
+ return path.join(findRootDir(), 'koala-wrapper/koalaui/common', './dist/lib/src/index.js');
+}
+
+export function getCompatPath() {
+ return path.join(findRootDir(), 'koala-wrapper/koalaui/compat', './dist/src/index.js');
+}
diff --git a/arkui-plugins/test/arktsconfig_gen.js b/arkui-plugins/test/arktsconfig_gen.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd8b94608f2c4529b089562a12a7cab008464a46
--- /dev/null
+++ b/arkui-plugins/test/arktsconfig_gen.js
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+// 获取当前目录
+const currentDirectory = process.cwd();
+let workSpace = currentDirectory;
+for (let i = 0; i < 4; i++) {
+ workSpace = path.dirname(workSpace);
+}
+// JSON 文件路径
+const jsonFilePath = path.join(__dirname, 'arktsconfig_template.json');
+const outJsonFilePath = path.join(__dirname, 'dist/cache/arktsconfig.json');
+
+try {
+ // 读取 JSON 文件内容
+ const data = fs.readFileSync(jsonFilePath, 'utf8');
+ const jsonData = JSON.parse(data);
+
+ // 处理 baseUrl 字段
+ if (jsonData.compilerOptions.baseUrl) {
+ jsonData.compilerOptions.baseUrl = jsonData.compilerOptions.baseUrl.replace(/workspace/g, workSpace);
+ }
+
+ // 处理 Paths 字段
+ if (jsonData.compilerOptions.paths) {
+ for (const key in jsonData.compilerOptions.paths) {
+ const values = jsonData.compilerOptions.paths[key];
+ for (let i = 0; i < values.length; i++) {
+ if (key.startsWith('@ohos.arkui.')) {
+ values[i] = currentDirectory + "/dist/cache/" + key;
+ } else {
+ values[i] = values[i].replace(/workspace/g, workSpace);
+ }
+ }
+ }
+ }
+
+ // 将修改后的内容写回 JSON 文件
+ fs.writeFileSync(outJsonFilePath, JSON.stringify(jsonData, null, 2), 'utf8');
+} catch (error) {
+ console.error('处理 JSON 文件时出错:', error);
+}
\ No newline at end of file
diff --git a/arkui-plugins/test/arktsconfig_template.json b/arkui-plugins/test/arktsconfig_template.json
new file mode 100644
index 0000000000000000000000000000000000000000..1353fee749d190171066c383a713f7792aa28807
--- /dev/null
+++ b/arkui-plugins/test/arktsconfig_template.json
@@ -0,0 +1,2797 @@
+{
+ "compilerOptions": {
+ "package": "entry",
+ "baseUrl": "workspace/developtools/ace_ets2bundle/arkui-plugins/test/dist/cache/",
+ "include": [
+ "./0_SRC_Memo_2_FunctionTransformer.ets"
+ ],
+ "paths": {
+ "std": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/ets2panda/lib/stdlib/std"
+ ],
+ "escompat": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/build-tools/ets2panda/lib/stdlib/escompat"
+ ],
+ "@ohos.InputMethodExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.InputMethodExtensionAbility"
+ ],
+ "@ohos.InputMethodExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.InputMethodExtensionContext"
+ ],
+ "@ohos.InputMethodSubtype": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.InputMethodSubtype"
+ ],
+ "@ohos.PiPWindow": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.PiPWindow"
+ ],
+ "@ohos.UiTest": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.UiTest"
+ ],
+ "@ohos.WallpaperExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.WallpaperExtensionAbility"
+ ],
+ "@ohos.WorkSchedulerExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.WorkSchedulerExtensionAbility"
+ ],
+ "@ohos.ability.ability": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.ability"
+ ],
+ "@ohos.ability.dataUriUtils": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.dataUriUtils"
+ ],
+ "@ohos.ability.errorCode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.errorCode"
+ ],
+ "@ohos.ability.featureAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.featureAbility"
+ ],
+ "@ohos.ability.particleAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.particleAbility"
+ ],
+ "@ohos.ability.screenLockFileManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.screenLockFileManager"
+ ],
+ "@ohos.ability.wantConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ability.wantConstant"
+ ],
+ "@ohos.abilityAccessCtrl": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.abilityAccessCtrl"
+ ],
+ "@ohos.accessibility.GesturePath": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.accessibility.GesturePath"
+ ],
+ "@ohos.accessibility.GesturePoint": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.accessibility.GesturePoint"
+ ],
+ "@ohos.accessibility.config": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.accessibility.config"
+ ],
+ "@ohos.accessibility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.accessibility"
+ ],
+ "@ohos.account.appAccount": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.account.appAccount"
+ ],
+ "@ohos.account.distributedAccount": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.account.distributedAccount"
+ ],
+ "@ohos.account.osAccount": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.account.osAccount"
+ ],
+ "@ohos.advertising.AdComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.advertising.AdComponent"
+ ],
+ "@ohos.advertising.AdsServiceExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.advertising.AdsServiceExtensionAbility"
+ ],
+ "@ohos.advertising.AutoAdComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.advertising.AutoAdComponent"
+ ],
+ "@ohos.advertising": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.advertising"
+ ],
+ "@ohos.ai.intelligentVoice": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ai.intelligentVoice"
+ ],
+ "@ohos.ai.mindSporeLite": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.ai.mindSporeLite"
+ ],
+ "@ohos.animation.windowAnimationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.animation.windowAnimationManager"
+ ],
+ "@ohos.animator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.animator"
+ ],
+ "@ohos.app.ability.Ability": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.Ability"
+ ],
+ "@ohos.app.ability.AbilityConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.AbilityConstant"
+ ],
+ "@ohos.app.ability.AbilityLifecycleCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.AbilityLifecycleCallback"
+ ],
+ "@ohos.app.ability.AbilityStage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.AbilityStage"
+ ],
+ "@ohos.app.ability.ActionExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ActionExtensionAbility"
+ ],
+ "@ohos.app.ability.ApplicationStateChangeCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ApplicationStateChangeCallback"
+ ],
+ "@ohos.app.ability.AtomicServiceOptions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.AtomicServiceOptions"
+ ],
+ "@ohos.app.ability.AutoFillExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.AutoFillExtensionAbility"
+ ],
+ "@ohos.app.ability.ChildProcess": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ChildProcess"
+ ],
+ "@ohos.app.ability.ChildProcessArgs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ChildProcessArgs"
+ ],
+ "@ohos.app.ability.ChildProcessOptions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ChildProcessOptions"
+ ],
+ "@ohos.app.ability.Configuration": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.Configuration"
+ ],
+ "@ohos.app.ability.ConfigurationConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ConfigurationConstant"
+ ],
+ "@ohos.app.ability.DriverExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.DriverExtensionAbility"
+ ],
+ "@ohos.app.ability.EmbeddableUIAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.EmbeddableUIAbility"
+ ],
+ "@ohos.app.ability.EmbeddedUIExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.EmbeddedUIExtensionAbility"
+ ],
+ "@ohos.app.ability.EnvironmentCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.EnvironmentCallback"
+ ],
+ "@ohos.app.ability.ExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ExtensionAbility"
+ ],
+ "@ohos.app.ability.FenceExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.FenceExtensionAbility"
+ ],
+ "@ohos.app.ability.FenceExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.FenceExtensionContext"
+ ],
+ "@ohos.app.ability.InsightIntentContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.InsightIntentContext"
+ ],
+ "@ohos.app.ability.InsightIntentExecutor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.InsightIntentExecutor"
+ ],
+ "@ohos.app.ability.MediaControlExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.MediaControlExtensionAbility"
+ ],
+ "@ohos.app.ability.OpenLinkOptions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.OpenLinkOptions"
+ ],
+ "@ohos.app.ability.PhotoEditorExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.PhotoEditorExtensionAbility"
+ ],
+ "@ohos.app.ability.PrintExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.PrintExtensionAbility"
+ ],
+ "@ohos.app.ability.ServiceExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ServiceExtensionAbility"
+ ],
+ "@ohos.app.ability.ShareExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.ShareExtensionAbility"
+ ],
+ "@ohos.app.ability.StartOptions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.StartOptions"
+ ],
+ "@ohos.app.ability.UIAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.UIAbility"
+ ],
+ "@ohos.app.ability.UIExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.UIExtensionAbility"
+ ],
+ "@ohos.app.ability.UIExtensionContentSession": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.UIExtensionContentSession"
+ ],
+ "@ohos.app.ability.UIServiceExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.UIServiceExtensionAbility"
+ ],
+ "@ohos.app.ability.UserAuthExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.UserAuthExtensionAbility"
+ ],
+ "@ohos.app.ability.VpnExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.VpnExtensionAbility"
+ ],
+ "@ohos.app.ability.Want": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.Want"
+ ],
+ "@ohos.app.ability.abilityDelegatorRegistry": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.abilityDelegatorRegistry"
+ ],
+ "@ohos.app.ability.abilityManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.abilityManager"
+ ],
+ "@ohos.app.ability.appManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.appManager"
+ ],
+ "@ohos.app.ability.appRecovery": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.appRecovery"
+ ],
+ "@ohos.app.ability.application": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.application"
+ ],
+ "@ohos.app.ability.autoFillManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.autoFillManager"
+ ],
+ "@ohos.app.ability.autoStartupManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.autoStartupManager"
+ ],
+ "@ohos.app.ability.childProcessManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.childProcessManager"
+ ],
+ "@ohos.app.ability.common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.common"
+ ],
+ "@ohos.app.ability.contextConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.contextConstant"
+ ],
+ "@ohos.app.ability.dataUriUtils": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.dataUriUtils"
+ ],
+ "@ohos.app.ability.dialogRequest": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.dialogRequest"
+ ],
+ "@ohos.app.ability.dialogSession": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.dialogSession"
+ ],
+ "@ohos.app.ability.errorManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.errorManager"
+ ],
+ "@ohos.app.ability.insightIntent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.insightIntent"
+ ],
+ "@ohos.app.ability.insightIntentDriver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.insightIntentDriver"
+ ],
+ "@ohos.app.ability.missionManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.missionManager"
+ ],
+ "@ohos.app.ability.quickFixManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.quickFixManager"
+ ],
+ "@ohos.app.ability.sendableContextManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.sendableContextManager"
+ ],
+ "@ohos.app.ability.wantAgent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.wantAgent"
+ ],
+ "@ohos.app.ability.wantConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.ability.wantConstant"
+ ],
+ "@ohos.app.appstartup.StartupConfig": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.appstartup.StartupConfig"
+ ],
+ "@ohos.app.appstartup.StartupConfigEntry": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.appstartup.StartupConfigEntry"
+ ],
+ "@ohos.app.appstartup.StartupListener": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.appstartup.StartupListener"
+ ],
+ "@ohos.app.appstartup.StartupTask": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.appstartup.StartupTask"
+ ],
+ "@ohos.app.appstartup.startupManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.appstartup.startupManager"
+ ],
+ "@ohos.app.businessAbilityRouter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.businessAbilityRouter"
+ ],
+ "@ohos.app.form.FormExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.FormExtensionAbility"
+ ],
+ "@ohos.app.form.formAgent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formAgent"
+ ],
+ "@ohos.app.form.formBindingData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formBindingData"
+ ],
+ "@ohos.app.form.formHost": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formHost"
+ ],
+ "@ohos.app.form.formInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formInfo"
+ ],
+ "@ohos.app.form.formObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formObserver"
+ ],
+ "@ohos.app.form.formProvider": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.app.form.formProvider"
+ ],
+ "@ohos.application.AccessibilityExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.AccessibilityExtensionAbility"
+ ],
+ "@ohos.application.BackupExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.BackupExtensionAbility"
+ ],
+ "@ohos.application.Configuration": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.Configuration"
+ ],
+ "@ohos.application.ConfigurationConstant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.ConfigurationConstant"
+ ],
+ "@ohos.application.DataShareExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.DataShareExtensionAbility"
+ ],
+ "@ohos.application.StaticSubscriberExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.StaticSubscriberExtensionAbility"
+ ],
+ "@ohos.application.StaticSubscriberExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.StaticSubscriberExtensionContext"
+ ],
+ "@ohos.application.Want": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.Want"
+ ],
+ "@ohos.application.WindowExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.WindowExtensionAbility"
+ ],
+ "@ohos.application.abilityDelegatorRegistry": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.abilityDelegatorRegistry"
+ ],
+ "@ohos.application.abilityManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.abilityManager"
+ ],
+ "@ohos.application.appManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.appManager"
+ ],
+ "@ohos.application.formBindingData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.formBindingData"
+ ],
+ "@ohos.application.formError": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.formError"
+ ],
+ "@ohos.application.formHost": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.formHost"
+ ],
+ "@ohos.application.formInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.formInfo"
+ ],
+ "@ohos.application.formProvider": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.formProvider"
+ ],
+ "@ohos.application.missionManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.missionManager"
+ ],
+ "@ohos.application.testRunner": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.testRunner"
+ ],
+ "@ohos.application.uriPermissionManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.application.uriPermissionManager"
+ ],
+ "@ohos.arkui.Prefetcher": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.Prefetcher"
+ ],
+ "@ohos.arkui.StateManagement": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.StateManagement"
+ ],
+ "@ohos.arkui.StateManagement.runtime": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.StateManagement.runtime"
+ ],
+ "@ohos.arkui.UIContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.UIContext"
+ ],
+ "@ohos.arkui.advanced.Chip": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.Chip"
+ ],
+ "@ohos.arkui.advanced.ChipGroup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ChipGroup"
+ ],
+ "@ohos.arkui.advanced.ComposeListItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ComposeListItem"
+ ],
+ "@ohos.arkui.advanced.ComposeTitleBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ComposeTitleBar"
+ ],
+ "@ohos.arkui.advanced.Counter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.Counter"
+ ],
+ "@ohos.arkui.advanced.Dialog": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.Dialog"
+ ],
+ "@ohos.arkui.advanced.DownloadFileButton": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.DownloadFileButton"
+ ],
+ "@ohos.arkui.advanced.EditableTitleBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.EditableTitleBar"
+ ],
+ "@ohos.arkui.advanced.ExceptionPrompt": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ExceptionPrompt"
+ ],
+ "@ohos.arkui.advanced.Filter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.Filter"
+ ],
+ "@ohos.arkui.advanced.FoldSplitContainer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.FoldSplitContainer"
+ ],
+ "@ohos.arkui.advanced.FormMenu": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.FormMenu"
+ ],
+ "@ohos.arkui.advanced.FullScreenLaunchComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.FullScreenLaunchComponent"
+ ],
+ "@ohos.arkui.advanced.GridObjectSortComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.GridObjectSortComponent"
+ ],
+ "@ohos.arkui.advanced.InnerFullScreenLaunchComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.InnerFullScreenLaunchComponent"
+ ],
+ "@ohos.arkui.advanced.Popup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.Popup"
+ ],
+ "@ohos.arkui.advanced.ProgressButton": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ProgressButton"
+ ],
+ "@ohos.arkui.advanced.SegmentButton": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SegmentButton"
+ ],
+ "@ohos.arkui.advanced.SelectTitleBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SelectTitleBar"
+ ],
+ "@ohos.arkui.advanced.SelectionMenu": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SelectionMenu"
+ ],
+ "@ohos.arkui.advanced.SplitLayout": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SplitLayout"
+ ],
+ "@ohos.arkui.advanced.SubHeader": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SubHeader"
+ ],
+ "@ohos.arkui.advanced.SwipeRefresher": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.SwipeRefresher"
+ ],
+ "@ohos.arkui.advanced.TabTitleBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.TabTitleBar"
+ ],
+ "@ohos.arkui.advanced.ToolBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.ToolBar"
+ ],
+ "@ohos.arkui.advanced.TreeView": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.advanced.TreeView"
+ ],
+ "@ohos.arkui.component.AbilityComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.AbilityComponent"
+ ],
+ "@ohos.arkui.component.ActionSheet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ActionSheet"
+ ],
+ "@ohos.arkui.component.AlertDialog": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.AlertDialog"
+ ],
+ "@ohos.arkui.component.AlphabetIndexer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.AlphabetIndexer"
+ ],
+ "@ohos.arkui.component.Animator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Animator"
+ ],
+ "@ohos.arkui.component.Badge": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Badge"
+ ],
+ "@ohos.arkui.component.Blank": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Blank"
+ ],
+ "@ohos.arkui.component.Button": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Button"
+ ],
+ "@ohos.arkui.component.Calendar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Calendar"
+ ],
+ "@ohos.arkui.component.CalendarPicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.CalendarPicker"
+ ],
+ "@ohos.arkui.component.Canvas": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Canvas"
+ ],
+ "@ohos.arkui.component.Checkbox": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Checkbox"
+ ],
+ "@ohos.arkui.component.CheckboxGroup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.CheckboxGroup"
+ ],
+ "@ohos.arkui.component.Circle": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Circle"
+ ],
+ "@ohos.arkui.component.Column": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Column"
+ ],
+ "@ohos.arkui.component.ColumnSplit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ColumnSplit"
+ ],
+ "@ohos.arkui.component.Common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Common"
+ ],
+ "@ohos.arkui.component.CommonTsEtsApi": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.CommonTsEtsApi"
+ ],
+ "@ohos.arkui.component.Component3d": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Component3d"
+ ],
+ "@ohos.arkui.component.ContainerSpan": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ContainerSpan"
+ ],
+ "@ohos.arkui.component.ContentSlot": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ContentSlot"
+ ],
+ "@ohos.arkui.component.ContextMenu": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ContextMenu"
+ ],
+ "@ohos.arkui.component.Counter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Counter"
+ ],
+ "@ohos.arkui.component.CustomDialogController": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.CustomDialogController"
+ ],
+ "@ohos.arkui.component.DataPanel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.DataPanel"
+ ],
+ "@ohos.arkui.component.DatePicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.DatePicker"
+ ],
+ "@ohos.arkui.component.Divider": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Divider"
+ ],
+ "@ohos.arkui.component.EffectComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.EffectComponent"
+ ],
+ "@ohos.arkui.component.Ellipse": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Ellipse"
+ ],
+ "@ohos.arkui.component.EmbeddedComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.EmbeddedComponent"
+ ],
+ "@ohos.arkui.component.Enums": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Enums"
+ ],
+ "@ohos.arkui.component.Flex": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Flex"
+ ],
+ "@ohos.arkui.component.FlowItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.FlowItem"
+ ],
+ "@ohos.arkui.component.Focus": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Focus"
+ ],
+ "@ohos.arkui.component.FolderStack": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.FolderStack"
+ ],
+ "@ohos.arkui.component.ForEach": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ForEach"
+ ],
+ "@ohos.arkui.component.FormComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.FormComponent"
+ ],
+ "@ohos.arkui.component.FormLink": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.FormLink"
+ ],
+ "@ohos.arkui.component.Gauge": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Gauge"
+ ],
+ "@ohos.arkui.component.Gesture": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Gesture"
+ ],
+ "@ohos.arkui.component.Grid": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Grid"
+ ],
+ "@ohos.arkui.component.GridCol": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.GridCol"
+ ],
+ "@ohos.arkui.component.GridContainer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.GridContainer"
+ ],
+ "@ohos.arkui.component.GridItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.GridItem"
+ ],
+ "@ohos.arkui.component.GridRow": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.GridRow"
+ ],
+ "@ohos.arkui.component.Hyperlink": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Hyperlink"
+ ],
+ "@ohos.arkui.component.Image": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Image"
+ ],
+ "@ohos.arkui.component.ImageAnimator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ImageAnimator"
+ ],
+ "@ohos.arkui.component.ImageCommon": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ImageCommon"
+ ],
+ "@ohos.arkui.component.ImageSpan": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ImageSpan"
+ ],
+ "@ohos.arkui.component.IndicatorComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.IndicatorComponent"
+ ],
+ "@ohos.arkui.component.Inspector": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Inspector"
+ ],
+ "@ohos.arkui.component.IsolatedComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.IsolatedComponent"
+ ],
+ "@ohos.arkui.component.LazyForEach": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.LazyForEach"
+ ],
+ "@ohos.arkui.component.Line": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Line"
+ ],
+ "@ohos.arkui.component.Linearindicator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Linearindicator"
+ ],
+ "@ohos.arkui.component.List": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.List"
+ ],
+ "@ohos.arkui.component.ListItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ListItem"
+ ],
+ "@ohos.arkui.component.ListItemGroup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ListItemGroup"
+ ],
+ "@ohos.arkui.component.LoadingProgress": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.LoadingProgress"
+ ],
+ "@ohos.arkui.component.Marquee": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Marquee"
+ ],
+ "@ohos.arkui.component.Matrix2d": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Matrix2d"
+ ],
+ "@ohos.arkui.component.MediaCachedImage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.MediaCachedImage"
+ ],
+ "@ohos.arkui.component.Menu": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Menu"
+ ],
+ "@ohos.arkui.component.MenuItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.MenuItem"
+ ],
+ "@ohos.arkui.component.MenuItemGroup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.MenuItemGroup"
+ ],
+ "@ohos.arkui.component.NavDestination": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.NavDestination"
+ ],
+ "@ohos.arkui.component.NavRouter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.NavRouter"
+ ],
+ "@ohos.arkui.component.Navigation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Navigation"
+ ],
+ "@ohos.arkui.component.Navigator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Navigator"
+ ],
+ "@ohos.arkui.component.NodeContainer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.NodeContainer"
+ ],
+ "@ohos.arkui.component.PageTransition": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.PageTransition"
+ ],
+ "@ohos.arkui.component.Panel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Panel"
+ ],
+ "@ohos.arkui.component.Particle": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Particle"
+ ],
+ "@ohos.arkui.component.Path": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Path"
+ ],
+ "@ohos.arkui.component.PatternLock": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.PatternLock"
+ ],
+ "@ohos.arkui.component.Polygon": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Polygon"
+ ],
+ "@ohos.arkui.component.Polyline": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Polyline"
+ ],
+ "@ohos.arkui.component.Progress": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Progress"
+ ],
+ "@ohos.arkui.component.QRCode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.QRCode"
+ ],
+ "@ohos.arkui.component.Radio": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Radio"
+ ],
+ "@ohos.arkui.component.Rating": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Rating"
+ ],
+ "@ohos.arkui.component.Rect": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Rect"
+ ],
+ "@ohos.arkui.component.Refresh": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Refresh"
+ ],
+ "@ohos.arkui.component.RelativeContainer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.RelativeContainer"
+ ],
+ "@ohos.arkui.component.RichEditor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.RichEditor"
+ ],
+ "@ohos.arkui.component.RichText": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.RichText"
+ ],
+ "@ohos.arkui.component.Row": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Row"
+ ],
+ "@ohos.arkui.component.RowSplit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.RowSplit"
+ ],
+ "@ohos.arkui.component.Scroll": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Scroll"
+ ],
+ "@ohos.arkui.component.ScrollBar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.ScrollBar"
+ ],
+ "@ohos.arkui.component.Search": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Search"
+ ],
+ "@ohos.arkui.component.Select": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Select"
+ ],
+ "@ohos.arkui.component.Shape": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Shape"
+ ],
+ "@ohos.arkui.component.Sidebar": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Sidebar"
+ ],
+ "@ohos.arkui.component.Slider": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Slider"
+ ],
+ "@ohos.arkui.component.Span": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Span"
+ ],
+ "@ohos.arkui.component.Stack": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Stack"
+ ],
+ "@ohos.arkui.component.StateManagement": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.StateManagement"
+ ],
+ "@ohos.arkui.component.StepperItem": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.StepperItem"
+ ],
+ "@ohos.arkui.component.StyledString": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.StyledString"
+ ],
+ "@ohos.arkui.component.Swiper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Swiper"
+ ],
+ "@ohos.arkui.component.SymbolGlyph": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.SymbolGlyph"
+ ],
+ "@ohos.arkui.component.SymbolSpan": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.SymbolSpan"
+ ],
+ "@ohos.arkui.component.TabContent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TabContent"
+ ],
+ "@ohos.arkui.component.Tabs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Tabs"
+ ],
+ "@ohos.arkui.component.Text": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Text"
+ ],
+ "@ohos.arkui.component.TextArea": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextArea"
+ ],
+ "@ohos.arkui.component.TextClock": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextClock"
+ ],
+ "@ohos.arkui.component.TextCommon": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextCommon"
+ ],
+ "@ohos.arkui.component.TextInput": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextInput"
+ ],
+ "@ohos.arkui.component.TextPicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextPicker"
+ ],
+ "@ohos.arkui.component.TextTimer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TextTimer"
+ ],
+ "@ohos.arkui.component.TimePicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.TimePicker"
+ ],
+ "@ohos.arkui.component.Toggle": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Toggle"
+ ],
+ "@ohos.arkui.component.Units": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Units"
+ ],
+ "@ohos.arkui.component.Video": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.Video"
+ ],
+ "@ohos.arkui.component.WaterFlow": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.WaterFlow"
+ ],
+ "@ohos.arkui.component.WithTheme": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.WithTheme"
+ ],
+ "@ohos.arkui.component.XComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component.XComponent"
+ ],
+ "@ohos.arkui.component": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.component"
+ ],
+ "@ohos.arkui.componentSnapshot": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.componentSnapshot"
+ ],
+ "@ohos.arkui.componentUtils": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.componentUtils"
+ ],
+ "@ohos.arkui.dragController": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.dragController"
+ ],
+ "@ohos.arkui.drawableDescriptor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.drawableDescriptor"
+ ],
+ "@ohos.arkui.inspector": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.inspector"
+ ],
+ "@ohos.arkui.modifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.modifier"
+ ],
+ "@ohos.arkui.node": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.node"
+ ],
+ "@ohos.arkui.observer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.observer"
+ ],
+ "@ohos.arkui.performanceMonitor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.performanceMonitor"
+ ],
+ "@ohos.arkui.shape": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.shape"
+ ],
+ "@ohos.arkui.stateManagement": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.stateManagement"
+ ],
+ "@ohos.arkui.theme": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.theme"
+ ],
+ "@ohos.arkui.uiExtension": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.arkui.uiExtension"
+ ],
+ "@ohos.atomicservice.AtomicServiceNavigation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.atomicservice.AtomicServiceNavigation"
+ ],
+ "@ohos.atomicservice.AtomicServiceTabs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.atomicservice.AtomicServiceTabs"
+ ],
+ "@ohos.atomicservice.AtomicServiceWeb": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.atomicservice.AtomicServiceWeb"
+ ],
+ "@ohos.atomicservice.InterstitialDialogAction": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.atomicservice.InterstitialDialogAction"
+ ],
+ "@ohos.atomicservice.NavPushPathHelper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.atomicservice.NavPushPathHelper"
+ ],
+ "@ohos.backgroundTaskManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.backgroundTaskManager"
+ ],
+ "@ohos.base": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.base"
+ ],
+ "@ohos.batteryInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.batteryInfo"
+ ],
+ "@ohos.batteryStatistics": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.batteryStatistics"
+ ],
+ "@ohos.bluetooth.a2dp": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.a2dp"
+ ],
+ "@ohos.bluetooth.access": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.access"
+ ],
+ "@ohos.bluetooth.baseProfile": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.baseProfile"
+ ],
+ "@ohos.bluetooth.ble": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.ble"
+ ],
+ "@ohos.bluetooth.connection": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.connection"
+ ],
+ "@ohos.bluetooth.constant": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.constant"
+ ],
+ "@ohos.bluetooth": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth"
+ ],
+ "@ohos.bluetooth.hfp": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.hfp"
+ ],
+ "@ohos.bluetooth.hid": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.hid"
+ ],
+ "@ohos.bluetooth.map": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.map"
+ ],
+ "@ohos.bluetooth.pan": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.pan"
+ ],
+ "@ohos.bluetooth.pbap": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.pbap"
+ ],
+ "@ohos.bluetooth.socket": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.socket"
+ ],
+ "@ohos.bluetooth.wearDetection": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetooth.wearDetection"
+ ],
+ "@ohos.bluetoothManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bluetoothManager"
+ ],
+ "@ohos.brightness": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.brightness"
+ ],
+ "@ohos.buffer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.buffer"
+ ],
+ "@ohos.bundle.appControl": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.appControl"
+ ],
+ "@ohos.bundle.appDomainVerify": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.appDomainVerify"
+ ],
+ "@ohos.bundle.bundleManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.bundleManager"
+ ],
+ "@ohos.bundle.bundleMonitor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.bundleMonitor"
+ ],
+ "@ohos.bundle.bundleResourceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.bundleResourceManager"
+ ],
+ "@ohos.bundle": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle"
+ ],
+ "@ohos.bundle.defaultAppManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.defaultAppManager"
+ ],
+ "@ohos.bundle.distributedBundleManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.distributedBundleManager"
+ ],
+ "@ohos.bundle.freeInstall": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.freeInstall"
+ ],
+ "@ohos.bundle.innerBundleManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.innerBundleManager"
+ ],
+ "@ohos.bundle.installer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.installer"
+ ],
+ "@ohos.bundle.launcherBundleManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.launcherBundleManager"
+ ],
+ "@ohos.bundle.overlay": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.overlay"
+ ],
+ "@ohos.bundle.shortcutManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundle.shortcutManager"
+ ],
+ "@ohos.bundleState": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bundleState"
+ ],
+ "@ohos.bytrace": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.bytrace"
+ ],
+ "@ohos.calendarManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.calendarManager"
+ ],
+ "@ohos.charger": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.charger"
+ ],
+ "@ohos.commonEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.commonEvent"
+ ],
+ "@ohos.commonEventManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.commonEventManager"
+ ],
+ "@ohos.configPolicy": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.configPolicy"
+ ],
+ "@ohos.connectedTag": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.connectedTag"
+ ],
+ "@ohos.contact": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.contact"
+ ],
+ "@ohos.continuation.continuationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.continuation.continuationManager"
+ ],
+ "@ohos.cooperate": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.cooperate"
+ ],
+ "@ohos.curves": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.curves"
+ ],
+ "@ohos.customization.customConfig": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.customization.customConfig"
+ ],
+ "@ohos.data.DataShareResultSet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.DataShareResultSet"
+ ],
+ "@ohos.data.ValuesBucket": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.ValuesBucket"
+ ],
+ "@ohos.data.cloudData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.cloudData"
+ ],
+ "@ohos.data.cloudExtension": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.cloudExtension"
+ ],
+ "@ohos.data.commonType": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.commonType"
+ ],
+ "@ohos.data.dataAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.dataAbility"
+ ],
+ "@ohos.data.dataShare": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.dataShare"
+ ],
+ "@ohos.data.dataSharePredicates": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.dataSharePredicates"
+ ],
+ "@ohos.data.distributedData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.distributedData"
+ ],
+ "@ohos.data.distributedDataObject": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.distributedDataObject"
+ ],
+ "@ohos.data.distributedKVStore": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.distributedKVStore"
+ ],
+ "@ohos.data.preferences": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.preferences"
+ ],
+ "@ohos.data.rdb": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.rdb"
+ ],
+ "@ohos.data.relationalStore": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.relationalStore"
+ ],
+ "@ohos.data.sendablePreferences": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.sendablePreferences"
+ ],
+ "@ohos.data.sendableRelationalStore": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.sendableRelationalStore"
+ ],
+ "@ohos.data.storage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.storage"
+ ],
+ "@ohos.data.unifiedDataChannel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.unifiedDataChannel"
+ ],
+ "@ohos.data.uniformDataStruct": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.uniformDataStruct"
+ ],
+ "@ohos.data.uniformTypeDescriptor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.data.uniformTypeDescriptor"
+ ],
+ "@ohos.deviceAttest": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.deviceAttest"
+ ],
+ "@ohos.deviceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.deviceInfo"
+ ],
+ "@ohos.deviceStatus.dragInteraction": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.deviceStatus.dragInteraction"
+ ],
+ "@ohos.display": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.display"
+ ],
+ "@ohos.distributedBundle": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.distributedBundle"
+ ],
+ "@ohos.distributedDeviceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.distributedDeviceManager"
+ ],
+ "@ohos.distributedHardware.deviceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.distributedHardware.deviceManager"
+ ],
+ "@ohos.distributedHardware.hardwareManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.distributedHardware.hardwareManager"
+ ],
+ "@ohos.distributedMissionManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.distributedMissionManager"
+ ],
+ "@ohos.dlpPermission": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.dlpPermission"
+ ],
+ "@ohos.document": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.document"
+ ],
+ "@ohos.driver.deviceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.driver.deviceManager"
+ ],
+ "@ohos.effectKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.effectKit"
+ ],
+ "@ohos.enterprise.EnterpriseAdminExtensionAbility": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.EnterpriseAdminExtensionAbility"
+ ],
+ "@ohos.enterprise.accountManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.accountManager"
+ ],
+ "@ohos.enterprise.adminManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.adminManager"
+ ],
+ "@ohos.enterprise.applicationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.applicationManager"
+ ],
+ "@ohos.enterprise.bluetoothManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.bluetoothManager"
+ ],
+ "@ohos.enterprise.browser": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.browser"
+ ],
+ "@ohos.enterprise.bundleManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.bundleManager"
+ ],
+ "@ohos.enterprise.dateTimeManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.dateTimeManager"
+ ],
+ "@ohos.enterprise.deviceControl": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.deviceControl"
+ ],
+ "@ohos.enterprise.deviceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.deviceInfo"
+ ],
+ "@ohos.enterprise.deviceSettings": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.deviceSettings"
+ ],
+ "@ohos.enterprise.locationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.locationManager"
+ ],
+ "@ohos.enterprise.networkManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.networkManager"
+ ],
+ "@ohos.enterprise.restrictions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.restrictions"
+ ],
+ "@ohos.enterprise.securityManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.securityManager"
+ ],
+ "@ohos.enterprise.systemManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.systemManager"
+ ],
+ "@ohos.enterprise.usbManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.usbManager"
+ ],
+ "@ohos.enterprise.wifiManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.enterprise.wifiManager"
+ ],
+ "@ohos.events.emitter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.events.emitter"
+ ],
+ "@ohos.faultLogger": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.faultLogger"
+ ],
+ "@ohos.file.AlbumPickerComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.AlbumPickerComponent"
+ ],
+ "@ohos.file.BackupExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.BackupExtensionContext"
+ ],
+ "@ohos.file.PhotoPickerComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.PhotoPickerComponent"
+ ],
+ "@ohos.file.RecentPhotoComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.RecentPhotoComponent"
+ ],
+ "@ohos.file.backup": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.backup"
+ ],
+ "@ohos.file.cloudSync": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.cloudSync"
+ ],
+ "@ohos.file.cloudSyncManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.cloudSyncManager"
+ ],
+ "@ohos.file.environment": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.environment"
+ ],
+ "@ohos.file.fileAccess": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.fileAccess"
+ ],
+ "@ohos.file.fileExtensionInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.fileExtensionInfo"
+ ],
+ "@ohos.file.fileuri": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.fileuri"
+ ],
+ "@ohos.file.fs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.fs"
+ ],
+ "@ohos.file.hash": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.hash"
+ ],
+ "@ohos.file.photoAccessHelper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.photoAccessHelper"
+ ],
+ "@ohos.file.picker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.picker"
+ ],
+ "@ohos.file.recent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.recent"
+ ],
+ "@ohos.file.securityLabel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.securityLabel"
+ ],
+ "@ohos.file.sendablePhotoAccessHelper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.sendablePhotoAccessHelper"
+ ],
+ "@ohos.file.statvfs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.statvfs"
+ ],
+ "@ohos.file.storageStatistics": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.storageStatistics"
+ ],
+ "@ohos.file.trash": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.trash"
+ ],
+ "@ohos.file.volumeManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.file.volumeManager"
+ ],
+ "@ohos.fileio": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.fileio"
+ ],
+ "@ohos.filemanagement.userFileManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.filemanagement.userFileManager"
+ ],
+ "@ohos.fileshare": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.fileshare"
+ ],
+ "@ohos.font": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.font"
+ ],
+ "@ohos.geoLocationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.geoLocationManager"
+ ],
+ "@ohos.geolocation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.geolocation"
+ ],
+ "@ohos.graphics.colorSpaceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.colorSpaceManager"
+ ],
+ "@ohos.graphics.common2D": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.common2D"
+ ],
+ "@ohos.graphics.displaySync": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.displaySync"
+ ],
+ "@ohos.graphics.drawing": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.drawing"
+ ],
+ "@ohos.graphics.hdrCapability": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.hdrCapability"
+ ],
+ "@ohos.graphics.scene": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.scene"
+ ],
+ "@ohos.graphics.sendableColorSpaceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.sendableColorSpaceManager"
+ ],
+ "@ohos.graphics.text": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.text"
+ ],
+ "@ohos.graphics.uiEffect": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.graphics.uiEffect"
+ ],
+ "@ohos.hiAppEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiAppEvent"
+ ],
+ "@ohos.hiSysEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiSysEvent"
+ ],
+ "@ohos.hiTraceChain": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiTraceChain"
+ ],
+ "@ohos.hiTraceMeter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiTraceMeter"
+ ],
+ "@ohos.hichecker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hichecker"
+ ],
+ "@ohos.hidebug": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hidebug"
+ ],
+ "@ohos.hilog": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hilog"
+ ],
+ "@ohos.hiviewdfx.hiAppEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiviewdfx.hiAppEvent"
+ ],
+ "@ohos.hiviewdfx.jsLeakWatcher": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.hiviewdfx.jsLeakWatcher"
+ ],
+ "@ohos.i18n": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.i18n"
+ ],
+ "@ohos.identifier.oaid": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.identifier.oaid"
+ ],
+ "@ohos.inputMethod.Panel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.inputMethod.Panel"
+ ],
+ "@ohos.inputMethod": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.inputMethod"
+ ],
+ "@ohos.inputMethodEngine": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.inputMethodEngine"
+ ],
+ "@ohos.inputMethodList": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.inputMethodList"
+ ],
+ "@ohos.intl": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.intl"
+ ],
+ "@ohos.logLibrary": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.logLibrary"
+ ],
+ "@ohos.matrix4": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.matrix4"
+ ],
+ "@ohos.measure": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.measure"
+ ],
+ "@ohos.mediaquery": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.mediaquery"
+ ],
+ "@ohos.multimedia.audio": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.audio"
+ ],
+ "@ohos.multimedia.audioHaptic": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.audioHaptic"
+ ],
+ "@ohos.multimedia.avCastPicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.avCastPicker"
+ ],
+ "@ohos.multimedia.avCastPickerParam": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.avCastPickerParam"
+ ],
+ "@ohos.multimedia.avVolumePanel": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.avVolumePanel"
+ ],
+ "@ohos.multimedia.avsession": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.avsession"
+ ],
+ "@ohos.multimedia.camera": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.camera"
+ ],
+ "@ohos.multimedia.cameraPicker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.cameraPicker"
+ ],
+ "@ohos.multimedia.drm": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.drm"
+ ],
+ "@ohos.multimedia.image": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.image"
+ ],
+ "@ohos.multimedia.media": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.media"
+ ],
+ "@ohos.multimedia.movingphotoview": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.movingphotoview"
+ ],
+ "@ohos.multimedia.sendableImage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.sendableImage"
+ ],
+ "@ohos.multimedia.systemSoundManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimedia.systemSoundManager"
+ ],
+ "@ohos.multimodalInput.gestureEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.gestureEvent"
+ ],
+ "@ohos.multimodalInput.infraredEmitter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.infraredEmitter"
+ ],
+ "@ohos.multimodalInput.inputConsumer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputConsumer"
+ ],
+ "@ohos.multimodalInput.inputDevice": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputDevice"
+ ],
+ "@ohos.multimodalInput.inputDeviceCooperate": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputDeviceCooperate"
+ ],
+ "@ohos.multimodalInput.inputEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputEvent"
+ ],
+ "@ohos.multimodalInput.inputEventClient": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputEventClient"
+ ],
+ "@ohos.multimodalInput.inputMonitor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.inputMonitor"
+ ],
+ "@ohos.multimodalInput.intentionCode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.intentionCode"
+ ],
+ "@ohos.multimodalInput.keyCode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.keyCode"
+ ],
+ "@ohos.multimodalInput.keyEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.keyEvent"
+ ],
+ "@ohos.multimodalInput.mouseEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.mouseEvent"
+ ],
+ "@ohos.multimodalInput.pointer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.pointer"
+ ],
+ "@ohos.multimodalInput.shortKey": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.shortKey"
+ ],
+ "@ohos.multimodalInput.touchEvent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.multimodalInput.touchEvent"
+ ],
+ "@ohos.net.connection": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.connection"
+ ],
+ "@ohos.net.ethernet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.ethernet"
+ ],
+ "@ohos.net.http": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.http"
+ ],
+ "@ohos.net.mdns": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.mdns"
+ ],
+ "@ohos.net.netFirewall": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.netFirewall"
+ ],
+ "@ohos.net.networkSecurity": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.networkSecurity"
+ ],
+ "@ohos.net.policy": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.policy"
+ ],
+ "@ohos.net.sharing": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.sharing"
+ ],
+ "@ohos.net.socket": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.socket"
+ ],
+ "@ohos.net.statistics": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.statistics"
+ ],
+ "@ohos.net.vpn": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.vpn"
+ ],
+ "@ohos.net.vpnExtension": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.vpnExtension"
+ ],
+ "@ohos.net.webSocket": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.net.webSocket"
+ ],
+ "@ohos.nfc.cardEmulation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.nfc.cardEmulation"
+ ],
+ "@ohos.nfc.controller": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.nfc.controller"
+ ],
+ "@ohos.nfc.tag": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.nfc.tag"
+ ],
+ "@ohos.notification": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.notification"
+ ],
+ "@ohos.notificationManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.notificationManager"
+ ],
+ "@ohos.notificationSubscribe": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.notificationSubscribe"
+ ],
+ "@ohos.pasteboard": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.pasteboard"
+ ],
+ "@ohos.pluginComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.pluginComponent"
+ ],
+ "@ohos.power": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.power"
+ ],
+ "@ohos.print": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.print"
+ ],
+ "@ohos.privacyManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.privacyManager"
+ ],
+ "@ohos.prompt": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.prompt"
+ ],
+ "@ohos.promptAction": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.promptAction"
+ ],
+ "@ohos.reminderAgent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.reminderAgent"
+ ],
+ "@ohos.reminderAgentManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.reminderAgentManager"
+ ],
+ "@ohos.request": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.request"
+ ],
+ "@ohos.resourceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceManager"
+ ],
+ "@ohos.resourceschedule.backgroundTaskManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceschedule.backgroundTaskManager"
+ ],
+ "@ohos.resourceschedule.deviceStandby": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceschedule.deviceStandby"
+ ],
+ "@ohos.resourceschedule.systemload": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceschedule.systemload"
+ ],
+ "@ohos.resourceschedule.usageStatistics": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceschedule.usageStatistics"
+ ],
+ "@ohos.resourceschedule.workScheduler": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.resourceschedule.workScheduler"
+ ],
+ "@ohos.router": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.router"
+ ],
+ "@ohos.rpc": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.rpc"
+ ],
+ "@ohos.runningLock": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.runningLock"
+ ],
+ "@ohos.screen": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.screen"
+ ],
+ "@ohos.screenLock": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.screenLock"
+ ],
+ "@ohos.screenshot": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.screenshot"
+ ],
+ "@ohos.secureElement": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.secureElement"
+ ],
+ "@ohos.security.asset": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.asset"
+ ],
+ "@ohos.security.cert": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.cert"
+ ],
+ "@ohos.security.certManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.certManager"
+ ],
+ "@ohos.security.certManagerDialog": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.certManagerDialog"
+ ],
+ "@ohos.security.cryptoFramework": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.cryptoFramework"
+ ],
+ "@ohos.security.huks": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.huks"
+ ],
+ "@ohos.security.securityGuard": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.security.securityGuard"
+ ],
+ "@ohos.sendableResourceManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.sendableResourceManager"
+ ],
+ "@ohos.sensor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.sensor"
+ ],
+ "@ohos.settings": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.settings"
+ ],
+ "@ohos.statfs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.statfs"
+ ],
+ "@ohos.stationary": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.stationary"
+ ],
+ "@ohos.systemCapability": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemCapability"
+ ],
+ "@ohos.systemDateTime": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemDateTime"
+ ],
+ "@ohos.systemParameterEnhance": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemParameterEnhance"
+ ],
+ "@ohos.systemTime": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemTime"
+ ],
+ "@ohos.systemTimer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemTimer"
+ ],
+ "@ohos.systemparameter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.systemparameter"
+ ],
+ "@ohos.telephony.call": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.call"
+ ],
+ "@ohos.telephony.data": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.data"
+ ],
+ "@ohos.telephony.observer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.observer"
+ ],
+ "@ohos.telephony.radio": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.radio"
+ ],
+ "@ohos.telephony.sim": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.sim"
+ ],
+ "@ohos.telephony.sms": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.sms"
+ ],
+ "@ohos.telephony.vcard": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.telephony.vcard"
+ ],
+ "@ohos.thermal": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.thermal"
+ ],
+ "@ohos.uiAppearance": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.uiAppearance"
+ ],
+ "@ohos.uiExtensionHost": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.uiExtensionHost"
+ ],
+ "@ohos.update": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.update"
+ ],
+ "@ohos.uri": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.uri"
+ ],
+ "@ohos.url": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.url"
+ ],
+ "@ohos.usb": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.usb"
+ ],
+ "@ohos.usbManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.usbManager"
+ ],
+ "@ohos.userIAM.faceAuth": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.userIAM.faceAuth"
+ ],
+ "@ohos.userIAM.userAuth": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.userIAM.userAuth"
+ ],
+ "@ohos.userIAM.userAuthIcon": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.userIAM.userAuthIcon"
+ ],
+ "@ohos.util.ArrayList": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.ArrayList"
+ ],
+ "@ohos.util.Deque": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.Deque"
+ ],
+ "@ohos.util.HashMap": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.HashMap"
+ ],
+ "@ohos.util.HashSet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.HashSet"
+ ],
+ "@ohos.util.LightWeightMap": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.LightWeightMap"
+ ],
+ "@ohos.util.LightWeightSet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.LightWeightSet"
+ ],
+ "@ohos.util.LinkedList": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.LinkedList"
+ ],
+ "@ohos.util.List": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.List"
+ ],
+ "@ohos.util.PlainArray": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.PlainArray"
+ ],
+ "@ohos.util.Queue": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.Queue"
+ ],
+ "@ohos.util.Stack": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.Stack"
+ ],
+ "@ohos.util.TreeMap": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.TreeMap"
+ ],
+ "@ohos.util.TreeSet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.TreeSet"
+ ],
+ "@ohos.util": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util"
+ ],
+ "@ohos.util.json": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.json"
+ ],
+ "@ohos.util.stream": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.util.stream"
+ ],
+ "@ohos.vibrator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.vibrator"
+ ],
+ "@ohos.wallpaper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wallpaper"
+ ],
+ "@ohos.wantAgent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wantAgent"
+ ],
+ "@ohos.web.netErrorList": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.web.netErrorList"
+ ],
+ "@ohos.web.webview": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.web.webview"
+ ],
+ "@ohos.wifi": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wifi"
+ ],
+ "@ohos.wifiManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wifiManager"
+ ],
+ "@ohos.wifiManagerExt": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wifiManagerExt"
+ ],
+ "@ohos.wifiext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.wifiext"
+ ],
+ "@ohos.window": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.window"
+ ],
+ "@ohos.worker": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.worker"
+ ],
+ "@ohos.zlib": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@ohos.zlib"
+ ],
+ "@ohos.@system.app": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.app"
+ ],
+ "@ohos.@system.battery": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.battery"
+ ],
+ "@ohos.@system.bluetooth": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.bluetooth"
+ ],
+ "@ohos.@system.brightness": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.brightness"
+ ],
+ "@ohos.@system.cipher": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.cipher"
+ ],
+ "@ohos.@system.configuration": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.configuration"
+ ],
+ "@ohos.@system.device": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.device"
+ ],
+ "@ohos.@system.fetch": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.fetch"
+ ],
+ "@ohos.@system.file": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.file"
+ ],
+ "@ohos.@system.geolocation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.geolocation"
+ ],
+ "@ohos.@system.mediaquery": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.mediaquery"
+ ],
+ "@ohos.@system.network": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.network"
+ ],
+ "@ohos.@system.notification": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.notification"
+ ],
+ "@ohos.@system.package": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.package"
+ ],
+ "@ohos.@system.prompt": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.prompt"
+ ],
+ "@ohos.@system.request": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.request"
+ ],
+ "@ohos.@system.router": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.router"
+ ],
+ "@ohos.@system.sensor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.sensor"
+ ],
+ "@ohos.@system.storage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.storage"
+ ],
+ "@ohos.@system.vibrator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/@system.vibrator"
+ ],
+ "@ohos.ability.abilityResult": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/abilityResult"
+ ],
+ "@ohos.ability.connectOptions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/connectOptions"
+ ],
+ "@ohos.ability.dataAbilityHelper": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/dataAbilityHelper"
+ ],
+ "@ohos.ability.dataAbilityOperation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/dataAbilityOperation"
+ ],
+ "@ohos.ability.dataAbilityResult": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/dataAbilityResult"
+ ],
+ "@ohos.ability.startAbilityParameter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/startAbilityParameter"
+ ],
+ "@ohos.ability.want": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/ability/want"
+ ],
+ "@ohos.advertising.advertisement": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/advertising/advertisement"
+ ],
+ "@ohos.app.appVersionInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/app/appVersionInfo"
+ ],
+ "@ohos.app.context": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/app/context"
+ ],
+ "@ohos.app.processInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/app/processInfo"
+ ],
+ "@ohos.application.AbilityDelegator": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityDelegator"
+ ],
+ "@ohos.application.AbilityFirstFrameStateData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityFirstFrameStateData"
+ ],
+ "@ohos.application.AbilityFirstFrameStateObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityFirstFrameStateObserver"
+ ],
+ "@ohos.application.AbilityForegroundStateObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityForegroundStateObserver"
+ ],
+ "@ohos.application.AbilityMonitor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityMonitor"
+ ],
+ "@ohos.application.AbilityRunningInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityRunningInfo"
+ ],
+ "@ohos.application.AbilityStageContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityStageContext"
+ ],
+ "@ohos.application.AbilityStageMonitor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityStageMonitor"
+ ],
+ "@ohos.application.AbilityStartCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityStartCallback"
+ ],
+ "@ohos.application.AbilityStateData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AbilityStateData"
+ ],
+ "@ohos.application.AccessibilityExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AccessibilityExtensionContext"
+ ],
+ "@ohos.application.AppForegroundStateObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AppForegroundStateObserver"
+ ],
+ "@ohos.application.AppStateData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AppStateData"
+ ],
+ "@ohos.application.ApplicationContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ApplicationContext"
+ ],
+ "@ohos.application.ApplicationStateObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ApplicationStateObserver"
+ ],
+ "@ohos.application.AutoFillExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoFillExtensionContext"
+ ],
+ "@ohos.application.AutoFillPopupConfig": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoFillPopupConfig"
+ ],
+ "@ohos.application.AutoFillRect": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoFillRect"
+ ],
+ "@ohos.application.AutoFillRequest": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoFillRequest"
+ ],
+ "@ohos.application.AutoFillType": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoFillType"
+ ],
+ "@ohos.application.AutoStartupCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoStartupCallback"
+ ],
+ "@ohos.application.AutoStartupInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/AutoStartupInfo"
+ ],
+ "@ohos.application.BaseContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/BaseContext"
+ ],
+ "@ohos.application.BusinessAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/BusinessAbilityInfo"
+ ],
+ "@ohos.application.Context": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/Context"
+ ],
+ "@ohos.application.ContinuableInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ContinuableInfo"
+ ],
+ "@ohos.application.ContinueCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ContinueCallback"
+ ],
+ "@ohos.application.ContinueDeviceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ContinueDeviceInfo"
+ ],
+ "@ohos.application.ContinueMissionInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ContinueMissionInfo"
+ ],
+ "@ohos.application.CustomData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/CustomData"
+ ],
+ "@ohos.application.DriverExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/DriverExtensionContext"
+ ],
+ "@ohos.application.EmbeddableUIAbilityContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/EmbeddableUIAbilityContext"
+ ],
+ "@ohos.application.ErrorObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ErrorObserver"
+ ],
+ "@ohos.application.EventHub": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/EventHub"
+ ],
+ "@ohos.application.ExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ExtensionContext"
+ ],
+ "@ohos.application.ExtensionRunningInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ExtensionRunningInfo"
+ ],
+ "@ohos.application.FormExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/FormExtensionContext"
+ ],
+ "@ohos.application.LoopObserver": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/LoopObserver"
+ ],
+ "@ohos.application.MediaControlExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MediaControlExtensionContext"
+ ],
+ "@ohos.application.MissionCallbacks": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionCallbacks"
+ ],
+ "@ohos.application.MissionDeviceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionDeviceInfo"
+ ],
+ "@ohos.application.MissionInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionInfo"
+ ],
+ "@ohos.application.MissionListener": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionListener"
+ ],
+ "@ohos.application.MissionParameter": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionParameter"
+ ],
+ "@ohos.application.MissionSnapshot": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MissionSnapshot"
+ ],
+ "@ohos.application.MultiAppMode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/MultiAppMode"
+ ],
+ "@ohos.application.PageNodeInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/PageNodeInfo"
+ ],
+ "@ohos.application.PhotoEditorExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/PhotoEditorExtensionContext"
+ ],
+ "@ohos.application.ProcessData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ProcessData"
+ ],
+ "@ohos.application.ProcessInformation": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ProcessInformation"
+ ],
+ "@ohos.application.ProcessRunningInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ProcessRunningInfo"
+ ],
+ "@ohos.application.RunningAppClone": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/RunningAppClone"
+ ],
+ "@ohos.application.RunningMultiAppInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/RunningMultiAppInfo"
+ ],
+ "@ohos.application.RunningMultiInstanceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/RunningMultiInstanceInfo"
+ ],
+ "@ohos.application.SendableContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/SendableContext"
+ ],
+ "@ohos.application.ServiceExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ServiceExtensionContext"
+ ],
+ "@ohos.application.UIAbilityContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIAbilityContext"
+ ],
+ "@ohos.application.UIExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIExtensionContext"
+ ],
+ "@ohos.application.UIServiceExtensionConnectCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIServiceExtensionConnectCallback"
+ ],
+ "@ohos.application.UIServiceExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIServiceExtensionContext"
+ ],
+ "@ohos.application.UIServiceHostProxy": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIServiceHostProxy"
+ ],
+ "@ohos.application.UIServiceProxy": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/UIServiceProxy"
+ ],
+ "@ohos.application.ViewData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/ViewData"
+ ],
+ "@ohos.application.VpnExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/VpnExtensionContext"
+ ],
+ "@ohos.application.WindowExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/WindowExtensionContext"
+ ],
+ "@ohos.application.WorkSchedulerExtensionContext": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/WorkSchedulerExtensionContext"
+ ],
+ "@ohos.application.abilityDelegatorArgs": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/abilityDelegatorArgs"
+ ],
+ "@ohos.application.shellCmdResult": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/application/shellCmdResult"
+ ],
+ "@ohos.arkui.AlphabetIndexerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/AlphabetIndexerModifier"
+ ],
+ "@ohos.arkui.AttributeUpdater": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/AttributeUpdater"
+ ],
+ "@ohos.arkui.BlankModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/BlankModifier"
+ ],
+ "@ohos.arkui.BuilderNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/BuilderNode"
+ ],
+ "@ohos.arkui.ButtonModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ButtonModifier"
+ ],
+ "@ohos.arkui.CalendarPickerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/CalendarPickerModifier"
+ ],
+ "@ohos.arkui.CheckboxGroupModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/CheckboxGroupModifier"
+ ],
+ "@ohos.arkui.CheckboxModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/CheckboxModifier"
+ ],
+ "@ohos.arkui.ColumnModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ColumnModifier"
+ ],
+ "@ohos.arkui.ColumnSplitModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ColumnSplitModifier"
+ ],
+ "@ohos.arkui.CommonModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/CommonModifier"
+ ],
+ "@ohos.arkui.ComponentContent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ComponentContent"
+ ],
+ "@ohos.arkui.ContainerSpanModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ContainerSpanModifier"
+ ],
+ "@ohos.arkui.Content": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/Content"
+ ],
+ "@ohos.arkui.CounterModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/CounterModifier"
+ ],
+ "@ohos.arkui.DataPanelModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/DataPanelModifier"
+ ],
+ "@ohos.arkui.DatePickerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/DatePickerModifier"
+ ],
+ "@ohos.arkui.DividerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/DividerModifier"
+ ],
+ "@ohos.arkui.FormComponentModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/FormComponentModifier"
+ ],
+ "@ohos.arkui.FrameNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/FrameNode"
+ ],
+ "@ohos.arkui.GaugeModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/GaugeModifier"
+ ],
+ "@ohos.arkui.Graphics": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/Graphics"
+ ],
+ "@ohos.arkui.GridColModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/GridColModifier"
+ ],
+ "@ohos.arkui.GridItemModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/GridItemModifier"
+ ],
+ "@ohos.arkui.GridModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/GridModifier"
+ ],
+ "@ohos.arkui.GridRowModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/GridRowModifier"
+ ],
+ "@ohos.arkui.HyperlinkModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/HyperlinkModifier"
+ ],
+ "@ohos.arkui.ImageAnimatorModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ImageAnimatorModifier"
+ ],
+ "@ohos.arkui.ImageModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ImageModifier"
+ ],
+ "@ohos.arkui.ImageSpanModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ImageSpanModifier"
+ ],
+ "@ohos.arkui.LineModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/LineModifier"
+ ],
+ "@ohos.arkui.ListItemGroupModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ListItemGroupModifier"
+ ],
+ "@ohos.arkui.ListItemModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ListItemModifier"
+ ],
+ "@ohos.arkui.ListModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ListModifier"
+ ],
+ "@ohos.arkui.LoadingProgressModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/LoadingProgressModifier"
+ ],
+ "@ohos.arkui.MarqueeModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/MarqueeModifier"
+ ],
+ "@ohos.arkui.MenuItemModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/MenuItemModifier"
+ ],
+ "@ohos.arkui.MenuModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/MenuModifier"
+ ],
+ "@ohos.arkui.NavDestinationModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NavDestinationModifier"
+ ],
+ "@ohos.arkui.NavRouterModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NavRouterModifier"
+ ],
+ "@ohos.arkui.NavigationModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NavigationModifier"
+ ],
+ "@ohos.arkui.NavigatorModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NavigatorModifier"
+ ],
+ "@ohos.arkui.NodeContent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NodeContent"
+ ],
+ "@ohos.arkui.NodeController": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/NodeController"
+ ],
+ "@ohos.arkui.PanelModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/PanelModifier"
+ ],
+ "@ohos.arkui.ParticleModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ParticleModifier"
+ ],
+ "@ohos.arkui.PathModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/PathModifier"
+ ],
+ "@ohos.arkui.PatternLockModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/PatternLockModifier"
+ ],
+ "@ohos.arkui.PolygonModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/PolygonModifier"
+ ],
+ "@ohos.arkui.PolylineModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/PolylineModifier"
+ ],
+ "@ohos.arkui.ProgressModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ProgressModifier"
+ ],
+ "@ohos.arkui.QRCodeModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/QRCodeModifier"
+ ],
+ "@ohos.arkui.RadioModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RadioModifier"
+ ],
+ "@ohos.arkui.RatingModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RatingModifier"
+ ],
+ "@ohos.arkui.RectModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RectModifier"
+ ],
+ "@ohos.arkui.RefreshModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RefreshModifier"
+ ],
+ "@ohos.arkui.RenderNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RenderNode"
+ ],
+ "@ohos.arkui.RichEditorModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RichEditorModifier"
+ ],
+ "@ohos.arkui.RowModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RowModifier"
+ ],
+ "@ohos.arkui.RowSplitModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/RowSplitModifier"
+ ],
+ "@ohos.arkui.ScrollModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ScrollModifier"
+ ],
+ "@ohos.arkui.SearchModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SearchModifier"
+ ],
+ "@ohos.arkui.SelectModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SelectModifier"
+ ],
+ "@ohos.arkui.ShapeModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ShapeModifier"
+ ],
+ "@ohos.arkui.SideBarContainerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SideBarContainerModifier"
+ ],
+ "@ohos.arkui.SliderModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SliderModifier"
+ ],
+ "@ohos.arkui.SpanModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SpanModifier"
+ ],
+ "@ohos.arkui.StackModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/StackModifier"
+ ],
+ "@ohos.arkui.StepperItemModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/StepperItemModifier"
+ ],
+ "@ohos.arkui.SwiperModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SwiperModifier"
+ ],
+ "@ohos.arkui.SymbolGlyphModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SymbolGlyphModifier"
+ ],
+ "@ohos.arkui.SymbolSpanModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/SymbolSpanModifier"
+ ],
+ "@ohos.arkui.TabsModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TabsModifier"
+ ],
+ "@ohos.arkui.TextAreaModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextAreaModifier"
+ ],
+ "@ohos.arkui.TextClockModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextClockModifier"
+ ],
+ "@ohos.arkui.TextInputModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextInputModifier"
+ ],
+ "@ohos.arkui.TextModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextModifier"
+ ],
+ "@ohos.arkui.TextPickerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextPickerModifier"
+ ],
+ "@ohos.arkui.TextTimerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TextTimerModifier"
+ ],
+ "@ohos.arkui.TimePickerModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/TimePickerModifier"
+ ],
+ "@ohos.arkui.ToggleModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/ToggleModifier"
+ ],
+ "@ohos.arkui.VideoModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/VideoModifier"
+ ],
+ "@ohos.arkui.WaterFlowModifier": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/WaterFlowModifier"
+ ],
+ "@ohos.arkui.XComponentNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/XComponentNode"
+ ],
+ "@ohos.arkui.component.column": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/column"
+ ],
+ "@ohos.arkui.component.common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/common"
+ ],
+ "@ohos.arkui.component.customComponent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/customComponent"
+ ],
+ "@ohos.arkui.component.enums": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/enums"
+ ],
+ "@ohos.arkui.component.styledString": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/styledString"
+ ],
+ "@ohos.arkui.component.text": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/text"
+ ],
+ "@ohos.arkui.component.units": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/component/units"
+ ],
+ "@ohos.arkui.external.resource": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/external/resource"
+ ],
+ "@koalaui.arkts-arkui.Button": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.Button"
+ ],
+ "@koalaui.arkts-arkui.Column": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.Column"
+ ],
+ "@koalaui.arkts-arkui.Common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.Common"
+ ],
+ "@koalaui.arkts-arkui.StructBase": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.StructBase"
+ ],
+ "@koalaui.arkts-arkui.Text": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.Text"
+ ],
+ "@koalaui.arkts-arkui.UserView": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.arkts-arkui.UserView"
+ ],
+ "@koalaui.runtime.annotations": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.annotations"
+ ],
+ "@koalaui.runtime.common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.common"
+ ],
+ "@koalaui.runtime.internals": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.internals"
+ ],
+ "@koalaui.runtime.memo.bind": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.bind"
+ ],
+ "@koalaui.runtime.memo.changeListener": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.changeListener"
+ ],
+ "@koalaui.runtime.memo.contextLocal": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.contextLocal"
+ ],
+ "@koalaui.runtime.memo.entry": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.entry"
+ ],
+ "@koalaui.runtime.memo.node": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.node"
+ ],
+ "@koalaui.runtime.memo.remember": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.remember"
+ ],
+ "@koalaui.runtime.memo.repeat": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.repeat"
+ ],
+ "@koalaui.runtime.memo.testing": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.memo.testing"
+ ],
+ "@koalaui.runtime.states.Disposable": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.states.Disposable"
+ ],
+ "@koalaui.runtime.states.GlobalStateManager": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.states.GlobalStateManager"
+ ],
+ "@koalaui.runtime.states.State": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.states.State"
+ ],
+ "@koalaui.runtime.tree.IncrementalNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.tree.IncrementalNode"
+ ],
+ "@koalaui.runtime.tree.PrimeNumbers": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.tree.PrimeNumbers"
+ ],
+ "@koalaui.runtime.tree.ReadonlyTreeNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.tree.ReadonlyTreeNode"
+ ],
+ "@koalaui.runtime.tree.TreeNode": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.tree.TreeNode"
+ ],
+ "@koalaui.runtime.tree.TreePath": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/runtime-api/@koalaui.runtime.tree.TreePath"
+ ],
+ "@ohos.arkui.stateManagement.common": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/stateManagement/common"
+ ],
+ "@ohos.arkui.stateManagement.runtime": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/stateManagement/runtime"
+ ],
+ "@ohos.arkui.stateManagement.storage": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/arkui/stateManagement/storage"
+ ],
+ "@ohos.bundle.PermissionDef": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/PermissionDef"
+ ],
+ "@ohos.bundle.abilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/abilityInfo"
+ ],
+ "@ohos.bundle.applicationInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/applicationInfo"
+ ],
+ "@ohos.bundle.bundleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/bundleInfo"
+ ],
+ "@ohos.bundle.bundleInstaller": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/bundleInstaller"
+ ],
+ "@ohos.bundle.bundleStatusCallback": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/bundleStatusCallback"
+ ],
+ "@ohos.bundle.customizeData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/customizeData"
+ ],
+ "@ohos.bundle.elementName": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/elementName"
+ ],
+ "@ohos.bundle.hapModuleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/hapModuleInfo"
+ ],
+ "@ohos.bundle.launcherAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/launcherAbilityInfo"
+ ],
+ "@ohos.bundle.moduleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/moduleInfo"
+ ],
+ "@ohos.bundle.remoteAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/remoteAbilityInfo"
+ ],
+ "@ohos.bundle.shortcutInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundle/shortcutInfo"
+ ],
+ "@ohos.bundleManager.AbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/AbilityInfo"
+ ],
+ "@ohos.bundleManager.AppProvisionInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/AppProvisionInfo"
+ ],
+ "@ohos.bundleManager.ApplicationInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/ApplicationInfo"
+ ],
+ "@ohos.bundleManager.BundleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/BundleInfo"
+ ],
+ "@ohos.bundleManager.BundlePackInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/BundlePackInfo"
+ ],
+ "@ohos.bundleManager.BundleResourceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/BundleResourceInfo"
+ ],
+ "@ohos.bundleManager.DispatchInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/DispatchInfo"
+ ],
+ "@ohos.bundleManager.ElementName": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/ElementName"
+ ],
+ "@ohos.bundleManager.ExtensionAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/ExtensionAbilityInfo"
+ ],
+ "@ohos.bundleManager.HapModuleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/HapModuleInfo"
+ ],
+ "@ohos.bundleManager.LauncherAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/LauncherAbilityInfo"
+ ],
+ "@ohos.bundleManager.LauncherAbilityResourceInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/LauncherAbilityResourceInfo"
+ ],
+ "@ohos.bundleManager.Metadata": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/Metadata"
+ ],
+ "@ohos.bundleManager.OverlayModuleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/OverlayModuleInfo"
+ ],
+ "@ohos.bundleManager.PermissionDef": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/PermissionDef"
+ ],
+ "@ohos.bundleManager.RecoverableApplicationInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/RecoverableApplicationInfo"
+ ],
+ "@ohos.bundleManager.RemoteAbilityInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/RemoteAbilityInfo"
+ ],
+ "@ohos.bundleManager.SharedBundleInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/SharedBundleInfo"
+ ],
+ "@ohos.bundleManager.ShortcutInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/ShortcutInfo"
+ ],
+ "@ohos.bundleManager.Skill": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/bundleManager/Skill"
+ ],
+ "@ohos.commonEvent.commonEventData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/commonEvent/commonEventData"
+ ],
+ "@ohos.commonEvent.commonEventPublishData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/commonEvent/commonEventPublishData"
+ ],
+ "@ohos.commonEvent.commonEventSubscribeInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/commonEvent/commonEventSubscribeInfo"
+ ],
+ "@ohos.commonEvent.commonEventSubscriber": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/commonEvent/commonEventSubscriber"
+ ],
+ "@ohos.continuation.continuationExtraParams": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/continuation/continuationExtraParams"
+ ],
+ "@ohos.continuation.continuationResult": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/continuation/continuationResult"
+ ],
+ "@ohos.data.rdb.resultSet": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/data/rdb/resultSet"
+ ],
+ "@ohos.device-define.default.json": [
+ ""
+ ],
+ "@ohos.device-define.liteWearable.json": [
+ ""
+ ],
+ "@ohos.device-define.tablet.json": [
+ ""
+ ],
+ "@ohos.device-define.wearable.json": [
+ ""
+ ],
+ "@ohos.global.rawFileDescriptor": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/global/rawFileDescriptor"
+ ],
+ "@ohos.global.resource": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/global/resource"
+ ],
+ "@ohos.global.sendableResource": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/global/sendableResource"
+ ],
+ "@ohos.graphics3d.Scene": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/graphics3d/Scene"
+ ],
+ "@ohos.graphics3d.SceneNodes": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/graphics3d/SceneNodes"
+ ],
+ "@ohos.graphics3d.ScenePostProcessSettings": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/graphics3d/ScenePostProcessSettings"
+ ],
+ "@ohos.graphics3d.SceneResources": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/graphics3d/SceneResources"
+ ],
+ "@ohos.graphics3d.SceneTypes": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/graphics3d/SceneTypes"
+ ],
+ "@ohos.multimedia.ringtonePlayer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/multimedia/ringtonePlayer"
+ ],
+ "@ohos.multimedia.soundPool": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/multimedia/soundPool"
+ ],
+ "@ohos.multimedia.systemTonePlayer": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/multimedia/systemTonePlayer"
+ ],
+ "@ohos.notification.NotificationCommonDef": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/NotificationCommonDef"
+ ],
+ "@ohos.notification.notificationActionButton": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationActionButton"
+ ],
+ "@ohos.notification.notificationContent": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationContent"
+ ],
+ "@ohos.notification.notificationFlags": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationFlags"
+ ],
+ "@ohos.notification.notificationRequest": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationRequest"
+ ],
+ "@ohos.notification.notificationSlot": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationSlot"
+ ],
+ "@ohos.notification.notificationSorting": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationSorting"
+ ],
+ "@ohos.notification.notificationSortingMap": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationSortingMap"
+ ],
+ "@ohos.notification.notificationSubscribeInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationSubscribeInfo"
+ ],
+ "@ohos.notification.notificationSubscriber": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationSubscriber"
+ ],
+ "@ohos.notification.notificationTemplate": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationTemplate"
+ ],
+ "@ohos.notification.notificationUserInput": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/notification/notificationUserInput"
+ ],
+ "@ohos.permissions": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/permissions"
+ ],
+ "@ohos.security.PermissionRequestResult": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/security/PermissionRequestResult"
+ ],
+ "@ohos.tag.nfctech": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/tag/nfctech"
+ ],
+ "@ohos.tag.tagSession": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/tag/tagSession"
+ ],
+ "@ohos.wantAgent.triggerInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/wantAgent/triggerInfo"
+ ],
+ "@ohos.wantAgent.wantAgentInfo": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/api/wantAgent/wantAgentInfo"
+ ],
+ "@ohos.@arkts.collections": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/arkts/@arkts.collections"
+ ],
+ "@ohos.@arkts.lang": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/arkts/@arkts.lang"
+ ],
+ "@ohos.@arkts.math.Decimal": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/arkts/@arkts.math.Decimal"
+ ],
+ "@ohos.@arkts.utils": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/arkts/@arkts.utils"
+ ],
+ "@ohos.@kit.AVSessionKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AVSessionKit"
+ ],
+ "@ohos.@kit.AbilityKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AbilityKit"
+ ],
+ "@ohos.@kit.AccessibilityKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AccessibilityKit"
+ ],
+ "@ohos.@kit.AdsKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AdsKit"
+ ],
+ "@ohos.@kit.ArkData": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkData"
+ ],
+ "@ohos.@kit.ArkGraphics2D": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkGraphics2D"
+ ],
+ "@ohos.@kit.ArkGraphics3D": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkGraphics3D"
+ ],
+ "@ohos.@kit.ArkTS": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkTS"
+ ],
+ "@ohos.@kit.ArkUI": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkUI"
+ ],
+ "@ohos.@kit.ArkWeb": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ArkWeb"
+ ],
+ "@ohos.@kit.AssetStoreKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AssetStoreKit"
+ ],
+ "@ohos.@kit.AudioKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.AudioKit"
+ ],
+ "@ohos.@kit.BackgroundTasksKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.BackgroundTasksKit"
+ ],
+ "@ohos.@kit.BasicServicesKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.BasicServicesKit"
+ ],
+ "@ohos.@kit.CalendarKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.CalendarKit"
+ ],
+ "@ohos.@kit.CameraKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.CameraKit"
+ ],
+ "@ohos.@kit.ConnectivityKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ConnectivityKit"
+ ],
+ "@ohos.@kit.ContactsKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ContactsKit"
+ ],
+ "@ohos.@kit.CoreFileKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.CoreFileKit"
+ ],
+ "@ohos.@kit.CryptoArchitectureKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.CryptoArchitectureKit"
+ ],
+ "@ohos.@kit.DataLossPreventionKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DataLossPreventionKit"
+ ],
+ "@ohos.@kit.DataProtectionKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DataProtectionKit"
+ ],
+ "@ohos.@kit.DeviceCertificateKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DeviceCertificateKit"
+ ],
+ "@ohos.@kit.DistributedServiceKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DistributedServiceKit"
+ ],
+ "@ohos.@kit.DriverDevelopmentKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DriverDevelopmentKit"
+ ],
+ "@ohos.@kit.DrmKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.DrmKit"
+ ],
+ "@ohos.@kit.FormKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.FormKit"
+ ],
+ "@ohos.@kit.IMEKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.IMEKit"
+ ],
+ "@ohos.@kit.IPCKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.IPCKit"
+ ],
+ "@ohos.@kit.ImageKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.ImageKit"
+ ],
+ "@ohos.@kit.InputKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.InputKit"
+ ],
+ "@ohos.@kit.LocalizationKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.LocalizationKit"
+ ],
+ "@ohos.@kit.LocationKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.LocationKit"
+ ],
+ "@ohos.@kit.MDMKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.MDMKit"
+ ],
+ "@ohos.@kit.MediaKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.MediaKit"
+ ],
+ "@ohos.@kit.MediaLibraryKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.MediaLibraryKit"
+ ],
+ "@ohos.@kit.MindSporeLiteKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.MindSporeLiteKit"
+ ],
+ "@ohos.@kit.MultimodalAwarenessKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.MultimodalAwarenessKit"
+ ],
+ "@ohos.@kit.NetworkKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.NetworkKit"
+ ],
+ "@ohos.@kit.NotificationKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.NotificationKit"
+ ],
+ "@ohos.@kit.PerformanceAnalysisKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.PerformanceAnalysisKit"
+ ],
+ "@ohos.@kit.SecurityGuardKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.SecurityGuardKit"
+ ],
+ "@ohos.@kit.SensorServiceKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.SensorServiceKit"
+ ],
+ "@ohos.@kit.TelephonyKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.TelephonyKit"
+ ],
+ "@ohos.@kit.TestKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.TestKit"
+ ],
+ "@ohos.@kit.UniversalKeystoreKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.UniversalKeystoreKit"
+ ],
+ "@ohos.@kit.UserAuthenticationKit": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.UserAuthenticationKit"
+ ],
+ "@ohos.@kit.network": [
+ "workspace/out/sdk/ohos-sdk/linux/ets/ets1.2/kits/@kit.network"
+ ]
+ },
+ "entry": "",
+ "dynamicPaths": {}
+ }
+}
\ No newline at end of file
diff --git a/arkui-plugins/test/demo/interop/builder_interop.ets b/arkui-plugins/test/demo/interop/builder_interop.ets
new file mode 100644
index 0000000000000000000000000000000000000000..85fed0d237feac5e68ac419d2bb54185eb832a5f
--- /dev/null
+++ b/arkui-plugins/test/demo/interop/builder_interop.ets
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+
+// ArkTS1.2
+'use static'
+import { Entry, Text, Column, Component, Button, ClickEvent } from '@ohos.arkui.component'
+import { State } from '@ohos.arkui.stateManagement'
+import hilog from '@ohos.hilog'
+import { demoBuilder1_1 } from 'har1'
+
+@Entry
+@Component
+struct MyStateSample {
+ @State stateVar: string = 'state var';
+ message: string = 'var';
+
+ build() {
+ Column(undefined) {
+ Text('Hello World').fontSize(20)
+ Button(this.message).backgroundColor('#FFFF00FF')
+ .onClick((e: ClickEvent) => {
+ hilog.info(0x0000, 'testTag', 'On Click');
+ })
+ Text(this.stateVar).fontSize(20)
+ demoBuilder1_1({ a:"a23", b:this.stateVar})
+ }
+ }
+}
+
+
+//ArkT1.1
+@Builder
+export function demoBuilder1_1( param1:aa) {
+
+}
+export class aa {
+ a:string = ''
+ b:string = ''
+}
+
+
+//transform 1.1 Builder to compatibleComponent
+
+compatibleComponent((() => {
+ let global = ESValue.getGlobal();
+ let viewStackProcessor = global.getProperty("ViewStackProcessor");
+ let createId = viewStackProcessor.getProperty("AllocateNewElmetIdForNextComponent");
+ let elmtId = createId.invoke();
+ let createCompatibleNode = global.getProperty("createCompatibleNodeWithFunc");
+ let paramObject0 = ESValue.instantiateEmptyObject();
+ paramObject0.setProperty("a", ESValue.wrap("a23"));
+ paramObject0.setProperty("b", ESValue.wrap(this.stateVar));
+ let component = createCompatibleNode.invoke(ESValue.wrap(demoBuilder1_1), elmtId, paramObject0);
+ let viewPUCreate = global.getProperty("viewPUCreate");
+ viewPUCreate.invoke(component);
+ return {
+ component: component,
+ name: "demoBuilder1_1",
+ };
+}), ((instance: ESValue) => {
+ let param = instance.getProperty("arg1");
+ param.setProperty("a", ESValue.wrap("a23"));
+ param.setProperty("b", ESValue.wrap(this.stateVar));
+ let global = ESValue.getGlobal();
+ let runPendingJobs = global.getProperty("runPendingJobs");
+ runPendingJobs.invoke();
+}));
diff --git a/arkui-plugins/test/demo/interop/link_link_interop.ets b/arkui-plugins/test/demo/interop/link_link_interop.ets
new file mode 100644
index 0000000000000000000000000000000000000000..e5d5f8b47edd55d7d01c159e17e8b08ce229b646
--- /dev/null
+++ b/arkui-plugins/test/demo/interop/link_link_interop.ets
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+
+// ArkTS1.2
+import { memo, __memo_context_type, __memo_id_type } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins
+import { ArkUICompatible, InteropComponent, Text, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView, } from "@ohos.arkui.component" // TextAttribute should be insert by ui-plugins
+import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy, Observed, Track, Provide, Consume } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins
+import { MyText } from 'har2/src/main/ets/components/MainPage'
+import { Child1 } from 'har1'
+
+
+@Component
+struct MyStateSample {
+ @State stateVar: new MyText();
+ build() {
+ Column() {
+ Button(this.stateVar.text)
+ .onClick((e: ClickEvent) => {
+ this.stateVar.text += '~';
+ })
+ Child({stateVar: this.stateVar})
+ }
+ }
+}
+
+@Component
+struct Child {
+ @Link stateVar;
+ build() {
+ Column() {
+ Button(this.stateVar.text)
+ .onClick((e: ClickEvent) => {
+ this.stateVar.text += '~';
+ })
+ Child1({stateVar: this.stateVar, text: this.stateVar})
+ }
+ }
+}
+
+class MyText {
+ text: string = 'MyText';
+}
+
+
+//ArkT1.1
+import { MyText } from 'har2/src/main/ets/components/MainPage'
+
+@Component
+export struct Child1{
+ @Link stateVar: MyText;
+ @Link text: MyText;
+ build() {
+ Column() {
+ Button(this.stateVar.text)
+ .onClick(() => {
+ this.stateVar.text += '~';
+ })
+ Button(this.text.text)
+ .onClick(() => {
+ this.text.text = 'ArkTS1.1';
+ })
+ }
+ }
+}
+
+
+//transform 1.1struct 'Child1' to ArkUICompatible
+
+ArkUICompatible(__memo_context, ((__memo_id) + (252133223)), (() => {
+ let global = ESValue.getGlobal();
+ let param = ESValue.instantiateEmptyObject();
+ let createState = global.getProperty("createStateVariable");
+ let stateVar_SetSource = ((value: MyText) => {
+ (this).stateVar = value;
+ });
+ let stateVar_ProxyState = createState.invoke(ESValue.wrap((this).stateVar), ESValue.wrap(stateVar_SetSource));
+ (this).__backing_stateVar!.setProxy(stateVar_ProxyState);
+ let stateVar_SetProxy = ((value: MyText) => {
+ stateVar_ProxyState.invokeMethod("set", ESValue.wrap(value));
+ });
+ (this).__backing_stateVar!.setProxyValue = stateVar_SetProxy;
+ let stateVar_NotifyCallback = ((propertyName: string) => {
+ stateVar_ProxyState.invokeMethod("notifyPropertyHasChangedPU");
+ });
+ (this).__backing_stateVar!.setNotifyCallback(stateVar_NotifyCallback);
+ param.setProperty("stateVar", stateVar_ProxyState);
+ param.setProperty("text", stateVar_ProxyState);
+ let extraInfo = ESValue.instantiateEmptyObject();
+ extraInfo.setProperty("page", "har1/src/main/ets/components/MainPage");
+ let esundefined = ESValue.wrap(undefined);
+ let blank = (() => {});
+ let esblank = ESValue.wrap((blank as object));
+ let viewStackProcessor = global.getProperty("ViewStackProcessor");
+ let createId = viewStackProcessor.getProperty("AllocateNewElmetIdForNextComponent");
+ let elmtId = createId.invoke();
+ let har1 = ESValue.load("@normalized:N&entry&com.example.Interop2use1&har1/src/main/ets/components/MainPage&1.0.0");
+ let structObject = har1.getProperty("Child1");
+ let component = structObject.instantiate(esundefined, param, esundefined, elmtId, esblank, extraInfo);
+ let create = structObject.getProperty("create");
+ create.invoke(component);
+ return {
+ component: component,
+ name: "Child1",
+ };
+}), ((instance: ESValue) => {}));
\ No newline at end of file
diff --git a/arkui-plugins/test/demo/interop/provide_consume_interop.ets b/arkui-plugins/test/demo/interop/provide_consume_interop.ets
new file mode 100644
index 0000000000000000000000000000000000000000..48076c7918884869ca94f1c051360dcf7a448c9b
--- /dev/null
+++ b/arkui-plugins/test/demo/interop/provide_consume_interop.ets
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+
+// ArkTS1.2
+import { memo, __memo_context_type, __memo_id_type } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins
+import { ArkUICompatible, InteropComponent, Text, TextAttribute, Column, Component, Button, ButtonAttribute, ClickEvent, UserView, } from "@ohos.arkui.component" // TextAttribute should be insert by ui-plugins
+import { State, StateDecoratedVariable, MutableState, stateOf, observableProxy, Observed, Track, Provide, Consume } from "@ohos.arkui.stateManagement" // should be insert by ui-plugins
+import { MyText } from 'har2/src/main/ets/components/MainPage'
+import { Child1 } from 'har1'
+
+
+@Component
+struct MyStateSample {
+ @Provide stateVar: MyText = new MyText();
+ build() {
+ Column() {
+ Button(this.stateVar.text)
+ .onClick((e: ClickEvent) => {
+ this.stateVar.text += '~';
+ })
+ Child1()
+ }
+ }
+}
+
+class MyText {
+ text: string = 'MyText';
+}
+
+
+//ArkT1.1
+import { MyText } from 'har2/src/main/ets/components/MainPage'
+
+@Component
+export struct Child1{
+ @Consume stateVar: MyText;
+ build() {
+ Column() {
+ Button(this.stateVar.text)
+ .onClick(() => {
+ this.stateVar.text += '~';
+ })
+ }
+ }
+}
+
+
+
+//transform 1.1struct 'Child1' to ArkUICompatible
+
+ArkUICompatible(__memo_context, ((__memo_id) + (252133223)), (() => {
+ let global = ESValue.getGlobal();
+ let param = ESValue.instantiateEmptyObject();
+ let createState = global.getProperty("createStateVariable");
+ let setFindProvideInterop = global.getProperty("setFindProvideInterop");
+ let findProvideInterop = ((providedPropName: string): Object => {
+ let provide = (this).findProvide