pmd-scala: checkstyle / formatting

This commit is contained in:
Andreas Dangel
2016-12-02 15:05:25 +01:00
parent d55cf8afd8
commit f3b362b359
10 changed files with 133 additions and 113 deletions

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.0//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
<suppressions>
<suppress files="[\\/]generated-sources[\\/]" checks="[a-zA-Z0-9]*"/>
<!-- Part of pmd-scala is under LGPL -->
<suppress checks="RegexpHeadercheck" files="org/sonar/plugins/scala/.*"/>
</suppressions>

View File

@ -56,6 +56,14 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<suppressionsLocation>pmd-scala-checkstyle-suppressions.xml</suppressionsLocation>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -1,6 +1,7 @@
/** /**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/ */
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import org.sonar.plugins.scala.cpd.ScalaTokenizer; import org.sonar.plugins.scala.cpd.ScalaTokenizer;

View File

@ -1,6 +1,7 @@
/** /**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/ */
package net.sourceforge.pmd.lang.scala; package net.sourceforge.pmd.lang.scala;
import net.sourceforge.pmd.lang.BaseLanguageModule; import net.sourceforge.pmd.lang.BaseLanguageModule;

View File

@ -17,19 +17,20 @@
* License along with this program; if not, write to the Free Software * License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/ */
package org.sonar.plugins.scala.cpd; package org.sonar.plugins.scala.cpd;
import java.util.List; import java.util.List;
import org.sonar.plugins.scala.compiler.Lexer;
import org.sonar.plugins.scala.compiler.Token;
import net.sourceforge.pmd.cpd.SourceCode; import net.sourceforge.pmd.cpd.SourceCode;
import net.sourceforge.pmd.cpd.TokenEntry; import net.sourceforge.pmd.cpd.TokenEntry;
import net.sourceforge.pmd.cpd.Tokenizer; import net.sourceforge.pmd.cpd.Tokenizer;
import net.sourceforge.pmd.cpd.Tokens; import net.sourceforge.pmd.cpd.Tokens;
import net.sourceforge.pmd.lang.ast.TokenMgrError; import net.sourceforge.pmd.lang.ast.TokenMgrError;
import org.sonar.plugins.scala.compiler.Lexer;
import org.sonar.plugins.scala.compiler.Token;
/** /**
* Scala tokenizer for PMD CPD. * Scala tokenizer for PMD CPD.
* *
@ -42,10 +43,9 @@ public final class ScalaTokenizer implements Tokenizer {
try { try {
Lexer lexer = new Lexer(); Lexer lexer = new Lexer();
List<Token> tokens = lexer.getTokensOfFile(filename); List<Token> tokens = lexer.getTokensOfFile(filename);
for (Token token : tokens) { for (Token token : tokens) {
String tokenVal = String tokenVal = token.tokenVal() != null ? token.tokenVal() : Integer.toString(token.tokenType());
token.tokenVal() != null ? token.tokenVal() : Integer.toString(token.tokenType());
TokenEntry cpdToken = new TokenEntry(tokenVal, filename, token.line()); TokenEntry cpdToken = new TokenEntry(tokenVal, filename, token.line());
cpdTokens.add(cpdToken); cpdTokens.add(cpdToken);
@ -53,11 +53,13 @@ public final class ScalaTokenizer implements Tokenizer {
cpdTokens.add(TokenEntry.getEOF()); cpdTokens.add(TokenEntry.getEOF());
} catch (RuntimeException e) { } catch (RuntimeException e) {
e.printStackTrace(); e.printStackTrace();
// Wrap exceptions of the Scala tokenizer in a TokenMgrError, so they are correctly handled // Wrap exceptions of the Scala tokenizer in a TokenMgrError, so
// when CPD is executed with the '--skipLexicalErrors' command line option // they are correctly handled
// when CPD is executed with the '--skipLexicalErrors' command line
// option
throw new TokenMgrError( throw new TokenMgrError(
"Lexical error in file " + filename + ". The scala tokenizer exited with error: " + e.getMessage(), "Lexical error in file " + filename + ". The scala tokenizer exited with error: " + e.getMessage(),
TokenMgrError.LEXICAL_ERROR); TokenMgrError.LEXICAL_ERROR);
} }
} }

View File

@ -17,6 +17,7 @@
* License along with this program; if not, write to the Free Software * License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/ */
package org.sonar.plugins.scala.language; package org.sonar.plugins.scala.language;
import java.io.IOException; import java.io.IOException;
@ -28,92 +29,89 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.sonar.plugins.scala.util.StringUtils; import org.sonar.plugins.scala.util.StringUtils;
/** /**
* This class implements a Scala comment and the computation * This class implements a Scala comment and the computation of several base
* of several base metrics for a comment. * metrics for a comment.
* *
* @author Felix Müller * @author Felix Müller
* @since 0.1 * @since 0.1
*/ */
public class Comment { public class Comment {
private final CommentType type; private final CommentType type;
private final List<String> lines; private final List<String> lines;
public Comment(String content, CommentType type) throws IOException { public Comment(String content, CommentType type) throws IOException {
lines = StringUtils.convertStringToListOfLines(content); lines = StringUtils.convertStringToListOfLines(content);
this.type = type; this.type = type;
} }
public int getNumberOfLines() { public int getNumberOfLines() {
return lines.size() - getNumberOfBlankLines() - getNumberOfCommentedOutLinesOfCode(); return lines.size() - getNumberOfBlankLines() - getNumberOfCommentedOutLinesOfCode();
} }
public int getNumberOfBlankLines() { public int getNumberOfBlankLines() {
int numberOfBlankLines = 0; int numberOfBlankLines = 0;
for (String comment : lines) { for (String comment : lines) {
boolean isBlank = true; boolean isBlank = true;
for (int i = 0; isBlank && i < comment.length(); i++) { for (int i = 0; isBlank && i < comment.length(); i++) {
char character = comment.charAt(i); char character = comment.charAt(i);
if (!Character.isWhitespace(character) && character != '*' && character != '/') { if (!Character.isWhitespace(character) && character != '*' && character != '/') {
isBlank = false; isBlank = false;
}
}
if (isBlank) {
numberOfBlankLines++;
}
} }
} return numberOfBlankLines;
if (isBlank) {
numberOfBlankLines++;
}
}
return numberOfBlankLines;
}
public int getNumberOfCommentedOutLinesOfCode() {
if (isDocComment()) {
return 0;
} }
int numberOfCommentedOutLinesOfCode = 0; public int getNumberOfCommentedOutLinesOfCode() {
for (String line : lines) { if (isDocComment()) {
String strippedLine = org.apache.commons.lang3.StringUtils.strip(line, " /*"); return 0;
if (CodeDetector.hasDetectedCode(strippedLine)) { }
numberOfCommentedOutLinesOfCode++;
}
}
return numberOfCommentedOutLinesOfCode;
}
public boolean isDocComment() { int numberOfCommentedOutLinesOfCode = 0;
return type == CommentType.DOC; for (String line : lines) {
} String strippedLine = org.apache.commons.lang3.StringUtils.strip(line, " /*");
if (CodeDetector.hasDetectedCode(strippedLine)) {
public boolean isHeaderComment() { numberOfCommentedOutLinesOfCode++;
return type == CommentType.HEADER; }
} }
return numberOfCommentedOutLinesOfCode;
@Override
public int hashCode() {
return new HashCodeBuilder().append(type).append(lines).toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Comment)) {
return false;
} }
Comment other = (Comment) obj; public boolean isDocComment() {
return new EqualsBuilder().append(type, other.type).append(lines, other.lines).isEquals(); return type == CommentType.DOC;
} }
@Override public boolean isHeaderComment() {
public String toString() { return type == CommentType.HEADER;
final String firstLine = lines.isEmpty() ? "" : lines.get(0); }
final String lastLine = lines.isEmpty() ? "" : lines.get(lines.size() - 1);
return new ToStringBuilder(this).append("type", type) @Override
.append("firstLine", firstLine) public int hashCode() {
.append("lastLine", lastLine) return new HashCodeBuilder().append(type).append(lines).toHashCode();
.append("numberOfLines", getNumberOfLines()) }
.append("numberOfCommentedOutLinesOfCode", getNumberOfCommentedOutLinesOfCode())
.toString(); @Override
} public boolean equals(Object obj) {
} if (!(obj instanceof Comment)) {
return false;
}
Comment other = (Comment) obj;
return new EqualsBuilder().append(type, other.type).append(lines, other.lines).isEquals();
}
@Override
public String toString() {
final String firstLine = lines.isEmpty() ? "" : lines.get(0);
final String lastLine = lines.isEmpty() ? "" : lines.get(lines.size() - 1);
return new ToStringBuilder(this).append("type", type).append("firstLine", firstLine)
.append("lastLine", lastLine).append("numberOfLines", getNumberOfLines())
.append("numberOfCommentedOutLinesOfCode", getNumberOfCommentedOutLinesOfCode()).toString();
}
}

View File

@ -17,18 +17,17 @@
* License along with this program; if not, write to the Free Software * License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/ */
package org.sonar.plugins.scala.language; package org.sonar.plugins.scala.language;
/** /**
* This enum is a helper to distinguish between the * This enum is a helper to distinguish between the different types of comments
* different types of comments in Sonar. * in Sonar.
* *
* @author Felix Müller * @author Felix Müller
* @since 0.1 * @since 0.1
*/ */
public enum CommentType { public enum CommentType {
NORMAL, NORMAL, DOC, HEADER;
DOC, }
HEADER;
}

View File

@ -17,6 +17,7 @@
* License along with this program; if not, write to the Free Software * License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/ */
package org.sonar.plugins.scala.util; package org.sonar.plugins.scala.util;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -28,22 +29,22 @@ import java.util.List;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
public final class StringUtils { public final class StringUtils {
private StringUtils() { private StringUtils() {
// to prevent instantiation // to prevent instantiation
}
public static List<String> convertStringToListOfLines(String string) throws IOException {
final List<String> lines = new ArrayList<>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new StringReader(string));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
IOUtils.closeQuietly(reader);
} }
return lines;
} public static List<String> convertStringToListOfLines(String string) throws IOException {
} final List<String> lines = new ArrayList<>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new StringReader(string));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} finally {
IOUtils.closeQuietly(reader);
}
return lines;
}
}

View File

@ -1,17 +1,18 @@
/** /**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/ */
package net.sourceforge.pmd; package net.sourceforge.pmd;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import org.junit.runners.Parameterized.Parameters;
import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; import net.sourceforge.pmd.lang.scala.ScalaLanguageModule;
import org.junit.runners.Parameterized.Parameters;
public class LanguageVersionTest extends AbstractLanguageVersionTest { public class LanguageVersionTest extends AbstractLanguageVersionTest {
public LanguageVersionTest(String name, String terseName, String version, LanguageVersion expected) { public LanguageVersionTest(String name, String terseName, String version, LanguageVersion expected) {
@ -20,8 +21,7 @@ public class LanguageVersionTest extends AbstractLanguageVersionTest {
@Parameters @Parameters
public static Collection<Object[]> data() { public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { return Arrays.asList(new Object[][] { { ScalaLanguageModule.NAME, ScalaLanguageModule.TERSE_NAME, "",
{ ScalaLanguageModule.NAME, ScalaLanguageModule.TERSE_NAME, "", LanguageRegistry.getLanguage(ScalaLanguageModule.NAME).getDefaultVersion() } LanguageRegistry.getLanguage(ScalaLanguageModule.NAME).getDefaultVersion(), }, });
});
} }
} }

View File

@ -1,13 +1,12 @@
/** /**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/ */
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.sourceforge.pmd.testframework.AbstractTokenizerTest;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.After; import org.junit.After;
@ -15,6 +14,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.sonar.plugins.scala.cpd.ScalaTokenizer; import org.sonar.plugins.scala.cpd.ScalaTokenizer;
import net.sourceforge.pmd.testframework.AbstractTokenizerTest;
public class ScalaTokenizerTest extends AbstractTokenizerTest { public class ScalaTokenizerTest extends AbstractTokenizerTest {