Skip to content

Commit 8c72589

Browse files
committed
Add bracenewline.py
Also renamed newline.py to eofnewline.py.
1 parent e340651 commit 8c72589

File tree

5 files changed

+180
-6
lines changed

5 files changed

+180
-6
lines changed

wpiformat/test/test_bracenewline.py

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import os
2+
3+
from wpiformat.config import Config
4+
from wpiformat.bracenewline import BraceNewline
5+
6+
7+
def test_bracenewline():
8+
task = BraceNewline()
9+
10+
inputs = []
11+
outputs = []
12+
13+
# Brackets on same line
14+
inputs.append(("./Test.cpp",
15+
"void func1() {}" + os.linesep + \
16+
"void func2() {}" + os.linesep))
17+
outputs.append((
18+
"void func1() {}" + os.linesep + \
19+
os.linesep + \
20+
"void func2() {}" + os.linesep, True, True))
21+
22+
# Brackets on next line
23+
inputs.append(("./Test.cpp",
24+
"void func1() {" + os.linesep + \
25+
"}" + os.linesep + \
26+
"void func2() {" + os.linesep + \
27+
"}" + os.linesep))
28+
outputs.append((
29+
"void func1() {" + os.linesep + \
30+
"}" + os.linesep + \
31+
os.linesep + \
32+
"void func2() {" + os.linesep + \
33+
"}" + os.linesep, True, True))
34+
35+
# Comments after brackets
36+
inputs.append(("./Test.cpp",
37+
"void func1() {" + os.linesep + \
38+
"} // This is a comment" + os.linesep + \
39+
"void func2() {" + os.linesep + \
40+
"} /* This is a comment */" + os.linesep + \
41+
"void func3() {" + os.linesep + \
42+
"}" + os.linesep))
43+
outputs.append((
44+
"void func1() {" + os.linesep + \
45+
"} // This is a comment" + os.linesep + \
46+
os.linesep + \
47+
"void func2() {" + os.linesep + \
48+
"} /* This is a comment */" + os.linesep + \
49+
os.linesep + \
50+
"void func3() {" + os.linesep + \
51+
"}" + os.linesep, True, True))
52+
53+
# Don't add line separators to uncondensed if statements (after last brace
54+
# is OK)
55+
inputs.append(("./Test.cpp",
56+
"void func1() {" + os.linesep + \
57+
" if (1) {" + os.linesep + \
58+
" }" + os.linesep + \
59+
" else {" + os.linesep + \
60+
" }" + os.linesep + \
61+
"}" + os.linesep))
62+
outputs.append((inputs[len(inputs) - 1][1], False, True))
63+
64+
# Don't add line separators to condensed if statements (after last brace
65+
# is OK)
66+
inputs.append(("./Test.cpp",
67+
"void func1() {" + os.linesep + \
68+
" if (1) {" + os.linesep + \
69+
" } else if () {" + os.linesep + \
70+
" } else {" + os.linesep + \
71+
" // comment" + os.linesep + \
72+
" }" + os.linesep + \
73+
"}" + os.linesep))
74+
outputs.append((inputs[len(inputs) - 1][1], False, True))
75+
76+
# Don't add line separators before #endif statements
77+
inputs.append(("./Main.cpp",
78+
"using decay_t = typename decay<T>::type;" + os.linesep + \
79+
"} // namespace std" + os.linesep + \
80+
"#endif" + os.linesep))
81+
outputs.append((inputs[len(inputs) - 1][1], False, True))
82+
83+
# Don't insert line separators within multiline comments
84+
inputs.append(("./Main.java",
85+
"/* to fine tune the pid loop." + os.linesep + \
86+
" *" + os.linesep + \
87+
" * @return the {@link PIDController} used by this {@link PIDSubsystem}" + os.linesep + \
88+
" */" + os.linesep + \
89+
"public PIDController getPIDController() {" + os.linesep))
90+
outputs.append((inputs[len(inputs) - 1][1], False, True))
91+
92+
# Don't insert line separators within single line comments
93+
inputs.append(("./Main.java",
94+
"// @return the {@link PIDController} used by this {@link PIDSubsystem}" + os.linesep + \
95+
"public PIDController getPIDController() {" + os.linesep))
96+
outputs.append((inputs[len(inputs) - 1][1], False, True))
97+
98+
assert len(inputs) == len(outputs)
99+
100+
config_file = Config(os.path.abspath(os.getcwd()), ".styleguide")
101+
for i in range(len(inputs)):
102+
output, file_changed, success = task.run_pipeline(
103+
config_file, inputs[i][0], inputs[i][1])
104+
assert output == outputs[i][0]
105+
assert file_changed == outputs[i][1]
106+
assert success == outputs[i][2]

wpiformat/test/test_newline.py renamed to wpiformat/test/test_eofnewline.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import os
22

33
from wpiformat.config import Config
4-
from wpiformat.newline import Newline
4+
from wpiformat.eofnewline import EofNewline
55

66

7-
def test_newline():
8-
task = Newline()
7+
def test_eofnewline():
8+
task = EofNewline()
99

1010
inputs = []
1111
outputs = []

wpiformat/wpiformat/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
import sys
1010

1111
from wpiformat.bracecomment import BraceComment
12+
from wpiformat.bracenewline import BraceNewline
1213
from wpiformat.clangformat import ClangFormat
1314
from wpiformat.config import Config
15+
from wpiformat.eofnewline import EofNewline
1416
from wpiformat.includeguard import IncludeGuard
1517
from wpiformat.includeorder import IncludeOrder
1618
from wpiformat.javaclass import JavaClass
1719
from wpiformat.licenseupdate import LicenseUpdate
1820
from wpiformat.lint import Lint
19-
from wpiformat.newline import Newline
2021
from wpiformat.pyformat import PyFormat
2122
from wpiformat.stdlib import Stdlib
2223
from wpiformat.task import Task
@@ -329,10 +330,11 @@ def main():
329330
# so it can clean up their formatting.
330331
task_pipeline = [
331332
BraceComment(),
333+
BraceNewline(),
334+
EofNewline(),
332335
IncludeGuard(),
333336
LicenseUpdate(str(args.year)),
334337
JavaClass(),
335-
Newline(),
336338
Stdlib(),
337339
IncludeOrder(),
338340
UsingDeclaration(),

wpiformat/wpiformat/bracenewline.py

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""This task ensures braces are followed by two line separators."""
2+
3+
import re
4+
5+
from wpiformat.task import Task
6+
7+
8+
class BraceNewline(Task):
9+
10+
def should_process_file(self, config_file, name):
11+
return config_file.is_c_file(name) or config_file.is_cpp_file(
12+
name) or name.endswith("java")
13+
14+
def run_pipeline(self, config_file, name, lines):
15+
linesep = Task.get_linesep(lines)
16+
17+
comment_regex = re.compile("//|/\*|\*/")
18+
19+
lines_list = lines.split(linesep)
20+
21+
in_multiline_comment = False
22+
for i in range(len(lines_list)):
23+
match = comment_regex.search(lines_list[i])
24+
if not match:
25+
line = lines_list[i].rstrip()
26+
else:
27+
# While in a multiline comment, we only care about "*/"
28+
if in_multiline_comment:
29+
if match.group() == "*/":
30+
line = lines_list[i][
31+
match.start() + len("*/"):].rstrip()
32+
in_multiline_comment = False
33+
else:
34+
line = lines_list[i][0:match.start()].rstrip()
35+
36+
# If multiline comment is starting
37+
if match.group() == "/*":
38+
line = lines_list[i][0:match.start()]
39+
in_multiline_comment = True
40+
41+
# If comment ends on same line, handle it immediately
42+
comment_end = lines_list[i].find("*/")
43+
if comment_end != -1:
44+
line += lines_list[i][comment_end + len("*/"):]
45+
line = line.rstrip()
46+
in_multiline_comment = False
47+
48+
if in_multiline_comment:
49+
continue
50+
51+
# If line with "}" isn't at end of file
52+
if i + 1 < len(lines_list) and line.endswith("}"):
53+
next_line = lines_list[i + 1].lstrip()
54+
55+
# If next line is already empty, there's nothing to do
56+
if len(next_line) > 0:
57+
if next_line[0] != "}" and "else" not in next_line and "#endif" not in next_line:
58+
lines_list.insert(i + 1, "")
59+
i += 1
60+
61+
output = linesep.join(lines_list)
62+
63+
if output != lines:
64+
return (output, True, True)
65+
else:
66+
return (lines, False, True)

wpiformat/wpiformat/newline.py renamed to wpiformat/wpiformat/eofnewline.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from wpiformat.task import Task
44

55

6-
class Newline(Task):
6+
class EofNewline(Task):
77

88
def run_pipeline(self, config_file, name, lines):
99
output = lines.rstrip() + Task.get_linesep(lines)

0 commit comments

Comments
 (0)