Resolve a Pascal class/interface name to the node ID of its defining file's class node. Pascal convention: TFooBar is defined in FooBar.pas, IFooBar in FooBar.pas. Strips the leading T/I prefix, finds the file, and returns _make_id(_file_stem(found_file), class_name). Returns None
(from_path: Path, class_name: str)
| 13027 | |
| 13028 | |
| 13029 | def _pascal_resolve_class(from_path: Path, class_name: str) -> str | None: |
| 13030 | """Resolve a Pascal class/interface name to the node ID of its defining file's class node. |
| 13031 | |
| 13032 | Pascal convention: TFooBar is defined in FooBar.pas, IFooBar in FooBar.pas. |
| 13033 | Strips the leading T/I prefix, finds the file, and returns |
| 13034 | _make_id(_file_stem(found_file), class_name). |
| 13035 | |
| 13036 | Returns None when no matching file is found on disk (RTL, stdlib, or |
| 13037 | unconventionally-named class — caller should create a stub node). |
| 13038 | """ |
| 13039 | prefix = class_name[:1] |
| 13040 | unit_name = class_name[1:] if prefix in ("T", "I") else class_name |
| 13041 | |
| 13042 | root = _pascal_project_root(from_path) |
| 13043 | root_key = str(root) |
| 13044 | if root_key not in _pascal_class_stem_cache: |
| 13045 | stem_map: dict[str, str] = {} |
| 13046 | for ext in (".pas", ".pp", ".dpr", ".dpk"): |
| 13047 | for f in root.rglob("*" + ext): |
| 13048 | stem_map[f.stem.lower()] = _file_stem(f) |
| 13049 | _pascal_class_stem_cache[root_key] = stem_map |
| 13050 | |
| 13051 | file_stem = _pascal_class_stem_cache[root_key].get(unit_name.lower()) |
| 13052 | if file_stem: |
| 13053 | return _make_id(file_stem, class_name) |
| 13054 | return None |
| 13055 | |
| 13056 | |
| 13057 | _PAS_TOKEN_RE = re.compile( |
no test coverage detected