Fixing the Comment Flag Insertion Bug
During our development session today, we discovered an interesting bug in how Aditi handles comment flags for non-deterministic violations. The question that led to this discovery was simple but insightful: “Does Aditi work from bottom to top when inserting comments?”
The Discovery
When examining the code to answer this question, we found that while Aditi correctly sorts fixes in reverse order (bottom-to-top), there was a fundamental issue with how comment flags were being applied.
Expected behavior: When flagging a violation, insert a comment on the line above:
// AsciiDocDITA.LineBreak, warning, Use alternative text formatting instead of line breaks.
This line has a +
line break violation.
Actual behavior: The comment was replacing the violation text itself!
Root Cause Analysis
The bug was in the _apply_fixes_to_file
method in processor.py
. Here’s what was happening:
- Non-deterministic rules create
Fix
objects withreplacement_text
containing the comment - The processor treats all fixes as replacements by default
- Comment flags were replacing the original text instead of being inserted above it
The code had special handling for insert_at_line
and line_to_replace
attributes, but comment flags weren’t using either of these mechanisms.
The Fix
We added detection for comment flags using the existing is_comment_flag
property:
if fix.is_comment_flag:
# Insert comment on the line above the violation
lines = content.splitlines(keepends=True)
line_idx = fix.violation.line - 1
if 0 <= line_idx < len(lines):
# Insert the comment before the violation line
lines.insert(line_idx, fix.replacement_text + '\n')
content = ''.join(lines)
applied_fixes.append(fix)
Why Bottom-to-Top Matters
The existing bottom-to-top processing (sorting fixes by line number in reverse) is crucial for maintaining line number accuracy:
# Sort fixes by line number (reverse order to avoid offset issues)
sorted_fixes = sorted(fixes, key=lambda f: f.violation.line, reverse=True)
When you insert a line at position 10, all subsequent lines (11, 12, 13…) shift down by one. By processing from bottom to top:
- Insert at line 50 → doesn’t affect lines 1-49
- Insert at line 30 → doesn’t affect lines 1-29
- Insert at line 10 → all previous insertions remain accurate
Lessons Learned
- Question assumptions: The user’s question revealed our assumption that fixes were always replacements
- Semantic clarity: Having an
is_comment_flag
property made the fix clean and obvious - Test edge cases: Comment insertion is fundamentally different from text replacement
- Bottom-to-top is essential: For any operation that changes line numbers
This fix ensures that technical writers reviewing flagged violations will see clear comments above each issue, making the review process much more intuitive.