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 )