[OverlayLibrary] allow rename into a name we previously renamed out of

This commit is contained in:
Jan Petykiewicz 2026-09-14 21:57:07 -07:00
commit eb81101672
2 changed files with 46 additions and 23 deletions

View file

@ -273,7 +273,6 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
self._layers: list[_SourceLayer] = []
self._entries: dict[str, Pattern | _SourceEntry] = {}
self._order: list[str] = []
self._target_remap: dict[str, str] = {}
def __iter__(self) -> Iterator[str]:
return (name for name in self._order if name in self._entries)
@ -345,6 +344,10 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
source_target_map=dict(source_to_visible),
child_graph=child_graph,
)
# Include dangling targets so each source tracks current names directly.
for children in child_graph.values():
for child in children:
layer.source_target_map.setdefault(child, child)
layer_index = len(self._layers)
self._layers.append(layer)
@ -371,6 +374,7 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
entry = self._entries.pop(old_name)
self._entries[new_name] = entry
self._order = [name for name in self._order if name != new_name]
idx = self._order.index(old_name)
self._order[idx] = new_name
@ -378,28 +382,13 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
self.move_references(old_name, new_name)
return self
def _resolve_target(self, target: str) -> str:
seen: set[str] = set()
current = target
while current in self._target_remap:
if current in seen:
raise LibraryError(f'Cycle encountered while resolving target remap for {target!r}')
seen.add(current)
current = self._target_remap[current]
return current
def _set_target_remap(self, old_target: str, new_target: str) -> None:
resolved_new = self._resolve_target(new_target)
if resolved_new == old_target:
raise LibraryError(f'Ref target remap would create a cycle: {old_target!r} -> {new_target!r}')
self._target_remap[old_target] = resolved_new
for key in list(self._target_remap):
self._target_remap[key] = self._resolve_target(self._target_remap[key])
def move_references(self, old_target: str, new_target: str) -> OverlayLibrary:
if old_target == new_target:
return self
self._set_target_remap(old_target, new_target)
for layer in self._layers:
for source_target, current_target in layer.source_target_map.items():
if current_target == old_target:
layer.source_target_map[source_target] = new_target
for entry in list(self._entries.values()):
if isinstance(entry, Pattern) and old_target in entry.refs:
entry.refs[new_target].extend(entry.refs[old_target])
@ -407,8 +396,7 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
return self
def _effective_target(self, layer: _SourceLayer, target: str) -> str:
visible = layer.source_target_map.get(target, target)
return self._resolve_target(visible)
return layer.source_target_map.get(target, target)
def _remap_source_pattern(self, layer: _SourceLayer, source_pat: Pattern) -> Pattern:
def remap(target: str | None) -> str | None:
@ -528,7 +516,6 @@ class OverlayLibrary(ILibrary, IMaterializable, IBorrowing):
]
new._order = [name for name in self._order if name in keep and name in self._entries]
new._entries = {name: self._entries[name] for name in new._order}
new._target_remap = dict(self._target_remap)
return new
def find_refs_local(