• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# coding=utf-8
2#
3# Copyright (c) 2025 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from enum import Enum
17from json import dumps
18
19from taihe.codegen.abi.analyses import (
20    IfaceABIInfo,
21)
22from taihe.codegen.ani.analyses import (
23    EnumANIInfo,
24    GlobFuncANIInfo,
25    IfaceANIInfo,
26    IfaceMethodANIInfo,
27    Namespace,
28    PackageGroupANIInfo,
29    StructANIInfo,
30    StructFieldANIInfo,
31    TypeANIInfo,
32    UnionANIInfo,
33    UnionFieldANIInfo,
34)
35from taihe.codegen.ani.writer import StsWriter
36from taihe.semantics.declarations import (
37    EnumDecl,
38    GlobFuncDecl,
39    IfaceDecl,
40    IfaceMethodDecl,
41    PackageDecl,
42    PackageGroup,
43    StructDecl,
44    UnionDecl,
45)
46from taihe.semantics.types import Type
47from taihe.utils.analyses import AnalysisManager
48from taihe.utils.outputs import FileKind, OutputManager
49
50
51class FuncKind(Enum):
52    GLOBAL = "export function "
53    STATIC = "static "
54    INTERFACE = ""
55
56
57class STSCodeGenerator:
58    def __init__(self, om: OutputManager, am: AnalysisManager):
59        self.om = om
60        self.am = am
61
62    def generate(self, pg: PackageGroup):
63        pg_ani_info = PackageGroupANIInfo.get(self.am, pg)
64        self.gen_ohos_base()
65        for module, ns in pg_ani_info.module_dict.items():
66            self.gen_module_file(module, ns)
67
68    def gen_module_file(self, module: str, ns: Namespace):
69        with StsWriter(
70            self.om,
71            f"{module}.ets",
72            FileKind.ETS,
73        ) as target:
74            target.add_import_decl("@ohos.base", "AsyncCallback")
75            target.add_import_decl("@ohos.base", "BusinessError")
76            self.gen_namespace(ns, target)
77            self.gen_utils(target)
78
79    def gen_namespace(self, ns: Namespace, target: StsWriter):
80        for head in ns.injected_heads:
81            target.write_block(head)
82        for code in ns.injected_codes:
83            target.write_block(code)
84        for pkg in ns.packages:
85            self.gen_package(pkg, target)
86        for child_ns_name, child_ns in ns.children.items():
87            sts_decl = f"namespace {child_ns_name}"
88            if child_ns.is_default:
89                sts_decl = f"export default {sts_decl}"
90            else:
91                sts_decl = f"export {sts_decl}"
92            with target.indented(
93                f"{sts_decl} {{",
94                f"}}",
95            ):
96                self.gen_namespace(child_ns, target)
97
98    def stat_on_off_funcs(
99        self,
100        funcs: list[GlobFuncDecl],
101    ):
102        glob_func_on_off_map: dict[
103            tuple[str, tuple[str, ...]],
104            list[tuple[str, GlobFuncDecl]],
105        ] = {}
106        for func in funcs:
107            func_ani_info = GlobFuncANIInfo.get(self.am, func)
108            if func_ani_info.sts_func_name is None:
109                continue
110            if func_ani_info.on_off_type is None:
111                continue
112            func_name = func_ani_info.sts_func_name
113            type_name = func_ani_info.on_off_type
114            sts_params_ty: list[str] = []
115            for sts_param in func_ani_info.sts_params:
116                ty_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
117                sts_params_ty.append(ty_ani_info.type_desc)
118            glob_func_on_off_map.setdefault(
119                (func_name, tuple(sts_params_ty)), []
120            ).append((type_name, func))
121        return glob_func_on_off_map
122
123    def stat_good_on_off_funcs(
124        self,
125        funcs: list[GlobFuncDecl],
126    ):
127        on_off_funcs = self.stat_on_off_funcs(funcs)
128        return [
129            (method_name, type_name, method)
130            for (method_name, _), method_list in on_off_funcs.items()
131            if len(method_list) == 1
132            for type_name, method in method_list
133        ]
134
135    def stat_bad_on_off_funcs(
136        self,
137        funcs: list[GlobFuncDecl],
138    ):
139        on_off_funcs = self.stat_on_off_funcs(funcs)
140        bad_on_off_funcs: dict[str, list[tuple[str, GlobFuncDecl]]] = {}
141        for (method_name, _), method_list in on_off_funcs.items():
142            if len(method_list) <= 1:
143                continue
144            for type_name, method in method_list:
145                bad_on_off_funcs.setdefault(method_name, []).append((type_name, method))
146        return bad_on_off_funcs
147
148    def stat_on_off_methods(
149        self,
150        methods: list[IfaceMethodDecl],
151    ):
152        method_on_off_map: dict[
153            tuple[str, tuple[str, ...]],
154            list[tuple[str, IfaceMethodDecl]],
155        ] = {}
156        for method in methods:
157            method_ani_info = IfaceMethodANIInfo.get(self.am, method)
158            if method_ani_info.sts_method_name is None:
159                continue
160            if method_ani_info.on_off_type is None:
161                continue
162            method_name = method_ani_info.sts_method_name
163            type_name = method_ani_info.on_off_type
164            sts_params_ty: list[str] = []
165            for sts_param in method_ani_info.sts_params:
166                ty_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
167                sts_params_ty.append(ty_ani_info.type_desc)
168            method_on_off_map.setdefault(
169                (method_name, tuple(sts_params_ty)), []
170            ).append((type_name, method))
171        return method_on_off_map
172
173    def stat_good_on_off_methods(
174        self,
175        methods: list[IfaceMethodDecl],
176    ):
177        on_off_methods = self.stat_on_off_methods(methods)
178        return [
179            (method_name, type_name, method)
180            for (method_name, _), method_list in on_off_methods.items()
181            if len(method_list) == 1
182            for type_name, method in method_list
183        ]
184
185    def stat_bad_on_off_methods(
186        self,
187        methods: list[IfaceMethodDecl],
188    ):
189        on_off_methods = self.stat_on_off_methods(methods)
190        bad_on_off_methods: dict[str, list[tuple[str, IfaceMethodDecl]]] = {}
191        for (method_name, _), method_list in on_off_methods.items():
192            if len(method_list) <= 1:
193                continue
194            for type_name, method in method_list:
195                bad_on_off_methods.setdefault(method_name, []).append(
196                    (type_name, method)
197                )
198        return bad_on_off_methods
199
200    def gen_package(self, pkg: PackageDecl, target: StsWriter):
201        self.gen_native_funcs(pkg.functions, target)
202        ctors_map: dict[str, list[GlobFuncDecl]] = {}
203        statics_map: dict[str, list[GlobFuncDecl]] = {}
204        funcs: list[GlobFuncDecl] = []
205        for func in pkg.functions:
206            func_ani_info = GlobFuncANIInfo.get(self.am, func)
207            if class_name := func_ani_info.sts_static_scope:
208                statics_map.setdefault(class_name, []).append(func)
209            elif class_name := func_ani_info.sts_ctor_scope:
210                ctors_map.setdefault(class_name, []).append(func)
211            else:
212                funcs.append(func)
213        self.gen_global_funcs(funcs, target)
214        for enum in pkg.enums:
215            self.gen_enum(enum, target)
216        for union in pkg.unions:
217            self.gen_union(union, target)
218        for struct in pkg.structs:
219            self.gen_struct_interface(struct, target)
220        for struct in pkg.structs:
221            self.gen_struct_class(struct, target)
222        for iface in pkg.interfaces:
223            self.gen_iface_interface(iface, target)
224        for iface in pkg.interfaces:
225            self.gen_iface_class(iface, target, statics_map, ctors_map)
226
227    def gen_native_funcs(
228        self,
229        funcs: list[GlobFuncDecl],
230        target: StsWriter,
231    ):
232        # native funcs
233        for func in funcs:
234            func_ani_info = GlobFuncANIInfo.get(self.am, func)
235            sts_native_params = []
236            for param in func.params:
237                type_ani_info = TypeANIInfo.get(self.am, param.ty_ref.resolved_ty)
238                sts_native_params.append(
239                    f"{param.name}: {type_ani_info.sts_type_in(target)}"
240                )
241            sts_native_params_str = ", ".join(sts_native_params)
242            if return_ty_ref := func.return_ty_ref:
243                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
244                sts_return_ty_name = type_ani_info.sts_type_in(target)
245            else:
246                sts_return_ty_name = "void"
247            target.writelns(
248                f"native function {func_ani_info.sts_native_name}({sts_native_params_str}): {sts_return_ty_name};",
249            )
250
251    def gen_global_funcs(
252        self,
253        funcs: list[GlobFuncDecl],
254        target: StsWriter,
255    ):
256        self.gen_global_good_on_off_funcs(funcs, target)
257        self.gen_global_bad_on_off_funcs(funcs, target)
258        self.gen_global_regular_funcs(funcs, target)
259
260    def gen_global_good_on_off_funcs(
261        self,
262        funcs: list[GlobFuncDecl],
263        target: StsWriter,
264    ):
265        good_on_off_funcs = self.stat_good_on_off_funcs(funcs)
266        for func_name, type_name, func in good_on_off_funcs:
267            func_ani_info = GlobFuncANIInfo.get(self.am, func)
268            sts_params = ["type: String"]
269            sts_args = []
270            for sts_param in func_ani_info.sts_params:
271                type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
272                sts_params.append(
273                    f"{sts_param.name}: {type_ani_info.sts_type_in(target)}"
274                )
275                sts_args.append(sts_param.name)
276            sts_params_str = ", ".join(sts_params)
277            sts_native_call = func_ani_info.call_native_with(sts_args)
278            if return_ty_ref := func.return_ty_ref:
279                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
280                sts_return_ty_name = type_ani_info.sts_type_in(target)
281            else:
282                sts_return_ty_name = "void"
283            with target.indented(
284                f"export function {func_name}({sts_params_str}): {sts_return_ty_name} {{",
285                f"}}",
286            ):
287                with target.indented(
288                    f"if (type !== '{type_name}') {{",
289                    f"}}",
290                ):
291                    target.writelns(
292                        f"throw new Error(`Invalid type: ${{type}}`);",
293                    )
294                target.writelns(
295                    f"return {sts_native_call};",
296                )
297
298    def gen_global_bad_on_off_funcs(
299        self,
300        funcs: list[GlobFuncDecl],
301        target: StsWriter,
302    ):
303        bad_on_off_funcs = self.stat_bad_on_off_funcs(funcs)
304        for func_name, func_list in bad_on_off_funcs.items():
305            max_sts_params = max(
306                len(GlobFuncANIInfo.get(self.am, func).sts_params)
307                for _, func in func_list
308            )
309            sts_params = ["type: Object | String"]
310            sts_args = []
311            for index in range(max_sts_params):
312                param_types = []
313                for _, func in func_list:
314                    func_ani_info = GlobFuncANIInfo.get(self.am, func)
315                    if index < len(func_ani_info.sts_params):
316                        param_ty = func_ani_info.sts_params[index].ty_ref.resolved_ty
317                        type_ani_info = TypeANIInfo.get(self.am, param_ty)
318                        param_types.append(type_ani_info.sts_type_in(target))
319                param_types_str = " | ".join(["Object", *param_types])
320                param_name = f"p_{index}"
321                sts_params.append(f"{param_name}?: {param_types_str}")
322                sts_args.append(param_name)
323            sts_params_str = ", ".join(sts_params)
324            with target.indented(
325                f"export function {func_name}({sts_params_str}): void {{",
326                f"}}",
327            ):
328                with target.indented(
329                    f"switch (type as String) {{",
330                    f"}}",
331                    indent="",
332                ):
333                    for type_name, func in func_list:
334                        func_ani_info = GlobFuncANIInfo.get(self.am, func)
335                        sts_args_fix = []
336                        for sts_arg, param in zip(
337                            sts_args, func_ani_info.sts_params, strict=False
338                        ):
339                            type_ani_info = TypeANIInfo.get(
340                                self.am, param.ty_ref.resolved_ty
341                            )
342                            sts_args_fix.append(
343                                f"{sts_arg} as {type_ani_info.sts_type_in(target)}"
344                            )
345                        sts_native_call = func_ani_info.call_native_with(sts_args_fix)
346                        target.writelns(
347                            f'case "{type_name}": return {sts_native_call};',
348                        )
349                    target.writelns(
350                        f"default: throw new Error(`Unknown type: ${{type}}`);",
351                    )
352
353    def gen_global_regular_funcs(
354        self,
355        funcs: list[GlobFuncDecl],
356        target: StsWriter,
357    ):
358        for func in funcs:
359            func_ani_info = GlobFuncANIInfo.get(self.am, func)
360            sts_params = []
361            sts_args = []
362            for sts_param in func_ani_info.sts_params:
363                type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
364                sts_params.append(
365                    f"{sts_param.name}: {type_ani_info.sts_type_in(target)}"
366                )
367                sts_args.append(sts_param.name)
368            sts_native_call = func_ani_info.call_native_with(sts_args)
369            if return_ty_ref := func.return_ty_ref:
370                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
371                sts_return_ty_name = type_ani_info.sts_type_in(target)
372                sts_resolved_ty_name = type_ani_info.sts_type_in(target)
373            else:
374                sts_return_ty_name = "void"
375                sts_resolved_ty_name = "undefined"
376            if (
377                sts_func_name := func_ani_info.sts_func_name
378            ) is not None and func_ani_info.on_off_type is None:
379                self.gen_normal_func(
380                    sts_func_name,
381                    sts_params,
382                    sts_return_ty_name,
383                    sts_native_call,
384                    target,
385                    FuncKind.GLOBAL,
386                )
387                if (sts_promise_name := func_ani_info.sts_promise_name) is not None:
388                    self.gen_promise_function(
389                        sts_promise_name,
390                        sts_params,
391                        sts_return_ty_name,
392                        sts_native_call,
393                        sts_resolved_ty_name,
394                        target,
395                        FuncKind.GLOBAL,
396                    )
397                if (sts_async_name := func_ani_info.sts_async_name) is not None:
398                    self.gen_async_function(
399                        sts_async_name,
400                        sts_params,
401                        sts_return_ty_name,
402                        sts_native_call,
403                        sts_resolved_ty_name,
404                        target,
405                        FuncKind.GLOBAL,
406                    )
407
408    def gen_enum(
409        self,
410        enum: EnumDecl,
411        target: StsWriter,
412    ):
413        enum_ani_info = EnumANIInfo.get(self.am, enum)
414        if enum_ani_info.const:
415            type_ani_info = TypeANIInfo.get(self.am, enum.ty_ref.resolved_ty)
416            for item in enum.items:
417                if isinstance(item.value, float):
418                    target.writelns(
419                        f"export const {item.name}: {type_ani_info.sts_type_in(target)} = {dumps(item.value)}f;",
420                    )
421                else:
422                    target.writelns(
423                        f"export const {item.name}: {type_ani_info.sts_type_in(target)} = {dumps(item.value)};",
424                    )
425            return
426        sts_decl = f"enum {enum_ani_info.sts_type_name}"
427        if enum_ani_info.is_default:
428            sts_decl = f"export default {sts_decl}"
429        else:
430            sts_decl = f"export {sts_decl}"
431        with target.indented(
432            f"{sts_decl} {{",
433            f"}}",
434        ):
435            for item in enum.items:
436                if item.value is None:
437                    target.writelns(
438                        f"{item.name},",
439                    )
440                else:
441                    target.writelns(
442                        f"{item.name} = {dumps(item.value)},",
443                    )
444
445    def gen_union(
446        self,
447        union: UnionDecl,
448        target: StsWriter,
449    ):
450        union_ani_info = UnionANIInfo.get(self.am, union)
451        sts_types = []
452        for field in union.fields:
453            field_ani_info = UnionFieldANIInfo.get(self.am, field)
454            match field_ani_info.field_ty:
455                case "null":
456                    sts_types.append("null")
457                case "undefined":
458                    sts_types.append("undefined")
459                case field_ty if isinstance(field_ty, Type):
460                    ty_ani_info = TypeANIInfo.get(self.am, field_ty)
461                    sts_types.append(ty_ani_info.sts_type_in(target))
462        sts_types_str = " | ".join(sts_types)
463        sts_decl = f"type {union_ani_info.sts_type_name}"
464        if union_ani_info.is_default:
465            sts_decl = f"export default {sts_decl}"
466        else:
467            sts_decl = f"export {sts_decl}"
468        target.writelns(
469            f"{sts_decl} = {sts_types_str};",
470        )
471
472    def gen_struct_interface(
473        self,
474        struct: StructDecl,
475        target: StsWriter,
476    ):
477        struct_ani_info = StructANIInfo.get(self.am, struct)
478        if struct_ani_info.is_class():
479            # no interface
480            return
481        sts_decl = f"interface {struct_ani_info.sts_type_name}"
482        if struct_ani_info.sts_iface_parents:
483            parents = []
484            for parent in struct_ani_info.sts_iface_parents:
485                parent_ty = parent.ty_ref.resolved_ty
486                parent_ani_info = TypeANIInfo.get(self.am, parent_ty)
487                parents.append(parent_ani_info.sts_type_in(target))
488            extends_str = ", ".join(parents) if parents else ""
489            sts_decl = f"{sts_decl} extends {extends_str}"
490        if struct_ani_info.is_default:
491            sts_decl = f"export default {sts_decl}"
492        else:
493            sts_decl = f"export {sts_decl}"
494        with target.indented(
495            f"{sts_decl} {{",
496            f"}}",
497        ):
498            # TODO: hack inject
499            for injected in struct_ani_info.interface_injected_codes:
500                target.write_block(injected)
501            for field in struct_ani_info.sts_fields:
502                field_ani_info = StructFieldANIInfo.get(self.am, field)
503                readonly_str = "readonly " if field_ani_info.readonly else ""
504                ty_ani_info = TypeANIInfo.get(self.am, field.ty_ref.resolved_ty)
505                target.writelns(
506                    f"{readonly_str}{field.name}: {ty_ani_info.sts_type_in(target)};",
507                )
508
509    def gen_struct_class(
510        self,
511        struct: StructDecl,
512        target: StsWriter,
513    ):
514        struct_ani_info = StructANIInfo.get(self.am, struct)
515        sts_decl = f"class {struct_ani_info.sts_impl_name}"
516        if struct_ani_info.is_class():
517            if struct_ani_info.sts_iface_parents:
518                parents = []
519                for parent in struct_ani_info.sts_iface_parents:
520                    parent_ty = parent.ty_ref.resolved_ty
521                    parent_ani_info = TypeANIInfo.get(self.am, parent_ty)
522                    parents.append(parent_ani_info.sts_type_in(target))
523                implements_str = ", ".join(parents) if parents else ""
524                sts_decl = f"{sts_decl} implements {implements_str}"
525            if struct_ani_info.is_default:
526                sts_decl = f"export default {sts_decl}"
527            else:
528                sts_decl = f"export {sts_decl}"
529        else:
530            sts_decl = f"{sts_decl} implements {struct_ani_info.sts_type_name}"
531
532        with target.indented(
533            f"{sts_decl} {{",
534            f"}}",
535        ):
536            # TODO: hack inject
537            for injected in struct_ani_info.class_injected_codes:
538                target.write_block(injected)
539            for parts in struct_ani_info.sts_final_fields:
540                final = parts[-1]
541                final_ani_info = StructFieldANIInfo.get(self.am, final)
542                readonly_str = "readonly " if final_ani_info.readonly else ""
543                ty_ani_info = TypeANIInfo.get(self.am, final.ty_ref.resolved_ty)
544                target.writelns(
545                    f"{readonly_str}{final.name}: {ty_ani_info.sts_type_in(target)};"
546                )
547
548            params = []
549            for parts in struct_ani_info.sts_final_fields:
550                final = parts[-1]
551                ty_ani_info = TypeANIInfo.get(self.am, final.ty_ref.resolved_ty)
552                params.append(f"{final.name}: {ty_ani_info.sts_type_in(target)}")
553            params_str = ", ".join(params)
554            with target.indented(
555                f"constructor({params_str}) {{",
556                f"}}",
557            ):
558                for parts in struct_ani_info.sts_final_fields:
559                    final = parts[-1]
560                    target.writelns(
561                        f"this.{final.name} = {final.name};",
562                    )
563
564    def gen_iface_interface(
565        self,
566        iface: IfaceDecl,
567        target: StsWriter,
568    ):
569        iface_ani_info = IfaceANIInfo.get(self.am, iface)
570        if iface_ani_info.is_class():
571            # no interface
572            return
573        sts_decl = f"interface {iface_ani_info.sts_type_name}"
574        if iface_ani_info.sts_iface_parents:
575            parents = []
576            for parent in iface_ani_info.sts_iface_parents:
577                parent_ty = parent.ty_ref.resolved_ty
578                parent_ani_info = TypeANIInfo.get(self.am, parent_ty)
579                parents.append(parent_ani_info.sts_type_in(target))
580            extends_str = ", ".join(parents) if parents else ""
581            sts_decl = f"{sts_decl} extends {extends_str}"
582        if iface_ani_info.is_default:
583            sts_decl = f"export default {sts_decl}"
584        else:
585            sts_decl = f"export {sts_decl}"
586        with target.indented(
587            f"{sts_decl} {{",
588            f"}}",
589        ):
590            # TODO: hack inject
591            for injected in iface_ani_info.interface_injected_codes:
592                target.write_block(injected)
593            self.gen_iface_methods(iface.methods, target)
594
595    def gen_iface_methods(
596        self,
597        methods: list[IfaceMethodDecl],
598        target: StsWriter,
599    ):
600        self.gen_iface_on_off_methods(methods, target)
601        self.gen_iface_regular_methods(methods, target)
602
603    def gen_iface_on_off_methods(
604        self,
605        methods: list[IfaceMethodDecl],
606        target: StsWriter,
607    ):
608        method_on_off_map = self.stat_on_off_methods(methods)
609        for (
610            sts_method_name,
611            sts_params_ani_desc,
612        ), method_list in method_on_off_map.items():
613            sts_params = []
614            sts_params.append("type: string")
615            for index in range(len(sts_params_ani_desc)):
616                param_name = f"p_{index}"
617                sts_param_i_types = []
618                for _, method in method_list:
619                    method_ani_info = IfaceMethodANIInfo.get(self.am, method)
620                    param_ty = method_ani_info.sts_params[index].ty_ref.resolved_ty
621                    type_ani_info = TypeANIInfo.get(self.am, param_ty)
622                    sts_param_i_types.append(type_ani_info.sts_type_in(target))
623                sts_param_ty_name = " | ".join(sts_param_i_types)
624                sts_params.append(f"{param_name}: {sts_param_ty_name}")
625            sts_params_str = ", ".join(sts_params)
626            sts_return_ty_names = set()
627            for _, method in method_list:
628                if return_ty_ref := method.return_ty_ref:
629                    type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
630                    sts_return_ty_names.add(type_ani_info.sts_type_in(target))
631                else:
632                    sts_return_ty_names.add("void")
633            sts_return_ty_name = sts_return_ty_names.pop()
634            target.writelns(
635                f"{sts_method_name}({sts_params_str}): {sts_return_ty_name};",
636            )
637
638    def gen_iface_regular_methods(
639        self,
640        methods: list[IfaceMethodDecl],
641        target: StsWriter,
642    ):
643        for method in methods:
644            method_ani_info = IfaceMethodANIInfo.get(self.am, method)
645            sts_params = []
646            for sts_param in method_ani_info.sts_params:
647                type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
648                sts_params.append(
649                    f"{sts_param.name}: {type_ani_info.sts_type_in(target)}"
650                )
651            if return_ty_ref := method.return_ty_ref:
652                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
653                sts_return_ty_name = type_ani_info.sts_type_in(target)
654            else:
655                sts_return_ty_name = "void"
656            if (
657                sts_method_name := method_ani_info.sts_method_name
658            ) is not None and method_ani_info.on_off_type is None:
659                self.gen_iface_normal_method(
660                    sts_method_name,
661                    sts_params,
662                    sts_return_ty_name,
663                    target,
664                )
665                if (sts_promise_name := method_ani_info.sts_promise_name) is not None:
666                    self.gen_iface_promise_method(
667                        sts_promise_name,
668                        sts_params,
669                        sts_return_ty_name,
670                        target,
671                    )
672                if (sts_async_name := method_ani_info.sts_async_name) is not None:
673                    self.gen_iface_async_method(
674                        sts_async_name,
675                        sts_params,
676                        sts_return_ty_name,
677                        target,
678                    )
679            if (get_name := method_ani_info.get_name) is not None:
680                self.gen_iface_get_method(
681                    get_name,
682                    sts_params,
683                    sts_return_ty_name,
684                    target,
685                )
686            if (set_name := method_ani_info.set_name) is not None:
687                self.gen_iface_set_method(
688                    set_name,
689                    sts_params,
690                    sts_return_ty_name,
691                    target,
692                )
693
694    def gen_iface_normal_method(
695        self,
696        sts_method_name: str,
697        sts_params: list[str],
698        sts_return_ty_name: str,
699        target: StsWriter,
700    ):
701        sts_params_str = ", ".join(sts_params)
702        target.writelns(
703            f"{sts_method_name}({sts_params_str}): {sts_return_ty_name};",
704        )
705
706    def gen_iface_promise_method(
707        self,
708        sts_promise_name: str,
709        sts_params: list[str],
710        sts_return_ty_name: str,
711        target: StsWriter,
712    ):
713        sts_params_str = ", ".join(sts_params)
714        target.writelns(
715            f"{sts_promise_name}({sts_params_str}): Promise<{sts_return_ty_name}>;",
716        )
717
718    def gen_iface_async_method(
719        self,
720        sts_async_name: str,
721        sts_params: list[str],
722        sts_return_ty_name: str,
723        target: StsWriter,
724    ):
725        callback_param = f"callback: AsyncCallback<{sts_return_ty_name}>"
726        sts_params_with_cb_str = ", ".join([*sts_params, callback_param])
727        target.writelns(
728            f"{sts_async_name}({sts_params_with_cb_str}): void;",
729        )
730
731    def gen_iface_get_method(
732        self,
733        get_name: str,
734        sts_params: list[str],
735        sts_return_ty_name: str,
736        target: StsWriter,
737    ):
738        sts_params_str = ", ".join(sts_params)
739        target.writelns(
740            f"get {get_name}({sts_params_str}): {sts_return_ty_name};",
741        )
742
743    def gen_iface_set_method(
744        self,
745        set_name: str,
746        sts_params: list[str],
747        sts_return_ty_name: str,
748        target: StsWriter,
749    ):
750        sts_params_str = ", ".join(sts_params)
751        target.writelns(
752            f"set {set_name}({sts_params_str});",
753        )
754
755    def gen_iface_class(
756        self,
757        iface: IfaceDecl,
758        target: StsWriter,
759        statics_map: dict[str, list[GlobFuncDecl]],
760        ctors_map: dict[str, list[GlobFuncDecl]],
761    ):
762        iface_ani_info = IfaceANIInfo.get(self.am, iface)
763        sts_decl = f"class {iface_ani_info.sts_impl_name}"
764        if iface_ani_info.is_class():
765            if iface_ani_info.sts_iface_parents:
766                parents = []
767                for parent in iface_ani_info.sts_iface_parents:
768                    parent_ty = parent.ty_ref.resolved_ty
769                    parent_ani_info = TypeANIInfo.get(self.am, parent_ty)
770                    parents.append(parent_ani_info.sts_type_in(target))
771                implements_str = ", ".join(parents) if parents else ""
772                sts_decl = f"{sts_decl} implements {implements_str}"
773            if iface_ani_info.is_default:
774                sts_decl = f"export default {sts_decl}"
775            else:
776                sts_decl = f"export {sts_decl}"
777        else:
778            sts_decl = f"{sts_decl} implements {iface_ani_info.sts_type_name}"
779
780        with target.indented(
781            f"{sts_decl} {{",
782            f"}}",
783        ):
784            # TODO: hack inject
785            for injected in iface_ani_info.class_injected_codes:
786                target.write_block(injected)
787            target.writelns(
788                f"private _vtbl_ptr: long;",
789                f"private _data_ptr: long;",
790                f"private static native _obj_drop(data_ptr: long): void;",
791                f"private static native _obj_dup(data_ptr: long): long;",
792                f"private static _registry = new FinalizationRegistry<long>((data_ptr: long) => {{ {iface_ani_info.sts_impl_name}._obj_drop(data_ptr); }});",
793            )
794            with target.indented(
795                f"private _register(): void {{",
796                f"}}",
797            ):
798                target.writelns(
799                    f"{iface_ani_info.sts_impl_name}._registry.register(this, this._data_ptr, this);",
800                )
801            with target.indented(
802                f"private _unregister(): void {{",
803                f"}}",
804            ):
805                target.writelns(
806                    f"{iface_ani_info.sts_impl_name}._registry.unregister(this);",
807                )
808            with target.indented(
809                f"private _initialize(_vtbl_ptr: long, _data_ptr: long): void {{",
810                f"}}",
811            ):
812                target.writelns(
813                    f"this._vtbl_ptr = _vtbl_ptr;",
814                    f"this._data_ptr = _data_ptr;",
815                    f"this._register();",
816                )
817            with target.indented(
818                f"public _copy_from(other: {iface_ani_info.sts_impl_name}): void {{",
819                f"}}",
820            ):
821                target.writelns(
822                    f"this._initialize(other._vtbl_ptr, {iface_ani_info.sts_impl_name}._obj_dup(other._data_ptr));",
823                )
824            with target.indented(
825                f"public _move_from(other: {iface_ani_info.sts_impl_name}): void {{",
826                f"}}",
827            ):
828                target.writelns(
829                    f"this._initialize(other._vtbl_ptr, other._data_ptr);",
830                    f"other._unregister();",
831                )
832            ctors = ctors_map.get(iface.name, [])
833            for ctor in ctors:
834                self.gen_class_ctor(ctor, iface_ani_info, target)
835            self.gen_static_funcs(statics_map.get(iface.name, []), target)
836            iface_abi_info = IfaceABIInfo.get(self.am, iface)
837            for ancestor in iface_abi_info.ancestor_dict:
838                self.gen_native_methods(ancestor.methods, target)
839                self.gen_class_methods(ancestor.methods, target)
840
841    def gen_class_ctor(
842        self,
843        ctor: GlobFuncDecl,
844        iface_ani_info: IfaceANIInfo,
845        target: StsWriter,
846    ):
847        ctor_ani_info = GlobFuncANIInfo.get(self.am, ctor)
848        sts_params = []
849        sts_args = []
850        for sts_param in ctor_ani_info.sts_params:
851            type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
852            sts_params.append(f"{sts_param.name}: {type_ani_info.sts_type_in(target)}")
853            sts_args.append(sts_param.name)
854        sts_params_str = ", ".join(sts_params)
855        sts_native_call = ctor_ani_info.call_native_with(sts_args)
856        with target.indented(
857            f"constructor({sts_params_str}) {{",
858            f"}}",
859        ):
860            target.writelns(
861                f"this._move_from({sts_native_call} as {iface_ani_info.sts_impl_name});",
862            )
863
864    def gen_static_funcs(
865        self,
866        funcs: list[GlobFuncDecl],
867        target: StsWriter,
868    ):
869        self.gen_static_on_off_funcs(funcs, target)
870        self.gen_static_regular_funcs(funcs, target)
871
872    def gen_static_on_off_funcs(
873        self,
874        funcs: list[GlobFuncDecl],
875        target: StsWriter,
876    ):
877        func_on_off_map = self.stat_on_off_funcs(funcs)
878        for (
879            sts_func_name,
880            sts_params_ani_desc,
881        ), func_list in func_on_off_map.items():
882            sts_params = []
883            sts_args_any = []
884            sts_params.append("type: string")
885            for index in range(len(sts_params_ani_desc)):
886                param_name = f"p_{index}"
887                sts_param_i_types = []
888                for _, func in func_list:
889                    func_ani_info = GlobFuncANIInfo.get(self.am, func)
890                    param_ty = func_ani_info.sts_params[index].ty_ref.resolved_ty
891                    type_ani_info = TypeANIInfo.get(self.am, param_ty)
892                    sts_param_i_types.append(type_ani_info.sts_type_in(target))
893                sts_param_ty_name = " | ".join(sts_param_i_types)
894                sts_params.append(f"{param_name}: {sts_param_ty_name}")
895                sts_args_any.append(param_name)
896            sts_params_str = ", ".join(sts_params)
897            sts_return_ty_names = set()
898            for _, func in func_list:
899                if return_ty_ref := func.return_ty_ref:
900                    type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
901                    sts_return_ty_names.add(type_ani_info.sts_type_in(target))
902                else:
903                    sts_return_ty_names.add("void")
904            sts_return_ty_name = sts_return_ty_names.pop()
905            with target.indented(
906                f"static {sts_func_name}({sts_params_str}): {sts_return_ty_name} {{",
907                f"}}",
908            ):
909                with target.indented(
910                    f"switch(type) {{",
911                    f"}}",
912                    indent="",
913                ):
914                    for type_name, func in func_list:
915                        func_ani_info = GlobFuncANIInfo.get(self.am, func)
916                        sts_args_fix = []
917                        for sts_arg_any, param in zip(
918                            sts_args_any, func_ani_info.sts_params, strict=True
919                        ):
920                            type_ani_info = TypeANIInfo.get(
921                                self.am, param.ty_ref.resolved_ty
922                            )
923                            sts_args_fix.append(
924                                f"{sts_arg_any} as {type_ani_info.sts_type_in(target)}"
925                            )
926                        sts_native_call = func_ani_info.call_native_with(sts_args_fix)
927                        target.writelns(
928                            f'case "{type_name}": return {sts_native_call};',
929                        )
930                    target.writelns(
931                        f"default: throw new Error(`Unknown type: ${{type}}`);",
932                    )
933
934    def gen_static_regular_funcs(
935        self,
936        funcs: list[GlobFuncDecl],
937        target: StsWriter,
938    ):
939        for func in funcs:
940            func_ani_info = GlobFuncANIInfo.get(self.am, func)
941            sts_params = []
942            sts_args = []
943            for sts_param in func_ani_info.sts_params:
944                type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
945                sts_params.append(
946                    f"{sts_param.name}: {type_ani_info.sts_type_in(target)}"
947                )
948                sts_args.append(sts_param.name)
949            sts_native_call = func_ani_info.call_native_with(sts_args)
950            if return_ty_ref := func.return_ty_ref:
951                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
952                sts_return_ty_name = type_ani_info.sts_type_in(target)
953                sts_resolved_ty_name = type_ani_info.sts_type_in(target)
954            else:
955                sts_return_ty_name = "void"
956                sts_resolved_ty_name = "undefined"
957            if (
958                sts_func_name := func_ani_info.sts_func_name
959            ) is not None and func_ani_info.on_off_type is None:
960                self.gen_normal_func(
961                    sts_func_name,
962                    sts_params,
963                    sts_return_ty_name,
964                    sts_native_call,
965                    target,
966                    FuncKind.STATIC,
967                )
968                if (sts_promise_name := func_ani_info.sts_promise_name) is not None:
969                    self.gen_promise_function(
970                        sts_promise_name,
971                        sts_params,
972                        sts_return_ty_name,
973                        sts_native_call,
974                        sts_resolved_ty_name,
975                        target,
976                        FuncKind.STATIC,
977                    )
978                if (sts_async_name := func_ani_info.sts_async_name) is not None:
979                    self.gen_async_function(
980                        sts_async_name,
981                        sts_params,
982                        sts_return_ty_name,
983                        sts_native_call,
984                        sts_resolved_ty_name,
985                        target,
986                        FuncKind.STATIC,
987                    )
988            if (get_name := func_ani_info.get_name) is not None:
989                self.gen_get_func(
990                    get_name,
991                    sts_params,
992                    sts_return_ty_name,
993                    sts_native_call,
994                    target,
995                    FuncKind.STATIC,
996                )
997            if (set_name := func_ani_info.set_name) is not None:
998                self.gen_set_func(
999                    set_name,
1000                    sts_params,
1001                    sts_return_ty_name,
1002                    sts_native_call,
1003                    target,
1004                    FuncKind.STATIC,
1005                )
1006
1007    def gen_native_methods(
1008        self,
1009        methods: list[IfaceMethodDecl],
1010        target: StsWriter,
1011    ):
1012        # native
1013        for method in methods:
1014            method_ani_info = IfaceMethodANIInfo.get(self.am, method)
1015            sts_native_params = []
1016            for param in method.params:
1017                type_ani_info = TypeANIInfo.get(self.am, param.ty_ref.resolved_ty)
1018                sts_native_params.append(
1019                    f"{param.name}: {type_ani_info.sts_type_in(target)}"
1020                )
1021            sts_native_params_str = ", ".join(sts_native_params)
1022            if return_ty_ref := method.return_ty_ref:
1023                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
1024                sts_return_ty_name = type_ani_info.sts_type_in(target)
1025            else:
1026                sts_return_ty_name = "void"
1027            target.writelns(
1028                f"native {method_ani_info.sts_native_name}({sts_native_params_str}): {sts_return_ty_name};",
1029            )
1030
1031    def gen_class_methods(
1032        self,
1033        methods: list[IfaceMethodDecl],
1034        target: StsWriter,
1035    ):
1036        self.gen_iface_on_off_meths(methods, target)
1037        self.gen_iface_regular_meths(methods, target)
1038
1039    def gen_iface_on_off_meths(
1040        self,
1041        methods: list[IfaceMethodDecl],
1042        target: StsWriter,
1043    ):
1044        method_on_off_map = self.stat_on_off_methods(methods)
1045        for (
1046            sts_method_name,
1047            sts_params_ani_desc,
1048        ), method_list in method_on_off_map.items():
1049            sts_params = []
1050            sts_args_any = []
1051            sts_params.append("type: string")
1052            for index in range(len(sts_params_ani_desc)):
1053                param_name = f"p_{index}"
1054                sts_param_i_types = []
1055                for _, method in method_list:
1056                    method_ani_info = IfaceMethodANIInfo.get(self.am, method)
1057                    param_ty = method_ani_info.sts_params[index].ty_ref.resolved_ty
1058                    type_ani_info = TypeANIInfo.get(self.am, param_ty)
1059                    sts_param_i_types.append(type_ani_info.sts_type_in(target))
1060                sts_param_ty_name = " | ".join(sts_param_i_types)
1061                sts_params.append(f"{param_name}: {sts_param_ty_name}")
1062                sts_args_any.append(param_name)
1063            sts_params_str = ", ".join(sts_params)
1064            sts_return_ty_names = set()
1065            for _, method in method_list:
1066                if return_ty_ref := method.return_ty_ref:
1067                    type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
1068                    sts_return_ty_names.add(type_ani_info.sts_type_in(target))
1069                else:
1070                    sts_return_ty_names.add("void")
1071            sts_return_ty_name = sts_return_ty_names.pop()
1072            with target.indented(
1073                f"{sts_method_name}({sts_params_str}): {sts_return_ty_name} {{",
1074                f"}}",
1075            ):
1076                with target.indented(
1077                    f"switch(type) {{",
1078                    f"}}",
1079                    indent="",
1080                ):
1081                    for type_name, method in method_list:
1082                        method_ani_info = IfaceMethodANIInfo.get(self.am, method)
1083                        sts_args_fix = []
1084                        for sts_arg_any, param in zip(
1085                            sts_args_any, method_ani_info.sts_params, strict=True
1086                        ):
1087                            type_ani_info = TypeANIInfo.get(
1088                                self.am, param.ty_ref.resolved_ty
1089                            )
1090                            sts_args_fix.append(
1091                                f"{sts_arg_any} as {type_ani_info.sts_type_in(target)}"
1092                            )
1093                        sts_native_call = method_ani_info.call_native_with(sts_args_fix)
1094                        target.writelns(
1095                            f'case "{type_name}": return {sts_native_call};',
1096                        )
1097                    target.writelns(
1098                        f"default: throw new Error(`Unknown type: ${{type}}`);",
1099                    )
1100
1101    def gen_iface_regular_meths(
1102        self,
1103        methods: list[IfaceMethodDecl],
1104        target: StsWriter,
1105    ):
1106        for method in methods:
1107            method_ani_info = IfaceMethodANIInfo.get(self.am, method)
1108            sts_params = []
1109            sts_args = []
1110            for sts_param in method_ani_info.sts_params:
1111                type_ani_info = TypeANIInfo.get(self.am, sts_param.ty_ref.resolved_ty)
1112                sts_params.append(
1113                    f"{sts_param.name}: {type_ani_info.sts_type_in(target)}"
1114                )
1115                sts_args.append(sts_param.name)
1116            sts_native_call = method_ani_info.call_native_with(sts_args)
1117            if return_ty_ref := method.return_ty_ref:
1118                type_ani_info = TypeANIInfo.get(self.am, return_ty_ref.resolved_ty)
1119                sts_return_ty_name = type_ani_info.sts_type_in(target)
1120                sts_resolved_ty_name = type_ani_info.sts_type_in(target)
1121            else:
1122                sts_return_ty_name = "void"
1123                sts_resolved_ty_name = "undefined"
1124            if (
1125                sts_method_name := method_ani_info.sts_method_name
1126            ) is not None and method_ani_info.on_off_type is None:
1127                self.gen_normal_func(
1128                    sts_method_name,
1129                    sts_params,
1130                    sts_return_ty_name,
1131                    sts_native_call,
1132                    target,
1133                    FuncKind.INTERFACE,
1134                )
1135                if (sts_promise_name := method_ani_info.sts_promise_name) is not None:
1136                    self.gen_promise_function(
1137                        sts_promise_name,
1138                        sts_params,
1139                        sts_return_ty_name,
1140                        sts_native_call,
1141                        sts_resolved_ty_name,
1142                        target,
1143                        FuncKind.INTERFACE,
1144                    )
1145                if (sts_async_name := method_ani_info.sts_async_name) is not None:
1146                    self.gen_async_function(
1147                        sts_async_name,
1148                        sts_params,
1149                        sts_return_ty_name,
1150                        sts_native_call,
1151                        sts_resolved_ty_name,
1152                        target,
1153                        FuncKind.INTERFACE,
1154                    )
1155            if (get_name := method_ani_info.get_name) is not None:
1156                self.gen_get_func(
1157                    get_name,
1158                    sts_params,
1159                    sts_return_ty_name,
1160                    sts_native_call,
1161                    target,
1162                    FuncKind.INTERFACE,
1163                )
1164            if (set_name := method_ani_info.set_name) is not None:
1165                self.gen_set_func(
1166                    set_name,
1167                    sts_params,
1168                    sts_return_ty_name,
1169                    sts_native_call,
1170                    target,
1171                    FuncKind.INTERFACE,
1172                )
1173
1174    def gen_iface_normal_meth(
1175        self,
1176        sts_method_name: str,
1177        sts_params: list[str],
1178        sts_return_ty_name: str,
1179        sts_native_call: str,
1180        target: StsWriter,
1181    ):
1182        sts_params_str = ", ".join(sts_params)
1183        with target.indented(
1184            f"{sts_method_name}({sts_params_str}): {sts_return_ty_name} {{",
1185            f"}}",
1186        ):
1187            target.writelns(
1188                f"return {sts_native_call};",
1189            )
1190
1191    def gen_get_func(
1192        self,
1193        get_name: str,
1194        sts_params: list[str],
1195        sts_return_ty_name: str,
1196        sts_native_call: str,
1197        target: StsWriter,
1198        func_kind: FuncKind,
1199    ):
1200        sts_params_str = ", ".join(sts_params)
1201        with target.indented(
1202            f"{func_kind.value}get {get_name}({sts_params_str}): {sts_return_ty_name} {{",
1203            f"}}",
1204        ):
1205            target.writelns(
1206                f"return {sts_native_call};",
1207            )
1208
1209    def gen_set_func(
1210        self,
1211        set_name: str,
1212        sts_params: list[str],
1213        sts_return_ty_name: str,
1214        sts_native_call: str,
1215        target: StsWriter,
1216        func_kind: FuncKind,
1217    ):
1218        sts_params_str = ", ".join(sts_params)
1219        with target.indented(
1220            f"{func_kind.value}set {set_name}({sts_params_str}) {{",
1221            f"}}",
1222        ):
1223            target.writelns(
1224                f"return {sts_native_call};",
1225            )
1226
1227    def gen_normal_func(
1228        self,
1229        sts_func_name: str,
1230        sts_params: list[str],
1231        sts_return_ty_name: str,
1232        sts_native_call: str,
1233        target: StsWriter,
1234        func_kind: FuncKind,
1235    ):
1236        sts_params_str = ", ".join(sts_params)
1237        with target.indented(
1238            f"{func_kind.value}{sts_func_name}({sts_params_str}): {sts_return_ty_name} {{",
1239            f"}}",
1240        ):
1241            target.writelns(
1242                f"return {sts_native_call};",
1243            )
1244
1245    def gen_promise_function(
1246        self,
1247        sts_promise_name: str,
1248        sts_params: list[str],
1249        sts_return_ty_name: str,
1250        sts_native_call: str,
1251        sts_resolved_ty_name: str,
1252        target: StsWriter,
1253        func_kind: FuncKind,
1254    ):
1255        sts_params_str = ", ".join(sts_params)
1256        with target.indented(
1257            f"{func_kind.value}{sts_promise_name}({sts_params_str}): Promise<{sts_return_ty_name}> {{",
1258            f"}}",
1259        ):
1260            with target.indented(
1261                f"return new Promise<{sts_return_ty_name}>((resolve, reject): void => {{",
1262                f"}});",
1263            ):
1264                with target.indented(
1265                    f"taskpool.execute((): {sts_return_ty_name} => {{",
1266                    f"}})",
1267                ):
1268                    target.writelns(
1269                        f"return {sts_native_call};",
1270                    )
1271                with target.indented(
1272                    f".then((ret: NullishType): void => {{",
1273                    f"}})",
1274                ):
1275                    target.writelns(
1276                        f"resolve(ret as {sts_resolved_ty_name});",
1277                    )
1278                with target.indented(
1279                    f".catch((ret: NullishType): void => {{",
1280                    f"}});",
1281                ):
1282                    target.writelns(
1283                        f"reject(ret as Error);",
1284                    )
1285
1286    def gen_async_function(
1287        self,
1288        sts_async_name: str,
1289        sts_params: list[str],
1290        sts_return_ty_name: str,
1291        sts_native_call: str,
1292        sts_resolved_ty_name: str,
1293        target: StsWriter,
1294        func_kind: FuncKind,
1295    ):
1296        callback_param = f"callback: AsyncCallback<{sts_return_ty_name}>"
1297        sts_params_with_cb_str = ", ".join([*sts_params, callback_param])
1298        with target.indented(
1299            f"{func_kind.value}{sts_async_name}({sts_params_with_cb_str}): void {{",
1300            f"}}",
1301        ):
1302            with target.indented(
1303                f"taskpool.execute((): {sts_return_ty_name} => {{",
1304                f"}})",
1305            ):
1306                target.writelns(
1307                    f"return {sts_native_call};",
1308                )
1309            with target.indented(
1310                f".then((ret: NullishType): void => {{",
1311                f"}})",
1312            ):
1313                target.writelns(
1314                    f"let err: BusinessError = new BusinessError();",
1315                    f"callback(err, ret as {sts_resolved_ty_name});",
1316                )
1317            with target.indented(
1318                f".catch((ret: NullishType): void => {{",
1319                f"}});",
1320            ):
1321                target.writelns(
1322                    f"let res: {sts_resolved_ty_name};",
1323                    f"callback(ret as BusinessError, res);",
1324                )
1325
1326    def gen_ohos_base(self):
1327        with StsWriter(
1328            self.om,
1329            "@ohos.base.ets",
1330            FileKind.ETS,
1331        ) as target:
1332            target.writelns(
1333                "export class BusinessError<T = void> extends Error {",
1334                "    code: number;",
1335                "    data?: T;",
1336                "    constructor() {",
1337                "        super();",
1338                "        this.code = 0;",
1339                "    }",
1340                "    constructor(code: number, error: Error) {",
1341                "        super(error.name, error.message, new ErrorOptions(error.cause));",
1342                "        this.code = code;",
1343                "    }",
1344                "    constructor(code: number, data: T, error: Error) {",
1345                "        super(error.name, error.message, new ErrorOptions(error.cause));",
1346                "        this.code = code;",
1347                "        this.data = data;",
1348                "    }",
1349                "}",
1350                "export type AsyncCallback<T, E = void> = (error: BusinessError<E>, data: T) => void;",
1351            )
1352
1353    def gen_utils(
1354        self,
1355        target: StsWriter,
1356    ):
1357        target.writelns(
1358            "function __fromArrayBufferToBigInt(arr: ArrayBuffer): BigInt {",
1359            "    let res: BigInt = 0n;",
1360            "    for (let i: int = 0; i < arr.getByteLength(); i++) {",
1361            "        res |= BigInt(arr.at(i).toLong() & 0xff) << BigInt(i * 8);",
1362            "    }",
1363            "    let m: int = arr.getByteLength();",
1364            "    if (arr.at(m - 1) < 0) {",
1365            "        res |= -1n << BigInt(m * 8 - 1);",
1366            "    }",
1367            "    return res;",
1368            "}",
1369        )
1370        target.writelns(
1371            "function __fromBigIntToArrayBuffer(val: BigInt, blk: int): ArrayBuffer {",
1372            "    let n_7 = BigInt(blk * 8 - 1);",
1373            "    let n_8 = BigInt(blk * 8);",
1374            "    let ocp: BigInt = val;",
1375            "    let n: int = 0;",
1376            "    while (true) {",
1377            "        n += blk;",
1378            "        let t_7 = ocp >> n_7;",
1379            "        let t_8 = ocp >> n_8;",
1380            "        if (t_7 == t_8) {",
1381            "            break;",
1382            "        }",
1383            "        ocp = t_8;",
1384            "    }",
1385            "    let buf = new ArrayBuffer(n);",
1386            "    for (let i: int = 0; i < n; i++) {",
1387            "        buf.set(i, (val & 255n).getLong().toByte())",
1388            "        val >>= 8n;",
1389            "    }",
1390            "    return buf;",
1391            "}",
1392        )