(input_path: Optional[str], libapp_path: Optional[str])
| 619 | return library_ids[normalized] |
| 620 | |
| 621 | def ensure_class(library: Optional[int], name: str, super_name: Optional[str]) -> int: |
| 622 | key = (library, name) |
| 623 | if key not in class_ids: |
| 624 | class_ids[key] = len(class_ids) |
| 625 | class_names.setdefault(name, class_ids[key]) |
| 626 | if super_name: |
| 627 | class_supers[class_ids[key]] = super_name |
| 628 | return class_ids[key] |
| 629 | |
| 630 | for dart_file in sorted(asm_dir.rglob("*.dart")): |
| 631 | current_lib: Optional[int] = None |
| 632 | current_class: Optional[int] = None |
| 633 | pending_name: Optional[str] = None |
| 634 | pending_owner: Optional[int] = None |
| 635 | |
| 636 | for line in dart_file.read_text(encoding="utf-8", errors="ignore").splitlines(): |
| 637 | m_header = header_re.match(line.strip()) |
| 638 | if m_header: |
| 639 | current_lib = ensure_library(m_header.group(1).strip()) |
| 640 | current_class = None |
| 641 | pending_name = None |
| 642 | continue |
| 643 | |
| 644 | decl = _parse_blutter_class_decl(line) |
| 645 | if decl is not None: |
| 646 | cls_name, super_name = decl |
| 647 | current_class = ( |
| 648 | ensure_class(current_lib, cls_name, super_name) if cls_name else None |
| 649 | ) |
| 650 | pending_name = None |
| 651 | continue |
| 652 | |
| 653 | stripped = line.strip() |
| 654 | if line.startswith(" ") and stripped.endswith("{") and not stripped.startswith("//"): |
| 655 | head_name = _extract_blutter_function_name(line) |
| 656 | if head_name: |
| 657 | pending_name = head_name |
| 658 | pending_owner = current_class |
| 659 | |
| 660 | m_addr = addr_re.search(line) |
| 661 | if not m_addr: |
| 662 | continue |
| 663 | try: |
| 664 | entry = int(m_addr.group(1), 16) |
| 665 | size = int(m_addr.group(2), 16) |
| 666 | except ValueError: |
| 667 | continue |
no test coverage detected