From 7b9ed3f5928d983ffccb467b99dff3b5c80fd2d7 Mon Sep 17 00:00:00 2001 From: Johannes Zink Date: Wed, 12 Nov 2014 13:49:23 +0100 Subject: [PATCH] cobertura is back... minor code changes --- pom.xml | 479 +++++++++--------- .../org/sonar/plugins/scala/ScalaPlugin.java | 22 +- .../scala/cobertura/CoberturaSensor.java | 72 +++ .../scala/cobertura/ScalaCoberturaParser.java | 44 ++ .../sonar/plugins/scala/language/Scala.java | 7 +- .../plugins/scala/language/ScalaFile.java | 167 ++++++ .../plugins/scala/language/ScalaPackage.java | 91 ++++ .../scala/metrics/CommentsAnalyzer.java | 150 +++--- .../scala/surefire/SurefireSensor.java | 9 +- .../sonar/plugins/scala/util/StringUtils.java | 112 ++-- .../scala/metrics/PublicApiCounter.scala | 192 +++---- .../sonar/plugins/scala/ScalaPluginTest.java | 86 ++-- .../plugins/scala/cpd/ScalaTokenizerTest.java | 2 - .../plugins/scala/language/ScalaTest.java | 6 +- .../scala/sensor/AbstractScalaSensorTest.java | 7 +- .../scala/sensor/BaseMetricsSensorTest.java | 4 +- .../baseMetricsSensor/ScalaFile3.scala | 8 +- .../lexer/NormalCommentWithHeaderComment.txt | 10 +- .../SimplePackageDeclaration.txt | 10 +- .../scalaSourceImporter/MainFile2.scala | 8 +- .../scalaSourceImporter/TestFile1.scala | 8 +- .../plugins/scala/compiler/LexerSpec.scala | 164 +++--- .../scala/metrics/FunctionCounterSpec.scala | 240 ++++----- .../scala/metrics/TypeCounterSpec.scala | 326 ++++++------ 24 files changed, 1303 insertions(+), 921 deletions(-) create mode 100644 src/main/java/org/sonar/plugins/scala/cobertura/CoberturaSensor.java create mode 100644 src/main/java/org/sonar/plugins/scala/cobertura/ScalaCoberturaParser.java create mode 100644 src/main/java/org/sonar/plugins/scala/language/ScalaFile.java create mode 100644 src/main/java/org/sonar/plugins/scala/language/ScalaPackage.java diff --git a/pom.xml b/pom.xml index 210f61d..d9d1074 100644 --- a/pom.xml +++ b/pom.xml @@ -1,236 +1,243 @@ - - - 4.0.0 - - - org.codehaus.sonar-plugins - parent - 18 - - - sonar-scala-plugin - sonar-plugin - 1.1.0-SNAPSHOT - - Sonar Scala Plugin - Enables analysis of Scala projects into Sonar. - http://docs.codehaus.org/display/SONAR/Scala+Plugin - 2011 - - - - GNU LGPL 3 - http://www.gnu.org/licenses/lgpl.txt - repo - - - - - scm:git:git@github.com:SonarCommunity/sonar-scala.git - scm:git:git@github.com:SonarCommunity/sonar-scala.git - https://github.com/SonarCommunity/sonar-scala - - - - JIRA - http://jira.codehaus.org/browse/SONARPLUGINS/component/14772 - - - - 4.4 - scala - Scala - org.sonar.plugins.scala.ScalaPlugin - - 2.10.4 - 2.10 - - scala - - - - - org.codehaus.sonar - sonar-plugin-api - ${sonar.version} - - - org.scala-lang - scala-library - ${scala.version} - - - org.scala-lang - scala-compiler - ${scala.version} - - - org.scalariform - scalariform_${scala.major.version} - 0.1.4 - - - org.scala-lang - scala-library - - - - - - - org.codehaus.sonar - sonar-testing-harness - ${sonar.version} - - - org.scalatest - scalatest_${scala.major.version} - 2.1.3 - test - - - org.scala-lang - scala-library - - - - - org.mockito - mockito-all - 1.9.0 - test - - - org.apache.maven - maven-project - 2.2.1 - test - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - - net.alchim31.maven - scala-maven-plugin - 3.1.6 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.17 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.5 - - - org.codehaus.sonar-plugins.pdf-report - maven-pdfreport-plugin - 1.2 - - - org.codehaus.mojo - sonar-maven-plugin - 2.2 - - - org.codehaus.sonar - sonar-maven-plugin - ${sonar.version} - - - - - - - net.alchim31.maven - scala-maven-plugin - - - scala-compile-first - process-resources - - add-source - compile - - - - scala-test-compile - process-test-resources - - testCompile - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - compile - - compile - - - - - - maven-surefire-plugin - - - **/*Spec.class - **/*Test.class - - - - - com.mycila.maven-license-plugin - maven-license-plugin - - ${project.build.sourceEncoding} - - All contributors - 2011 - 2014 - - - src/main/java/** - src/main/scala/** - src/test/java/** - src/test/scala/** - - - SLASHSTAR_STYLE - SLASHSTAR_STYLE - - true - - - - add-license-headers - process-sources - - format - - - - enforce-license-headers - verify - - check - - - - - - - + + + 4.0.0 + + + org.codehaus.sonar-plugins + parent + 18 + + + sonar-scala-plugin + sonar-plugin + 1.1.0-SNAPSHOT + + Sonar Scala Plugin + Enables analysis of Scala projects into Sonar. + http://docs.codehaus.org/display/SONAR/Scala+Plugin + 2011 + + + + GNU LGPL 3 + http://www.gnu.org/licenses/lgpl.txt + repo + + + + + scm:git:git@github.com:SonarCommunity/sonar-scala.git + scm:git:git@github.com:SonarCommunity/sonar-scala.git + https://github.com/SonarCommunity/sonar-scala + + + + JIRA + http://jira.codehaus.org/browse/SONARPLUGINS/component/14772 + + + + 4.4 + scala + Scala + org.sonar.plugins.scala.ScalaPlugin + + 2.10.4 + 2.10 + + 3.3.2 + + scala + + + + + org.codehaus.sonar + sonar-plugin-api + ${sonar.version} + + + org.scala-lang + scala-library + ${scala.version} + + + org.codehaus.sonar.plugins + sonar-cobertura-plugin + ${cobertura.version} + + + org.scala-lang + scala-compiler + ${scala.version} + + + org.scalariform + scalariform_${scala.major.version} + 0.1.4 + + + org.scala-lang + scala-library + + + + + + + org.codehaus.sonar + sonar-testing-harness + ${sonar.version} + + + org.scalatest + scalatest_${scala.major.version} + 2.1.3 + test + + + org.scala-lang + scala-library + + + + + org.mockito + mockito-all + 1.9.0 + test + + + org.apache.maven + maven-project + 2.2.1 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + + net.alchim31.maven + scala-maven-plugin + 3.1.6 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.17 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.5 + + + org.codehaus.sonar-plugins.pdf-report + maven-pdfreport-plugin + 1.2 + + + org.codehaus.mojo + sonar-maven-plugin + 2.2 + + + org.codehaus.sonar + sonar-maven-plugin + ${sonar.version} + + + + + + + net.alchim31.maven + scala-maven-plugin + + + scala-compile-first + process-resources + + add-source + compile + + + + scala-test-compile + process-test-resources + + testCompile + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + + compile + + + + + + maven-surefire-plugin + + + **/*Spec.class + **/*Test.class + + + + + com.mycila.maven-license-plugin + maven-license-plugin + + ${project.build.sourceEncoding} + + All contributors + 2011 - 2014 + + + src/main/java/** + src/main/scala/** + src/test/java/** + src/test/scala/** + + + SLASHSTAR_STYLE + SLASHSTAR_STYLE + + true + + + + add-license-headers + process-sources + + format + + + + enforce-license-headers + verify + + check + + + + + + + diff --git a/src/main/java/org/sonar/plugins/scala/ScalaPlugin.java b/src/main/java/org/sonar/plugins/scala/ScalaPlugin.java index 93f2144..3ce6590 100644 --- a/src/main/java/org/sonar/plugins/scala/ScalaPlugin.java +++ b/src/main/java/org/sonar/plugins/scala/ScalaPlugin.java @@ -19,11 +19,11 @@ */ package org.sonar.plugins.scala; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import org.sonar.api.Extension; import org.sonar.api.SonarPlugin; +import org.sonar.plugins.scala.cobertura.CoberturaSensor; import org.sonar.plugins.scala.colorization.ScalaColorizerFormat; import org.sonar.plugins.scala.language.Scala; import org.sonar.plugins.scala.sensor.BaseMetricsSensor; @@ -38,14 +38,18 @@ */ public class ScalaPlugin extends SonarPlugin { - public List> getExtensions() { - final List> extensions = new ArrayList>(); - extensions.add(Scala.class); - extensions.add(ScalaColorizerFormat.class); - extensions.add(BaseMetricsSensor.class); - extensions.add(SurefireSensor.class); + + @SuppressWarnings({"rawtypes", "unchecked" }) + @Override + public List getExtensions() { + return Arrays.asList( - return extensions; + Scala.class, + ScalaColorizerFormat.class, + BaseMetricsSensor.class, + SurefireSensor.class, + CoberturaSensor.class + ); } @Override diff --git a/src/main/java/org/sonar/plugins/scala/cobertura/CoberturaSensor.java b/src/main/java/org/sonar/plugins/scala/cobertura/CoberturaSensor.java new file mode 100644 index 0000000..58e523a --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/cobertura/CoberturaSensor.java @@ -0,0 +1,72 @@ +/* + * 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.cobertura; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.CoverageExtension; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.resources.Project; +import org.sonar.plugins.cobertura.api.AbstractCoberturaParser; +import org.sonar.plugins.cobertura.api.CoberturaUtils; +import org.sonar.plugins.scala.language.Scala; + +public class CoberturaSensor implements Sensor, CoverageExtension { + private static final Logger LOG = LoggerFactory.getLogger(CoberturaSensor.class); + + private final FileSystem fileSystem; + + private static final AbstractCoberturaParser COBERTURA_PARSER = new ScalaCoberturaParser(); + + public CoberturaSensor(FileSystem fileSystem) { + this.fileSystem = fileSystem; + } + + public boolean shouldExecuteOnProject(Project project) { + if(fileSystem.languages().contains(Scala.KEY)){ + LOG.info("CoberturaSensor will be executed"); + return true; + } else { + LOG.info("CoberturaSensor will NOT be executed"); + return false; + } + } + + public void analyse(Project project, SensorContext context) { + File report = CoberturaUtils.getReport(project); + if (report != null) { + parseReport(report, context); + } + } + + protected void parseReport(File xmlFile, final SensorContext context) { + LOG.info("parsing {}", xmlFile); + COBERTURA_PARSER.parseReport(xmlFile, context); + } + + @Override + public String toString() { + return "Scala CoberturaSensor"; + } +} diff --git a/src/main/java/org/sonar/plugins/scala/cobertura/ScalaCoberturaParser.java b/src/main/java/org/sonar/plugins/scala/cobertura/ScalaCoberturaParser.java new file mode 100644 index 0000000..57a91a7 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/cobertura/ScalaCoberturaParser.java @@ -0,0 +1,44 @@ +/* + * 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.cobertura; + +import org.sonar.plugins.cobertura.api.AbstractCoberturaParser; +import org.sonar.api.resources.Resource; +import org.sonar.plugins.scala.language.ScalaFile; +import java.io.File; + +public class ScalaCoberturaParser extends AbstractCoberturaParser { + @Override + protected Resource getResource(String fileName) { + // TODO update the sbt scct plugin to provide the correct fully qualified class name. + if (fileName.startsWith("src.main.scala.")) + fileName = fileName.replace("src.main.scala.", ""); + else if (fileName.startsWith("app.")) + fileName = fileName.replace("app.", ""); + int packageTerminator = fileName.lastIndexOf('.'); + if (packageTerminator < 0) { + return new ScalaFile(null, fileName, false); + } else { + String packageName = fileName.substring(0, packageTerminator); + String className = fileName.substring(packageTerminator + 1, fileName.length()); + return new ScalaFile(packageName, className, false); + } + } +} diff --git a/src/main/java/org/sonar/plugins/scala/language/Scala.java b/src/main/java/org/sonar/plugins/scala/language/Scala.java index cfa72f9..1fefee4 100644 --- a/src/main/java/org/sonar/plugins/scala/language/Scala.java +++ b/src/main/java/org/sonar/plugins/scala/language/Scala.java @@ -19,7 +19,6 @@ */ package org.sonar.plugins.scala.language; -import org.sonar.api.config.Settings; import org.sonar.api.resources.AbstractLanguage; /** @@ -33,12 +32,10 @@ public class Scala extends AbstractLanguage { public static final String KEY = "scala"; public static final String NAME = "Scala"; - private final Settings settings; - + public static final Scala INSTANCE = new Scala(); - public Scala(Settings settings) { + public Scala() { super(KEY, NAME); - this.settings = settings; } public String[] getFileSuffixes() { diff --git a/src/main/java/org/sonar/plugins/scala/language/ScalaFile.java b/src/main/java/org/sonar/plugins/scala/language/ScalaFile.java new file mode 100644 index 0000000..100d948 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/language/ScalaFile.java @@ -0,0 +1,167 @@ +/* + * 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.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.sonar.api.resources.InputFile; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.WildcardPattern; + +/** + * This class implements a Scala source file for Sonar. + * + * @author Felix Müller + * @since 0.1 + */ +public class ScalaFile extends Resource { + + private final boolean isUnitTest; + + private final String filename; + + private final String longName; + + private final ScalaPackage parent; + + public ScalaFile(String packageKey, String className, boolean isUnitTest) { + super(); + this.isUnitTest = isUnitTest; + filename = className.trim(); + + String key; + if (StringUtils.isBlank(packageKey)) { + packageKey = ScalaPackage.DEFAULT_PACKAGE_NAME; + key = new StringBuilder().append(packageKey).append(".").append(this.filename).toString(); + longName = filename; + } else { + packageKey = packageKey.trim(); + key = new StringBuilder().append(packageKey).append(".").append(this.filename).toString(); + longName = key; + } + parent = new ScalaPackage(packageKey); + setKey(key); + } + + @Override + public String getName() { + return filename; + } + + @Override + public String getLongName() { + return longName; + } + + @Override + public String getDescription() { + return null; + } + + @Override + public Language getLanguage() { + return Scala.INSTANCE; + } + + @Override + public String getScope() { + return Scopes.FILE; + } + + @Override + public String getQualifier() { + return isUnitTest ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE; + } + + @Override + public ScalaPackage getParent() { + return parent; + } + + @Override + public boolean matchFilePattern(String antPattern) { + final String patternWithoutFileSuffix = StringUtils.substringBeforeLast(antPattern, "."); + final WildcardPattern matcher = WildcardPattern.create(patternWithoutFileSuffix, "."); + return matcher.match(getKey()); + } + + public boolean isUnitTest() { + return isUnitTest; + } + + /** + * Shortcut for {@link #fromInputFile(InputFile, boolean)} for source files. + */ + public static ScalaFile fromInputFile(InputFile inputFile) { + return ScalaFile.fromInputFile(inputFile, false); + } + + /** + * Creates a {@link ScalaFile} from a file in the source directories. + * + * @param inputFile + * the file object with relative path + * @param isUnitTest + * whether it is a unit test file or a source file + * @return the {@link ScalaFile} created if exists, null otherwise + */ + public static ScalaFile fromInputFile(InputFile inputFile, boolean isUnitTest) { + if (inputFile == null || inputFile.getFile() == null || inputFile.getRelativePath() == null) { + return null; + } + + String packageName = PackageResolver.resolvePackageNameOfFile(inputFile.getFile().getAbsolutePath()); + String className = resolveClassName(inputFile); + + if (isPackageObjectInFirstLevelPackage(packageName, className)) { + String lastFolderName = extractLastFolderName(inputFile); + return new ScalaFile(StringUtils.EMPTY, lastFolderName + "." + className, isUnitTest); + } + + return new ScalaFile(packageName, className, isUnitTest); + } + + private static boolean isPackageObjectInFirstLevelPackage(String packageName, String className) { + return "".equalsIgnoreCase(packageName) && "package".equalsIgnoreCase(className); + } + + private static String extractLastFolderName(InputFile inputFile) { + String absolutePath = inputFile.getFile().getAbsolutePath(); + int lastPathSeparator = absolutePath.lastIndexOf("/"); + return absolutePath.substring(absolutePath.lastIndexOf("/", lastPathSeparator - 1) + 1, lastPathSeparator); + } + + private static String resolveClassName(InputFile inputFile) { + String classname = inputFile.getRelativePath(); + if (inputFile.getRelativePath().indexOf('/') >= 0) { + classname = StringUtils.substringAfterLast(inputFile.getRelativePath(), "/"); + } + return StringUtils.substringBeforeLast(classname, "."); + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("key", getKey()).append("fileName", filename) + .append("isUnitTest", isUnitTest).append("longName", longName).append("parent", parent).toString(); + } +} diff --git a/src/main/java/org/sonar/plugins/scala/language/ScalaPackage.java b/src/main/java/org/sonar/plugins/scala/language/ScalaPackage.java new file mode 100644 index 0000000..12e14fc --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/language/ScalaPackage.java @@ -0,0 +1,91 @@ +/* + * 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.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.WildcardPattern; + +/** + * This class implements a logical Scala package. + * + * @author Felix Müller + * @since 0.1 + */ +@SuppressWarnings("rawtypes") +public class ScalaPackage extends Resource { + public static final String DEFAULT_PACKAGE_NAME = "[default]"; + + public ScalaPackage(String key) { + super(); + setKey(StringUtils.defaultIfEmpty(StringUtils.trim(key), DEFAULT_PACKAGE_NAME)); + } + + @Override + public String getName() { + return getKey(); + } + + @Override + public String getLongName() { + return null; + } + + @Override + public String getDescription() { + return null; + } + + @Override + public Language getLanguage() { + return Scala.INSTANCE; + } + + @Override + public String getScope() { + return Scopes.DIRECTORY; + } + + @Override + public String getQualifier() { + return Qualifiers.PACKAGE; + } + + @Override + public Resource getParent() { + return null; + } + + @Override + public boolean matchFilePattern(String antPattern) { + String patternWithoutFileSuffix = StringUtils.substringBeforeLast(antPattern, "."); + WildcardPattern matcher = WildcardPattern.create(patternWithoutFileSuffix, "."); + return matcher.match(getKey()); + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("key", getKey()).toString(); + } +} diff --git a/src/main/java/org/sonar/plugins/scala/metrics/CommentsAnalyzer.java b/src/main/java/org/sonar/plugins/scala/metrics/CommentsAnalyzer.java index affacec..b1b850d 100644 --- a/src/main/java/org/sonar/plugins/scala/metrics/CommentsAnalyzer.java +++ b/src/main/java/org/sonar/plugins/scala/metrics/CommentsAnalyzer.java @@ -1,76 +1,76 @@ -/* - * 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.metrics; - -import java.util.List; - -import org.sonar.plugins.scala.language.Comment; - -/** - * This class implements the computation of basic - * line metrics for a {@link Comment}. - * - * @author Felix Müller - * @since 0.1 - */ -public class CommentsAnalyzer { - - private final List comments; - - public CommentsAnalyzer(List comments) { - this.comments = comments; - } - - public int countCommentLines() { - int commentLines = 0; - for (Comment comment : comments) { - if (!comment.isHeaderComment()) { - commentLines += comment.getNumberOfLines(); - } - } - return commentLines; - } - - public int countHeaderCommentLines() { - int headerCommentLines = 0; - for (Comment comment : comments) { - if (comment.isHeaderComment()) { - headerCommentLines += comment.getNumberOfLines(); - } - } - return headerCommentLines; - } - - public int countCommentedOutLinesOfCode() { - int commentedOutLinesOfCode = 0; - for (Comment comment : comments) { - commentedOutLinesOfCode += comment.getNumberOfCommentedOutLinesOfCode(); - } - return commentedOutLinesOfCode; - } - - public int countBlankCommentLines() { - int blankCommentLines = 0; - for (Comment comment : comments) { - blankCommentLines += comment.getNumberOfBlankLines(); - } - return blankCommentLines; - } +/* + * 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.metrics; + +import java.util.List; + +import org.sonar.plugins.scala.language.Comment; + +/** + * This class implements the computation of basic + * line metrics for a {@link Comment}. + * + * @author Felix Müller + * @since 0.1 + */ +public class CommentsAnalyzer { + + private final List comments; + + public CommentsAnalyzer(List comments) { + this.comments = comments; + } + + public int countCommentLines() { + int commentLines = 0; + for (Comment comment : comments) { + if (!comment.isHeaderComment()) { + commentLines += comment.getNumberOfLines(); + } + } + return commentLines; + } + + public int countHeaderCommentLines() { + int headerCommentLines = 0; + for (Comment comment : comments) { + if (comment.isHeaderComment()) { + headerCommentLines += comment.getNumberOfLines(); + } + } + return headerCommentLines; + } + + public int countCommentedOutLinesOfCode() { + int commentedOutLinesOfCode = 0; + for (Comment comment : comments) { + commentedOutLinesOfCode += comment.getNumberOfCommentedOutLinesOfCode(); + } + return commentedOutLinesOfCode; + } + + public int countBlankCommentLines() { + int blankCommentLines = 0; + for (Comment comment : comments) { + blankCommentLines += comment.getNumberOfBlankLines(); + } + return blankCommentLines; + } } \ No newline at end of file diff --git a/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java b/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java index d992a2e..1208a92 100644 --- a/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java +++ b/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java @@ -49,7 +49,14 @@ public SurefireSensor (Settings settings, FileSystem fileSystem){ } public boolean shouldExecuteOnProject(Project project) { - return fileSystem.hasFiles(fileSystem.predicates().hasLanguage(Scala.KEY)); + + if(project.getAnalysisType().isDynamic(true) && Scala.INSTANCE.getKey().equals(project.getLanguageKey())){ + LOG.info("SurefireSensor will be executed"); + return true; + } else { + LOG.info("SurefireSensor will NOT be executed"); + return false; + } } public void analyse(Project project, SensorContext context) { diff --git a/src/main/java/org/sonar/plugins/scala/util/StringUtils.java b/src/main/java/org/sonar/plugins/scala/util/StringUtils.java index 2680457..382d1e8 100644 --- a/src/main/java/org/sonar/plugins/scala/util/StringUtils.java +++ b/src/main/java/org/sonar/plugins/scala/util/StringUtils.java @@ -1,57 +1,57 @@ -/* - * 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; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class StringUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class); - - private StringUtils() { - // to prevent instantiation - } - - public static List convertStringToListOfLines(String string) throws IOException { - final List lines = new ArrayList(); - BufferedReader reader = null; - try { - reader = new BufferedReader(new StringReader(string)); - String line = null; - while ((line = reader.readLine()) != null) { - lines.add(line); - } - } catch (IOException ioe) { - LOGGER.error("Error while reading the lines of a given string", ioe); - throw ioe; - } finally { - IOUtils.closeQuietly(reader); - } - return lines; - } +/* + * 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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class StringUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class); + + private StringUtils() { + // to prevent instantiation + } + + public static List convertStringToListOfLines(String string) throws IOException { + final List lines = new ArrayList(); + BufferedReader reader = null; + try { + reader = new BufferedReader(new StringReader(string)); + String line = null; + while ((line = reader.readLine()) != null) { + lines.add(line); + } + } catch (IOException ioe) { + LOGGER.error("Error while reading the lines of a given string", ioe); + throw ioe; + } finally { + IOUtils.closeQuietly(reader); + } + return lines; + } } \ No newline at end of file diff --git a/src/main/scala/org/sonar/plugins/scala/metrics/PublicApiCounter.scala b/src/main/scala/org/sonar/plugins/scala/metrics/PublicApiCounter.scala index 3a6ed9a..abe0238 100644 --- a/src/main/scala/org/sonar/plugins/scala/metrics/PublicApiCounter.scala +++ b/src/main/scala/org/sonar/plugins/scala/metrics/PublicApiCounter.scala @@ -1,97 +1,97 @@ -/* - * 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.metrics - -import org.sonar.plugins.scala.compiler.{ Compiler, Parser } - -/** - * This object is a helper object for counting public api members. - * - * @author Felix Müller - * @since 0.1 - */ -object PublicApiCounter { - - import Compiler._ - - private lazy val parser = new Parser() - - private case class PublicApi(isDocumented: Boolean) - - def countPublicApi(source: String) = { - countPublicApiTrees(parser.parse(source)).size - } - - def countUndocumentedPublicApi(source: String) = { - countPublicApiTrees(parser.parse(source)).count(!_.isDocumented) - } - - private def countPublicApiTrees(tree: Tree, wasDocDefBefore: Boolean = false, - foundPublicApiMembers: List[PublicApi] = Nil) : List[PublicApi] = tree match { - - // recursive descent until found a syntax tree with countable public api declarations - case PackageDef(_, content) => - foundPublicApiMembers ++ content.flatMap(countPublicApiTrees(_, false, Nil)) - - case Template(_, _, content) => - foundPublicApiMembers ++ content.flatMap(countPublicApiTrees(_, false, Nil)) - - case DocDef(_, content) => - countPublicApiTrees(content, true, foundPublicApiMembers) - - case Block(stats, expr) => - foundPublicApiMembers ++ stats.flatMap(countPublicApiTrees(_, false, Nil)) ++ countPublicApiTrees(expr) - - case Apply(_, args) => - foundPublicApiMembers ++ args.flatMap(countPublicApiTrees(_, false, Nil)) - - case classDef: ClassDef if classDef.mods.hasFlag(Flag.PRIVATE) => - countPublicApiTrees(classDef.impl, false, foundPublicApiMembers) - - case moduleDef: ModuleDef if moduleDef.mods.hasFlag(Flag.PRIVATE) => - countPublicApiTrees(moduleDef.impl, false, foundPublicApiMembers) - - case defDef: DefDef if isEmptyConstructor(defDef) || defDef.mods.hasFlag(Flag.PRIVATE) => - countPublicApiTrees(defDef.rhs, false, foundPublicApiMembers) - - case valDef: ValDef if valDef.mods.hasFlag(Flag.PRIVATE) => - countPublicApiTrees(valDef.rhs, false, foundPublicApiMembers) - - /* - * Countable public api declarations are classes, objects, traits, functions, - * methods and attributes with public access. - */ - - case ClassDef(_, _, _, impl) => - countPublicApiTrees(impl, false, foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore))) - - case ModuleDef(_, _, impl) => - countPublicApiTrees(impl, false, foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore))) - - case defDef: DefDef => - foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore)) - - case valDef: ValDef => - foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore)) - - case _ => - foundPublicApiMembers - } +/* + * 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.metrics + +import org.sonar.plugins.scala.compiler.{ Compiler, Parser } + +/** + * This object is a helper object for counting public api members. + * + * @author Felix Müller + * @since 0.1 + */ +object PublicApiCounter { + + import Compiler._ + + private lazy val parser = new Parser() + + private case class PublicApi(isDocumented: Boolean) + + def countPublicApi(source: String) = { + countPublicApiTrees(parser.parse(source)).size + } + + def countUndocumentedPublicApi(source: String) = { + countPublicApiTrees(parser.parse(source)).count(!_.isDocumented) + } + + private def countPublicApiTrees(tree: Tree, wasDocDefBefore: Boolean = false, + foundPublicApiMembers: List[PublicApi] = Nil) : List[PublicApi] = tree match { + + // recursive descent until found a syntax tree with countable public api declarations + case PackageDef(_, content) => + foundPublicApiMembers ++ content.flatMap(countPublicApiTrees(_, false, Nil)) + + case Template(_, _, content) => + foundPublicApiMembers ++ content.flatMap(countPublicApiTrees(_, false, Nil)) + + case DocDef(_, content) => + countPublicApiTrees(content, true, foundPublicApiMembers) + + case Block(stats, expr) => + foundPublicApiMembers ++ stats.flatMap(countPublicApiTrees(_, false, Nil)) ++ countPublicApiTrees(expr) + + case Apply(_, args) => + foundPublicApiMembers ++ args.flatMap(countPublicApiTrees(_, false, Nil)) + + case classDef: ClassDef if classDef.mods.hasFlag(Flag.PRIVATE) => + countPublicApiTrees(classDef.impl, false, foundPublicApiMembers) + + case moduleDef: ModuleDef if moduleDef.mods.hasFlag(Flag.PRIVATE) => + countPublicApiTrees(moduleDef.impl, false, foundPublicApiMembers) + + case defDef: DefDef if isEmptyConstructor(defDef) || defDef.mods.hasFlag(Flag.PRIVATE) => + countPublicApiTrees(defDef.rhs, false, foundPublicApiMembers) + + case valDef: ValDef if valDef.mods.hasFlag(Flag.PRIVATE) => + countPublicApiTrees(valDef.rhs, false, foundPublicApiMembers) + + /* + * Countable public api declarations are classes, objects, traits, functions, + * methods and attributes with public access. + */ + + case ClassDef(_, _, _, impl) => + countPublicApiTrees(impl, false, foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore))) + + case ModuleDef(_, _, impl) => + countPublicApiTrees(impl, false, foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore))) + + case defDef: DefDef => + foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore)) + + case valDef: ValDef => + foundPublicApiMembers ++ List(PublicApi(wasDocDefBefore)) + + case _ => + foundPublicApiMembers + } } \ No newline at end of file diff --git a/src/test/java/org/sonar/plugins/scala/ScalaPluginTest.java b/src/test/java/org/sonar/plugins/scala/ScalaPluginTest.java index e8c8bd4..7b70a4e 100644 --- a/src/test/java/org/sonar/plugins/scala/ScalaPluginTest.java +++ b/src/test/java/org/sonar/plugins/scala/ScalaPluginTest.java @@ -1,44 +1,44 @@ -/* - * 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; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; -import org.sonar.plugins.scala.surefire.SurefireSensor; - -public class ScalaPluginTest { - - @Test - public void shouldHaveExtensions() { - assertThat(new ScalaPlugin().getExtensions().size(), greaterThan(0)); - } - - @Test - public void shouldHaveSurefirePlugin() { - assertTrue(new ScalaPlugin().getExtensions().contains(SurefireSensor.class)); - } - - @Test - public void shouldGetPathToDependencies() { - assertThat(ScalaPlugin.getPathToScalaLibrary(), containsString("scala-library")); - } +/* + * 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; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import org.junit.Test; +import org.sonar.plugins.scala.surefire.SurefireSensor; + +public class ScalaPluginTest { + + @Test + public void shouldHaveExtensions() { + assertThat(new ScalaPlugin().getExtensions().size(), greaterThan(0)); + } + + @Test + public void shouldHaveSurefirePlugin() { + assertTrue(new ScalaPlugin().getExtensions().contains(SurefireSensor.class)); + } + + @Test + public void shouldGetPathToDependencies() { + assertThat(ScalaPlugin.getPathToScalaLibrary(), containsString("scala-library")); + } } diff --git a/src/test/java/org/sonar/plugins/scala/cpd/ScalaTokenizerTest.java b/src/test/java/org/sonar/plugins/scala/cpd/ScalaTokenizerTest.java index f8ea2d9..5ea94e3 100644 --- a/src/test/java/org/sonar/plugins/scala/cpd/ScalaTokenizerTest.java +++ b/src/test/java/org/sonar/plugins/scala/cpd/ScalaTokenizerTest.java @@ -78,8 +78,6 @@ public void test4() throws Throwable { tokenizer.tokenize(sourceCode, tokens); assertEquals("class NewlinesToken {", sourceCode.getSlice(1, 1)); - assertEquals("val i = 42", sourceCode.getSlice(2, 2)); - } private File resourceToFile(String path) { diff --git a/src/test/java/org/sonar/plugins/scala/language/ScalaTest.java b/src/test/java/org/sonar/plugins/scala/language/ScalaTest.java index ebae744..a6dcebf 100644 --- a/src/test/java/org/sonar/plugins/scala/language/ScalaTest.java +++ b/src/test/java/org/sonar/plugins/scala/language/ScalaTest.java @@ -30,19 +30,19 @@ public class ScalaTest { @Test public void shouldHaveScalaLanguageKey() { - assertThat(new Scala(new Settings()).getKey(), equalTo("scala")); + assertThat(new Scala().getKey(), equalTo("scala")); assertThat(Scala.KEY, equalTo("scala")); } @Test public void shouldHaveScalaLanguageName() { - assertThat(new Scala(new Settings()).getName(), equalTo("Scala")); + assertThat(new Scala().getName(), equalTo("Scala")); assertThat(Scala.NAME, equalTo("Scala")); } @Test public void shouldHaveScalaFileSuffixes() { String[] suffixes = new String[] { "scala" }; - assertArrayEquals(new Scala(new Settings()).getFileSuffixes(), suffixes); + assertArrayEquals(new Scala().getFileSuffixes(), suffixes); } } \ No newline at end of file diff --git a/src/test/java/org/sonar/plugins/scala/sensor/AbstractScalaSensorTest.java b/src/test/java/org/sonar/plugins/scala/sensor/AbstractScalaSensorTest.java index c7afe5a..8488d2d 100644 --- a/src/test/java/org/sonar/plugins/scala/sensor/AbstractScalaSensorTest.java +++ b/src/test/java/org/sonar/plugins/scala/sensor/AbstractScalaSensorTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; import org.sonar.plugins.scala.language.Scala; import org.sonar.plugins.scala.util.FileTestUtils; @@ -37,15 +36,13 @@ public class AbstractScalaSensorTest { private AbstractScalaSensor abstractScalaSensor; - private Settings settings; private DefaultFileSystem fileSystem; @Before public void setUp() { - Settings settings = new Settings(); fileSystem = new DefaultFileSystem(); - abstractScalaSensor = new AbstractScalaSensor(new Scala(settings), fileSystem) { + abstractScalaSensor = new AbstractScalaSensor(new Scala(), fileSystem) { public void analyse(Project project, SensorContext context) { // dummy implementation, never called in this test @@ -71,6 +68,6 @@ public void shouldNotExecuteOnJavaProjects() { @Test public void shouldHaveScalaAsLanguage() { - assertThat(abstractScalaSensor.getScala(), equalTo(new Scala(settings))); + assertThat(abstractScalaSensor.getScala(), equalTo(new Scala())); } } \ No newline at end of file diff --git a/src/test/java/org/sonar/plugins/scala/sensor/BaseMetricsSensorTest.java b/src/test/java/org/sonar/plugins/scala/sensor/BaseMetricsSensorTest.java index 34d08fa..67b3546 100644 --- a/src/test/java/org/sonar/plugins/scala/sensor/BaseMetricsSensorTest.java +++ b/src/test/java/org/sonar/plugins/scala/sensor/BaseMetricsSensorTest.java @@ -49,14 +49,12 @@ public class BaseMetricsSensorTest { private DefaultFileSystem fileSystem; private Project project; private SensorContext sensorContext; - private Settings settings; @Before public void setUp() { - this.settings = new Settings(); this.fileSystem = new DefaultFileSystem(); - this.baseMetricsSensor = new BaseMetricsSensor(new Scala(settings), fileSystem); + this.baseMetricsSensor = new BaseMetricsSensor(new Scala(), fileSystem); this.project = mock(Project.class); this.sensorContext = mock(SensorContext.class); diff --git a/src/test/resources/baseMetricsSensor/ScalaFile3.scala b/src/test/resources/baseMetricsSensor/ScalaFile3.scala index 29c4213..c0a9855 100644 --- a/src/test/resources/baseMetricsSensor/ScalaFile3.scala +++ b/src/test/resources/baseMetricsSensor/ScalaFile3.scala @@ -1,5 +1,5 @@ -package baseMetricsSensor - -class ScalaFile3 { - +package baseMetricsSensor + +class ScalaFile3 { + } \ No newline at end of file diff --git a/src/test/resources/lexer/NormalCommentWithHeaderComment.txt b/src/test/resources/lexer/NormalCommentWithHeaderComment.txt index 2f52a33..a464296 100644 --- a/src/test/resources/lexer/NormalCommentWithHeaderComment.txt +++ b/src/test/resources/lexer/NormalCommentWithHeaderComment.txt @@ -1,6 +1,6 @@ -// Just a test - -/* - * This comment describes the - * content of the file. +// Just a test + +/* + * This comment describes the + * content of the file. */ \ No newline at end of file diff --git a/src/test/resources/packageResolver/SimplePackageDeclaration.txt b/src/test/resources/packageResolver/SimplePackageDeclaration.txt index 9f19b5f..cb17d23 100644 --- a/src/test/resources/packageResolver/SimplePackageDeclaration.txt +++ b/src/test/resources/packageResolver/SimplePackageDeclaration.txt @@ -1,6 +1,6 @@ -package one { - - object A { - val b = 1 - } +package one { + + object A { + val b = 1 + } } \ No newline at end of file diff --git a/src/test/resources/scalaSourceImporter/MainFile2.scala b/src/test/resources/scalaSourceImporter/MainFile2.scala index d2474a8..99a73e8 100644 --- a/src/test/resources/scalaSourceImporter/MainFile2.scala +++ b/src/test/resources/scalaSourceImporter/MainFile2.scala @@ -1,5 +1,5 @@ -package scalaSourceImporter - -class MainFile2 { - +package scalaSourceImporter + +class MainFile2 { + } \ No newline at end of file diff --git a/src/test/resources/scalaSourceImporter/TestFile1.scala b/src/test/resources/scalaSourceImporter/TestFile1.scala index efbd263..c73f66e 100644 --- a/src/test/resources/scalaSourceImporter/TestFile1.scala +++ b/src/test/resources/scalaSourceImporter/TestFile1.scala @@ -1,5 +1,5 @@ -package scalaSourceImporter - -class TestFile1 { - +package scalaSourceImporter + +class TestFile1 { + } \ No newline at end of file diff --git a/src/test/scala/org/sonar/plugins/scala/compiler/LexerSpec.scala b/src/test/scala/org/sonar/plugins/scala/compiler/LexerSpec.scala index 828341b..5530003 100644 --- a/src/test/scala/org/sonar/plugins/scala/compiler/LexerSpec.scala +++ b/src/test/scala/org/sonar/plugins/scala/compiler/LexerSpec.scala @@ -1,83 +1,83 @@ -/* - * 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 tools.nsc.ast.parser.Tokens._ - -import java.util.Arrays -import org.junit.runner.RunWith -import org.scalatest.{ShouldMatchers, FlatSpec} -import org.scalatest.junit.JUnitRunner - -import org.sonar.plugins.scala.language.{ Comment, CommentType } -import org.sonar.plugins.scala.util.FileTestUtils - -@RunWith(classOf[JUnitRunner]) -class LexerSpec extends FlatSpec with ShouldMatchers { - - private val lexer = new Lexer() - - private val headerComment = "/*\r\n * This comment describes the\r\n" + - " * content of the file.\r\n */" - - "A lexer" should "tokenize a simple declaration of a value" in { - val tokens = lexer.getTokens("val a = " + "\r\n" + "42") - tokens should equal (Arrays.asList(Token(VAL, 1), Token(IDENTIFIER, 1), Token(EQUALS, 1), Token(INTLIT, 2))) - } - - it should "tokenize a doc comment" in { - val comments = getCommentsOf("DocComment1") - comments should have size(1) - comments should contain (new Comment("/** Hello World */", CommentType.DOC)) - } - - it should "tokenize a header comment" in { - val comments = getCommentsOf("SimpleHeaderComment") - comments should have size(1) - comments should contain (new Comment(headerComment, CommentType.HEADER)) - } - - it should "not tokenize a header comment when it is not the first comment" in { - val comments = getCommentsOf("NormalCommentWithHeaderComment") - comments should have size(2) - comments should contain (new Comment("// Just a test", CommentType.NORMAL)) - comments should contain (new Comment(headerComment, CommentType.NORMAL)) - } - - it should "not tokenize a header comment when it is not starting with /*" in { - val comments = getCommentsOf("HeaderCommentWithWrongStart") - comments should have size(1) - comments should contain (new Comment("/**\r\n * This comment describes the\r\n" + - " * content of the file.\r\n */", CommentType.DOC)) - } - - it should "not tokenize a header comment when there was code before" in { - val comments = getCommentsOf("HeaderCommentWithCodeBefore") - comments should have size(1) - comments should contain (new Comment(headerComment, CommentType.NORMAL)) - } - - // TODO add more specs for lexer - - private def getCommentsOf(fileName: String) = { - val path = FileTestUtils.getRelativePath("/lexer/" + fileName + ".txt") - lexer.getCommentsOfFile(path) - } +/* + * 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 tools.nsc.ast.parser.Tokens._ + +import java.util.Arrays +import org.junit.runner.RunWith +import org.scalatest.{ShouldMatchers, FlatSpec} +import org.scalatest.junit.JUnitRunner + +import org.sonar.plugins.scala.language.{ Comment, CommentType } +import org.sonar.plugins.scala.util.FileTestUtils + +@RunWith(classOf[JUnitRunner]) +class LexerSpec extends FlatSpec with ShouldMatchers { + + private val lexer = new Lexer() + + private val headerComment = "/*\r\n * This comment describes the\r\n" + + " * content of the file.\r\n */" + + "A lexer" should "tokenize a simple declaration of a value" in { + val tokens = lexer.getTokens("val a = " + "\r\n" + "42") + tokens should equal (Arrays.asList(Token(VAL, 1), Token(IDENTIFIER, 1), Token(EQUALS, 1), Token(INTLIT, 2))) + } + + it should "tokenize a doc comment" in { + val comments = getCommentsOf("DocComment1") + comments should have size(1) + comments should contain (new Comment("/** Hello World */", CommentType.DOC)) + } + + it should "tokenize a header comment" in { + val comments = getCommentsOf("SimpleHeaderComment") + comments should have size(1) + comments should contain (new Comment(headerComment, CommentType.HEADER)) + } + + it should "not tokenize a header comment when it is not the first comment" in { + val comments = getCommentsOf("NormalCommentWithHeaderComment") + comments should have size(2) + comments should contain (new Comment("// Just a test", CommentType.NORMAL)) + comments should contain (new Comment(headerComment, CommentType.NORMAL)) + } + + it should "not tokenize a header comment when it is not starting with /*" in { + val comments = getCommentsOf("HeaderCommentWithWrongStart") + comments should have size(1) + comments should contain (new Comment("/**\r\n * This comment describes the\r\n" + + " * content of the file.\r\n */", CommentType.DOC)) + } + + it should "not tokenize a header comment when there was code before" in { + val comments = getCommentsOf("HeaderCommentWithCodeBefore") + comments should have size(1) + comments should contain (new Comment(headerComment, CommentType.NORMAL)) + } + + // TODO add more specs for lexer + + private def getCommentsOf(fileName: String) = { + val path = FileTestUtils.getRelativePath("/lexer/" + fileName + ".txt") + lexer.getCommentsOfFile(path) + } } \ No newline at end of file diff --git a/src/test/scala/org/sonar/plugins/scala/metrics/FunctionCounterSpec.scala b/src/test/scala/org/sonar/plugins/scala/metrics/FunctionCounterSpec.scala index 1e90b69..7b439de 100644 --- a/src/test/scala/org/sonar/plugins/scala/metrics/FunctionCounterSpec.scala +++ b/src/test/scala/org/sonar/plugins/scala/metrics/FunctionCounterSpec.scala @@ -1,121 +1,121 @@ -/* - * 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.metrics - -import org.junit.runner.RunWith -import org.scalatest.{ShouldMatchers, FlatSpec} -import org.scalatest.junit.JUnitRunner - -@RunWith(classOf[JUnitRunner]) -class FunctionCounterSpec extends FlatSpec with ShouldMatchers { - - "A function counter" should "count a simple function declaration" in { - FunctionCounter.countFunctions("def test = 42") should be (1) - } - - it should "count a simple method declaration" in { - FunctionCounter.countFunctions("def test { println(42) }") should be (1) - } - - it should "not count a simple function declared as a function literal" in { - FunctionCounter.countFunctions("(i: Int) => i + 1") should be (0) - } - - it should "count a simple function declaration nested in another function" in { - val source = """ - def test = { - def inc(i: Int) = i + 1 - }""" - FunctionCounter.countFunctions(source) should be (2) - } - - it should "count a simple function declaration nested in another method" in { - val source = """ - def test { - def inc(i: Int) = i + 1 - }""" - FunctionCounter.countFunctions(source) should be (2) - } - - it should "not count an empty constructor as a function declaration" in { - val source = "class Person(val name: String) { }" - FunctionCounter.countFunctions(source) should be (0) - } - - it should "count a constructor as a function declaration" in { - val source = """ - class Person(val name: String) { - def this(name: String) { - super(name) - println(name) - } - }""" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a simple function declaration nested in an object" in { - val source = """ - object Test { - def inc(i: Int) = { i + 1 } - }""" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a simple function declaration nested in a trait" in { - val source = """ - trait Test { - def inc(i: Int) = { i + 1 } - }""" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a function declaration with two parameter lists" in { - val source = "def sum(x: Int)(y: Int) = { x + y }" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a simple function declaration nested in a trait with self-type annotation" in { - val source = """ - trait Test { - self: HelloWorld => - def inc(i: Int) = { i + 1 } - }""" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a function declaration with two parameter lists nested in a trait with self-type annotation" in { - val source = """ - trait Test { - self: HelloWorld => - def sum(x: Int)(y: Int) = { x + y } - }""" - FunctionCounter.countFunctions(source) should be (1) - } - - it should "count a function declaration with if else block in its body" in { - val source = """ - def test(number: Int) : Int = - if (number < 42) - 23 - else - 42""" - FunctionCounter.countFunctions(source) should be (1) - } +/* + * 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.metrics + +import org.junit.runner.RunWith +import org.scalatest.{ShouldMatchers, FlatSpec} +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class FunctionCounterSpec extends FlatSpec with ShouldMatchers { + + "A function counter" should "count a simple function declaration" in { + FunctionCounter.countFunctions("def test = 42") should be (1) + } + + it should "count a simple method declaration" in { + FunctionCounter.countFunctions("def test { println(42) }") should be (1) + } + + it should "not count a simple function declared as a function literal" in { + FunctionCounter.countFunctions("(i: Int) => i + 1") should be (0) + } + + it should "count a simple function declaration nested in another function" in { + val source = """ + def test = { + def inc(i: Int) = i + 1 + }""" + FunctionCounter.countFunctions(source) should be (2) + } + + it should "count a simple function declaration nested in another method" in { + val source = """ + def test { + def inc(i: Int) = i + 1 + }""" + FunctionCounter.countFunctions(source) should be (2) + } + + it should "not count an empty constructor as a function declaration" in { + val source = "class Person(val name: String) { }" + FunctionCounter.countFunctions(source) should be (0) + } + + it should "count a constructor as a function declaration" in { + val source = """ + class Person(val name: String) { + def this(name: String) { + super(name) + println(name) + } + }""" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a simple function declaration nested in an object" in { + val source = """ + object Test { + def inc(i: Int) = { i + 1 } + }""" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a simple function declaration nested in a trait" in { + val source = """ + trait Test { + def inc(i: Int) = { i + 1 } + }""" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a function declaration with two parameter lists" in { + val source = "def sum(x: Int)(y: Int) = { x + y }" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a simple function declaration nested in a trait with self-type annotation" in { + val source = """ + trait Test { + self: HelloWorld => + def inc(i: Int) = { i + 1 } + }""" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a function declaration with two parameter lists nested in a trait with self-type annotation" in { + val source = """ + trait Test { + self: HelloWorld => + def sum(x: Int)(y: Int) = { x + y } + }""" + FunctionCounter.countFunctions(source) should be (1) + } + + it should "count a function declaration with if else block in its body" in { + val source = """ + def test(number: Int) : Int = + if (number < 42) + 23 + else + 42""" + FunctionCounter.countFunctions(source) should be (1) + } } \ No newline at end of file diff --git a/src/test/scala/org/sonar/plugins/scala/metrics/TypeCounterSpec.scala b/src/test/scala/org/sonar/plugins/scala/metrics/TypeCounterSpec.scala index e892115..b3b7006 100644 --- a/src/test/scala/org/sonar/plugins/scala/metrics/TypeCounterSpec.scala +++ b/src/test/scala/org/sonar/plugins/scala/metrics/TypeCounterSpec.scala @@ -1,164 +1,164 @@ -/* - * 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.metrics - -import org.junit.runner.RunWith -import org.scalatest.{ShouldMatchers, FlatSpec} -import org.scalatest.junit.JUnitRunner - -@RunWith(classOf[JUnitRunner]) -class TypeCounterSpec extends FlatSpec with ShouldMatchers { - - "A type counter" should "count type of a simple class declaration" in { - TypeCounter.countTypes("class A {}") should be (1) - } - - it should "count type of a simple object declaration" in { - TypeCounter.countTypes("object A {}") should be (1) - } - - it should "count type of a simple trait declaration" in { - TypeCounter.countTypes("trait A {}") should be (1) - } - - it should "count type of a simple case class declaration" in { - TypeCounter.countTypes("case class A {}") should be (1) - } - - it should "count type of a simple class declaration nested in a package" in { - val source = """ - package a.b - class A {}""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a package with imports" in { - val source = """ - package a.b - import java.util.List - class A {}""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a package with import and doc comment" in { - val source = """ - package a.b - import java.util.List - /** Doc comment... */ - class A {}""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple object declaration nested in a package" in { - val source = """ - package a.b - object A {}""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count types of a simple class declarations" in { - val source = """ - class A {} - class B {}""" - TypeCounter.countTypes(source) should be (2) - } - - it should "count type of a simple class declaration nested in a class" in { - TypeCounter.countTypes("class A { class B {} }") should be (2) - } - - it should "count type of a simple class declaration nested in an object" in { - TypeCounter.countTypes("object A { class B {} }") should be (2) - } - - it should "count type of a simple object declaration nested in a class" in { - TypeCounter.countTypes("class A { object B {} }") should be (2) - } - - it should "count type of a simple object declaration nested in an object" in { - TypeCounter.countTypes("object A { object B {} }") should be (2) - } - - it should "count type of a simple class declaration nested in a function" in { - val source = """ - def fooBar(i: Int) = { - class B { val a = 1 } - i + new B().a - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a value definition" in { - val source = """ - val fooBar = { - class B { val a = 1 } - 1 + new B().a - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in an assignment" in { - val source = """ - fooBar = { - class B { val a = 1 } - 1 + new B().a - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a code block" in { - val source = """ - { - 1 + new B().a - class B { val a = 1 } - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a loop" in { - val source = """ - var i = 0 - while (i == 2) { - i = i + new B().a - class B { val a = 1 } - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a match statement" in { - val source = """ - var i = 0 - i match { - case 0 => class B { val a = 1 } - case _ => - }""" - TypeCounter.countTypes(source) should be (1) - } - - it should "count type of a simple class declaration nested in a try statement" in { - val source = """ - try { - class B { val a = 1 } - } catch { - case _ => - }""" - TypeCounter.countTypes(source) should be (1) - } +/* + * 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.metrics + +import org.junit.runner.RunWith +import org.scalatest.{ShouldMatchers, FlatSpec} +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class TypeCounterSpec extends FlatSpec with ShouldMatchers { + + "A type counter" should "count type of a simple class declaration" in { + TypeCounter.countTypes("class A {}") should be (1) + } + + it should "count type of a simple object declaration" in { + TypeCounter.countTypes("object A {}") should be (1) + } + + it should "count type of a simple trait declaration" in { + TypeCounter.countTypes("trait A {}") should be (1) + } + + it should "count type of a simple case class declaration" in { + TypeCounter.countTypes("case class A {}") should be (1) + } + + it should "count type of a simple class declaration nested in a package" in { + val source = """ + package a.b + class A {}""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a package with imports" in { + val source = """ + package a.b + import java.util.List + class A {}""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a package with import and doc comment" in { + val source = """ + package a.b + import java.util.List + /** Doc comment... */ + class A {}""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple object declaration nested in a package" in { + val source = """ + package a.b + object A {}""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count types of a simple class declarations" in { + val source = """ + class A {} + class B {}""" + TypeCounter.countTypes(source) should be (2) + } + + it should "count type of a simple class declaration nested in a class" in { + TypeCounter.countTypes("class A { class B {} }") should be (2) + } + + it should "count type of a simple class declaration nested in an object" in { + TypeCounter.countTypes("object A { class B {} }") should be (2) + } + + it should "count type of a simple object declaration nested in a class" in { + TypeCounter.countTypes("class A { object B {} }") should be (2) + } + + it should "count type of a simple object declaration nested in an object" in { + TypeCounter.countTypes("object A { object B {} }") should be (2) + } + + it should "count type of a simple class declaration nested in a function" in { + val source = """ + def fooBar(i: Int) = { + class B { val a = 1 } + i + new B().a + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a value definition" in { + val source = """ + val fooBar = { + class B { val a = 1 } + 1 + new B().a + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in an assignment" in { + val source = """ + fooBar = { + class B { val a = 1 } + 1 + new B().a + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a code block" in { + val source = """ + { + 1 + new B().a + class B { val a = 1 } + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a loop" in { + val source = """ + var i = 0 + while (i == 2) { + i = i + new B().a + class B { val a = 1 } + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a match statement" in { + val source = """ + var i = 0 + i match { + case 0 => class B { val a = 1 } + case _ => + }""" + TypeCounter.countTypes(source) should be (1) + } + + it should "count type of a simple class declaration nested in a try statement" in { + val source = """ + try { + class B { val a = 1 } + } catch { + case _ => + }""" + TypeCounter.countTypes(source) should be (1) + } } \ No newline at end of file