-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added task for removing redundant "virtual" specifier instances
- Loading branch information
Showing
4 changed files
with
172 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import os | ||
|
||
from test.tasktest import * | ||
from wpiformat.virtualspecifier import VirtualSpecifier | ||
|
||
|
||
def test_virtualspecifier(): | ||
test = TaskTest(VirtualSpecifier()) | ||
|
||
# Redundant virtual specifier on function | ||
test.add_input("./PWM.h", | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" ~PWM() override;" + os.linesep + \ | ||
os.linesep + \ | ||
" protected:" + os.linesep + \ | ||
" virtual void InitSendable(SendableBuilder& builder) override;" + os.linesep + \ | ||
"};" + os.linesep) | ||
test.add_output( | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" ~PWM() override;" + os.linesep + \ | ||
os.linesep + \ | ||
" protected:" + os.linesep + \ | ||
" void InitSendable(SendableBuilder& builder) override;" + os.linesep + \ | ||
"};" + os.linesep, True, True) | ||
|
||
# Redundant virtual specifier on const function | ||
test.add_input("./PIDController.h", | ||
"class PIDController : public PIDInterface {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" virtual double GetP() const override;" + os.linesep + \ | ||
" virtual double GetI() const override;" + os.linesep + \ | ||
" virtual double GetD() const override;" + os.linesep + \ | ||
"};" + os.linesep) | ||
test.add_output( | ||
"class PIDController : public PIDInterface {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" double GetP() const override;" + os.linesep + \ | ||
" double GetI() const override;" + os.linesep + \ | ||
" double GetD() const override;" + os.linesep + \ | ||
"};" + os.linesep, True, True) | ||
|
||
# Redundant final specifier on const function | ||
test.add_input("./PIDController.h", | ||
"class PIDController : public PIDInterface {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" double GetP() const override;" + os.linesep + \ | ||
" double GetI() const final override;" + os.linesep + \ | ||
" double GetD() const override final;" + os.linesep + \ | ||
"};" + os.linesep) | ||
test.add_output( | ||
"class PIDController : public PIDInterface {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" double GetP() const override;" + os.linesep + \ | ||
" double GetI() const final;" + os.linesep + \ | ||
" double GetD() const final;" + os.linesep + \ | ||
"};" + os.linesep, True, True) | ||
|
||
# Redundant virtual specifier on destructor | ||
test.add_input("./PWM.h", | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" virtual ~PWM() override;" + os.linesep + \ | ||
os.linesep + \ | ||
" virtual void SetRaw(uint16_t value);" + os.linesep + \ | ||
"};" + os.linesep) | ||
test.add_output( | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" ~PWM() override;" + os.linesep + \ | ||
os.linesep + \ | ||
" virtual void SetRaw(uint16_t value);" + os.linesep + \ | ||
"};" + os.linesep, True, True) | ||
|
||
# Idempotence with virtual specifier on destructor | ||
test.add_input("./PWM.h", | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" virtual ~PWM();" + os.linesep + \ | ||
"};" + os.linesep) | ||
test.add_output( | ||
"class PWM : public SendableBase {" + os.linesep + \ | ||
" public:" + os.linesep + \ | ||
" explicit PWM(int channel);" + os.linesep + \ | ||
" virtual ~PWM();" + os.linesep + \ | ||
"};" + os.linesep, False, True) | ||
|
||
test.run(OutputType.FILE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
"""This task removes redundant "virtual" specifier instances. | ||
When the "override" specifier is specified in a C++ function signature, the | ||
"virtual" specifier is redundant because "override" implies "virtual". | ||
""" | ||
|
||
import regex | ||
|
||
from wpiformat.task import Task | ||
|
||
|
||
class VirtualSpecifier(Task): | ||
|
||
def should_process_file(self, config_file, name): | ||
return config_file.is_cpp_file(name) | ||
|
||
def run_pipeline(self, config_file, name, lines): | ||
linesep = Task.get_linesep(lines) | ||
|
||
file_changed = False | ||
output = "" | ||
|
||
# Function signature parts | ||
virtual_spec = r"(?P<virtual>virtual\s+)?" | ||
return_type = r"(?P<return_type>[\w,\*&]+\s+)" | ||
func_args = r"(?P<func_args>\([^\)]*\)(\s*const)?)" | ||
specifiers = r"(?P<specifiers>[^;{]*)?" | ||
|
||
# Construct regexes for function signatures | ||
regexes = [] | ||
regexes.append( | ||
regex.compile(virtual_spec + r"(?P<func_sig>" + return_type + | ||
r"(?P<func_name>\w+\s*)" + func_args + ")" + | ||
specifiers)) | ||
regexes.append( | ||
regex.compile(virtual_spec + r"(?P<func_sig>" + | ||
r"(?P<func_name>[\w~]+\s*)" + func_args + ")" + | ||
specifiers)) | ||
|
||
for rgx in regexes: | ||
pos = 0 | ||
for match in rgx.finditer(lines): | ||
# Append lines before match | ||
output += lines[pos:match.start()] | ||
|
||
# Append virtual specifier if it's not redundant | ||
if "final" not in match.group( | ||
"specifiers") and "override" not in match.group( | ||
"specifiers"): | ||
if match.group("virtual"): | ||
output += match.group("virtual") | ||
else: | ||
file_changed = True | ||
output += match.group("func_sig") | ||
|
||
# Strip redundant specifiers | ||
specifiers_in = match.group("specifiers") | ||
specifiers_out = specifiers_in | ||
if "final" in specifiers_out: | ||
specifiers_out = regex.sub(r"\s+override", "", | ||
specifiers_out) | ||
if specifiers_in != specifiers_out: | ||
file_changed = True | ||
output += specifiers_out | ||
|
||
pos = match.end() | ||
|
||
# Append leftover lines in file | ||
if pos < len(lines): | ||
output += lines[pos:] | ||
|
||
# Reset line buffer for next regex | ||
lines = output | ||
output = "" | ||
|
||
return (lines, file_changed, True) |