-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathComment_Fixer.py
More file actions
119 lines (97 loc) · 4.56 KB
/
Comment_Fixer.py
File metadata and controls
119 lines (97 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import os
import re
def fix_dart_comments(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
fixed_lines = []
i = 0
in_header = True
# Keywords to identify logical code blocks that should stay compact
code_keywords = [r'debugPrint\(', r'print\(', r'if\s*\(', r'final\s+', r'var\s+', r'return\s+', r'await\s+']
while i < len(lines):
line = lines[i]
stripped = line.strip()
# 1. Skip file header (Copyright/Licence blocks)
if in_header and stripped != "" and not stripped.startswith('//'):
in_header = False
if in_header or not stripped.startswith('//'):
fixed_lines.append(line)
i += 1
continue
# 2. Skip machine instructions (ignore / ignore_for_file)
if re.match(r'^//\s*ignore(_for_file)?:', stripped):
fixed_lines.append(line)
i += 1
continue
# --- 3. Process Comment Blocks ---
comment_block = []
indentation = len(line) - len(line.lstrip()) # Detect indentation level
while i < len(lines):
curr_stripped = lines[i].strip()
# Stop if the line is not a comment or is a machine instruction
if not curr_stripped.startswith('//') or re.match(r'^//\s*ignore(_for_file)?:', curr_stripped):
break
comment_block.append(lines[i])
i += 1
if not comment_block:
continue
# Process Full Stops (only on the last line of a block)
processed_block = []
for index, c_line in enumerate(comment_block):
c_stripped = c_line.strip()
is_code = any(re.search(kw, c_stripped) for kw in code_keywords)
# Apply full stop if it's the last line, is English, and not a code snippet
if index == len(comment_block) - 1 and not is_code:
if re.search(r'//\s+[A-Za-z0-9].*[^.!?:\;\'"]$', c_stripped):
if re.search(r'[A-Za-z]', c_stripped):
c_line = c_line.rstrip() + '.\n'
processed_block.append(c_line)
# --- Rule A: Blank Line BEFORE ---
if len(fixed_lines) > 0:
prev_line = fixed_lines[-1].strip()
# Exempt if follows opening brackets or is already separated
skip_before = prev_line.endswith('(') or prev_line.endswith('{') or \
prev_line.endswith('[') or \
prev_line == "" or prev_line.startswith('//')
if not skip_before:
fixed_lines.append('\n')
fixed_lines.extend(processed_block)
# --- Rule B: Blank Line AFTER ---
if i < len(lines):
next_line = lines[i].strip()
# Logic Step Exemption: Keep compact if inside a method and followed by logic keywords
is_logic_step = indentation > 0 and (
next_line.startswith('final ') or
next_line.startswith('var ') or
next_line.startswith('await ') or
next_line.startswith('if (')
)
# Exempt if followed by closing brackets, commas, named parameters, or logic steps
skip_after = next_line.startswith(')') or next_line.startswith('}') or \
next_line.startswith(']') or next_line.startswith(',') or \
re.search(r'^\w+:', next_line) or \
is_logic_step or \
next_line == "" or next_line.startswith('//')
if not skip_after:
fixed_lines.append('\n')
return fixed_lines
def main():
print("🚀 Running Comment Fixer...")
count = 0
for root, dirs, files in os.walk('.'):
# Skip hidden directories like .dart_tool
dirs[:] = [d for d in dirs if not d.startswith('.')]
for file in files:
if file.endswith('.dart'):
file_path = os.path.join(root, file)
with open(file_path, 'r', encoding='utf-8') as f:
original = f.readlines()
fixed = fix_dart_comments(file_path)
if original != fixed:
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(fixed)
print(f"✅ Formatted: {file_path}")
count += 1
print(f"\n✨ Process complete! {count} files were updated.")
if __name__ == "__main__":
main()