Added support for Scala to CPD.

The Scala tokenizer was extracted from the Sonar Scala plugin.
(https://github.com/SonarCommunity/sonar-scala) I copied the code
because the Sonar Scala plugin has a lot of unwanted dependencies. I
tried to keep the changes to the Scala Sonar plugin as minimal as
possible.

To tokenize the source files the official Scala compiler is used.
This commit is contained in:
Jan van Nunen
2015-01-09 15:20:25 +01:00
parent c1bc045c65
commit bffea4bb3b
20 changed files with 1440 additions and 0 deletions

92
pmd-scala/pom.xml Normal file
View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>pmd-scala</artifactId>
<name>PMD Scala</name>
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.2.4-SNAPSHOT</version>
</parent>
<properties>
<scala.version>2.10.4</scala.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<useDefaultDelimiters>false</useDefaultDelimiters>
<delimiters>
<delimiter>${*}</delimiter>
</delimiters>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<xdocDirectory>${project.build.directory}/generated-xdocs</xdocDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,19 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cpd;
import org.sonar.plugins.scala.cpd.ScalaTokenizer;
/**
* Language implementation for Scala
*/
public class ScalaLanguage extends AbstractLanguage {
/**
* Creates a new Scala Language instance.
*/
public ScalaLanguage() {
super("Scala", "scala", new ScalaTokenizer(), ".scala");
}
}

View File

@ -0,0 +1,25 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.scala;
import net.sourceforge.pmd.lang.BaseLanguageModule;
/**
* Language Module for Scala
*/
public class ScalaLanguageModule extends BaseLanguageModule {
/** The name. */
public static final String NAME = "Scala";
/** The terse name. */
public static final String TERSE_NAME = "scala";
/**
* Create a new instance of Scala Language Module.
*/
public ScalaLanguageModule() {
super(NAME, null, TERSE_NAME, null, "scala");
addVersion("", null, true);
}
}

View File

@ -0,0 +1,55 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.cpd;
import java.util.List;
import net.sourceforge.pmd.cpd.SourceCode;
import net.sourceforge.pmd.cpd.TokenEntry;
import net.sourceforge.pmd.cpd.Tokenizer;
import net.sourceforge.pmd.cpd.Tokens;
import org.sonar.plugins.scala.compiler.Lexer;
import org.sonar.plugins.scala.compiler.Token;
/**
* Scala tokenizer for PMD CPD.
*
* @since 0.1
*/
public final class ScalaTokenizer implements Tokenizer {
public void tokenize(SourceCode source, Tokens cpdTokens) {
String filename = source.getFileName();
Lexer lexer = new Lexer();
List<Token> tokens = lexer.getTokensOfFile(filename);
for (Token token : tokens) {
String tokenVal =
token.tokenVal() != null ? token.tokenVal() : Integer.toString(token.tokenType());
TokenEntry cpdToken = new TokenEntry(tokenVal, filename, token.line());
cpdTokens.add(cpdToken);
}
cpdTokens.add(TokenEntry.getEOF());
}
}

View File

@ -0,0 +1,119 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.language;
import java.io.IOException;
import java.util.List;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.sonar.plugins.scala.util.StringUtils;
/**
* This class implements a Scala comment and the computation
* of several base metrics for a comment.
*
* @author Felix Müller
* @since 0.1
*/
public class Comment {
private final CommentType type;
private final List<String> lines;
public Comment(String content, CommentType type) throws IOException {
lines = StringUtils.convertStringToListOfLines(content);
this.type = type;
}
public int getNumberOfLines() {
return lines.size() - getNumberOfBlankLines() - getNumberOfCommentedOutLinesOfCode();
}
public int getNumberOfBlankLines() {
int numberOfBlankLines = 0;
for (String comment : lines) {
boolean isBlank = true;
for (int i = 0; isBlank && i < comment.length(); i++) {
char character = comment.charAt(i);
if (!Character.isWhitespace(character) && character != '*' && character != '/') {
isBlank = false;
}
}
if (isBlank) {
numberOfBlankLines++;
}
}
return numberOfBlankLines;
}
public int getNumberOfCommentedOutLinesOfCode() {
if (isDocComment()) {
return 0;
}
int numberOfCommentedOutLinesOfCode = 0;
for (String line : lines) {
String strippedLine = org.apache.commons.lang3.StringUtils.strip(line, " /*");
if (CodeDetector.hasDetectedCode(strippedLine)) {
numberOfCommentedOutLinesOfCode++;
}
}
return numberOfCommentedOutLinesOfCode;
}
public boolean isDocComment() {
return type == CommentType.DOC;
}
public boolean isHeaderComment() {
return type == CommentType.HEADER;
}
@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;
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

@ -0,0 +1,34 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.language;
/**
* This enum is a helper to distinguish between the
* different types of comments in Sonar.
*
* @author Felix Müller
* @since 0.1
*/
public enum CommentType {
NORMAL,
DOC,
HEADER;
}

View File

@ -0,0 +1,51 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
public final class StringUtils {
private StringUtils() {
// to prevent instantiation
}
public static List<String> convertStringToListOfLines(String string) throws IOException {
final List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new StringReader(string));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (IOException ioe) {
throw ioe;
} finally {
IOUtils.closeQuietly(reader);
}
return lines;
}
}

View File

@ -0,0 +1 @@
net.sourceforge.pmd.cpd.ScalaLanguage

View File

@ -0,0 +1 @@
net.sourceforge.pmd.lang.scala.ScalaLanguageModule

View File

@ -0,0 +1,33 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.compiler
import scala.tools.nsc.{Settings, Global}
/**
* This is a wrapper for the Scala compiler. It is used to access
* the compiler in a more convenient way.
*
* @author Felix Müller
* @since 0.1
*/
object Compiler extends Global(new Settings()) {
override def forScaladoc = true
}

View File

@ -0,0 +1,128 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.compiler
import collection.mutable.ListBuffer
import org.sonar.plugins.scala.language.{Comment, CommentType}
import scala.reflect.io.AbstractFile
import scala.reflect.internal.util.BatchSourceFile
/**
* This class is a wrapper for accessing the lexer of the Scala compiler
* from Java in a more convenient way.
*
* @author Felix Müller
* @since 0.1
*/
class Lexer {
import scala.collection.JavaConversions._
import Compiler._
def getTokens(code: String): java.util.List[Token] = {
val unit = new CompilationUnit(new BatchSourceFile("", code.toCharArray))
tokenize(unit)
}
def getTokensOfFile(path: String): java.util.List[Token] = {
val unit = new CompilationUnit(new BatchSourceFile(AbstractFile.getFile(path)))
tokenize(unit)
}
private def tokenize(unit: CompilationUnit): java.util.List[Token] = {
val scanner = new syntaxAnalyzer.UnitScanner(unit)
val tokens = ListBuffer[Token]()
scanner.init()
while (scanner.token != scala.tools.nsc.ast.parser.Tokens.EOF) {
val tokenVal =
if (scala.tools.nsc.ast.parser.Tokens.isIdentifier(scanner.token)) scanner.name.toString() else null
val linenr = scanner.parensAnalyzer.line(scanner.offset) + 1
tokens += Token(scanner.token, linenr, tokenVal)
scanner.nextToken()
}
tokens
}
def getComments(code: String): java.util.List[Comment] = {
val unit = new CompilationUnit(new BatchSourceFile("", code.toCharArray))
tokenizeComments(unit)
}
def getCommentsOfFile(path: String): java.util.List[Comment] = {
val unit = new CompilationUnit(new BatchSourceFile(AbstractFile.getFile(path)))
tokenizeComments(unit)
}
private def tokenizeComments(unit: CompilationUnit): java.util.List[Comment] = {
val comments = ListBuffer[Comment]()
val scanner = new syntaxAnalyzer.UnitScanner(unit) {
private var lastDocCommentRange: Option[Range] = None
private var foundToken = false
override def nextToken() {
super.nextToken()
foundToken = token != 0
}
override def foundComment(value: String, start: Int, end: Int) = {
super.foundComment(value, start, end)
def isHeaderComment(value: String) = {
!foundToken && comments.isEmpty && value.trim().startsWith("/*")
}
lastDocCommentRange match {
case Some(r: Range) => {
if (r.start != start || r.end != end) {
comments += new Comment(value, CommentType.NORMAL)
}
}
case None => {
if (isHeaderComment(value)) {
comments += new Comment(value, CommentType.HEADER)
} else {
comments += new Comment(value, CommentType.NORMAL)
}
}
}
}
override def foundDocComment(value: String, start: Int, end: Int) = {
super.foundDocComment(value, start, end)
comments += new Comment(value, CommentType.DOC)
lastDocCommentRange = Some(Range(start, end))
}
}
scanner.init()
while (scanner.token != scala.tools.nsc.ast.parser.Tokens.EOF) {
scanner.nextToken()
}
comments
}
}

View File

@ -0,0 +1,61 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.compiler
import scala.reflect.internal.util.{ScriptSourceFile, BatchSourceFile}
import scala.reflect.io.AbstractFile
/**
* This class is a wrapper for accessing the parser of the Scala compiler
* from Java in a more convenient way.
*
* @author Felix Müller
* @since 0.1
*/
class Parser {
import Compiler._
def parse(code: String): Tree = {
val batchSourceFile = new BatchSourceFile("", code.toCharArray)
parse(batchSourceFile, code.toCharArray)
}
def parseFile(path: String): Tree = {
val batchSourceFile = new BatchSourceFile(AbstractFile.getFile(path))
parse(batchSourceFile, batchSourceFile.content.array)
}
private def parse(batchSourceFile: BatchSourceFile, code: Array[Char]): Tree = {
try {
val parser = new syntaxAnalyzer.SourceFileParser(new ScriptSourceFile(batchSourceFile, code, 0))
val tree = parser.templateStatSeq(false)._2
parser.makePackaging(0, parser.atPos(0, 0, 0)(Ident(nme.EMPTY_PACKAGE_NAME)), tree)
} catch {
case _: Throwable => {
val unit = new CompilationUnit(batchSourceFile)
val unitParser = new syntaxAnalyzer.UnitParser(unit) {
override def showSyntaxErrors() {}
}
unitParser.smartParse()
}
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.compiler
/**
* Represent a token. Lines must start at 1.
*
* @since 0.1
*/
case class Token(tokenType: Int, line: Int, tokenVal: String)

View File

@ -0,0 +1,66 @@
/*
* Sonar Scala Plugin
* Copyright (C) 2011 - 2014 All contributors
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.scala.language
import org.sonar.plugins.scala.compiler.{ Compiler, Parser }
/**
* This object is a helper object for detecting valid Scala code
* in a given piece of source code.
*
* @author Felix Müller
* @since 0.1
*/
object CodeDetector {
import Compiler._
private lazy val parser = new Parser()
def hasDetectedCode(code: String) = {
def lookingForSyntaxTreesWithCode(tree: Tree) : Boolean = tree match {
case PackageDef(identifier: RefTree, content) =>
if (!identifier.name.equals(nme.EMPTY_PACKAGE_NAME)) {
true
} else {
content.exists(lookingForSyntaxTreesWithCode)
}
case Apply(function, args) =>
args.exists(lookingForSyntaxTreesWithCode)
case ClassDef(_, _, _, _)
| ModuleDef(_, _, _)
| ValDef(_, _, _, _)
| DefDef(_, _, _, _, _, _)
| Function(_ , _)
| Assign(_, _)
| LabelDef(_, _, _) =>
true
case _ =>
false
}
lookingForSyntaxTreesWithCode(parser.parse(code))
}
}

View File

@ -0,0 +1,3 @@
# PMD Scala
Only CPD is supported. There are no PMD rules for Scala.

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/DECORATION/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd"
name="PMD Scala">
<body>
<menu ref="parent"/>
<menu ref="reports"/>
</body>
</project>

View File

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

View File

@ -0,0 +1,64 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cpd;
import java.io.File;
import java.io.IOException;
import net.sourceforge.pmd.testframework.AbstractTokenizerTest;
import net.sourceforge.pmd.testframework.StreamUtil;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sonar.plugins.scala.cpd.ScalaTokenizer;
public class ScalaTokenizerTest extends AbstractTokenizerTest {
private static final String FILENAME = "sample-LiftActor.scala";
private File tempFile;
@Before
@Override
public void buildTokenizer() {
createTempFileOnDisk();
this.tokenizer = new ScalaTokenizer();
this.sourceCode = new SourceCode(new SourceCode.FileCodeLoader(tempFile, "UTF-8"));
}
private void createTempFileOnDisk() {
try {
this.tempFile = File.createTempFile("scala-tokenizer-test-", ".scala");
FileUtils.writeStringToFile(tempFile, getSampleCode(), "UTF-8");
} catch (IOException e) {
throw new RuntimeException("Unable to create temporary file on disk for Scala tokenizer test", e);
}
}
@Override
public String getSampleCode() {
return StreamUtil.toString(ScalaTokenizer.class.getResourceAsStream(FILENAME));
}
@Test
public void tokenizeTest() throws IOException {
this.expectedTokenCount = 2591;
super.tokenizeTest();
}
@After
public void cleanUp() {
FileUtils.deleteQuietly(this.tempFile);
this.tempFile = null;
}
public static junit.framework.Test suite() {
return new junit.framework.JUnit4TestAdapter(ScalaTokenizerTest.class);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -867,6 +867,7 @@
<module>pmd-php</module>
<module>pmd-plsql</module>
<module>pmd-ruby</module>
<module>pmd-scala</module>
<module>pmd-test</module>
<module>pmd-vm</module>
<module>pmd-xml</module>