Skip to content

Commit 8d79bac

Browse files
committed
Add bracenewline.py
Also renamed newline.py to eofnewline.py.
1 parent 41d53da commit 8d79bac

File tree

5 files changed

+169
-6
lines changed

5 files changed

+169
-6
lines changed

wpiformat/test/test_bracenewline.py

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

wpiformat/test/test_newline.py 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 test.tasktest import *
4-
from wpiformat.newline import Newline
4+
from wpiformat.eofnewline import EofNewline
55

66

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

1010
file_appendix = \
1111
"#pragma once" + os.linesep + \

wpiformat/wpiformat/__init__.py

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

1111
from wpiformat.bracecomment import BraceComment
12+
from wpiformat.bracenewline import BraceNewline
1213
from wpiformat.cidentlist import CIdentList
1314
from wpiformat.clangformat import ClangFormat
1415
from wpiformat.config import Config
16+
from wpiformat.eofnewline import EofNewline
1517
from wpiformat.includeguard import IncludeGuard
1618
from wpiformat.includeorder import IncludeOrder
1719
from wpiformat.javaclass import JavaClass
1820
from wpiformat.jni import Jni
1921
from wpiformat.licenseupdate import LicenseUpdate
2022
from wpiformat.lint import Lint
21-
from wpiformat.newline import Newline
2223
from wpiformat.pyformat import PyFormat
2324
from wpiformat.stdlib import Stdlib
2425
from wpiformat.task import Task
@@ -351,11 +352,12 @@ def main():
351352
# so it can clean up their formatting.
352353
task_pipeline = [
353354
BraceComment(),
355+
BraceNewline(),
354356
CIdentList(),
357+
EofNewline(),
355358
IncludeGuard(),
356359
LicenseUpdate(str(args.year)),
357360
JavaClass(),
358-
Newline(),
359361
Stdlib(),
360362
IncludeOrder(),
361363
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 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)