Modify¶
{ #dev-architecture-code-modify }
Stable ID: ARCH-CODE-MODIFY
Purpose¶
Document the design decisions that determine how the modify step is implemented within the find-filter-modify workflow.
Scope¶
The modify step transforms code at matched locations that have passed the filter step. It does not locate or filter matches — those are the responsibilities of the find and filter steps.
Definition¶
When a match is found, the modify step either replaces the entire match or performs targeted manipulation within it.
Replace vs manipulate¶
Replace substitutes the entire matched node with new text or a new pattern. Manipulate performs targeted modifications within the match, such as inserting text before a placeholder or replacing a placeholder within the match.
Code owners typically prefer minimally invasive changes: layout should be preserved and comments should not be removed. Because whitespace and comments are ignored when building an AST, manipulation within the match produces smaller diffs that are easier for code owners to review and accept.
Decision¶
Both complete replacement of a match and manipulation within a match are supported.
Replacement text vs pattern¶
Replacing with text enables unstructured replacement, including migration to another programming language (transpilation).
Replacing with a pattern enables:
- enforcing correctness by checking that the find and replacement patterns share a base type;
- correctly handling syntax tokens, including separators, when placeholders are empty — for example:
- the keyword
elseis absent when that branch has no statements; - in the function call
f($$before, 1), the comma is removed when$$beforeis empty.
Decision - Replacement text vs pattern¶
At minimum, replacement by text is supported.
AST-aware removal¶
When an AST node is removed, the resulting code may no longer be syntactically correct.
For example, removing the function call f() from:
if cond:
f()
results in invalid Python code.
Correctness of the final code is not guaranteed by text replacement.
Decision - AST-aware removal¶
The user is responsible for ensuring that removal of an AST node results in correct code.
For efficiency, it is recommended that the standard libraries provide, for each language, functionality for correct removal of an AST node in all situations.
Meta data¶
Analysis or a match (with a failing filter) do not justify that the the file or folder containing that source code changes. This not only holds for the content, but also the meta-data of the file and folder. A file and folder, including their meta-data, are only allowed to change when the contained source code changes.
Identity transformations¶
An identity transformation, like a node replaced by itself, is a corner case in which nothing syntactically and semantically changes.
Should an identity transformation be considered a change?
The memory usage increases when the original content and the modified content have to be compared.
As file access is slow, preventing unnecessary file access will improve execution performance.
Scarce resources are needed to develop and maintain the logic to check for real, non-trivial changes.
A transformation can always be designed, e.g., by including an equality check, to not perform the identity transformation.
Decision - Identity transformations¶
As performance is not considered a bottleneck, we decided not to check for the corner case of the identity transformation.
Invariants / guarantees¶
- Both complete replacement and manipulation within a match are supported.
- At minimum, replacement by text is supported.
- The user is responsible for ensuring that node removal produces syntactically correct code.