Skip to content
Snippets Groups Projects
Commit 2ab59df2 authored by Campbell Barton's avatar Campbell Barton
Browse files

code_clean: add support for running edits in multiple passes

When an edit cannot be applied because it overlaps one that did,
re-run all edits again until no edits could be applied or the document
reaches a previously visited state (unlikely but possible in theory).
parent e4062ff4
Branches
Tags
No related merge requests found
......@@ -1153,6 +1153,18 @@ def wash_source_with_edits(arg_group: Tuple[str, str, str, str, bool, Any]) -> N
with open(source, 'r', encoding='utf-8') as fh:
data = fh.read()
edit_generator_class = edit_class_from_id(edit_to_apply)
# After performing all edits, store the result in this set.
#
# This is a heavy solution that guarantees edits never oscillate between
# multiple states, so re-visiting a previously visited state will always exit.
data_states = set()
# When overlapping edits are found, keep attempting edits.
edit_again = True
while edit_again:
edit_again = False
edits = edit_generator_class.edit_list_from_file(source, data, shared_edit_data)
# Sort by span, in a way that tries shorter spans first
# This is more efficient when testing multiple overlapping edits,
......@@ -1183,6 +1195,9 @@ def wash_source_with_edits(arg_group: Tuple[str, str, str, str, bool, Any]) -> N
for (start, end), text, text_always_fail, extra_build_args in edits:
if end >= edit_prev_start:
# Run the edits again, in case this would have succeeded,
# but was skipped due to edit-overlap.
edit_again = True
continue
build_args_for_edit = build_args
if extra_build_args:
......@@ -1213,6 +1228,18 @@ def wash_source_with_edits(arg_group: Tuple[str, str, str, str, bool, Any]) -> N
# Update the last successful edit, the end of the next edit must not overlap this one.
edit_prev_start = start
# Finished applying `edits`, check if further edits should be applied.
if edit_again:
data_states_len = len(data_states)
data_states.add(data)
if data_states_len == len(data_states):
# Avoid the *extremely* unlikely case that edits re-visit previously visited states.
edit_again = False
else:
# It is interesting to know how many passes run when debugging.
# print("Passes for: ", source, len(data_states))
pass
# -----------------------------------------------------------------------------
# Edit Source Code From Args
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment