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 16"""Defines the types for declarations.""" 17 18from abc import ABCMeta, abstractmethod 19from collections.abc import Iterable 20from dataclasses import dataclass, field 21from typing import TYPE_CHECKING, Any, Generic, Protocol, TypeVar 22 23from typing_extensions import override 24 25from taihe.semantics.format import PrettyFormatter 26from taihe.semantics.types import ( 27 EnumType, 28 IfaceType, 29 StructType, 30 UnionType, 31 UserType, 32) 33from taihe.utils.exceptions import DeclRedefError 34from taihe.utils.sources import SourceLocation 35 36if TYPE_CHECKING: 37 from taihe.semantics.types import Type 38 from taihe.semantics.visitor import DeclVisitor 39 40 41############# 42# Attribute # 43############# 44 45 46@dataclass 47class AttrItemDecl: 48 """Represents an attribute item.""" 49 50 loc: SourceLocation | None 51 name: str 52 53 args: list[Any] = field(default_factory=list[Any]) 54 kwargs: dict[str, Any] = field(default_factory=dict[str, Any]) 55 56 57################ 58# Declarations # 59################ 60 61 62class DeclProtocol(Protocol): 63 def _accept(self, v: "DeclVisitor[Any]") -> Any: 64 ... 65 66 67class Decl(metaclass=ABCMeta): 68 """Represents any declaration.""" 69 70 loc: SourceLocation | None 71 72 attrs: dict[str, list[AttrItemDecl]] 73 74 def __init__( 75 self, 76 loc: SourceLocation | None, 77 ): 78 self.loc = loc 79 self.attrs = {} 80 81 def __repr__(self) -> str: 82 return f"<{self.__class__.__qualname__} {self.description}>" 83 84 @property 85 @abstractmethod 86 def description(self) -> str: 87 """Human-readable description of this declaration.""" 88 89 @property 90 @abstractmethod 91 def parent_pkg(self) -> "PackageDecl": 92 """Return the parent package of this declaration.""" 93 94 def add_attr(self, i: AttrItemDecl): 95 self.attrs.setdefault(i.name, []).append(i) 96 97 def get_all_attrs(self, name: str) -> Iterable[AttrItemDecl]: 98 return self.attrs.get(name, []) 99 100 def get_last_attr(self, name: str) -> AttrItemDecl | None: 101 return self.attrs.get(name, [None])[-1] 102 103 @abstractmethod 104 def _accept(self, v: "DeclVisitor[Any]") -> Any: 105 """Accept a visitor.""" 106 107 108class NamedDecl(Decl, metaclass=ABCMeta): 109 """Represents a declaration with a name.""" 110 111 name: str 112 113 def __init__( 114 self, 115 loc: SourceLocation | None, 116 name: str, 117 ): 118 super().__init__(loc) 119 self.name = name 120 121 122T = TypeVar("T", bound=Decl) 123 124 125class DeclWithParent(Decl, Generic[T], metaclass=ABCMeta): 126 _node_parent: T | None = None 127 128 @property 129 @override 130 def parent_pkg(self) -> "PackageDecl": 131 pass 132 return self._node_parent.parent_pkg 133 134 def set_parent(self, parent: T): 135 self._node_parent = parent 136 137 138class NamedDeclWithParent(NamedDecl, Generic[T], metaclass=ABCMeta): 139 _node_parent: T | None = None 140 141 @property 142 @override 143 def parent_pkg(self) -> "PackageDecl": 144 pass 145 return self._node_parent.parent_pkg 146 147 def set_parent(self, parent: T): 148 self._node_parent = parent 149 150 151################### 152# Type References # 153################### 154 155 156class TypeRefDecl(DeclWithParent[Decl], metaclass=ABCMeta): 157 """Repersents a reference to a `Type`. 158 159 Each user of a `Type` must be encapsulated in a `TypeRefDecl`. 160 Also, `TypeRefDecl` is NOT a `TypeDecl`. 161 In other words, `TypeRefDecl` is a pointer, instead of a declaration. 162 163 For example: 164 ``` 165 struct Foo { ... } // `Foo` is a `TypeDecl`. 166 167 fn func(foo: Foo); // `Foo` is `TypeRefDecl(ty=UserType(ty_decl=TypeDecl('Foo')))`. 168 fn func(foo: BadType); // `BadType` is `TypeRefDecl(ty=None)`. 169 ``` 170 """ 171 172 is_resolved: bool = False 173 """Whether this type reference is resolved.""" 174 175 maybe_resolved_ty: "Type | None" = None 176 """The resolved type, if any. 177 178 This field is `None` either if the type reference is not resolved yet, 179 or if the type reference is invalid. 180 """ 181 182 def __init__( 183 self, 184 loc: SourceLocation | None, 185 ): 186 super().__init__(loc) 187 188 @property 189 @override 190 def description(self) -> str: 191 return f"type reference {self.text}" 192 193 @property 194 def resolved_ty(self) -> "Type": 195 pass 196 return self.maybe_resolved_ty 197 198 @property 199 def text(self) -> str: 200 return PrettyFormatter().get_type_ref_decl(self) 201 202 203class ParamDecl(NamedDeclWithParent[Decl]): 204 ty_ref: TypeRefDecl 205 206 def __init__( 207 self, 208 loc: SourceLocation | None, 209 name: str, 210 ty_ref: TypeRefDecl, 211 ): 212 super().__init__(loc, name) 213 self.ty_ref = ty_ref 214 ty_ref.set_parent(self) 215 216 @property 217 @override 218 def description(self) -> str: 219 return f"parameter {self.name}" 220 221 @override 222 def _accept(self, v: "DeclVisitor[T]") -> Any: 223 return v.visit_param_decl(self) 224 225 226class ShortTypeRefDecl(TypeRefDecl): 227 symbol: str 228 229 def __init__( 230 self, 231 loc: SourceLocation | None, 232 symbol: str, 233 ): 234 super().__init__(loc) 235 self.symbol = symbol 236 237 @override 238 def _accept(self, v: "DeclVisitor[T]") -> Any: 239 return v.visit_short_type_ref_decl(self) 240 241 242class LongTypeRefDecl(TypeRefDecl): 243 pkname: str 244 symbol: str 245 246 def __init__( 247 self, 248 loc: SourceLocation | None, 249 pkname: str, 250 symbol: str, 251 ): 252 super().__init__(loc) 253 self.pkname = pkname 254 self.symbol = symbol 255 256 @override 257 def _accept(self, v: "DeclVisitor[T]") -> Any: 258 return v.visit_long_type_ref_decl(self) 259 260 261class GenericTypeRefDecl(TypeRefDecl): 262 symbol: str 263 args_ty_ref: list[TypeRefDecl] 264 265 def __init__( 266 self, 267 loc: SourceLocation | None, 268 symbol: str, 269 ): 270 super().__init__(loc) 271 self.symbol = symbol 272 self.args_ty_ref = [] 273 274 def add_arg_ty_ref(self, p: TypeRefDecl): 275 self.args_ty_ref.append(p) 276 p.set_parent(self) 277 278 @override 279 def _accept(self, v: "DeclVisitor[T]") -> Any: 280 return v.visit_generic_type_ref_decl(self) 281 282 283class CallbackTypeRefDecl(TypeRefDecl): 284 params: list[ParamDecl] 285 return_ty_ref: TypeRefDecl | None 286 287 def __init__( 288 self, 289 loc: SourceLocation | None, 290 return_ty_ref: TypeRefDecl | None = None, 291 ): 292 super().__init__(loc) 293 self.params = [] 294 self.return_ty_ref = return_ty_ref 295 if return_ty_ref: 296 return_ty_ref.set_parent(self) 297 298 @override 299 def _accept(self, v: "DeclVisitor[T]") -> Any: 300 return v.visit_callback_type_ref_decl(self) 301 302 def add_param(self, p: ParamDecl): 303 self.params.append(p) 304 p.set_parent(self) 305 306 307##################### 308# Import References # 309##################### 310 311 312class PackageRefDecl(DeclWithParent[Decl]): 313 symbol: str 314 315 is_resolved: bool = False 316 """Whether this package reference is resolved.""" 317 318 maybe_resolved_pkg: "PackageDecl | None" = None 319 """The resolved package, if any. 320 321 This field is `None` either if the package reference is not resolved yet, 322 or if the package reference is invalid. 323 """ 324 325 def __init__( 326 self, 327 loc: SourceLocation | None, 328 symbol: str, 329 ): 330 super().__init__(loc) 331 self.symbol = symbol 332 333 @property 334 @override 335 def description(self) -> str: 336 return f"package reference {self.symbol}" 337 338 @property 339 def resolved_pkg(self) -> "PackageDecl": 340 pass 341 return self.maybe_resolved_pkg 342 343 @override 344 def _accept(self, v: "DeclVisitor[T]") -> Any: 345 return v.visit_package_ref_decl(self) 346 347 348class DeclarationRefDecl(DeclWithParent[Decl]): 349 symbol: str 350 351 pkg_ref: PackageRefDecl 352 353 is_resolved: bool = False 354 """Whether this declaration reference is resolved.""" 355 356 maybe_resolved_decl: "PackageLevelDecl | None" = None 357 """The resolved declaration, if any. 358 359 This field is `None` either if the declaration reference is not resolved yet, 360 or if the declaration reference is invalid. 361 """ 362 363 def __init__( 364 self, 365 loc: SourceLocation | None, 366 symbol: str, 367 pkg_ref: PackageRefDecl, 368 ): 369 super().__init__(loc) 370 self.symbol = symbol 371 self.pkg_ref = pkg_ref 372 pkg_ref.set_parent(self) 373 374 @property 375 @override 376 def description(self) -> str: 377 return f"type reference {self.symbol}" 378 379 @property 380 def resolved_decl(self) -> "PackageLevelDecl": 381 pass 382 return self.maybe_resolved_decl 383 384 @override 385 def _accept(self, v: "DeclVisitor[T]") -> Any: 386 return v.visit_declaration_ref_decl(self) 387 388 389####################### 390# Import Declarations # 391####################### 392 393 394class ImportDecl(NamedDeclWithParent["PackageDecl"], metaclass=ABCMeta): 395 """Represents a package or declaration import. 396 397 Invariant: the `name` field in base class `Decl` always represents actual name of imports. 398 399 For example: 400 401 ``` 402 >>> use foo; 403 PackageImportDecl(name='foo', pkg_ref=PackageRefDecl(name='foo')) 404 405 >>> use foo as bar; 406 PackageImportDecl(name='bar', pkg_ref=PackageRefDecl(name='foo')) 407 408 >>> from foo use Bar; 409 DeclarationImportDecl( 410 name='Bar', 411 decl_ref=DeclarationRefDecl(name='Bar', pkg_ref=PackageRefDecl(name='foo')), 412 ) 413 414 >>> from foo use Bar as Baz; 415 DeclarationImportDecl( 416 name='Baz', 417 decl_ref=DeclarationRefDecl(name='Bar', pkg_ref=PackageRefDecl(name='foo')), 418 ) 419 ``` 420 """ 421 422 423class PackageImportDecl(ImportDecl): 424 pkg_ref: PackageRefDecl 425 426 def __init__( 427 self, 428 pkg_ref: PackageRefDecl, 429 *, 430 loc: SourceLocation | None = None, 431 name: str = "", 432 ): 433 super().__init__( 434 name=name or pkg_ref.symbol, 435 loc=loc or pkg_ref.loc, 436 ) 437 self.pkg_ref = pkg_ref 438 pkg_ref.set_parent(self) 439 440 @property 441 @override 442 def description(self) -> str: 443 return f"package import {self.name}" 444 445 def is_alias(self) -> bool: 446 return self.name != self.pkg_ref.symbol 447 448 @override 449 def _accept(self, v: "DeclVisitor[T]") -> Any: 450 return v.visit_package_import_decl(self) 451 452 453class DeclarationImportDecl(ImportDecl): 454 decl_ref: DeclarationRefDecl 455 456 def __init__( 457 self, 458 decl_ref: DeclarationRefDecl, 459 *, 460 loc: SourceLocation | None = None, 461 name: str = "", 462 ): 463 super().__init__( 464 name=name or decl_ref.symbol, 465 loc=loc or decl_ref.loc, 466 ) 467 self.decl_ref = decl_ref 468 decl_ref.set_parent(self) 469 470 @property 471 @override 472 def description(self) -> str: 473 return f"declaration import {self.name}" 474 475 def is_alias(self) -> bool: 476 return self.name != self.decl_ref.symbol 477 478 @override 479 def _accept(self, v: "DeclVisitor[T]") -> Any: 480 return v.visit_decl_import_decl(self) 481 482 483############################ 484# Field Level Declarations # 485############################ 486 487 488class EnumItemDecl(NamedDeclWithParent["EnumDecl"]): 489 value: int | float | str | bool | None 490 491 def __init__( 492 self, 493 loc: SourceLocation | None, 494 name: str, 495 value: int | float | str | bool | None = None, 496 ): 497 super().__init__(loc, name) 498 self.value = value 499 500 @property 501 @override 502 def description(self): 503 return f"enum item {self.name}" 504 505 @property 506 def parent_enum(self) -> "EnumDecl": 507 pass 508 return self._node_parent 509 510 @override 511 def _accept(self, v: "DeclVisitor[T]") -> Any: 512 return v.visit_enum_item_decl(self) 513 514 515class UnionFieldDecl(NamedDeclWithParent["UnionDecl"]): 516 ty_ref: TypeRefDecl | None 517 518 def __init__( 519 self, 520 loc: SourceLocation | None, 521 name: str, 522 ty_ref: TypeRefDecl | None = None, 523 ): 524 super().__init__(loc, name) 525 self.ty_ref = ty_ref 526 if ty_ref: 527 ty_ref.set_parent(self) 528 529 @property 530 @override 531 def description(self) -> str: 532 return f"union field {self.name}" 533 534 @property 535 def parent_union(self) -> "UnionDecl": 536 pass 537 return self._node_parent 538 539 @override 540 def _accept(self, v: "DeclVisitor[T]") -> Any: 541 return v.visit_union_field_decl(self) 542 543 544class StructFieldDecl(NamedDeclWithParent["StructDecl"]): 545 ty_ref: TypeRefDecl 546 547 def __init__( 548 self, 549 loc: SourceLocation | None, 550 name: str, 551 ty_ref: TypeRefDecl, 552 ): 553 super().__init__(loc, name) 554 self.ty_ref = ty_ref 555 ty_ref.set_parent(self) 556 557 @property 558 @override 559 def description(self) -> str: 560 return f"struct field {self.name}" 561 562 @property 563 def parent_struct(self) -> "StructDecl": 564 pass 565 return self._node_parent 566 567 @override 568 def _accept(self, v: "DeclVisitor[T]") -> Any: 569 return v.visit_struct_field_decl(self) 570 571 572class IfaceParentDecl(DeclWithParent["IfaceDecl"]): 573 ty_ref: TypeRefDecl 574 575 def __init__( 576 self, 577 loc: SourceLocation | None, 578 ty_ref: TypeRefDecl, 579 ): 580 super().__init__(loc) 581 self.ty_ref = ty_ref 582 ty_ref.set_parent(self) 583 584 @property 585 @override 586 def description(self) -> str: 587 return f"interface parent ({self.ty_ref.description})" 588 589 @property 590 def parent_iface(self) -> "IfaceDecl": 591 pass 592 return self._node_parent 593 594 @override 595 def _accept(self, v: "DeclVisitor[T]") -> Any: 596 return v.visit_iface_parent_decl(self) 597 598 599class IfaceMethodDecl(NamedDeclWithParent["IfaceDecl"]): 600 params: list[ParamDecl] 601 return_ty_ref: TypeRefDecl | None 602 603 def __init__( 604 self, 605 loc: SourceLocation | None, 606 name: str, 607 return_ty_ref: TypeRefDecl | None = None, 608 ): 609 super().__init__(loc, name) 610 self.params = [] 611 self.return_ty_ref = return_ty_ref 612 if return_ty_ref: 613 return_ty_ref.set_parent(self) 614 615 @property 616 @override 617 def description(self) -> str: 618 return f"interface method {self.name}" 619 620 @property 621 def parent_iface(self) -> "IfaceDecl": 622 pass 623 return self._node_parent 624 625 def add_param(self, p: ParamDecl): 626 self.params.append(p) 627 p.set_parent(self) 628 629 @override 630 def _accept(self, v: "DeclVisitor[T]") -> Any: 631 return v.visit_iface_func_decl(self) 632 633 634############################## 635# Package Level Declarations # 636############################## 637 638 639class PackageLevelDecl(NamedDeclWithParent["PackageDecl"], metaclass=ABCMeta): 640 @property 641 def full_name(self): 642 return f"{self.parent_pkg.name}.{self.name}" 643 644 645class GlobFuncDecl(PackageLevelDecl): 646 params: list[ParamDecl] 647 return_ty_ref: TypeRefDecl | None 648 649 def __init__( 650 self, 651 loc: SourceLocation | None, 652 name: str, 653 return_ty_ref: TypeRefDecl | None = None, 654 ): 655 super().__init__(loc, name) 656 self.params = [] 657 self.return_ty_ref = return_ty_ref 658 if return_ty_ref: 659 return_ty_ref.set_parent(self) 660 661 @property 662 @override 663 def description(self) -> str: 664 return f"function {self.name}" 665 666 def add_param(self, p: ParamDecl): 667 self.params.append(p) 668 p.set_parent(self) 669 670 @override 671 def _accept(self, v: "DeclVisitor[T]") -> Any: 672 return v.visit_glob_func_decl(self) 673 674 675##################### 676# Type Declarations # 677##################### 678 679 680class TypeDecl(PackageLevelDecl, metaclass=ABCMeta): 681 @abstractmethod 682 def as_type(self, ty_ref: TypeRefDecl) -> UserType: 683 """Return the type decalaration as type.""" 684 685 686class EnumDecl(TypeDecl): 687 items: list[EnumItemDecl] 688 ty_ref: TypeRefDecl 689 690 def __init__( 691 self, 692 loc: SourceLocation | None, 693 name: str, 694 ty_ref: TypeRefDecl, 695 ): 696 super().__init__(loc, name) 697 self.items = [] 698 self.ty_ref = ty_ref 699 ty_ref.set_parent(self) 700 701 @property 702 @override 703 def description(self) -> str: 704 return f"enum {self.name}" 705 706 def add_item(self, i: EnumItemDecl): 707 self.items.append(i) 708 i.set_parent(self) 709 710 @override 711 def as_type(self, ty_ref: TypeRefDecl) -> EnumType: 712 return EnumType(ty_ref, self) 713 714 @override 715 def _accept(self, v: "DeclVisitor[T]") -> Any: 716 return v.visit_enum_decl(self) 717 718 719class UnionDecl(TypeDecl): 720 fields: list[UnionFieldDecl] 721 722 def __init__(self, loc: SourceLocation | None, name: str): 723 super().__init__(loc, name) 724 self.fields = [] 725 726 @property 727 @override 728 def description(self) -> str: 729 return f"union {self.name}" 730 731 def add_field(self, f: UnionFieldDecl): 732 self.fields.append(f) 733 f.set_parent(self) 734 735 @override 736 def as_type(self, ty_ref: TypeRefDecl) -> UnionType: 737 return UnionType(ty_ref, self) 738 739 @override 740 def _accept(self, v: "DeclVisitor[T]") -> Any: 741 return v.visit_union_decl(self) 742 743 744class StructDecl(TypeDecl): 745 fields: list[StructFieldDecl] 746 747 def __init__(self, loc: SourceLocation | None, name: str): 748 super().__init__(loc, name) 749 self.fields = [] 750 751 @property 752 @override 753 def description(self) -> str: 754 return f"struct {self.name}" 755 756 def add_field(self, f: StructFieldDecl): 757 self.fields.append(f) 758 f.set_parent(self) 759 760 @override 761 def as_type(self, ty_ref: TypeRefDecl) -> StructType: 762 return StructType(ty_ref, self) 763 764 @override 765 def _accept(self, v: "DeclVisitor[T]") -> Any: 766 return v.visit_struct_decl(self) 767 768 769class IfaceDecl(TypeDecl): 770 methods: list[IfaceMethodDecl] 771 parents: list[IfaceParentDecl] 772 773 def __init__(self, loc: SourceLocation | None, name: str): 774 super().__init__(loc, name) 775 self.methods = [] 776 self.parents = [] 777 778 @property 779 @override 780 def description(self) -> str: 781 return f"interface {self.name}" 782 783 def add_method(self, f: IfaceMethodDecl): 784 self.methods.append(f) 785 f.set_parent(self) 786 787 def add_parent(self, p: IfaceParentDecl): 788 self.parents.append(p) 789 p.set_parent(self) 790 791 @override 792 def as_type(self, ty_ref: TypeRefDecl) -> IfaceType: 793 return IfaceType(ty_ref, self) 794 795 @override 796 def _accept(self, v: "DeclVisitor[T]") -> Any: 797 return v.visit_iface_decl(self) 798 799 800###################### 801# The main container # 802###################### 803 804 805class PackageDecl(NamedDecl): 806 """A collection of named identities sharing the same scope.""" 807 808 _node_parent: "PackageGroup | None" = None 809 810 # Imports 811 _pkg_import_dict: dict[str, PackageImportDecl] 812 _decl_import_dict: dict[str, DeclarationImportDecl] 813 814 # Symbols 815 _declaration_dict: dict[str, PackageLevelDecl] 816 817 # Things that the package contains. 818 functions: list[GlobFuncDecl] 819 structs: list[StructDecl] 820 unions: list[UnionDecl] 821 interfaces: list[IfaceDecl] 822 enums: list[EnumDecl] 823 824 def __init__(self, name: str, loc: SourceLocation | None): 825 super().__init__(loc, name) 826 827 self._pkg_import_dict = {} 828 self._decl_import_dict = {} 829 830 self._declaration_dict = {} 831 832 self.functions = [] 833 self.structs = [] 834 self.unions = [] 835 self.interfaces = [] 836 self.enums = [] 837 838 @property 839 @override 840 def description(self) -> str: 841 return f"package {self.name}" 842 843 @property 844 @override 845 def parent_pkg(self) -> "PackageDecl": 846 return self 847 848 @property 849 def parent_group(self) -> "PackageGroup": 850 pass 851 return self._node_parent 852 853 @property 854 def segments(self) -> list[str]: 855 return self.name.split(".") 856 857 @property 858 def pkg_imports(self) -> Iterable[PackageImportDecl]: 859 return self._pkg_import_dict.values() 860 861 @property 862 def decl_imports(self) -> Iterable[DeclarationImportDecl]: 863 return self._decl_import_dict.values() 864 865 @property 866 def declarations(self) -> Iterable[PackageLevelDecl]: 867 return self._declaration_dict.values() 868 869 def set_group(self, group: "PackageGroup"): 870 self._node_parent = group 871 872 def lookup(self, name: str) -> PackageLevelDecl | None: 873 return self._declaration_dict.get(name) 874 875 def lookup_pkg_import(self, name: str) -> PackageImportDecl | None: 876 return self._pkg_import_dict.get(name) 877 878 def lookup_decl_import(self, name: str) -> DeclarationImportDecl | None: 879 return self._decl_import_dict.get(name) 880 881 def add_import(self, i: ImportDecl): 882 if isinstance(i, DeclarationImportDecl): 883 self.add_decl_import(i) 884 elif isinstance(i, PackageImportDecl): 885 self.add_pkg_import(i) 886 else: 887 raise NotImplementedError(f"unexpected import {i.description}") 888 889 def add_decl_import(self, i: DeclarationImportDecl): 890 if (prev := self._decl_import_dict.setdefault(i.name, i)) != i: 891 raise DeclRedefError(prev, i) 892 i.set_parent(self) 893 894 def add_pkg_import(self, i: PackageImportDecl): 895 if (prev := self._pkg_import_dict.setdefault(i.name, i)) != i: 896 raise DeclRedefError(prev, i) 897 i.set_parent(self) 898 899 def add_declaration(self, d: PackageLevelDecl): 900 if isinstance(d, GlobFuncDecl): 901 self.add_function(d) 902 elif isinstance(d, StructDecl): 903 self.add_struct(d) 904 elif isinstance(d, UnionDecl): 905 self.add_union(d) 906 elif isinstance(d, IfaceDecl): 907 self.add_interface(d) 908 elif isinstance(d, EnumDecl): 909 self.add_enum(d) 910 else: 911 raise NotImplementedError(f"unexpected declaration {d.description}") 912 913 def add_function(self, f: GlobFuncDecl): 914 self._register_to_decl(f) 915 self.functions.append(f) 916 f.set_parent(self) 917 918 def add_enum(self, e: EnumDecl): 919 self._register_to_decl(e) 920 self.enums.append(e) 921 e.set_parent(self) 922 923 def add_struct(self, s: StructDecl): 924 self._register_to_decl(s) 925 self.structs.append(s) 926 s.set_parent(self) 927 928 def add_union(self, u: UnionDecl): 929 self._register_to_decl(u) 930 self.unions.append(u) 931 u.set_parent(self) 932 933 def add_interface(self, i: IfaceDecl): 934 self._register_to_decl(i) 935 self.interfaces.append(i) 936 i.set_parent(self) 937 938 def _register_to_decl(self, d: PackageLevelDecl): 939 if (prev := self._declaration_dict.setdefault(d.name, d)) != d: 940 raise DeclRedefError(prev, d) 941 942 @override 943 def _accept(self, v: "DeclVisitor[T]") -> Any: 944 return v.visit_package_decl(self) 945 946 947class PackageGroup: 948 """Stores all known packages for a compilation instance.""" 949 950 _package_dict: dict[str, PackageDecl] 951 952 def __init__(self): 953 super().__init__() 954 self._package_dict = {} 955 956 def __repr__(self) -> str: 957 packages_str = ", ".join(repr(x) for x in self._package_dict) 958 return f"{self.__class__.__qualname__}({packages_str})" 959 960 @property 961 def packages(self) -> Iterable[PackageDecl]: 962 return self._package_dict.values() 963 964 def lookup(self, name: str) -> PackageDecl | None: 965 return self._package_dict.get(name) 966 967 def add(self, d: PackageDecl): 968 if (prev := self._package_dict.setdefault(d.name, d)) != d: 969 raise DeclRedefError(prev, d) 970 d.set_group(self) 971 972 def _accept(self, v: "DeclVisitor[T]"): 973 return v.visit_package_group(self)