Enable RedundantModifier checkstyle, add fixer

Add `fixModifiers.gradle` to run after `check` task.

The `RedundantModifierChecker` doesn't catch all errors at once.
We need run `check -> fixModifiers` pair several times to reach `SUCCESSFUL`.

The `fixThis` has been ported from the SA, but without applying.

* Polishing for `fixModifiers.gradle`
* Fix all redundant modifier with the `fixModifiers.gradle`

NOTE: Since all these task modify files on Windows we have to run them with the `-Dfile.encoding=UTF-8`.
Otherwise they are read and write with the Windows default `cp1251` making them incompatible with Unix system.
This commit is contained in:
Artem Bilan
2016-03-17 13:10:05 -04:00
parent 714734115a
commit c2954881ad
62 changed files with 259 additions and 141 deletions

View File

@@ -4,4 +4,6 @@
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files="package-info\.java" checks=".*" />
<suppress files="[\\/]test[\\/]" checks="RequireThis" />
<suppress files="[\\/]test[\\/]" checks="Javadoc*" />
</suppressions>

View File

@@ -125,7 +125,7 @@
<!-- <module name="OuterTypeFilename" /> -->
<!-- Modifiers -->
<!-- <module name="RedundantModifier" /> -->
<module name="RedundantModifier" />
<!-- Regexp -->
<!-- <module name="RegexpSinglelineJava"> -->

View File

@@ -0,0 +1,50 @@
task fixModifiers << {
fileTree("${buildDir}/reports/checkstyle").include('*.xml').each { report ->
def xml = new XmlParser(false, false).parse(report)
xml.file.each { f ->
def errors = f.error
def modifierErrors = []
errors.each { error ->
if (error.@source == 'com.puppycrawl.tools.checkstyle.checks.modifier.RedundantModifierCheck') {
modifierErrors.add(error)
}
}
if (modifierErrors) {
def errorInx = 0
def error = modifierErrors[errorInx++]
def file = new File(f.@name)
println "Fixing file $file ..."
boolean headerFixed
def outSource = ''
file.eachLine { line, ln ->
if (!headerFixed) {
def matcher = line =~ /Copyright (20\d\d)(?:-20\d\d)?/
if (matcher.count) {
def years = matcher[0][1]
if (years != now) {
years = years + "-$now"
line = line.replaceFirst(/(20\d\d)(?:-20\d\d)?/, years)
}
headerFixed = true
}
}
while (error && ln == (error.@line as int)) {
def message = error.@message
def modifier = message.substring(message.indexOf('\'') + 1, message.lastIndexOf('\''))
line = line.replaceFirst(modifier + ' ', '')
println "Fixed line $line"
error = modifierErrors[errorInx++]
}
outSource += line + System.lineSeparator()
}
file.write(outSource)
println()
}
}
}
}

View File

@@ -0,0 +1,65 @@
task fixThis << {
fileTree("${buildDir}/reports/checkstyle").include('*.xml').each { report ->
println "processing $report"
def xml = new XmlParser(false, false).parse(report)
xml.file.each { f ->
// println "processing $f"
def errors = f.error
def hasThisError = false
def thisErrors = []
errors.each { error ->
if (error.@source == 'com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck') {
thisErrors.add(error)
hasThisError = true
}
}
// println hasThisError
// println f.@name
if (hasThisError) {
def errorInx = 0
def error = thisErrors[errorInx++]
def lx = Integer.valueOf(error.@line)
println error
def file = new File(f.@name)
def outSource = ''
def ln = 0
file.eachLine { line ->
// println line
ln++
def matcher = line =~ /Copyright (20\d\d)(?:-20\d\d)?/
if (matcher.count) {
def years = matcher[0][1]
if (years != now) {
years = years + "-$now"
}
line.replaceFirst(/(20\d\d)(?:-20\d\d)?/, years)
}
if (error && ln == lx) {
// println line
def beforeIndex = Integer.valueOf(error.@column) - 1
def chars = line.toCharArray()
for (int i = 0; i < beforeIndex; i++) {
if (chars[i] == '\t') { // tabs before code == 8
beforeIndex -= 7;
}
else if (chars[i] != ' ') { // tabs after code start are only counted as 1
break;
}
}
line = line.substring(0, beforeIndex) + "this." + line.substring(beforeIndex)
// println line
error = thisErrors[errorInx++]
while (error && lx == Integer.valueOf(error.@line)) {
error = thisErrors[errorInx++]
}
if (error) {
lx = Integer.valueOf(error.@line)
}
}
outSource += line + '\n'
}
file.write(outSource)
}
}
}
}