From: Duarte Meneses Date: Wed, 5 Jun 2019 16:01:49 +0000 (-0500) Subject: Extract implementation from plugin API - Scanner FS X-Git-Tag: 8.0~354 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=97e15208790028ed50187e58cd4580e6cef8e6b3;p=sonarqube.git Extract implementation from plugin API - Scanner FS --- diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java index 5293d3128cf..5bd1c1377a5 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java @@ -29,8 +29,8 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextRange; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.DefaultTextRange; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.DefaultSensorDescriptor; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java index 2093e773d49..a15596379af 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java @@ -27,8 +27,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextRange; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.DefaultTextRange; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.DefaultSensorDescriptor; import org.sonar.scanner.sensor.SensorContextTester; @@ -77,9 +77,9 @@ public class SymbolReferencesSensorTest { sensor.execute(context); assertThat(context.referencesForSymbolAt("foo:src/foo.xoo", 1, 2)) - .containsOnly(new DefaultTextRange(new DefaultTextPointer(1, 7), new DefaultTextPointer(1,10))); + .containsOnly(new DefaultTextRange(new DefaultTextPointer(1, 7), new DefaultTextPointer(1, 10))); assertThat(context.referencesForSymbolAt("foo:src/foo.xoo", 1, 13)) - .containsOnly(new DefaultTextRange(new DefaultTextPointer(1, 23), new DefaultTextPointer(1,33))); + .containsOnly(new DefaultTextRange(new DefaultTextPointer(1, 23), new DefaultTextPointer(1, 33))); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java index 965d4d653e4..8cc02238d0a 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java @@ -26,8 +26,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.DefaultSensorDescriptor; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java index c5aa5d4534c..2f7d074ca10 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java @@ -29,9 +29,9 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.sensor.error.AnalysisError; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultTextPointer; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java index 1d6c610ca49..67f9325575c 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java @@ -20,16 +20,16 @@ package org.sonar.xoo.rule; import java.io.IOException; -import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.Version; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.DefaultSensorDescriptor; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java index ef30ede34f0..2b02d2df949 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java @@ -28,12 +28,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.scm.BlameCommand.BlameInput; import org.sonar.api.batch.scm.BlameCommand.BlameOutput; import org.sonar.api.batch.scm.BlameLine; import org.sonar.api.utils.DateUtils; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.xoo.Xoo; diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java index 79330b39fe1..a661855be61 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java @@ -21,7 +21,6 @@ package org.sonar.core.component; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import static com.google.common.base.Preconditions.checkArgument; @@ -45,10 +44,6 @@ public final class ComponentKeys { // only static stuff } - public static String createEffectiveKey(String projectKey, DefaultInputFile inputPath) { - return createEffectiveKey(projectKey, inputPath.getProjectRelativePath()); - } - public static String createEffectiveKey(String projectKey, @Nullable String path) { StringBuilder sb = new StringBuilder(MAX_COMPONENT_KEY_LENGTH); sb.append(projectKey); diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java index 5187d09bd24..e476adcab74 100644 --- a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java +++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java @@ -22,23 +22,13 @@ package org.sonar.core.component; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class ComponentKeysTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - @Test - public void create_effective_key() { - DefaultInputFile file = mock(DefaultInputFile.class); - when(file.getProjectRelativePath()).thenReturn("foo/Bar.php"); - assertThat(ComponentKeys.createEffectiveKey("my_project", file)).isEqualTo("my_project:foo/Bar.php"); - } - @Test public void create_key_from_module_key_path_and_branch() { assertThat(ComponentKeys.createKey("module_key", "file", "origin/master")).isEqualTo("module_key:origin/master:file"); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java deleted file mode 100644 index 2f45fb0f488..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.CheckForNull; -import javax.annotation.concurrent.Immutable; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.SystemUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -@Immutable -public abstract class AbstractProjectOrModule extends DefaultInputComponent { - private static final Logger LOGGER = Loggers.get(AbstractProjectOrModule.class); - private final Path baseDir; - private final Path workDir; - private final String name; - private final String originalName; - private final String description; - private final String keyWithBranch; - private final String branch; - private final Map properties; - - private final String key; - private final ProjectDefinition definition; - private final Charset encoding; - - public AbstractProjectOrModule(ProjectDefinition definition, int scannerComponentId) { - super(scannerComponentId); - this.baseDir = initBaseDir(definition); - this.workDir = initWorkingDir(definition); - this.name = definition.getName(); - this.originalName = definition.getOriginalName(); - this.description = definition.getDescription(); - this.keyWithBranch = definition.getKeyWithBranch(); - this.branch = definition.getBranch(); - this.properties = Collections.unmodifiableMap(new HashMap<>(definition.properties())); - - this.definition = definition; - this.key = definition.getKey(); - this.encoding = initEncoding(definition); - } - - private static Charset initEncoding(ProjectDefinition module) { - String encodingStr = module.properties().get(CoreProperties.ENCODING_PROPERTY); - Charset result; - if (StringUtils.isNotEmpty(encodingStr)) { - result = Charset.forName(StringUtils.trim(encodingStr)); - } else { - result = Charset.defaultCharset(); - } - return result; - } - - private static Path initBaseDir(ProjectDefinition module) { - Path result; - try { - result = module.getBaseDir().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS); - } catch (IOException e) { - throw new IllegalStateException("Unable to resolve module baseDir", e); - } - return result; - } - - private static Path initWorkingDir(ProjectDefinition module) { - File workingDirAsFile = module.getWorkDir(); - Path workingDir = workingDirAsFile.getAbsoluteFile().toPath().normalize(); - if (SystemUtils.IS_OS_WINDOWS) { - try { - Files.createDirectories(workingDir); - Files.setAttribute(workingDir, "dos:hidden", true, LinkOption.NOFOLLOW_LINKS); - } catch (IOException e) { - LOGGER.warn("Failed to set working directory hidden: {}", e.getMessage()); - } - } - return workingDir; - } - - /** - * Module key without branch - */ - @Override - public String key() { - return key; - } - - @Override - public boolean isFile() { - return false; - } - - public ProjectDefinition definition() { - return definition; - } - - public Path getBaseDir() { - return baseDir; - } - - public Path getWorkDir() { - return workDir; - } - - public String getKeyWithBranch() { - return keyWithBranch; - } - - @CheckForNull - public String getBranch() { - return branch; - } - - public Map properties() { - return properties; - } - - @CheckForNull - public String getOriginalName() { - return originalName; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public Charset getEncoding() { - return encoding; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java deleted file mode 100644 index 229280fca5b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.concurrent.atomic.AtomicInteger; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.IndexedFile; -import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.utils.PathUtils; - -/** - * @since 6.3 - */ -@Immutable -public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile { - private static AtomicInteger intGenerator = new AtomicInteger(0); - - private final String projectRelativePath; - private final String moduleRelativePath; - private final String projectKey; - private final String language; - private final Type type; - private final Path absolutePath; - private final SensorStrategy sensorStrategy; - - /** - * Testing purposes only! - */ - public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) { - this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, intGenerator.getAndIncrement(), - new SensorStrategy()); - } - - public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId, - SensorStrategy sensorStrategy) { - super(batchId); - this.projectKey = projectKey; - this.projectRelativePath = PathUtils.sanitize(projectRelativePath); - this.moduleRelativePath = PathUtils.sanitize(moduleRelativePath); - this.type = type; - this.language = language; - this.sensorStrategy = sensorStrategy; - this.absolutePath = absolutePath; - } - - @Override - public String relativePath() { - return sensorStrategy.isGlobal() ? projectRelativePath : moduleRelativePath; - } - - public String getModuleRelativePath() { - return moduleRelativePath; - } - - public String getProjectRelativePath() { - return projectRelativePath; - } - - @Override - public String absolutePath() { - return PathUtils.sanitize(path().toString()); - } - - @Override - public File file() { - return path().toFile(); - } - - @Override - public Path path() { - return absolutePath; - } - - @Override - public InputStream inputStream() throws IOException { - return Files.newInputStream(path()); - } - - @CheckForNull - @Override - public String language() { - return language; - } - - @Override - public Type type() { - return type; - } - - /** - * Component key (without branch). - */ - @Override - public String key() { - return new StringBuilder().append(projectKey).append(":").append(projectRelativePath).toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof DefaultIndexedFile)) { - return false; - } - - DefaultIndexedFile that = (DefaultIndexedFile) o; - return projectRelativePath.equals(that.projectRelativePath); - } - - @Override - public int hashCode() { - return projectRelativePath.hashCode(); - } - - @Override - public String toString() { - return projectRelativePath; - } - - @Override - public boolean isFile() { - return true; - } - - @Override - public String filename() { - return path().getFileName().toString(); - } - - @Override - public URI uri() { - return path().toUri(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java deleted file mode 100644 index 19a5cce029b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.util.HashSet; -import java.util.Set; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.measure.Metric; - -/** - * @since 5.2 - */ -public abstract class DefaultInputComponent implements InputComponent { - private int id; - private Set storedMetricKeys = new HashSet<>(); - - public DefaultInputComponent(int scannerId) { - this.id = scannerId; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - DefaultInputComponent that = (DefaultInputComponent) o; - return key().equals(that.key()); - } - - public int scannerId() { - return id; - } - - @Override - public int hashCode() { - return key().hashCode(); - } - - @Override - public String toString() { - return "[key=" + key() + "]"; - } - - public void setHasMeasureFor(Metric metric) { - storedMetricKeys.add(metric.key()); - } - - public boolean hasMeasureFor(Metric metric) { - return storedMetricKeys.contains(metric.key()); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java deleted file mode 100644 index 14a39ee1b32..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.net.URI; -import java.nio.file.Path; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.fs.InputDir; -import org.sonar.api.utils.PathUtils; - -/** - * @since 4.5 - */ -public class DefaultInputDir extends DefaultInputComponent implements InputDir { - - private final String relativePath; - private final String moduleKey; - private Path moduleBaseDir; - - public DefaultInputDir(String moduleKey, String relativePath) { - super(-1); - this.moduleKey = moduleKey; - this.relativePath = PathUtils.sanitize(relativePath); - } - - @Override - public String relativePath() { - return relativePath; - } - - @Override - public String absolutePath() { - return PathUtils.sanitize(path().toString()); - } - - @Override - public File file() { - return path().toFile(); - } - - @Override - public Path path() { - if (moduleBaseDir == null) { - throw new IllegalStateException("Can not return the java.nio.file.Path because module baseDir is not set (see method setModuleBaseDir(java.io.File))"); - } - return moduleBaseDir.resolve(relativePath); - } - - public String moduleKey() { - return moduleKey; - } - - @Override - public String key() { - StringBuilder sb = new StringBuilder().append(moduleKey).append(":"); - if (StringUtils.isEmpty(relativePath)) { - sb.append("/"); - } else { - sb.append(relativePath); - } - return sb.toString(); - } - - /** - * For testing purpose. Will be automatically set when dir is added to {@link DefaultFileSystem} - */ - public DefaultInputDir setModuleBaseDir(Path moduleBaseDir) { - this.moduleBaseDir = moduleBaseDir.normalize(); - return this; - } - - @Override - public boolean isFile() { - return false; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - DefaultInputDir that = (DefaultInputDir) o; - return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath); - } - - @Override - public int hashCode() { - return moduleKey.hashCode() + relativePath.hashCode() * 13; - } - - @Override - public String toString() { - return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]"; - } - - @Override - public URI uri() { - return path().toUri(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java deleted file mode 100644 index 19381e4c7ea..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.apache.commons.io.ByteOrderMark; -import org.apache.commons.io.input.BOMInputStream; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextPointer; -import org.sonar.api.batch.fs.TextRange; - -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -/** - * @since 4.2 - * To create {@link InputFile} in tests, use TestInputFileBuilder. - */ -public class DefaultInputFile extends DefaultInputComponent implements InputFile { - - private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; - - private final DefaultIndexedFile indexedFile; - private final String contents; - private final Consumer metadataGenerator; - - private boolean published; - private boolean excludedForCoverage; - private boolean excludedForDuplication; - private boolean ignoreAllIssues; - // Lazy init to save memory - private BitSet noSonarLines; - private Status status; - private Charset charset; - private Metadata metadata; - private Collection ignoreIssuesOnlineRanges; - private BitSet executableLines; - - public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator) { - this(indexedFile, metadataGenerator, null); - } - - // For testing - public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator, @Nullable String contents) { - super(indexedFile.scannerId()); - this.indexedFile = indexedFile; - this.metadataGenerator = metadataGenerator; - this.metadata = null; - this.published = false; - this.excludedForCoverage = false; - this.contents = contents; - } - - public void checkMetadata() { - if (metadata == null) { - metadataGenerator.accept(this); - } - } - - @Override - public InputStream inputStream() throws IOException { - return contents != null ? new ByteArrayInputStream(contents.getBytes(charset())) - : new BOMInputStream(Files.newInputStream(path()), - ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE); - } - - @Override - public String contents() throws IOException { - if (contents != null) { - return contents; - } else { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - try (InputStream inputStream = inputStream()) { - byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - result.write(buffer, 0, length); - } - } - return result.toString(charset().name()); - } - } - - public DefaultInputFile setPublished(boolean published) { - this.published = published; - return this; - } - - public boolean isPublished() { - return published; - } - - public DefaultInputFile setExcludedForCoverage(boolean excludedForCoverage) { - this.excludedForCoverage = excludedForCoverage; - return this; - } - - public boolean isExcludedForCoverage() { - return excludedForCoverage; - } - - public DefaultInputFile setExcludedForDuplication(boolean excludedForDuplication) { - this.excludedForDuplication = excludedForDuplication; - return this; - } - - public boolean isExcludedForDuplication() { - return excludedForDuplication; - } - - /** - * @deprecated since 6.6 - */ - @Deprecated - @Override - public String relativePath() { - return indexedFile.relativePath(); - } - - public String getModuleRelativePath() { - return indexedFile.getModuleRelativePath(); - } - - public String getProjectRelativePath() { - return indexedFile.getProjectRelativePath(); - } - - @Override - public String absolutePath() { - return indexedFile.absolutePath(); - } - - @Override - public File file() { - return indexedFile.file(); - } - - @Override - public Path path() { - return indexedFile.path(); - } - - @CheckForNull - @Override - public String language() { - return indexedFile.language(); - } - - @Override - public Type type() { - return indexedFile.type(); - } - - /** - * Component key (without branch). - */ - @Override - public String key() { - return indexedFile.key(); - } - - @Override - public int hashCode() { - return indexedFile.hashCode(); - } - - @Override - public String toString() { - return indexedFile.toString(); - } - - /** - * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)} - */ - @Override - public Status status() { - checkMetadata(); - return status; - } - - @Override - public int lines() { - checkMetadata(); - return metadata.lines(); - } - - @Override - public boolean isEmpty() { - checkMetadata(); - return metadata.isEmpty(); - } - - @Override - public Charset charset() { - checkMetadata(); - return charset; - } - - public int lastValidOffset() { - checkMetadata(); - return metadata.lastValidOffset(); - } - - /** - * Digest hash of the file. - */ - public String hash() { - checkMetadata(); - return metadata.hash(); - } - - public int nonBlankLines() { - checkMetadata(); - return metadata.nonBlankLines(); - } - - public int[] originalLineStartOffsets() { - checkMetadata(); - checkState(metadata.originalLineStartOffsets() != null, "InputFile is not properly initialized."); - checkState(metadata.originalLineStartOffsets().length == metadata.lines(), - "InputFile is not properly initialized. 'originalLineStartOffsets' property length should be equal to 'lines'"); - return metadata.originalLineStartOffsets(); - } - - public int[] originalLineEndOffsets() { - checkMetadata(); - checkState(metadata.originalLineEndOffsets() != null, "InputFile is not properly initialized."); - checkState(metadata.originalLineEndOffsets().length == metadata.lines(), - "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'"); - return metadata.originalLineEndOffsets(); - } - - @Override - public TextPointer newPointer(int line, int lineOffset) { - checkMetadata(); - DefaultTextPointer textPointer = new DefaultTextPointer(line, lineOffset); - checkValid(textPointer, "pointer"); - return textPointer; - } - - @Override - public TextRange newRange(TextPointer start, TextPointer end) { - checkMetadata(); - checkValid(start, "start pointer"); - checkValid(end, "end pointer"); - return newRangeValidPointers(start, end, false); - } - - @Override - public TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset) { - checkMetadata(); - TextPointer start = newPointer(startLine, startLineOffset); - TextPointer end = newPointer(endLine, endLineOffset); - return newRangeValidPointers(start, end, false); - } - - @Override - public TextRange selectLine(int line) { - checkMetadata(); - TextPointer startPointer = newPointer(line, 0); - TextPointer endPointer = newPointer(line, lineLength(line)); - return newRangeValidPointers(startPointer, endPointer, true); - } - - public void validate(TextRange range) { - checkMetadata(); - checkValid(range.start(), "start pointer"); - checkValid(range.end(), "end pointer"); - } - - /** - * Create Range from global offsets. Used for backward compatibility with older API. - */ - public TextRange newRange(int startOffset, int endOffset) { - checkMetadata(); - return newRangeValidPointers(newPointer(startOffset), newPointer(endOffset), false); - } - - public TextPointer newPointer(int globalOffset) { - checkMetadata(); - checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset); - checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset()); - int line = findLine(globalOffset); - int startLineOffset = originalLineStartOffsets()[line - 1]; - // In case the global offset is between \r and \n, move the pointer to a valid location - return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line - 1]) - startLineOffset); - } - - public DefaultInputFile setStatus(Status status) { - this.status = status; - return this; - } - - public DefaultInputFile setCharset(Charset charset) { - this.charset = charset; - return this; - } - - private void checkValid(TextPointer pointer, String owner) { - checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line()); - checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines()); - checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset()); - int lineLength = lineLength(pointer.line()); - checkArgument(pointer.lineOffset() <= lineLength, - "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line()); - } - - private int lineLength(int line) { - return originalLineEndOffsets()[line - 1] - originalLineStartOffsets()[line - 1]; - } - - private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) { - checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0), - "Start pointer %s should be before end pointer %s", start, end); - return new DefaultTextRange(start, end); - } - - private int findLine(int globalOffset) { - return Math.abs(Arrays.binarySearch(originalLineStartOffsets(), globalOffset) + 1); - } - - public DefaultInputFile setMetadata(Metadata metadata) { - this.metadata = metadata; - return this; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - - if (this.getClass() != obj.getClass()) { - return false; - } - - DefaultInputFile that = (DefaultInputFile) obj; - return this.getProjectRelativePath().equals(that.getProjectRelativePath()); - } - - @Override - public boolean isFile() { - return true; - } - - @Override - public String filename() { - return indexedFile.filename(); - } - - @Override - public URI uri() { - return indexedFile.uri(); - } - - public void noSonarAt(Set noSonarLines) { - if (this.noSonarLines == null) { - this.noSonarLines = new BitSet(lines()); - } - noSonarLines.forEach(l -> this.noSonarLines.set(l - 1)); - } - - public boolean hasNoSonarAt(int line) { - if (this.noSonarLines == null) { - return false; - } - return this.noSonarLines.get(line - 1); - } - - public boolean isIgnoreAllIssues() { - return ignoreAllIssues; - } - - public void setIgnoreAllIssues(boolean ignoreAllIssues) { - this.ignoreAllIssues = ignoreAllIssues; - } - - public void addIgnoreIssuesOnLineRanges(Collection lineRanges) { - if (this.ignoreIssuesOnlineRanges == null) { - this.ignoreIssuesOnlineRanges = new ArrayList<>(); - } - this.ignoreIssuesOnlineRanges.addAll(lineRanges); - } - - public boolean isIgnoreAllIssuesOnLine(@Nullable Integer line) { - if (line == null || ignoreIssuesOnlineRanges == null) { - return false; - } - return ignoreIssuesOnlineRanges.stream().anyMatch(r -> r[0] <= line && line <= r[1]); - } - - public void setExecutableLines(Set executableLines) { - checkState(this.executableLines == null, "Executable lines have already been saved for file: {}", this.toString()); - this.executableLines = new BitSet(lines()); - executableLines.forEach(l -> this.executableLines.set(l - 1)); - } - - public Optional> getExecutableLines() { - if (this.executableLines == null) { - return Optional.empty(); - } - return Optional.of(this.executableLines.stream().map(i -> i + 1).boxed().collect(Collectors.toSet())); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputModule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputModule.java deleted file mode 100644 index 73fa8dd7629..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputModule.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import javax.annotation.CheckForNull; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.scan.filesystem.PathResolver; - -import static org.sonar.api.config.internal.MultivalueProperty.parseAsCsv; - -@Immutable -public class DefaultInputModule extends AbstractProjectOrModule implements InputModule { - - private final List sourceDirsOrFiles; - private final List testDirsOrFiles; - - /** - * For testing only! - */ - public DefaultInputModule(ProjectDefinition definition) { - this(definition, 0); - } - - public DefaultInputModule(ProjectDefinition definition, int scannerComponentId) { - super(definition, scannerComponentId); - - this.sourceDirsOrFiles = initSources(definition, ProjectDefinition.SOURCES_PROPERTY); - this.testDirsOrFiles = initSources(definition, ProjectDefinition.TESTS_PROPERTY); - } - - @CheckForNull - private List initSources(ProjectDefinition module, String propertyKey) { - if (!module.properties().containsKey(propertyKey)) { - return null; - } - List result = new ArrayList<>(); - PathResolver pathResolver = new PathResolver(); - String srcPropValue = module.properties().get(propertyKey); - if (srcPropValue != null) { - for (String sourcePath : parseAsCsv(propertyKey, srcPropValue)) { - File dirOrFile = pathResolver.relativeFile(getBaseDir().toFile(), sourcePath); - if (dirOrFile.exists()) { - result.add(dirOrFile.toPath()); - } - } - } - return result; - } - - public Optional> getSourceDirsOrFiles() { - return Optional.ofNullable(sourceDirsOrFiles); - } - - public Optional> getTestDirsOrFiles() { - return Optional.ofNullable(testDirsOrFiles); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputProject.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputProject.java deleted file mode 100644 index b6f07c852f2..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputProject.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.scanner.fs.InputProject; - -@Immutable -public class DefaultInputProject extends AbstractProjectOrModule implements InputProject { - - /** - * For testing only! - */ - public DefaultInputProject(ProjectDefinition definition) { - super(definition, 0); - } - - public DefaultInputProject(ProjectDefinition definition, int scannerComponentId) { - super(definition, scannerComponentId); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextPointer.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextPointer.java deleted file mode 100644 index c10efd01de7..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextPointer.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import org.sonar.api.batch.fs.TextPointer; - -/** - * @since 5.2 - */ -public class DefaultTextPointer implements TextPointer { - - private final int line; - private final int lineOffset; - - public DefaultTextPointer(int line, int lineOffset) { - this.line = line; - this.lineOffset = lineOffset; - } - - @Override - public int line() { - return line; - } - - @Override - public int lineOffset() { - return lineOffset; - } - - @Override - public String toString() { - return "[line=" + line + ", lineOffset=" + lineOffset + "]"; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof DefaultTextPointer)) { - return false; - } - DefaultTextPointer other = (DefaultTextPointer) obj; - return other.line == this.line && other.lineOffset == this.lineOffset; - } - - @Override - public int hashCode() { - return 37 * this.line + lineOffset; - } - - @Override - public int compareTo(TextPointer o) { - if (this.line == o.line()) { - return Integer.compare(this.lineOffset, o.lineOffset()); - } - return Integer.compare(this.line, o.line()); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextRange.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextRange.java deleted file mode 100644 index efef79cf367..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultTextRange.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import org.sonar.api.batch.fs.TextPointer; -import org.sonar.api.batch.fs.TextRange; - -/** - * @since 5.2 - */ -public class DefaultTextRange implements TextRange { - - private final TextPointer start; - private final TextPointer end; - - public DefaultTextRange(TextPointer start, TextPointer end) { - this.start = start; - this.end = end; - } - - @Override - public TextPointer start() { - return start; - } - - @Override - public TextPointer end() { - return end; - } - - @Override - public boolean overlap(TextRange another) { - // [A,B] and [C,D] - // B > C && D > A - return this.end.compareTo(another.start()) > 0 && another.end().compareTo(this.start) > 0; - } - - @Override - public String toString() { - return "Range[from " + start + " to " + end + "]"; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof DefaultTextRange)) { - return false; - } - DefaultTextRange other = (DefaultTextRange) obj; - return start.equals(other.start) && end.equals(other.end); - } - - @Override - public int hashCode() { - return start.hashCode() * 17 + end.hashCode(); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputModuleHierarchy.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputModuleHierarchy.java deleted file mode 100644 index b3304cb4a34..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputModuleHierarchy.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.util.Collection; -import javax.annotation.CheckForNull; -import javax.annotation.concurrent.Immutable; - -@Immutable -public interface InputModuleHierarchy { - DefaultInputModule root(); - - boolean isRoot(DefaultInputModule module); - - Collection children(DefaultInputModule module); - - @CheckForNull - DefaultInputModule parent(DefaultInputModule module); - - @CheckForNull - String relativePath(DefaultInputModule module); - - @CheckForNull - String relativePathToRoot(DefaultInputModule module); -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java deleted file mode 100644 index 40ea16bd42b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.code.internal; - -import java.util.SortedMap; -import java.util.TreeMap; -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.sensor.code.NewSignificantCode; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.utils.Preconditions; - -public class DefaultSignificantCode extends DefaultStorable implements NewSignificantCode { - private SortedMap significantCodePerLine = new TreeMap<>(); - private InputFile inputFile; - - public DefaultSignificantCode() { - super(); - } - - public DefaultSignificantCode(@Nullable SensorStorage storage) { - super(storage); - } - - @Override - public DefaultSignificantCode onFile(InputFile inputFile) { - this.inputFile = inputFile; - return this; - } - - @Override - public DefaultSignificantCode addRange(TextRange range) { - Preconditions.checkState(this.inputFile != null, "addRange() should be called after on()"); - - int line = range.start().line(); - - Preconditions.checkArgument(line == range.end().line(), "Ranges of significant code must be located in a single line"); - Preconditions.checkState(!significantCodePerLine.containsKey(line), "Significant code was already reported for line '%s'. Can only report once per line.", line); - - significantCodePerLine.put(line, range); - return this; - } - - @Override - protected void doSave() { - Preconditions.checkState(inputFile != null, "Call onFile() first"); - storage.store(this); - } - - public InputFile inputFile() { - return inputFile; - } - - public SortedMap significantCodePerLine() { - return significantCodePerLine; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/package-info.java deleted file mode 100644 index 95f388572a9..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -@javax.annotation.ParametersAreNonnullByDefault -package org.sonar.api.batch.sensor.code.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java deleted file mode 100644 index 94fc1887361..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.coverage.internal; - -import java.util.Collections; -import java.util.SortedMap; -import java.util.TreeMap; -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.coverage.CoverageType; -import org.sonar.api.batch.sensor.coverage.NewCoverage; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultCoverage extends DefaultStorable implements NewCoverage { - - private InputFile inputFile; - private CoverageType type; - private int totalCoveredLines = 0; - private int totalConditions = 0; - private int totalCoveredConditions = 0; - private SortedMap hitsByLine = new TreeMap<>(); - private SortedMap conditionsByLine = new TreeMap<>(); - private SortedMap coveredConditionsByLine = new TreeMap<>(); - - public DefaultCoverage() { - super(); - } - - public DefaultCoverage(@Nullable SensorStorage storage) { - super(storage); - } - - @Override - public DefaultCoverage onFile(InputFile inputFile) { - this.inputFile = inputFile; - return this; - } - - public InputFile inputFile() { - return inputFile; - } - - @Override - public NewCoverage ofType(CoverageType type) { - this.type = requireNonNull(type, "type can't be null"); - return this; - } - - public CoverageType type() { - return type; - } - - @Override - public NewCoverage lineHits(int line, int hits) { - validateFile(); - if (isExcluded()) { - return this; - } - validateLine(line); - - if (!hitsByLine.containsKey(line)) { - hitsByLine.put(line, hits); - if (hits > 0) { - totalCoveredLines += 1; - } - } - return this; - } - - private void validateLine(int line) { - checkState(line <= inputFile.lines(), "Line %s is out of range in the file %s (lines: %s)", line, inputFile, inputFile.lines()); - checkState(line > 0, "Line number must be strictly positive: %s", line); - } - - private void validateFile() { - requireNonNull(inputFile, "Call onFile() first"); - } - - @Override - public NewCoverage conditions(int line, int conditions, int coveredConditions) { - validateFile(); - if (isExcluded()) { - return this; - } - validateLine(line); - - if (conditions > 0 && !conditionsByLine.containsKey(line)) { - totalConditions += conditions; - totalCoveredConditions += coveredConditions; - conditionsByLine.put(line, conditions); - coveredConditionsByLine.put(line, coveredConditions); - } - return this; - } - - public int coveredLines() { - return totalCoveredLines; - } - - public int linesToCover() { - return hitsByLine.size(); - } - - public int conditions() { - return totalConditions; - } - - public int coveredConditions() { - return totalCoveredConditions; - } - - public SortedMap hitsByLine() { - return Collections.unmodifiableSortedMap(hitsByLine); - } - - public SortedMap conditionsByLine() { - return Collections.unmodifiableSortedMap(conditionsByLine); - } - - public SortedMap coveredConditionsByLine() { - return Collections.unmodifiableSortedMap(coveredConditionsByLine); - } - - @Override - public void doSave() { - validateFile(); - if (!isExcluded()) { - storage.store(this); - } - } - - private boolean isExcluded() { - return ((DefaultInputFile) inputFile).isExcludedForCoverage(); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/package-info.java deleted file mode 100644 index a0b5e87657d..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -@javax.annotation.ParametersAreNonnullByDefault -package org.sonar.api.batch.sensor.coverage.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java deleted file mode 100644 index a2c592c37b5..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.cpd.internal; - -import java.util.ArrayList; -import java.util.List; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.cpd.NewCpdTokens; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -import static java.util.Collections.unmodifiableList; -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { - private static final Logger LOG = Loggers.get(DefaultCpdTokens.class); - private final List result = new ArrayList<>(); - private DefaultInputFile inputFile; - private int startLine = Integer.MIN_VALUE; - private int startIndex = 0; - private int currentIndex = 0; - private StringBuilder sb = new StringBuilder(); - private TextRange lastRange; - private boolean loggedTestCpdWarning = false; - - public DefaultCpdTokens(SensorStorage storage) { - super(storage); - } - - @Override - public DefaultCpdTokens onFile(InputFile inputFile) { - this.inputFile = (DefaultInputFile) requireNonNull(inputFile, "file can't be null"); - return this; - } - - public InputFile inputFile() { - return inputFile; - } - - @Override - public NewCpdTokens addToken(int startLine, int startLineOffset, int endLine, int endLineOffset, String image) { - checkInputFileNotNull(); - TextRange newRange; - try { - newRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to register token in file " + inputFile, e); - } - return addToken(newRange, image); - } - - @Override - public DefaultCpdTokens addToken(TextRange range, String image) { - requireNonNull(range, "Range should not be null"); - requireNonNull(image, "Image should not be null"); - checkInputFileNotNull(); - if (isExcludedForDuplication()) { - return this; - } - checkState(lastRange == null || lastRange.end().compareTo(range.start()) <= 0, - "Tokens of file %s should be provided in order.\nPrevious token: %s\nLast token: %s", inputFile, lastRange, range); - - int line = range.start().line(); - if (line != startLine) { - addNewTokensLine(result, startIndex, currentIndex, startLine, sb); - startIndex = currentIndex + 1; - startLine = line; - } - currentIndex++; - sb.append(image); - lastRange = range; - - return this; - } - - private boolean isExcludedForDuplication() { - if (inputFile.isExcludedForDuplication()) { - return true; - } - if (inputFile.type() == InputFile.Type.TEST) { - if (!loggedTestCpdWarning) { - LOG.warn("Duplication reported for '{}' will be ignored because it's a test file.", inputFile); - loggedTestCpdWarning = true; - } - return true; - } - return false; - } - - public List getTokenLines() { - return unmodifiableList(new ArrayList<>(result)); - } - - private static void addNewTokensLine(List result, int startUnit, int endUnit, int startLine, StringBuilder sb) { - if (sb.length() != 0) { - result.add(new TokensLine(startUnit, endUnit, startLine, sb.toString())); - sb.setLength(0); - } - } - - @Override - protected void doSave() { - checkState(inputFile != null, "Call onFile() first"); - if (isExcludedForDuplication()) { - return; - } - addNewTokensLine(result, startIndex, currentIndex, startLine, sb); - storage.store(this); - } - - private void checkInputFileNotNull() { - checkState(inputFile != null, "Call onFile() first"); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java deleted file mode 100644 index 3a9073a5095..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.error.internal; - -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextPointer; -import org.sonar.api.batch.sensor.error.AnalysisError; -import org.sonar.api.batch.sensor.error.NewAnalysisError; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultAnalysisError extends DefaultStorable implements NewAnalysisError, AnalysisError { - private InputFile inputFile; - private String message; - private TextPointer location; - - public DefaultAnalysisError() { - super(null); - } - - public DefaultAnalysisError(SensorStorage storage) { - super(storage); - } - - @Override - public InputFile inputFile() { - return inputFile; - } - - @Override - public String message() { - return message; - } - - @Override - public TextPointer location() { - return location; - } - - @Override - public NewAnalysisError onFile(InputFile inputFile) { - checkArgument(inputFile != null, "Cannot use a inputFile that is null"); - checkState(this.inputFile == null, "onFile() already called"); - this.inputFile = inputFile; - return this; - } - - @Override - public NewAnalysisError message(String message) { - this.message = message; - return this; - } - - @Override - public NewAnalysisError at(TextPointer location) { - checkState(this.location == null, "at() already called"); - this.location = location; - return this; - } - - @Override - protected void doSave() { - requireNonNull(this.inputFile, "inputFile is mandatory on AnalysisError"); - storage.store(this); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/package-info.java deleted file mode 100644 index 1abae586b1e..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -@javax.annotation.ParametersAreNonnullByDefault -package org.sonar.api.batch.sensor.error.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java deleted file mode 100644 index 822ffbc2a40..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.internal; - -import javax.annotation.Nullable; -import org.apache.commons.lang.builder.ToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkState; - -public abstract class DefaultStorable { - - protected final transient SensorStorage storage; - private transient boolean saved = false; - - public DefaultStorable() { - this.storage = null; - } - - public DefaultStorable(@Nullable SensorStorage storage) { - this.storage = storage; - } - - public final void save() { - requireNonNull(this.storage, "No persister on this object"); - checkState(!saved, "This object was already saved"); - doSave(); - this.saved = true; - } - - protected abstract void doSave(); - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java index fde8e22e5ac..1e0e5580de4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java @@ -19,16 +19,16 @@ */ package org.sonar.api.batch.sensor.internal; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; +import org.sonar.api.batch.sensor.code.NewSignificantCode; +import org.sonar.api.batch.sensor.coverage.NewCoverage; +import org.sonar.api.batch.sensor.cpd.NewCpdTokens; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; +import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import org.sonar.api.scanner.ScannerSide; /** @@ -52,17 +52,17 @@ public interface SensorStorage { /** * @since 5.2 */ - void store(DefaultCoverage defaultCoverage); + void store(NewCoverage defaultCoverage); /** * @since 5.5 */ - void store(DefaultCpdTokens defaultCpdTokens); + void store(NewCpdTokens cpdTokens); /** * @since 5.6 */ - void store(DefaultSymbolTable symbolTable); + void store(NewSymbolTable symbolTable); /** * @since 6.0 @@ -81,5 +81,5 @@ public interface SensorStorage { /** * @since 7.2 */ - void store(DefaultSignificantCode significantCode); + void store(NewSignificantCode significantCode); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java deleted file mode 100644 index 087681a5aa8..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.symbol.internal; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.batch.sensor.symbol.NewSymbol; -import org.sonar.api.batch.sensor.symbol.NewSymbolTable; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTable { - - private final Map> referencesBySymbol; - private DefaultInputFile inputFile; - - public DefaultSymbolTable(SensorStorage storage) { - super(storage); - referencesBySymbol = new LinkedHashMap<>(); - } - - public Map> getReferencesBySymbol() { - return referencesBySymbol; - } - - @Override - public DefaultSymbolTable onFile(InputFile inputFile) { - requireNonNull(inputFile, "file can't be null"); - this.inputFile = (DefaultInputFile) inputFile; - return this; - } - - public InputFile inputFile() { - return inputFile; - } - - @Override - public NewSymbol newSymbol(int startLine, int startLineOffset, int endLine, int endLineOffset) { - checkInputFileNotNull(); - TextRange declarationRange; - try { - declarationRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e); - } - return newSymbol(declarationRange); - } - - @Override - public NewSymbol newSymbol(int startOffset, int endOffset) { - checkInputFileNotNull(); - TextRange declarationRange; - try { - declarationRange = inputFile.newRange(startOffset, endOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e); - } - return newSymbol(declarationRange); - } - - @Override - public NewSymbol newSymbol(TextRange range) { - checkInputFileNotNull(); - TreeSet references = new TreeSet<>((o1, o2) -> o1.start().compareTo(o2.start())); - referencesBySymbol.put(range, references); - return new DefaultSymbol(inputFile, range, references); - } - - private static class DefaultSymbol implements NewSymbol { - - private final Collection references; - private final DefaultInputFile inputFile; - private final TextRange declaration; - - public DefaultSymbol(DefaultInputFile inputFile, TextRange declaration, Collection references) { - this.inputFile = inputFile; - this.declaration = declaration; - this.references = references; - } - - @Override - public NewSymbol newReference(int startOffset, int endOffset) { - TextRange referenceRange; - try { - referenceRange = inputFile.newRange(startOffset, endOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e); - } - return newReference(referenceRange); - } - - @Override - public NewSymbol newReference(int startLine, int startLineOffset, int endLine, int endLineOffset) { - TextRange referenceRange; - try { - referenceRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e); - } - return newReference(referenceRange); - } - - @Override - public NewSymbol newReference(TextRange range) { - requireNonNull(range, "Provided range is null"); - checkArgument(!declaration.overlap(range), "Overlapping symbol declaration and reference for symbol at %s", declaration); - references.add(range); - return this; - } - - } - - @Override - protected void doSave() { - checkInputFileNotNull(); - storage.store(this); - } - - private void checkInputFileNotNull() { - checkState(inputFile != null, "Call onFile() first"); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java deleted file mode 100644 index e8dcd39cf6c..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -@javax.annotation.ParametersAreNonnullByDefault -package org.sonar.api.batch.sensor.symbol.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java index a58e5f02e4f..a94fd4f2123 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/NoSonarFilter.java @@ -21,7 +21,6 @@ package org.sonar.api.issue; import java.util.Set; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.scanner.ScannerSide; /** @@ -34,7 +33,7 @@ import org.sonar.api.scanner.ScannerSide; * @since 3.6 */ @ScannerSide -public class NoSonarFilter { +public abstract class NoSonarFilter { /** * Register lines in a file that contains the NOSONAR flag. @@ -44,9 +43,5 @@ public class NoSonarFilter { * @since 5.0 * @since 7.6 the method can be called multiple times by different sensors, and NOSONAR lines are merged */ - public NoSonarFilter noSonarInFile(InputFile inputFile, Set noSonarLines) { - ((DefaultInputFile) inputFile).noSonarAt(noSonarLines); - return this; - } - + public abstract NoSonarFilter noSonarInFile(InputFile inputFile, Set noSonarLines); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputDirTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputDirTest.java deleted file mode 100644 index ed2c2b36a64..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputDirTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import java.io.File; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultInputDirTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void test() throws Exception { - File baseDir = temp.newFolder(); - DefaultInputDir inputDir = new DefaultInputDir("ABCDE", "src") - .setModuleBaseDir(baseDir.toPath()); - - assertThat(inputDir.key()).isEqualTo("ABCDE:src"); - assertThat(inputDir.file().getAbsolutePath()).isEqualTo(new File(baseDir, "src").getAbsolutePath()); - assertThat(inputDir.relativePath()).isEqualTo("src"); - assertThat(new File(inputDir.relativePath())).isRelative(); - assertThat(inputDir.absolutePath()).endsWith("src"); - assertThat(new File(inputDir.absolutePath())).isAbsolute(); - } - - @Test - public void testEqualsAndHashCode() throws Exception { - DefaultInputDir inputDir1 = new DefaultInputDir("ABCDE", "src"); - - DefaultInputDir inputDir2 = new DefaultInputDir("ABCDE", "src"); - - assertThat(inputDir1.equals(inputDir1)).isTrue(); - assertThat(inputDir1.equals(inputDir2)).isTrue(); - assertThat(inputDir1.equals("foo")).isFalse(); - - assertThat(inputDir1.hashCode()).isEqualTo(63545559); - - assertThat(inputDir1.toString()).contains("[moduleKey=ABCDE, relative=src, basedir=null"); - - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java deleted file mode 100644 index 85feccc8581..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.stream.Collectors; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.scanner.fs.FileMetadata; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; - -public class DefaultInputFileTest { - - private static final String PROJECT_RELATIVE_PATH = "module1/src/Foo.php"; - private static final String MODULE_RELATIVE_PATH = "src/Foo.php"; - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private DefaultIndexedFile indexedFile; - - private Path baseDir; - private SensorStrategy sensorStrategy; - - @Before - public void prepare() throws IOException { - baseDir = temp.newFolder().toPath(); - sensorStrategy = new SensorStrategy(); - indexedFile = new DefaultIndexedFile(baseDir.resolve(PROJECT_RELATIVE_PATH), "ABCDE", PROJECT_RELATIVE_PATH, MODULE_RELATIVE_PATH, InputFile.Type.TEST, "php", 0, - sensorStrategy); - } - - @Test - public void test() throws Exception { - - Metadata metadata = new Metadata(42, 42, "", new int[0], new int[0], 10); - DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> f.setMetadata(metadata)) - .setStatus(InputFile.Status.ADDED) - .setCharset(StandardCharsets.ISO_8859_1); - - assertThat(inputFile.absolutePath()).endsWith("Foo.php"); - assertThat(inputFile.filename()).isEqualTo("Foo.php"); - assertThat(inputFile.uri()).hasPath(baseDir.resolve(PROJECT_RELATIVE_PATH).toUri().getPath()); - assertThat(new File(inputFile.absolutePath())).isAbsolute(); - assertThat(inputFile.language()).isEqualTo("php"); - assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED); - assertThat(inputFile.type()).isEqualTo(InputFile.Type.TEST); - assertThat(inputFile.lines()).isEqualTo(42); - assertThat(inputFile.charset()).isEqualTo(StandardCharsets.ISO_8859_1); - - assertThat(inputFile.getModuleRelativePath()).isEqualTo(MODULE_RELATIVE_PATH); - assertThat(inputFile.getProjectRelativePath()).isEqualTo(PROJECT_RELATIVE_PATH); - - sensorStrategy.setGlobal(false); - assertThat(inputFile.relativePath()).isEqualTo(MODULE_RELATIVE_PATH); - assertThat(new File(inputFile.relativePath())).isRelative(); - sensorStrategy.setGlobal(true); - assertThat(inputFile.relativePath()).isEqualTo(PROJECT_RELATIVE_PATH); - assertThat(new File(inputFile.relativePath())).isRelative(); - } - - @Test - public void test_content() throws IOException { - Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH); - Files.createDirectories(testFile.getParent()); - String content = "test é string"; - Files.write(testFile, content.getBytes(StandardCharsets.ISO_8859_1)); - - assertThat(Files.readAllLines(testFile, StandardCharsets.ISO_8859_1).get(0)).hasSize(content.length()); - - Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10); - - DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata)) - .setStatus(InputFile.Status.ADDED) - .setCharset(StandardCharsets.ISO_8859_1); - - assertThat(inputFile.contents()).isEqualTo(content); - try (InputStream inputStream = inputFile.inputStream()) { - String result = new BufferedReader(new InputStreamReader(inputStream, inputFile.charset())).lines().collect(Collectors.joining()); - assertThat(result).isEqualTo(content); - } - - } - - @Test - public void test_content_exclude_bom() throws IOException { - Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH); - Files.createDirectories(testFile.getParent()); - try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(testFile.toFile()), StandardCharsets.UTF_8))) { - out.write('\ufeff'); - } - String content = "test é string €"; - Files.write(testFile, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); - - assertThat(Files.readAllLines(testFile, StandardCharsets.UTF_8).get(0)).hasSize(content.length() + 1); - - Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10); - - DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata)) - .setStatus(InputFile.Status.ADDED) - .setCharset(StandardCharsets.UTF_8); - - assertThat(inputFile.contents()).isEqualTo(content); - try (InputStream inputStream = inputFile.inputStream()) { - String result = new BufferedReader(new InputStreamReader(inputStream, inputFile.charset())).lines().collect(Collectors.joining()); - assertThat(result).isEqualTo(content); - } - - } - - @Test - public void test_equals_and_hashcode() throws Exception { - DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); - DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); - DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php", null), (f) -> mock(Metadata.class)); - - assertThat(f1).isEqualTo(f1); - assertThat(f1).isEqualTo(f1a); - assertThat(f1).isNotEqualTo(f2); - assertThat(f1.equals("foo")).isFalse(); - assertThat(f1.equals(null)).isFalse(); - - assertThat(f1.hashCode()).isEqualTo(f1.hashCode()); - assertThat(f1.hashCode()).isEqualTo(f1a.hashCode()); - } - - @Test - public void test_toString() throws Exception { - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); - assertThat(file.toString()).isEqualTo(MODULE_RELATIVE_PATH); - } - - @Test - public void checkValidPointer() { - Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - assertThat(file.newPointer(1, 0).line()).isEqualTo(1); - assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0); - // Don't fail - file.newPointer(1, 9); - file.newPointer(2, 0); - file.newPointer(2, 5); - - try { - file.newPointer(0, 1); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("0 is not a valid line for a file"); - } - try { - file.newPointer(3, 1); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("3 is not a valid line for pointer. File src/Foo.php has 2 line(s)"); - } - try { - file.newPointer(1, -1); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("-1 is not a valid line offset for a file"); - } - try { - file.newPointer(1, 10); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1"); - } - } - - @Test - public void checkValidPointerUsingGlobalOffset() { - Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {8, 15}, 16); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - assertThat(file.newPointer(0).line()).isEqualTo(1); - assertThat(file.newPointer(0).lineOffset()).isEqualTo(0); - - assertThat(file.newPointer(9).line()).isEqualTo(1); - // Ignore eol characters - assertThat(file.newPointer(9).lineOffset()).isEqualTo(8); - - assertThat(file.newPointer(10).line()).isEqualTo(2); - assertThat(file.newPointer(10).lineOffset()).isEqualTo(0); - - assertThat(file.newPointer(15).line()).isEqualTo(2); - assertThat(file.newPointer(15).lineOffset()).isEqualTo(5); - - assertThat(file.newPointer(16).line()).isEqualTo(2); - // Ignore eol characters - assertThat(file.newPointer(16).lineOffset()).isEqualTo(5); - - try { - file.newPointer(-1); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("-1 is not a valid offset for a file"); - } - - try { - file.newPointer(17); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("17 is not a valid offset for file src/Foo.php. Max offset is 16"); - } - } - - @Test - public void checkValidRange() { - Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde")); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - - assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isEqualTo(1); - // Don't fail - file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)); - file.newRange(file.newPointer(1, 0), file.newPointer(1, 9)); - file.newRange(file.newPointer(1, 0), file.newPointer(2, 0)); - assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 5))).isEqualTo(file.newRange(0, 15)); - - try { - file.newRange(file.newPointer(1, 0), file.newPointer(1, 0)); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("Start pointer [line=1, lineOffset=0] should be before end pointer [line=1, lineOffset=0]"); - } - try { - file.newRange(file.newPointer(1, 0), file.newPointer(1, 10)); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1"); - } - } - - @Test - public void selectLine() { - Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc")); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - - assertThat(file.selectLine(1).start().line()).isEqualTo(1); - assertThat(file.selectLine(1).start().lineOffset()).isEqualTo(0); - assertThat(file.selectLine(1).end().line()).isEqualTo(1); - assertThat(file.selectLine(1).end().lineOffset()).isEqualTo(9); - - // Don't fail when selecting empty line - assertThat(file.selectLine(3).start().line()).isEqualTo(3); - assertThat(file.selectLine(3).start().lineOffset()).isEqualTo(0); - assertThat(file.selectLine(3).end().line()).isEqualTo(3); - assertThat(file.selectLine(3).end().lineOffset()).isEqualTo(0); - - try { - file.selectLine(5); - fail(); - } catch (Exception e) { - assertThat(e).hasMessage("5 is not a valid line for pointer. File src/Foo.php has 4 line(s)"); - } - } - - @Test - public void checkValidRangeUsingGlobalOffset() { - Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - TextRange newRange = file.newRange(10, 13); - assertThat(newRange.start().line()).isEqualTo(2); - assertThat(newRange.start().lineOffset()).isEqualTo(0); - assertThat(newRange.end().line()).isEqualTo(2); - assertThat(newRange.end().lineOffset()).isEqualTo(3); - } - - @Test - public void testRangeOverlap() { - Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); - DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); - // Don't fail - assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)))).isTrue(); - assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isTrue(); - assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 1), file.newPointer(1, 2)))).isFalse(); - assertThat(file.newRange(file.newPointer(1, 2), file.newPointer(1, 3)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isFalse(); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputModuleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputModuleTest.java deleted file mode 100644 index 42394d7f81e..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputModuleTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultInputModuleTest { - - private static final String FILE_1 = "file1"; - private static final String TEST_1 = "test1"; - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void check_getters() throws IOException { - ProjectDefinition def = ProjectDefinition.create(); - def.setKey("moduleKey"); - File baseDir = temp.newFolder(); - Path src = baseDir.toPath().resolve(FILE_1); - Files.createFile(src); - Path test = baseDir.toPath().resolve(TEST_1); - Files.createFile(test); - def.setBaseDir(baseDir); - File workDir = temp.newFolder(); - def.setWorkDir(workDir); - def.setSources(FILE_1); - def.setTests(TEST_1); - DefaultInputModule module = new DefaultInputModule(def); - - assertThat(module.key()).isEqualTo("moduleKey"); - assertThat(module.definition()).isEqualTo(def); - assertThat(module.getBranch()).isNull(); - assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); - assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey"); - assertThat(module.getWorkDir()).isEqualTo(workDir.toPath()); - assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); - assertThat(module.getSourceDirsOrFiles().get()).containsExactlyInAnyOrder(src); - assertThat(module.getTestDirsOrFiles().get()).containsExactlyInAnyOrder(test); - assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); - - assertThat(module.isFile()).isFalse(); - } - - @Test - public void no_sources() throws IOException { - ProjectDefinition def = ProjectDefinition.create(); - def.setKey("moduleKey"); - File baseDir = temp.newFolder(); - Path src = baseDir.toPath().resolve(FILE_1); - Files.createFile(src); - Path test = baseDir.toPath().resolve(TEST_1); - Files.createFile(test); - def.setBaseDir(baseDir); - File workDir = temp.newFolder(); - def.setWorkDir(workDir); - DefaultInputModule module = new DefaultInputModule(def); - - assertThat(module.key()).isEqualTo("moduleKey"); - assertThat(module.definition()).isEqualTo(def); - assertThat(module.getBranch()).isNull(); - assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); - assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey"); - assertThat(module.getWorkDir()).isEqualTo(workDir.toPath()); - assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); - assertThat(module.getSourceDirsOrFiles()).isNotPresent(); - assertThat(module.getTestDirsOrFiles()).isNotPresent(); - assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); - - assertThat(module.isFile()).isFalse(); - } - - @Test - public void working_directory_should_be_hidden() throws IOException { - ProjectDefinition def = ProjectDefinition.create(); - File workDir = temp.newFolder(".sonar"); - def.setWorkDir(workDir); - File baseDir = temp.newFolder(); - def.setBaseDir(baseDir); - DefaultInputModule module = new DefaultInputModule(def); - assertThat(workDir.isHidden()).isTrue(); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputProjectTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputProjectTest.java deleted file mode 100644 index 8a4a33bdce3..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputProjectTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultInputProjectTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void testGetters() throws IOException { - ProjectDefinition def = ProjectDefinition.create(); - def.setKey("projectKey"); - def.setName("projectName"); - File baseDir = temp.newFolder(); - def.setBaseDir(baseDir); - def.setDescription("desc"); - File workDir = temp.newFolder(); - def.setWorkDir(workDir); - def.setSources("file1"); - def.setTests("test1"); - AbstractProjectOrModule project = new DefaultInputProject(def); - - assertThat(project.key()).isEqualTo("projectKey"); - assertThat(project.getName()).isEqualTo("projectName"); - assertThat(project.getOriginalName()).isEqualTo("projectName"); - assertThat(project.definition()).isEqualTo(def); - assertThat(project.getBranch()).isNull(); - assertThat(project.getBaseDir()).isEqualTo(baseDir.toPath()); - assertThat(project.getKeyWithBranch()).isEqualTo("projectKey"); - assertThat(project.getDescription()).isEqualTo("desc"); - assertThat(project.getWorkDir()).isEqualTo(workDir.toPath()); - assertThat(project.getEncoding()).isEqualTo(Charset.defaultCharset()); - - assertThat(project.properties()).hasSize(5); - - assertThat(project.isFile()).isFalse(); - } - - @Test - public void testEncoding() throws IOException { - ProjectDefinition def = ProjectDefinition.create(); - def.setKey("projectKey"); - def.setName("projectName"); - File baseDir = temp.newFolder(); - def.setBaseDir(baseDir); - def.setProjectVersion("version"); - def.setDescription("desc"); - File workDir = temp.newFolder(); - def.setWorkDir(workDir); - def.setSources("file1"); - def.setProperty("sonar.sourceEncoding", "UTF-16"); - AbstractProjectOrModule project = new DefaultInputProject(def); - - assertThat(project.getEncoding()).isEqualTo(StandardCharsets.UTF_16); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java index cc2d186da44..8296da8465e 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java @@ -27,6 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.IndexedFile; +import org.sonar.scanner.fs.DefaultIndexedFile; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java deleted file mode 100644 index 3055be6a419..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.InputFile.Status; -import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.scanner.fs.TestInputFileBuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestInputFileBuilderTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void setContent() throws IOException { - DefaultInputFile file = TestInputFileBuilder.create("module", "invalidPath") - .setContents("my content") - .setCharset(StandardCharsets.UTF_8) - .build(); - assertThat(file.contents()).isEqualTo("my content"); - assertThat(IOUtils.toString(file.inputStream())).isEqualTo("my content"); - } - - @Test - public void testGetters() { - DefaultInputFile file = TestInputFileBuilder.create("module", new File("baseDir"), new File("baseDir", "path")) - .setStatus(Status.SAME) - .setType(Type.MAIN) - .build(); - - assertThat(file.type()).isEqualTo(Type.MAIN); - assertThat(file.status()).isEqualTo(Status.SAME); - assertThat(file.isPublished()).isTrue(); - assertThat(file.type()).isEqualTo(Type.MAIN); - assertThat(file.relativePath()).isEqualTo("path"); - assertThat(file.absolutePath()).isEqualTo("baseDir/path"); - - } - - @Test - public void testCreateInputModule() throws IOException { - File baseDir = temp.newFolder(); - AbstractProjectOrModule module = TestInputFileBuilder.newDefaultInputModule("key", baseDir); - assertThat(module.key()).isEqualTo("key"); - assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java deleted file mode 100644 index 5d853e456ea..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.code.internal; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.scanner.fs.TestInputFileBuilder; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class DefaultSignificantCodeTest { - private SensorStorage sensorStorage = mock(SensorStorage.class); - private DefaultSignificantCode underTest = new DefaultSignificantCode(sensorStorage); - private InputFile inputFile = TestInputFileBuilder.create("module", "file1.xoo") - .setContents("this is\na file\n with some code") - .build(); - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void should_save_ranges() { - underTest.onFile(inputFile) - .addRange(inputFile.selectLine(1)) - .save(); - verify(sensorStorage).store(underTest); - } - - @Test - public void fail_if_save_without_file() { - exception.expect(IllegalStateException.class); - exception.expectMessage("Call onFile() first"); - underTest.save(); - } - - @Test - public void fail_if_add_range_to_same_line_twice() { - underTest.onFile(inputFile); - underTest.addRange(inputFile.selectLine(1)); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Significant code was already reported for line '1'."); - underTest.addRange(inputFile.selectLine(1)); - } - - @Test - public void fail_if_range_includes_many_lines() { - underTest.onFile(inputFile); - - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Ranges of significant code must be located in a single line"); - underTest.addRange(inputFile.newRange(1, 1, 2, 1)); - } - - @Test - public void fail_if_add_range_before_setting_file() { - exception.expect(IllegalStateException.class); - exception.expectMessage("addRange() should be called after on()"); - underTest.addRange(inputFile.selectLine(1)); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java deleted file mode 100644 index 1adb0c71e54..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.cpd.internal; - -import org.junit.Test; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.scanner.fs.TestInputFileBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -public class DefaultCpdTokensTest { - private final SensorStorage sensorStorage = mock(SensorStorage.class); - - private final DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") - .setLines(2) - .setOriginalLineStartOffsets(new int[] {0, 50}) - .setOriginalLineEndOffsets(new int[] {49, 100}) - .setLastValidOffset(101) - .build(); - - @Test - public void save_no_tokens() { - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(inputFile); - - tokens.save(); - - verify(sensorStorage).store(tokens); - - assertThat(tokens.inputFile()).isEqualTo(inputFile); - } - - @Test - public void save_one_token() { - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(inputFile) - .addToken(inputFile.newRange(1, 2, 1, 5), "foo"); - - tokens.save(); - - verify(sensorStorage).store(tokens); - - assertThat(tokens.getTokenLines()).extracting("value", "startLine", "hashCode", "startUnit", "endUnit").containsExactly(tuple("foo", 1, "foo".hashCode(), 1, 1)); - } - - @Test - public void handle_exclusions() { - inputFile.setExcludedForDuplication(true); - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(inputFile) - .addToken(inputFile.newRange(1, 2, 1, 5), "foo"); - - tokens.save(); - - verifyZeroInteractions(sensorStorage); - - assertThat(tokens.getTokenLines()).isEmpty(); - } - - @Test - public void dont_save_for_test_files() { - DefaultInputFile testInputFile = new TestInputFileBuilder("foo", "src/Foo.java") - .setLines(2) - .setOriginalLineStartOffsets(new int[] {0, 50}) - .setOriginalLineEndOffsets(new int[] {49, 100}) - .setLastValidOffset(101) - .setType(InputFile.Type.TEST) - .build(); - - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(testInputFile) - .addToken(testInputFile.newRange(1, 2, 1, 5), "foo"); - - tokens.save(); - verifyZeroInteractions(sensorStorage); - assertThat(tokens.getTokenLines()).isEmpty(); - } - - @Test - public void save_many_tokens() { - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(inputFile) - .addToken(inputFile.newRange(1, 2, 1, 5), "foo") - .addToken(inputFile.newRange(1, 6, 1, 10), "bar") - .addToken(inputFile.newRange(1, 20, 1, 25), "biz") - .addToken(inputFile.newRange(2, 1, 2, 10), "next"); - - tokens.save(); - - verify(sensorStorage).store(tokens); - - assertThat(tokens.getTokenLines()) - .extracting("value", "startLine", "hashCode", "startUnit", "endUnit") - .containsExactly( - tuple("foobarbiz", 1, "foobarbiz".hashCode(), 1, 3), - tuple("next", 2, "next".hashCode(), 4, 4)); - } - - @Test - public void basic_validation() { - SensorStorage sensorStorage = mock(SensorStorage.class); - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage); - try { - tokens.save(); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Call onFile() first"); - } - try { - tokens.addToken(inputFile.newRange(1, 2, 1, 5), "foo"); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Call onFile() first"); - } - try { - tokens.addToken(null, "foo"); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Range should not be null"); - } - try { - tokens.addToken(inputFile.newRange(1, 2, 1, 5), null); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Image should not be null"); - } - } - - @Test - public void validate_tokens_order() { - SensorStorage sensorStorage = mock(SensorStorage.class); - DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) - .onFile(inputFile) - .addToken(inputFile.newRange(1, 6, 1, 10), "bar"); - - try { - tokens.addToken(inputFile.newRange(1, 2, 1, 5), "foo"); - fail("Expected exception"); - } catch (Exception e) { - assertThat(e).hasMessage("Tokens of file src/Foo.java should be provided in order.\n" + - "Previous token: Range[from [line=1, lineOffset=6] to [line=1, lineOffset=10]]\n" + - "Last token: Range[from [line=1, lineOffset=2] to [line=1, lineOffset=5]]"); - } - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java deleted file mode 100644 index ae920c967fe..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.error.internal; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.sensor.error.NewAnalysisError; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.scanner.fs.TestInputFileBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.*; - -public class DefaultAnalysisErrorTest { - private InputFile inputFile; - private SensorStorage storage; - private TextPointer textPointer; - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Before - public void setUp() { - inputFile = new TestInputFileBuilder("module1", "src/File.java").build(); - textPointer = new DefaultTextPointer(5, 2); - storage = mock(SensorStorage.class); - } - - @Test - public void test_analysis_error() { - DefaultAnalysisError analysisError = new DefaultAnalysisError(storage); - analysisError.onFile(inputFile) - .at(textPointer) - .message("msg"); - - assertThat(analysisError.location()).isEqualTo(textPointer); - assertThat(analysisError.message()).isEqualTo("msg"); - assertThat(analysisError.inputFile()).isEqualTo(inputFile); - } - - @Test - public void test_save() { - DefaultAnalysisError analysisError = new DefaultAnalysisError(storage); - analysisError.onFile(inputFile).save(); - - verify(storage).store(analysisError); - verifyNoMoreInteractions(storage); - } - - @Test - public void test_no_storage() { - exception.expect(NullPointerException.class); - DefaultAnalysisError analysisError = new DefaultAnalysisError(); - analysisError.onFile(inputFile).save(); - } - - @Test - public void test_validation() { - try { - new DefaultAnalysisError(storage).onFile(null); - fail("Expected exception"); - } catch (IllegalArgumentException e) { - // expected - } - - NewAnalysisError error = new DefaultAnalysisError(storage).onFile(inputFile); - try { - error.onFile(inputFile); - fail("Expected exception"); - } catch (IllegalStateException e) { - // expected - } - - error = new DefaultAnalysisError(storage).at(textPointer); - try { - error.at(textPointer); - fail("Expected exception"); - } catch (IllegalStateException e) { - // expected - } - - try { - new DefaultAnalysisError(storage).save(); - fail("Expected exception"); - } catch (NullPointerException e) { - // expected - } - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java deleted file mode 100644 index c880f7f0bd9..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.api.batch.sensor.symbol.internal; - -import java.util.Map; -import java.util.Set; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.scanner.fs.TestInputFileBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class DefaultSymbolTableTest { - - private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") - .setLines(2) - .setOriginalLineStartOffsets(new int[] {0, 50}) - .setOriginalLineEndOffsets(new int[] {49, 100}) - .setLastValidOffset(101) - .build(); - - private Map> referencesPerSymbol; - - @Rule - public ExpectedException throwable = ExpectedException.none(); - - @Before - public void setUpSampleSymbols() { - - DefaultSymbolTable symbolTableBuilder = new DefaultSymbolTable(mock(SensorStorage.class)) - .onFile(INPUT_FILE); - symbolTableBuilder - .newSymbol(0, 10) - .newReference(12, 15) - .newReference(2, 10, 2, 15); - - symbolTableBuilder.newSymbol(1, 12, 1, 15).newReference(52, 55); - - symbolTableBuilder.save(); - - referencesPerSymbol = symbolTableBuilder.getReferencesBySymbol(); - } - - @Test - public void should_register_symbols() { - assertThat(referencesPerSymbol).hasSize(2); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java index 76ac2f6758a..20427354f25 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java @@ -22,8 +22,9 @@ package org.sonar.api.issue; import java.util.Arrays; import java.util.HashSet; import org.junit.Test; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.issue.DefaultNoSonarFilter; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +33,7 @@ public class NoSonarFilterTest { @Test public void should_store_nosonar_lines_on_inputfile() { DefaultInputFile f = TestInputFileBuilder.create("module1", "myfile.java").setLines(8).build(); - new NoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1, 4))); + new DefaultNoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1, 4))); assertThat(f.hasNoSonarAt(1)).isTrue(); assertThat(f.hasNoSonarAt(2)).isFalse(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java index 9d263b17667..dee0cc79aa7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/analysis/AnalysisTempFolderProvider.java @@ -25,9 +25,9 @@ import java.nio.file.Path; import org.picocontainer.ComponentLifecycle; import org.picocontainer.PicoContainer; import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.internal.DefaultTempFolder; +import org.sonar.scanner.fs.DefaultInputProject; public class AnalysisTempFolderProvider extends ProviderAdapter implements ComponentLifecycle { static final String TMP_NAME = ".sonartmp"; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java index 0800b49bc5e..c5c1112317d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java @@ -34,8 +34,6 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.duplications.block.Block; @@ -44,6 +42,8 @@ import org.sonar.duplications.index.CloneGroup; import org.sonar.duplications.index.ClonePart; import org.sonar.duplications.index.PackedMemoryCloneIndex.ResourceBlocks; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputComponent; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Duplicate; import org.sonar.scanner.protocol.output.ScannerReport.Duplication; @@ -160,7 +160,8 @@ public class CpdExecutor { saveDuplications(inputFile, filtered); } - @VisibleForTesting final void saveDuplications(final DefaultInputComponent component, List duplications) { + @VisibleForTesting + final void saveDuplications(final DefaultInputComponent component, List duplications) { if (duplications.size() > MAX_CLONE_GROUP_PER_FILE) { LOG.warn("Too many duplication groups on file {}. Keep only the first {} groups.", component, MAX_CLONE_GROUP_PER_FILE); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java index 54b8307b120..f40e5d107bd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java @@ -21,9 +21,9 @@ package org.sonar.scanner.cpd; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.config.Configuration; import org.sonar.duplications.block.BlockChunker; +import org.sonar.scanner.fs.DefaultInputProject; public class CpdSettings { private final Configuration settings; @@ -41,8 +41,8 @@ public class CpdSettings { } /** - * Not applicable to Java, as the {@link BlockChunker} that it uses does not record start and end units of each block. - * Also, it uses statements instead of tokens. + * Not applicable to Java, as the {@link BlockChunker} that it uses does not record start and end units of each block. + * Also, it uses statements instead of tokens. */ int getMinimumTokens(String languageKey) { return settings.getInt("sonar.cpd." + languageKey + ".minimumTokens").orElse(100); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensor.java index 13c59fc40dd..a66df96bbed 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensor.java @@ -32,7 +32,6 @@ import org.slf4j.LoggerFactory; import org.sonar.api.batch.Phase; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.scanner.sensor.ProjectSensor; @@ -44,6 +43,7 @@ import org.sonar.duplications.statement.Statement; import org.sonar.duplications.statement.StatementChunker; import org.sonar.duplications.token.TokenChunker; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputFile; /** * Special case for Java that use a dedicated block indexer. diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java index 3816f214c86..645d9fab4b1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java @@ -24,9 +24,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.stream.Collectors; - import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.duplications.block.Block; @@ -36,6 +34,7 @@ import org.sonar.duplications.index.CloneIndex; import org.sonar.duplications.index.PackedMemoryCloneIndex; import org.sonar.duplications.index.PackedMemoryCloneIndex.ResourceBlocks; import org.sonar.scanner.cpd.CpdSettings; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.report.ReportPublisher; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultCoverageBlock.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultCoverageBlock.java index 39c54302e68..364544377ed 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultCoverageBlock.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultCoverageBlock.java @@ -20,10 +20,10 @@ package org.sonar.scanner.deprecated.test; import java.util.List; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.CoverageBlock; import org.sonar.api.test.TestCase; import org.sonar.api.test.Testable; +import org.sonar.scanner.fs.DefaultInputFile; public class DefaultCoverageBlock implements CoverageBlock { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestCase.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestCase.java index ae10c57c836..960a6cf03b5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestCase.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestCase.java @@ -26,13 +26,13 @@ import java.util.Map; import javax.annotation.Nullable; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.CoverageBlock; import org.sonar.api.test.MutableTestCase; import org.sonar.api.test.TestPlan; import org.sonar.api.test.Testable; import org.sonar.api.test.exception.CoverageAlreadyExistsException; import org.sonar.api.test.exception.IllegalDurationException; +import org.sonar.scanner.fs.DefaultInputFile; public class DefaultTestCase implements MutableTestCase { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestable.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestable.java index 5e13e265232..20a0abfec50 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestable.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/DefaultTestable.java @@ -22,10 +22,10 @@ package org.sonar.scanner.deprecated.test; import java.util.List; import java.util.Map; import java.util.SortedSet; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.CoverageBlock; import org.sonar.api.test.MutableTestable; import org.sonar.api.test.TestCase; +import org.sonar.scanner.fs.DefaultInputFile; public class DefaultTestable implements MutableTestable { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestPlanBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestPlanBuilder.java index fc2f413c4e8..615ebd2f5cf 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestPlanBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestPlanBuilder.java @@ -25,9 +25,9 @@ import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.MutableTestPlan; import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder; +import org.sonar.scanner.fs.DefaultInputFile; public class TestPlanBuilder extends PerspectiveBuilder { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestableBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestableBuilder.java index 6fe7a1a4f37..84f74e12ff5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestableBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/test/TestableBuilder.java @@ -23,9 +23,9 @@ import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.MutableTestable; import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder; +import org.sonar.scanner.fs.DefaultInputFile; public class TestableBuilder extends PerspectiveBuilder { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java index d458edd0ca9..9fc2d130f4a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java @@ -34,7 +34,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java index de882ad0c54..1c1729634e1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java @@ -37,7 +37,6 @@ import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.PathUtils; import org.sonar.scanner.fs.predicates.DefaultFilePredicates; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java new file mode 100644 index 00000000000..e52e0b46e1f --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java @@ -0,0 +1,162 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import org.sonar.api.batch.fs.IndexedFile; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.fs.internal.SensorStrategy; +import org.sonar.api.utils.PathUtils; + +/** + * @since 6.3 + */ +@Immutable +public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile { + private static AtomicInteger intGenerator = new AtomicInteger(0); + + private final String projectRelativePath; + private final String moduleRelativePath; + private final String projectKey; + private final String language; + private final Type type; + private final Path absolutePath; + private final SensorStrategy sensorStrategy; + + /** + * Testing purposes only! + */ + public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) { + this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, intGenerator.getAndIncrement(), + new SensorStrategy()); + } + + public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId, + SensorStrategy sensorStrategy) { + super(batchId); + this.projectKey = projectKey; + this.projectRelativePath = PathUtils.sanitize(projectRelativePath); + this.moduleRelativePath = PathUtils.sanitize(moduleRelativePath); + this.type = type; + this.language = language; + this.sensorStrategy = sensorStrategy; + this.absolutePath = absolutePath; + } + + @Override + public String relativePath() { + return sensorStrategy.isGlobal() ? projectRelativePath : moduleRelativePath; + } + + public String getModuleRelativePath() { + return moduleRelativePath; + } + + public String getProjectRelativePath() { + return projectRelativePath; + } + + @Override + public String absolutePath() { + return PathUtils.sanitize(path().toString()); + } + + @Override + public File file() { + return path().toFile(); + } + + @Override + public Path path() { + return absolutePath; + } + + @Override + public InputStream inputStream() throws IOException { + return Files.newInputStream(path()); + } + + @CheckForNull + @Override + public String language() { + return language; + } + + @Override + public Type type() { + return type; + } + + /** + * Component key (without branch). + */ + @Override + public String key() { + return new StringBuilder().append(projectKey).append(":").append(projectRelativePath).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof DefaultIndexedFile)) { + return false; + } + + DefaultIndexedFile that = (DefaultIndexedFile) o; + return projectRelativePath.equals(that.projectRelativePath); + } + + @Override + public int hashCode() { + return projectRelativePath.hashCode(); + } + + @Override + public String toString() { + return projectRelativePath; + } + + @Override + public boolean isFile() { + return true; + } + + @Override + public String filename() { + return path().getFileName().toString(); + } + + @Override + public URI uri() { + return path().toUri(); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java new file mode 100644 index 00000000000..11601e0265f --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java @@ -0,0 +1,72 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.util.HashSet; +import java.util.Set; +import org.sonar.api.batch.fs.InputComponent; +import org.sonar.api.batch.measure.Metric; + +/** + * @since 5.2 + */ +public abstract class DefaultInputComponent implements InputComponent { + private int id; + private Set storedMetricKeys = new HashSet<>(); + + public DefaultInputComponent(int scannerId) { + this.id = scannerId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || this.getClass() != o.getClass()) { + return false; + } + + DefaultInputComponent that = (DefaultInputComponent) o; + return key().equals(that.key()); + } + + public int scannerId() { + return id; + } + + @Override + public int hashCode() { + return key().hashCode(); + } + + @Override + public String toString() { + return "[key=" + key() + "]"; + } + + public void setHasMeasureFor(Metric metric) { + storedMetricKeys.add(metric.key()); + } + + public boolean hasMeasureFor(Metric metric) { + return storedMetricKeys.contains(metric.key()); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java new file mode 100644 index 00000000000..13eb77be1c4 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java @@ -0,0 +1,122 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import java.net.URI; +import java.nio.file.Path; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.fs.InputDir; +import org.sonar.api.utils.PathUtils; + +/** + * @since 4.5 + */ +public class DefaultInputDir extends DefaultInputComponent implements InputDir { + + private final String relativePath; + private final String moduleKey; + private Path moduleBaseDir; + + public DefaultInputDir(String moduleKey, String relativePath) { + super(-1); + this.moduleKey = moduleKey; + this.relativePath = PathUtils.sanitize(relativePath); + } + + @Override + public String relativePath() { + return relativePath; + } + + @Override + public String absolutePath() { + return PathUtils.sanitize(path().toString()); + } + + @Override + public File file() { + return path().toFile(); + } + + @Override + public Path path() { + if (moduleBaseDir == null) { + throw new IllegalStateException("Can not return the java.nio.file.Path because module baseDir is not set (see method setModuleBaseDir(java.io.File))"); + } + return moduleBaseDir.resolve(relativePath); + } + + public String moduleKey() { + return moduleKey; + } + + @Override + public String key() { + StringBuilder sb = new StringBuilder().append(moduleKey).append(":"); + if (StringUtils.isEmpty(relativePath)) { + sb.append("/"); + } else { + sb.append(relativePath); + } + return sb.toString(); + } + + /** + * For testing purpose. Will be automatically set when dir is added to {@link DefaultFileSystem} + */ + public DefaultInputDir setModuleBaseDir(Path moduleBaseDir) { + this.moduleBaseDir = moduleBaseDir.normalize(); + return this; + } + + @Override + public boolean isFile() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || this.getClass() != o.getClass()) { + return false; + } + + DefaultInputDir that = (DefaultInputDir) o; + return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath); + } + + @Override + public int hashCode() { + return moduleKey.hashCode() + relativePath.hashCode() * 13; + } + + @Override + public String toString() { + return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]"; + } + + @Override + public URI uri() { + return path().toUri(); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java new file mode 100644 index 00000000000..c74f1c41296 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java @@ -0,0 +1,440 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.apache.commons.io.ByteOrderMark; +import org.apache.commons.io.input.BOMInputStream; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextPointer; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.fs.internal.Metadata; + +import static org.sonar.api.utils.Preconditions.checkArgument; +import static org.sonar.api.utils.Preconditions.checkState; + +/** + * @since 4.2 + * To create {@link InputFile} in tests, use TestInputFileBuilder. + */ +public class DefaultInputFile extends DefaultInputComponent implements InputFile { + + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + + private final DefaultIndexedFile indexedFile; + private final String contents; + private final Consumer metadataGenerator; + + private boolean published; + private boolean excludedForCoverage; + private boolean excludedForDuplication; + private boolean ignoreAllIssues; + // Lazy init to save memory + private BitSet noSonarLines; + private Status status; + private Charset charset; + private Metadata metadata; + private Collection ignoreIssuesOnlineRanges; + private BitSet executableLines; + + public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator) { + this(indexedFile, metadataGenerator, null); + } + + // For testing + public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator, @Nullable String contents) { + super(indexedFile.scannerId()); + this.indexedFile = indexedFile; + this.metadataGenerator = metadataGenerator; + this.metadata = null; + this.published = false; + this.excludedForCoverage = false; + this.contents = contents; + } + + public void checkMetadata() { + if (metadata == null) { + metadataGenerator.accept(this); + } + } + + @Override + public InputStream inputStream() throws IOException { + return contents != null ? new ByteArrayInputStream(contents.getBytes(charset())) + : new BOMInputStream(Files.newInputStream(path()), + ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE); + } + + @Override + public String contents() throws IOException { + if (contents != null) { + return contents; + } else { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + try (InputStream inputStream = inputStream()) { + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + } + return result.toString(charset().name()); + } + } + + public DefaultInputFile setPublished(boolean published) { + this.published = published; + return this; + } + + public boolean isPublished() { + return published; + } + + public DefaultInputFile setExcludedForCoverage(boolean excludedForCoverage) { + this.excludedForCoverage = excludedForCoverage; + return this; + } + + public boolean isExcludedForCoverage() { + return excludedForCoverage; + } + + public DefaultInputFile setExcludedForDuplication(boolean excludedForDuplication) { + this.excludedForDuplication = excludedForDuplication; + return this; + } + + public boolean isExcludedForDuplication() { + return excludedForDuplication; + } + + /** + * @deprecated since 6.6 + */ + @Deprecated + @Override + public String relativePath() { + return indexedFile.relativePath(); + } + + public String getModuleRelativePath() { + return indexedFile.getModuleRelativePath(); + } + + public String getProjectRelativePath() { + return indexedFile.getProjectRelativePath(); + } + + @Override + public String absolutePath() { + return indexedFile.absolutePath(); + } + + @Override + public File file() { + return indexedFile.file(); + } + + @Override + public Path path() { + return indexedFile.path(); + } + + @CheckForNull + @Override + public String language() { + return indexedFile.language(); + } + + @Override + public Type type() { + return indexedFile.type(); + } + + /** + * Component key (without branch). + */ + @Override + public String key() { + return indexedFile.key(); + } + + @Override + public int hashCode() { + return indexedFile.hashCode(); + } + + @Override + public String toString() { + return indexedFile.toString(); + } + + /** + * {@link #setStatus(Status)} + */ + @Override + public Status status() { + checkMetadata(); + return status; + } + + @Override + public int lines() { + checkMetadata(); + return metadata.lines(); + } + + @Override + public boolean isEmpty() { + checkMetadata(); + return metadata.isEmpty(); + } + + @Override + public Charset charset() { + checkMetadata(); + return charset; + } + + public int lastValidOffset() { + checkMetadata(); + return metadata.lastValidOffset(); + } + + /** + * Digest hash of the file. + */ + public String hash() { + checkMetadata(); + return metadata.hash(); + } + + public int nonBlankLines() { + checkMetadata(); + return metadata.nonBlankLines(); + } + + public int[] originalLineStartOffsets() { + checkMetadata(); + checkState(metadata.originalLineStartOffsets() != null, "InputFile is not properly initialized."); + checkState(metadata.originalLineStartOffsets().length == metadata.lines(), + "InputFile is not properly initialized. 'originalLineStartOffsets' property length should be equal to 'lines'"); + return metadata.originalLineStartOffsets(); + } + + public int[] originalLineEndOffsets() { + checkMetadata(); + checkState(metadata.originalLineEndOffsets() != null, "InputFile is not properly initialized."); + checkState(metadata.originalLineEndOffsets().length == metadata.lines(), + "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'"); + return metadata.originalLineEndOffsets(); + } + + @Override + public TextPointer newPointer(int line, int lineOffset) { + checkMetadata(); + DefaultTextPointer textPointer = new DefaultTextPointer(line, lineOffset); + checkValid(textPointer, "pointer"); + return textPointer; + } + + @Override + public TextRange newRange(TextPointer start, TextPointer end) { + checkMetadata(); + checkValid(start, "start pointer"); + checkValid(end, "end pointer"); + return newRangeValidPointers(start, end, false); + } + + @Override + public TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset) { + checkMetadata(); + TextPointer start = newPointer(startLine, startLineOffset); + TextPointer end = newPointer(endLine, endLineOffset); + return newRangeValidPointers(start, end, false); + } + + @Override + public TextRange selectLine(int line) { + checkMetadata(); + TextPointer startPointer = newPointer(line, 0); + TextPointer endPointer = newPointer(line, lineLength(line)); + return newRangeValidPointers(startPointer, endPointer, true); + } + + public void validate(TextRange range) { + checkMetadata(); + checkValid(range.start(), "start pointer"); + checkValid(range.end(), "end pointer"); + } + + /** + * Create Range from global offsets. Used for backward compatibility with older API. + */ + public TextRange newRange(int startOffset, int endOffset) { + checkMetadata(); + return newRangeValidPointers(newPointer(startOffset), newPointer(endOffset), false); + } + + public TextPointer newPointer(int globalOffset) { + checkMetadata(); + checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset); + checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset()); + int line = findLine(globalOffset); + int startLineOffset = originalLineStartOffsets()[line - 1]; + // In case the global offset is between \r and \n, move the pointer to a valid location + return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line - 1]) - startLineOffset); + } + + public DefaultInputFile setStatus(Status status) { + this.status = status; + return this; + } + + public DefaultInputFile setCharset(Charset charset) { + this.charset = charset; + return this; + } + + private void checkValid(TextPointer pointer, String owner) { + checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line()); + checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines()); + checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset()); + int lineLength = lineLength(pointer.line()); + checkArgument(pointer.lineOffset() <= lineLength, + "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line()); + } + + private int lineLength(int line) { + return originalLineEndOffsets()[line - 1] - originalLineStartOffsets()[line - 1]; + } + + private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) { + checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0), + "Start pointer %s should be before end pointer %s", start, end); + return new DefaultTextRange(start, end); + } + + private int findLine(int globalOffset) { + return Math.abs(Arrays.binarySearch(originalLineStartOffsets(), globalOffset) + 1); + } + + public DefaultInputFile setMetadata(Metadata metadata) { + this.metadata = metadata; + return this; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (this.getClass() != obj.getClass()) { + return false; + } + + DefaultInputFile that = (DefaultInputFile) obj; + return this.getProjectRelativePath().equals(that.getProjectRelativePath()); + } + + @Override + public boolean isFile() { + return true; + } + + @Override + public String filename() { + return indexedFile.filename(); + } + + @Override + public URI uri() { + return indexedFile.uri(); + } + + public void noSonarAt(Set noSonarLines) { + if (this.noSonarLines == null) { + this.noSonarLines = new BitSet(lines()); + } + noSonarLines.forEach(l -> this.noSonarLines.set(l - 1)); + } + + public boolean hasNoSonarAt(int line) { + if (this.noSonarLines == null) { + return false; + } + return this.noSonarLines.get(line - 1); + } + + public boolean isIgnoreAllIssues() { + return ignoreAllIssues; + } + + public void setIgnoreAllIssues(boolean ignoreAllIssues) { + this.ignoreAllIssues = ignoreAllIssues; + } + + public void addIgnoreIssuesOnLineRanges(Collection lineRanges) { + if (this.ignoreIssuesOnlineRanges == null) { + this.ignoreIssuesOnlineRanges = new ArrayList<>(); + } + this.ignoreIssuesOnlineRanges.addAll(lineRanges); + } + + public boolean isIgnoreAllIssuesOnLine(@Nullable Integer line) { + if (line == null || ignoreIssuesOnlineRanges == null) { + return false; + } + return ignoreIssuesOnlineRanges.stream().anyMatch(r -> r[0] <= line && line <= r[1]); + } + + public void setExecutableLines(Set executableLines) { + checkState(this.executableLines == null, "Executable lines have already been saved for file: {}", this.toString()); + this.executableLines = new BitSet(lines()); + executableLines.forEach(l -> this.executableLines.set(l - 1)); + } + + public Optional> getExecutableLines() { + if (this.executableLines == null) { + return Optional.empty(); + } + return Optional.of(this.executableLines.stream().map(i -> i + 1).boxed().collect(Collectors.toSet())); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java index eee66064b29..6764b6180d5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java @@ -31,12 +31,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultIndexedFile; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.Metadata; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.utils.PathUtils; @@ -218,14 +212,14 @@ public class TestInputFileBuilder { return setMetadata(new FileMetadata().readMetadata(new StringReader(content))); } - public org.sonar.api.batch.fs.internal.DefaultInputFile build() { + public DefaultInputFile build() { Path absolutePath = moduleBaseDir.resolve(relativePath); if (projectBaseDir == null) { projectBaseDir = moduleBaseDir; } String projectRelativePath = projectBaseDir.relativize(absolutePath).toString(); - org.sonar.api.batch.fs.internal.DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy()); - org.sonar.api.batch.fs.internal.DefaultInputFile inputFile = new org.sonar.api.batch.fs.internal.DefaultInputFile(indexedFile, + DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy()); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineStartOffsets, originalLineEndOffsets, lastValidOffset)), contents); inputFile.setStatus(status); @@ -234,7 +228,7 @@ public class TestInputFileBuilder { return inputFile; } - public static org.sonar.api.batch.fs.internal.DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { + public static DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { ProjectDefinition definition = ProjectDefinition.create() .setKey(moduleKey) .setBaseDir(baseDir) @@ -242,17 +236,17 @@ public class TestInputFileBuilder { return newDefaultInputModule(definition); } - public static org.sonar.api.batch.fs.internal.DefaultInputModule newDefaultInputModule(ProjectDefinition projectDefinition) { - return new org.sonar.api.batch.fs.internal.DefaultInputModule(projectDefinition, TestInputFileBuilder.nextBatchId()); + public static DefaultInputModule newDefaultInputModule(ProjectDefinition projectDefinition) { + return new DefaultInputModule(projectDefinition, TestInputFileBuilder.nextBatchId()); } - public static DefaultInputModule newDefaultInputModule(org.sonar.api.batch.fs.internal.AbstractProjectOrModule parent, String key) throws IOException { + public static DefaultInputModule newDefaultInputModule(AbstractProjectOrModule parent, String key) throws IOException { Path basedir = parent.getBaseDir().resolve(key); Files.createDirectory(basedir); return newDefaultInputModule(key, basedir.toFile()); } - public static org.sonar.api.batch.fs.internal.DefaultInputProject newDefaultInputProject(String projectKey, File baseDir) { + public static DefaultInputProject newDefaultInputProject(String projectKey, File baseDir) { ProjectDefinition definition = ProjectDefinition.create() .setKey(projectKey) .setBaseDir(baseDir) @@ -260,8 +254,8 @@ public class TestInputFileBuilder { return newDefaultInputProject(definition); } - public static org.sonar.api.batch.fs.internal.DefaultInputProject newDefaultInputProject(ProjectDefinition projectDefinition) { - return new org.sonar.api.batch.fs.internal.DefaultInputProject(projectDefinition, TestInputFileBuilder.nextBatchId()); + public static DefaultInputProject newDefaultInputProject(ProjectDefinition projectDefinition) { + return new DefaultInputProject(projectDefinition, TestInputFileBuilder.nextBatchId()); } public static DefaultInputProject newDefaultInputProject(String key, Path baseDir) throws IOException { @@ -269,7 +263,7 @@ public class TestInputFileBuilder { return newDefaultInputProject(key, baseDir.toFile()); } - public static org.sonar.api.batch.fs.internal.DefaultInputDir newDefaultInputDir(org.sonar.api.batch.fs.internal.AbstractProjectOrModule module, String relativePath) throws IOException { + public static DefaultInputDir newDefaultInputDir(AbstractProjectOrModule module, String relativePath) throws IOException { Path basedir = module.getBaseDir().resolve(relativePath); Files.createDirectory(basedir); return new DefaultInputDir(module.key(), relativePath) diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/AbstractDefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/AbstractDefaultIssue.java index 113d44544f7..4b13e2016d1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/AbstractDefaultIssue.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/AbstractDefaultIssue.java @@ -27,15 +27,15 @@ import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.sensor.internal.DefaultStorable; +import org.sonar.scanner.sensor.DefaultStorable; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue.Flow; import org.sonar.api.batch.sensor.issue.IssueLocation; import org.sonar.api.batch.sensor.issue.NewIssueLocation; import org.sonar.api.utils.PathUtils; +import org.sonar.scanner.fs.DefaultInputDir; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import static java.util.Collections.unmodifiableList; import static java.util.stream.Collectors.toList; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java index 8dd8829d9b3..5485c348c87 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultFilterableIssue.java @@ -25,12 +25,12 @@ import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextRange; import org.sonar.api.rule.RuleKey; import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.scanner.ProjectInfo; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.DefaultTextRange; import org.sonar.scanner.protocol.output.ScannerReport.Issue; @ThreadSafe diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssue.java index bf36bf5ac55..154dfc91c81 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssue.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssue.java @@ -20,13 +20,13 @@ package org.sonar.scanner.issue; import javax.annotation.Nullable; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.IssueLocation; import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.rule.RuleKey; +import org.sonar.scanner.fs.DefaultInputProject; import static java.lang.String.format; import static java.util.Objects.requireNonNull; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueLocation.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueLocation.java index 95147bc75a0..33018bbcc8f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueLocation.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultIssueLocation.java @@ -22,9 +22,9 @@ package org.sonar.scanner.issue; import javax.annotation.Nullable; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.issue.IssueLocation; import org.sonar.api.batch.sensor.issue.NewIssueLocation; +import org.sonar.scanner.fs.DefaultInputFile; import static java.util.Objects.requireNonNull; import static org.apache.commons.lang.StringUtils.abbreviate; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultNoSonarFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultNoSonarFilter.java new file mode 100644 index 00000000000..00d3ba518f1 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/DefaultNoSonarFilter.java @@ -0,0 +1,32 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.issue; + +import java.util.Set; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.issue.NoSonarFilter; +import org.sonar.scanner.fs.DefaultInputFile; + +public class DefaultNoSonarFilter extends NoSonarFilter { + public NoSonarFilter noSonarInFile(InputFile inputFile, Set noSonarLines) { + ((DefaultInputFile) inputFile).noSonarAt(noSonarLines); + return this; + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java index 2a3e6374dc0..87a4846a81a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssueFilters.java @@ -20,11 +20,11 @@ package org.sonar.scanner.issue; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.api.scan.issue.filter.IssueFilter; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.scanner.ProjectInfo; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.protocol.output.ScannerReport; /** diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssuePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssuePublisher.java index f8a652553ea..ac02497f474 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssuePublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/IssuePublisher.java @@ -24,13 +24,13 @@ import java.util.function.Consumer; import javax.annotation.concurrent.ThreadSafe; import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.ActiveRule; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.Issue.Flow; +import org.sonar.scanner.fs.DefaultInputComponent; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.Constants.Severity; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.IssueLocation; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java index 0cf870ea06b..e518408f13b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java @@ -24,13 +24,13 @@ import java.util.Collections; import java.util.List; import javax.annotation.concurrent.ThreadSafe; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.api.scan.issue.filter.IssueFilter; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.issue.DefaultFilterableIssue; import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer; import org.sonar.scanner.issue.ignore.pattern.IssuePattern; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java index 666b1732dea..8d825944b84 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java @@ -22,13 +22,13 @@ package org.sonar.scanner.issue.ignore; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.api.scan.issue.filter.IssueFilter; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.api.utils.WildcardPattern; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.issue.DefaultFilterableIssue; public class IgnoreIssuesFilter implements IssueFilter { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java index 858a4dd5d2f..4c3117835ca 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java @@ -23,10 +23,10 @@ import java.util.ArrayList; import java.util.List; import javax.annotation.CheckForNull; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.charhandler.CharHandler; import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter; import org.sonar.scanner.issue.ignore.pattern.BlockIssuePattern; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java index 19079dbac4f..2ab767f7f3b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java @@ -25,9 +25,9 @@ import java.util.List; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.charhandler.CharHandler; import org.sonar.scanner.issue.ignore.pattern.LineRange; import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader.DoubleRegexpMatcher; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java index cd9f6f67421..c75da29f0ed 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java @@ -34,11 +34,11 @@ import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextPointer; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.scanner.fs.InputProject; import org.sonar.core.util.CloseableIterator; +import org.sonar.scanner.fs.DefaultInputComponent; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component; import org.sonar.scanner.protocol.output.ScannerReport.Symbol; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java index ff393c42773..00d8bed5abf 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java @@ -25,12 +25,12 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java index dfd8163cb52..597785f7632 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java @@ -25,9 +25,9 @@ import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.scanner.fs.AbstractProjectOrModule; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType; import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus; @@ -44,7 +44,6 @@ public class ComponentsPublisher implements ReportPublisherStep { private final InputComponentStore inputComponentStore; private final DefaultInputProject project; - public ComponentsPublisher(DefaultInputProject project, InputComponentStore inputComponentStore) { this.project = project; this.inputComponentStore = inputComponentStore; @@ -123,7 +122,7 @@ public class ComponentsPublisher implements ReportPublisherStep { } private static void writeProjectLink(ScannerReport.Component.Builder componentBuilder, Map properties, ComponentLink.Builder linkBuilder, String linkProp, - ComponentLinkType linkType) { + ComponentLinkType linkType) { String link = properties.get(linkProp); if (StringUtils.isNotBlank(link)) { linkBuilder.setType(linkType); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java index 06f20e70e95..be1e838b810 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java @@ -25,9 +25,6 @@ import java.util.LinkedList; import java.util.Map.Entry; import java.util.regex.Pattern; import javax.annotation.Nullable; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -35,6 +32,9 @@ import org.sonar.scanner.ProjectInfo; import org.sonar.scanner.bootstrap.ScannerPlugin; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.cpd.CpdSettings; +import org.sonar.scanner.fs.AbstractProjectOrModule; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Metadata.BranchType; import org.sonar.scanner.protocol.output.ScannerReportWriter; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java index dbee000ded1..c2afdc1baf2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java @@ -36,7 +36,6 @@ import javax.annotation.Nullable; import okhttp3.HttpUrl; import org.apache.commons.io.FileUtils; import org.picocontainer.Startable; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.platform.Server; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; @@ -45,6 +44,7 @@ import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.ScanProperties; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java index 3ab19165dcc..765ac95da04 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java @@ -28,9 +28,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.charset.StandardCharsets; - import org.apache.commons.io.IOUtils; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.filesystem.InputComponentStore; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java index ad4ac749120..f04f204bf2b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java @@ -24,16 +24,16 @@ import java.util.Objects; import java.util.stream.StreamSupport; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.scanner.sensor.DefaultMeasure; import org.sonar.api.test.MutableTestPlan; import org.sonar.api.test.TestCase; import org.sonar.api.test.TestCase.Status; import org.sonar.scanner.deprecated.test.TestPlanBuilder; +import org.sonar.scanner.fs.DefaultInputComponent; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.filesystem.InputComponentStore; +import org.sonar.scanner.sensor.DefaultMeasure; import static org.sonar.api.measures.CoreMetrics.SKIPPED_TESTS; import static org.sonar.api.measures.CoreMetrics.TESTS; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java index 7ca0913805c..d1a7a30080c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositories.java @@ -21,7 +21,7 @@ package org.sonar.scanner.repository; import javax.annotation.CheckForNull; import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; @Immutable public abstract class ProjectRepositories { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java index 067f830edbe..aa6cbeb0db1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java @@ -27,10 +27,10 @@ import java.util.HashMap; import java.util.Map; import javax.annotation.CheckForNull; import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.scan.filesystem.PathResolver; +import org.sonar.scanner.fs.AbstractProjectOrModule; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; @Immutable public class DefaultInputModuleHierarchy implements InputModuleHierarchy { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java index ffe0e15f073..da0b8781dde 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java @@ -24,10 +24,10 @@ import java.util.Locale; import java.util.Map; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; public class InputModuleHierarchyProvider extends ProviderAdapter { @@ -51,7 +51,7 @@ public class InputModuleHierarchyProvider extends ProviderAdapter { } private static Map createChildren(DefaultInputModule parent, ScannerComponentIdGenerator scannerComponentIdGenerator, - Map parents) { + Map parents) { for (ProjectDefinition def : parent.definition().getSubProjects()) { DefaultInputModule child = createModule(def, scannerComponentIdGenerator.getAsInt()); parents.put(child, parent); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java index 08303ac0a0b..1219f2871dd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java @@ -22,15 +22,14 @@ package org.sonar.scanner.scan; import java.util.Locale; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; public class InputProjectProvider extends ProviderAdapter { - private static final Logger LOG = Loggers.get(DefaultInputModule.class); + private static final Logger LOG = Loggers.get(InputProjectProvider.class); private DefaultInputProject project = null; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java index fd409e22d6b..21d241c23f4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleConfigurationProvider.java @@ -25,9 +25,9 @@ import java.util.List; import java.util.Map; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; +import org.sonar.scanner.fs.DefaultInputModule; public class ModuleConfigurationProvider extends ProviderAdapter { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java index da1c14363ca..1bc1611097f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java @@ -20,8 +20,8 @@ package org.sonar.scanner.scan; import org.picocontainer.Startable; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.scan.filesystem.InputComponentStore; /** diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java index e771f958e7c..1a7a78f93cf 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java @@ -19,11 +19,11 @@ */ package org.sonar.scanner.scan; -import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.scan.filesystem.FileExclusions; import org.sonar.core.platform.ComponentContainer; import org.sonar.scanner.bootstrap.ExtensionInstaller; import org.sonar.scanner.deprecated.perspectives.ScannerPerspectives; +import org.sonar.scanner.fs.DefaultInputModule; import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem; import org.sonar.scanner.scan.filesystem.ModuleInputComponentStore; import org.sonar.scanner.sensor.ModuleSensorContext; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java index b3e127a80cd..0d17b4a8114 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectConfigurationProvider.java @@ -22,9 +22,9 @@ package org.sonar.scanner.scan; import java.util.LinkedHashMap; import java.util.Map; import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; +import org.sonar.scanner.fs.DefaultInputProject; public class ProjectConfigurationProvider extends ProviderAdapter { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java index 89bfe76c1f2..9bf6bf73115 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectLock.java @@ -24,7 +24,7 @@ import java.nio.channels.OverlappingFileLockException; import java.nio.file.Files; import java.nio.file.Path; import org.picocontainer.Startable; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; +import org.sonar.scanner.fs.AbstractProjectOrModule; public class ProjectLock implements Startable { private final DirectoryLock lock; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index 411625c7546..8cd93d031c4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -23,11 +23,8 @@ import com.google.common.annotations.VisibleForTesting; import javax.annotation.Nullable; import org.sonar.api.SonarEdition; import org.sonar.api.SonarRuntime; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.batch.rule.CheckFactory; -import org.sonar.api.issue.NoSonarFilter; import org.sonar.api.resources.Languages; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.scan.filesystem.PathResolver; @@ -66,7 +63,10 @@ import org.sonar.scanner.cpd.CpdSettings; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; import org.sonar.scanner.deprecated.test.TestPlanBuilder; import org.sonar.scanner.deprecated.test.TestableBuilder; +import org.sonar.scanner.fs.DefaultInputModule; import org.sonar.scanner.fs.FileMetadata; +import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.issue.DefaultNoSonarFilter; import org.sonar.scanner.issue.IssueFilters; import org.sonar.scanner.issue.IssuePublisher; import org.sonar.scanner.issue.ignore.EnforceIssuesFilter; @@ -203,7 +203,7 @@ public class ProjectScanContainer extends ComponentContainer { QProfileVerifier.class, // issues - NoSonarFilter.class, + DefaultNoSonarFilter.class, IssueFilters.class, IssuePublisher.class, diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java index 22a7751c035..2fa3bbeaf02 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java @@ -22,9 +22,9 @@ package org.sonar.scanner.scan; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.config.Configuration; import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.DefaultInputProject; import static org.sonar.core.config.ScannerProperties.BRANCH_NAME; import static org.sonar.core.config.ScannerProperties.ORGANIZATION; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java index 77ab7341bba..8c5b01e4b2b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/WorkDirectoriesInitializer.java @@ -24,9 +24,9 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Iterator; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.core.util.FileUtils; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; /** * Clean and create working directories of each module. diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java index bb8f5fc22f1..1bcbad7f75a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java @@ -25,10 +25,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.concurrent.Immutable; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.WildcardPattern; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import static java.util.stream.Collectors.toList; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java index 74e82cd8535..d25948764dd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java @@ -20,8 +20,8 @@ package org.sonar.scanner.scan.filesystem; import com.google.common.annotations.VisibleForTesting; -import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputModule; public class DefaultModuleFileSystem extends DefaultFileSystem { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java index 7e0dbc6f6af..294b0b946d1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultProjectFileSystem.java @@ -20,8 +20,8 @@ package org.sonar.scanner.scan.filesystem; import com.google.common.annotations.VisibleForTesting; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputProject; public class DefaultProjectFileSystem extends DefaultFileSystem { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 982d413a71f..56c21333962 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -30,16 +30,16 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputFileFilter; -import org.sonar.api.batch.fs.internal.DefaultIndexedFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.batch.scm.IgnoreCommand; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultIndexedFile; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader; import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.util.ProgressReport; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java index cd9f0db7347..4eab927136d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java @@ -35,9 +35,9 @@ import java.util.stream.Stream; import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; import org.sonar.scanner.fs.predicates.FileExtensionPredicate; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java index 80731033ac0..2da2f6db0c4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java @@ -23,10 +23,10 @@ import com.google.common.annotations.VisibleForTesting; import java.io.InputStream; import java.nio.charset.Charset; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.Metadata; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.FileMetadata; import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleCoverageAndDuplicationExclusions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleCoverageAndDuplicationExclusions.java index 5cb50568741..3ef961f83e2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleCoverageAndDuplicationExclusions.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleCoverageAndDuplicationExclusions.java @@ -20,7 +20,7 @@ package org.sonar.scanner.scan.filesystem; import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.scan.ModuleConfiguration; @Immutable diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectCoverageAndDuplicationExclusions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectCoverageAndDuplicationExclusions.java index 1cf496f1310..4ab146afb27 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectCoverageAndDuplicationExclusions.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectCoverageAndDuplicationExclusions.java @@ -20,7 +20,7 @@ package org.sonar.scanner.scan.filesystem; import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.scan.ProjectConfiguration; @Immutable diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java index 2a60b91322a..118b3eb5567 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java @@ -39,14 +39,14 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.IgnoreCommand; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.bootstrap.GlobalConfiguration; import org.sonar.scanner.bootstrap.GlobalServerSettings; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.scan.ModuleConfiguration; import org.sonar.scanner.scan.ModuleConfigurationProvider; import org.sonar.scanner.scan.ProjectServerSettings; @@ -163,7 +163,7 @@ public class ProjectFileIndexer { private static void logPaths(String label, Path baseDir, List paths) { if (!paths.isEmpty()) { StringBuilder sb = new StringBuilder(label); - for (Iterator it = paths.iterator(); it.hasNext();) { + for (Iterator it = paths.iterator(); it.hasNext(); ) { Path file = it.next(); Optional relativePathToBaseDir = PathResolver.relativize(baseDir, file); if (!relativePathToBaseDir.isPresent()) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java index 09561999935..2cd3f8d5240 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java @@ -22,7 +22,7 @@ package org.sonar.scanner.scan.filesystem; import javax.annotation.concurrent.Immutable; import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.repository.FileData; import org.sonar.scanner.repository.ProjectRepositoriesSupplier; import org.sonar.scanner.scm.ScmChangedFiles; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java index 3e6833cf34b..e2742ea4d3a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java @@ -30,11 +30,11 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.scm.BlameCommand.BlameOutput; import org.sonar.api.batch.scm.BlameLine; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder; import org.sonar.scanner.protocol.output.ScannerReportWriter; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java index b7fd4c8bf76..6e93b9d4ad6 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java @@ -23,11 +23,11 @@ import java.nio.file.Path; import java.util.Collection; import javax.annotation.CheckForNull; import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.util.ScannerUtils; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java index 5c0e2902d8e..3ee057eacb7 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java @@ -30,7 +30,6 @@ import org.sonar.api.Properties; import org.sonar.api.Property; import org.sonar.api.PropertyType; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.config.Configuration; import org.sonar.api.notifications.AnalysisWarnings; @@ -38,6 +37,7 @@ import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.config.ScannerProperties; +import org.sonar.scanner.fs.InputModuleHierarchy; import static org.sonar.api.CoreProperties.SCM_PROVIDER_KEY; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java index 819abc8adce..7b048096dab 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java @@ -26,10 +26,10 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder; import org.sonar.scanner.protocol.output.ScannerReportWriter; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmRevisionImpl.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmRevisionImpl.java index 6eb15be6e81..94cd490cbe2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmRevisionImpl.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmRevisionImpl.java @@ -20,12 +20,12 @@ package org.sonar.scanner.scm; import java.util.Optional; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.bootstrap.RawScannerProperties; import org.sonar.scanner.ci.CiConfiguration; +import org.sonar.scanner.fs.InputModuleHierarchy; import static org.apache.commons.lang.StringUtils.isBlank; import static org.sonar.scanner.scan.ScanProperties.SCM_REVISION; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java deleted file mode 100644 index b77d1141911..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.scanner.sensor; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.batch.sensor.issue.Issue.Flow; -import org.sonar.api.batch.sensor.issue.IssueLocation; -import org.sonar.api.batch.sensor.issue.NewIssueLocation; -import org.sonar.api.utils.PathUtils; - -import static java.util.Collections.unmodifiableList; -import static java.util.stream.Collectors.toList; -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -public abstract class AbstractDefaultIssue extends DefaultStorable { - protected IssueLocation primaryLocation; - protected List> flows = new ArrayList<>(); - protected DefaultInputProject project; - - protected AbstractDefaultIssue(DefaultInputProject project) { - this(project, null); - } - - public AbstractDefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) { - super(storage); - this.project = project; - } - - public IssueLocation primaryLocation() { - return primaryLocation; - } - - public List flows() { - return this.flows.stream() - .map(l -> () -> unmodifiableList(new ArrayList<>(l))) - .collect(toList()); - } - - public NewIssueLocation newLocation() { - return new DefaultIssueLocation(); - } - - public T at(NewIssueLocation primaryLocation) { - checkArgument(primaryLocation != null, "Cannot use a location that is null"); - checkState(this.primaryLocation == null, "at() already called"); - this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation); - checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component"); - return (T) this; - } - - public T addLocation(NewIssueLocation secondaryLocation) { - flows.add(Collections.singletonList(rewriteLocation((DefaultIssueLocation) secondaryLocation))); - return (T) this; - } - - public T addFlow(Iterable locations) { - List flowAsList = new ArrayList<>(); - for (NewIssueLocation issueLocation : locations) { - flowAsList.add(rewriteLocation((DefaultIssueLocation) issueLocation)); - } - flows.add(flowAsList); - return (T) this; - } - - private DefaultIssueLocation rewriteLocation(DefaultIssueLocation location) { - InputComponent component = location.inputComponent(); - Optional dirOrModulePath = Optional.empty(); - - if (component instanceof DefaultInputDir) { - DefaultInputDir dirComponent = (DefaultInputDir) component; - dirOrModulePath = Optional.of(project.getBaseDir().relativize(dirComponent.path())); - } else if (component instanceof DefaultInputModule && !Objects.equals(project.key(), component.key())) { - DefaultInputModule moduleComponent = (DefaultInputModule) component; - dirOrModulePath = Optional.of(project.getBaseDir().relativize(moduleComponent.getBaseDir())); - } - - if (dirOrModulePath.isPresent()) { - String path = PathUtils.sanitize(dirOrModulePath.get().toString()); - DefaultIssueLocation fixedLocation = new DefaultIssueLocation(); - fixedLocation.on(project); - StringBuilder fullMessage = new StringBuilder(); - if (path != null && !path.isEmpty()) { - fullMessage.append("[").append(path).append("] "); - } - fullMessage.append(location.message()); - fixedLocation.message(fullMessage.toString()); - return fixedLocation; - } else { - return location; - } - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java index 23dbd341c36..1dde73e2c5c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java @@ -22,7 +22,6 @@ package org.sonar.scanner.sensor; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.rule.AdHocRule; import org.sonar.api.batch.sensor.rule.NewAdHocRule; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAnalysisError.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAnalysisError.java new file mode 100644 index 00000000000..3da46d831d7 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAnalysisError.java @@ -0,0 +1,87 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextPointer; +import org.sonar.api.batch.sensor.error.AnalysisError; +import org.sonar.api.batch.sensor.error.NewAnalysisError; +import org.sonar.api.batch.sensor.internal.SensorStorage; + +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkArgument; +import static org.sonar.api.utils.Preconditions.checkState; + +public class DefaultAnalysisError extends DefaultStorable implements NewAnalysisError, AnalysisError { + private InputFile inputFile; + private String message; + private TextPointer location; + + public DefaultAnalysisError() { + super(null); + } + + public DefaultAnalysisError(SensorStorage storage) { + super(storage); + } + + @Override + public InputFile inputFile() { + return inputFile; + } + + @Override + public String message() { + return message; + } + + @Override + public TextPointer location() { + return location; + } + + @Override + public NewAnalysisError onFile(InputFile inputFile) { + checkArgument(inputFile != null, "Cannot use a inputFile that is null"); + checkState(this.inputFile == null, "onFile() already called"); + this.inputFile = inputFile; + return this; + } + + @Override + public NewAnalysisError message(String message) { + this.message = message; + return this; + } + + @Override + public NewAnalysisError at(TextPointer location) { + checkState(this.location == null, "at() already called"); + this.location = location; + return this; + } + + @Override + protected void doSave() { + requireNonNull(this.inputFile, "inputFile is mandatory on AnalysisError"); + storage.store(this); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCoverage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCoverage.java new file mode 100644 index 00000000000..5a2f04811b0 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCoverage.java @@ -0,0 +1,157 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import java.util.Collections; +import java.util.SortedMap; +import java.util.TreeMap; +import javax.annotation.Nullable; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.coverage.CoverageType; +import org.sonar.api.batch.sensor.coverage.NewCoverage; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.DefaultInputFile; + +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkState; + +public class DefaultCoverage extends DefaultStorable implements NewCoverage { + + private InputFile inputFile; + private CoverageType type; + private int totalCoveredLines = 0; + private int totalConditions = 0; + private int totalCoveredConditions = 0; + private SortedMap hitsByLine = new TreeMap<>(); + private SortedMap conditionsByLine = new TreeMap<>(); + private SortedMap coveredConditionsByLine = new TreeMap<>(); + + public DefaultCoverage() { + super(); + } + + public DefaultCoverage(@Nullable SensorStorage storage) { + super(storage); + } + + @Override + public DefaultCoverage onFile(InputFile inputFile) { + this.inputFile = inputFile; + return this; + } + + public InputFile inputFile() { + return inputFile; + } + + @Override + public NewCoverage ofType(CoverageType type) { + this.type = requireNonNull(type, "type can't be null"); + return this; + } + + public CoverageType type() { + return type; + } + + @Override + public NewCoverage lineHits(int line, int hits) { + validateFile(); + if (isExcluded()) { + return this; + } + validateLine(line); + + if (!hitsByLine.containsKey(line)) { + hitsByLine.put(line, hits); + if (hits > 0) { + totalCoveredLines += 1; + } + } + return this; + } + + private void validateLine(int line) { + checkState(line <= inputFile.lines(), "Line %s is out of range in the file %s (lines: %s)", line, inputFile, inputFile.lines()); + checkState(line > 0, "Line number must be strictly positive: %s", line); + } + + private void validateFile() { + requireNonNull(inputFile, "Call onFile() first"); + } + + @Override + public NewCoverage conditions(int line, int conditions, int coveredConditions) { + validateFile(); + if (isExcluded()) { + return this; + } + validateLine(line); + + if (conditions > 0 && !conditionsByLine.containsKey(line)) { + totalConditions += conditions; + totalCoveredConditions += coveredConditions; + conditionsByLine.put(line, conditions); + coveredConditionsByLine.put(line, coveredConditions); + } + return this; + } + + public int coveredLines() { + return totalCoveredLines; + } + + public int linesToCover() { + return hitsByLine.size(); + } + + public int conditions() { + return totalConditions; + } + + public int coveredConditions() { + return totalCoveredConditions; + } + + public SortedMap hitsByLine() { + return Collections.unmodifiableSortedMap(hitsByLine); + } + + public SortedMap conditionsByLine() { + return Collections.unmodifiableSortedMap(conditionsByLine); + } + + public SortedMap coveredConditionsByLine() { + return Collections.unmodifiableSortedMap(coveredConditionsByLine); + } + + @Override + public void doSave() { + validateFile(); + if (!isExcluded()) { + storage.store(this); + } + } + + private boolean isExcluded() { + return ((DefaultInputFile) inputFile).isExcludedForCoverage(); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCpdTokens.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCpdTokens.java new file mode 100644 index 00000000000..d470ab7c6c1 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultCpdTokens.java @@ -0,0 +1,136 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import java.util.ArrayList; +import java.util.List; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.sensor.cpd.NewCpdTokens; +import org.sonar.api.batch.sensor.cpd.internal.TokensLine; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.scanner.fs.DefaultInputFile; + +import static java.util.Collections.unmodifiableList; +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkState; + +public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { + private static final Logger LOG = Loggers.get(DefaultCpdTokens.class); + private final List result = new ArrayList<>(); + private DefaultInputFile inputFile; + private int startLine = Integer.MIN_VALUE; + private int startIndex = 0; + private int currentIndex = 0; + private StringBuilder sb = new StringBuilder(); + private TextRange lastRange; + private boolean loggedTestCpdWarning = false; + + public DefaultCpdTokens(SensorStorage storage) { + super(storage); + } + + @Override + public DefaultCpdTokens onFile(InputFile inputFile) { + this.inputFile = (DefaultInputFile) requireNonNull(inputFile, "file can't be null"); + return this; + } + + public InputFile inputFile() { + return inputFile; + } + + @Override + public NewCpdTokens addToken(int startLine, int startLineOffset, int endLine, int endLineOffset, String image) { + checkInputFileNotNull(); + TextRange newRange; + try { + newRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to register token in file " + inputFile, e); + } + return addToken(newRange, image); + } + + @Override + public DefaultCpdTokens addToken(TextRange range, String image) { + requireNonNull(range, "Range should not be null"); + requireNonNull(image, "Image should not be null"); + checkInputFileNotNull(); + if (isExcludedForDuplication()) { + return this; + } + checkState(lastRange == null || lastRange.end().compareTo(range.start()) <= 0, + "Tokens of file %s should be provided in order.\nPrevious token: %s\nLast token: %s", inputFile, lastRange, range); + + int line = range.start().line(); + if (line != startLine) { + addNewTokensLine(result, startIndex, currentIndex, startLine, sb); + startIndex = currentIndex + 1; + startLine = line; + } + currentIndex++; + sb.append(image); + lastRange = range; + + return this; + } + + private boolean isExcludedForDuplication() { + if (inputFile.isExcludedForDuplication()) { + return true; + } + if (inputFile.type() == InputFile.Type.TEST) { + if (!loggedTestCpdWarning) { + LOG.warn("Duplication reported for '{}' will be ignored because it's a test file.", inputFile); + loggedTestCpdWarning = true; + } + return true; + } + return false; + } + + public List getTokenLines() { + return unmodifiableList(new ArrayList<>(result)); + } + + private static void addNewTokensLine(List result, int startUnit, int endUnit, int startLine, StringBuilder sb) { + if (sb.length() != 0) { + result.add(new TokensLine(startUnit, endUnit, startLine, sb.toString())); + sb.setLength(0); + } + } + + @Override + protected void doSave() { + checkState(inputFile != null, "Call onFile() first"); + if (isExcludedForDuplication()) { + return; + } + addNewTokensLine(result, startIndex, currentIndex, startLine, sb); + storage.store(this); + } + + private void checkInputFileNotNull() { + checkState(inputFile != null, "Call onFile() first"); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java index 3c09a40aceb..7141a3ec39d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java @@ -20,13 +20,14 @@ package org.sonar.scanner.sensor; import javax.annotation.Nullable; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.NewExternalIssue; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.issue.AbstractDefaultIssue; import static java.lang.String.format; import static java.util.Objects.requireNonNull; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java index 42129a26177..0f972804991 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java @@ -25,11 +25,10 @@ import java.util.Iterator; import java.util.List; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.highlighting.TypeOfText; -import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.DefaultInputFile; import static java.util.Objects.requireNonNull; import static org.sonar.api.utils.Preconditions.checkState; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java deleted file mode 100644 index 369d7314c2f..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.scanner.sensor; - -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.IssueLocation; -import org.sonar.api.batch.sensor.issue.NewIssue; -import org.sonar.api.rule.RuleKey; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultIssue extends AbstractDefaultIssue implements Issue, NewIssue { - private RuleKey ruleKey; - private Double gap; - private Severity overriddenSeverity; - - public DefaultIssue(DefaultInputProject project) { - this(project, null); - } - - public DefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) { - super(project, storage); - } - - public DefaultIssue forRule(RuleKey ruleKey) { - this.ruleKey = ruleKey; - return this; - } - - public RuleKey ruleKey() { - return this.ruleKey; - } - - @Override - public DefaultIssue gap(@Nullable Double gap) { - checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap)); - this.gap = gap; - return this; - } - - @Override - public DefaultIssue overrideSeverity(@Nullable Severity severity) { - this.overriddenSeverity = severity; - return this; - } - - @Override - public Severity overriddenSeverity() { - return this.overriddenSeverity; - } - - @Override - public Double gap() { - return this.gap; - } - - @Override - public IssueLocation primaryLocation() { - return primaryLocation; - } - - @Override - public void doSave() { - requireNonNull(this.ruleKey, "ruleKey is mandatory on issue"); - checkState(primaryLocation != null, "Primary location is mandatory on every issue"); - storage.store(this); - } - -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java deleted file mode 100644 index b08d093c261..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * 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 02110-1301, USA. - */ -package org.sonar.scanner.sensor; - -import javax.annotation.Nullable; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.issue.IssueLocation; -import org.sonar.api.batch.sensor.issue.NewIssueLocation; - -import static java.util.Objects.requireNonNull; -import static org.apache.commons.lang.StringUtils.abbreviate; -import static org.apache.commons.lang.StringUtils.trim; -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultIssueLocation implements NewIssueLocation, IssueLocation { - - private InputComponent component; - private TextRange textRange; - private String message; - - @Override - public DefaultIssueLocation on(InputComponent component) { - checkArgument(component != null, "Component can't be null"); - checkState(this.component == null, "on() already called"); - this.component = component; - return this; - } - - @Override - public DefaultIssueLocation at(TextRange location) { - checkState(this.component != null, "at() should be called after on()"); - checkState(this.component.isFile(), "at() should be called only for an InputFile."); - DefaultInputFile file = (DefaultInputFile) this.component; - file.validate(location); - this.textRange = location; - return this; - } - - @Override - public DefaultIssueLocation message(String message) { - requireNonNull(message, "Message can't be null"); - if (message.contains("\u0000")) { - throw new IllegalArgumentException(unsupportedCharacterError(message, component)); - } - this.message = abbreviate(trim(message), MESSAGE_MAX_SIZE); - return this; - } - - private static String unsupportedCharacterError(String message, @Nullable InputComponent component) { - String error = "Character \\u0000 is not supported in issue message '" + message + "'"; - if (component != null) { - error += ", on component: " + component.toString(); - } - return error; - } - - @Override - public InputComponent inputComponent() { - return this.component; - } - - @Override - public TextRange textRange() { - return textRange; - } - - @Override - public String message() { - return this.message; - } - -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java index 87d1aa18c1d..1ad7b83ce99 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java @@ -25,7 +25,6 @@ import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.measure.Metric; -import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.NewMeasure; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java index b9ca180c598..13b72b07f7b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java @@ -32,14 +32,11 @@ import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; +import org.sonar.api.batch.sensor.code.NewSignificantCode; +import org.sonar.api.batch.sensor.coverage.NewCoverage; +import org.sonar.api.batch.sensor.cpd.NewCpdTokens; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; @@ -47,7 +44,7 @@ import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; +import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import org.sonar.api.config.Configuration; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.KeyValueFormat; @@ -58,6 +55,9 @@ import org.sonar.core.util.CloseableIterator; import org.sonar.duplications.block.Block; import org.sonar.duplications.internal.pmd.PmdBlockChunker; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputComponent; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; import org.sonar.scanner.issue.IssuePublisher; import org.sonar.scanner.protocol.Constants; import org.sonar.scanner.protocol.output.FileStructure; @@ -284,7 +284,8 @@ public class DefaultSensorStorage implements SensorStorage { } @Override - public void store(DefaultSymbolTable symbolTable) { + public void store(NewSymbolTable newSymbolTable) { + DefaultSymbolTable symbolTable = (DefaultSymbolTable) newSymbolTable; ScannerReportWriter writer = reportPublisher.getWriter(); DefaultInputFile inputFile = (DefaultInputFile) symbolTable.inputFile(); if (shouldSkipStorage(inputFile)) { @@ -320,7 +321,8 @@ public class DefaultSensorStorage implements SensorStorage { } @Override - public void store(DefaultCoverage defaultCoverage) { + public void store(NewCoverage coverage) { + DefaultCoverage defaultCoverage = (DefaultCoverage) coverage; DefaultInputFile inputFile = (DefaultInputFile) defaultCoverage.inputFile(); inputFile.setPublished(true); @@ -363,16 +365,9 @@ public class DefaultSensorStorage implements SensorStorage { } } - private static void validatePositiveLine(Map m, String filePath) { - for (int l : m.keySet()) { - if (l <= 0) { - throw new IllegalStateException(String.format("Measure with line %d for file '%s' must be > 0", l, filePath)); - } - } - } - @Override - public void store(DefaultCpdTokens defaultCpdTokens) { + public void store(NewCpdTokens cpdTokens) { + DefaultCpdTokens defaultCpdTokens = (DefaultCpdTokens) cpdTokens; DefaultInputFile inputFile = (DefaultInputFile) defaultCpdTokens.inputFile(); inputFile.setPublished(true); PmdBlockChunker blockChunker = new PmdBlockChunker(getCpdBlockSize(inputFile.language())); @@ -411,7 +406,8 @@ public class DefaultSensorStorage implements SensorStorage { } @Override - public void store(DefaultSignificantCode significantCode) { + public void store(NewSignificantCode newSignificantCode) { + DefaultSignificantCode significantCode = (DefaultSignificantCode) newSignificantCode; ScannerReportWriter writer = reportPublisher.getWriter(); DefaultInputFile inputFile = (DefaultInputFile) significantCode.inputFile(); if (shouldSkipStorage(inputFile)) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSignificantCode.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSignificantCode.java new file mode 100644 index 00000000000..04ff5f16e0b --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSignificantCode.java @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import java.util.SortedMap; +import java.util.TreeMap; +import javax.annotation.Nullable; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.sensor.code.NewSignificantCode; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.utils.Preconditions; + +public class DefaultSignificantCode extends DefaultStorable implements NewSignificantCode { + private SortedMap significantCodePerLine = new TreeMap<>(); + private InputFile inputFile; + + public DefaultSignificantCode() { + super(); + } + + public DefaultSignificantCode(@Nullable SensorStorage storage) { + super(storage); + } + + @Override + public DefaultSignificantCode onFile(InputFile inputFile) { + this.inputFile = inputFile; + return this; + } + + @Override + public DefaultSignificantCode addRange(TextRange range) { + Preconditions.checkState(this.inputFile != null, "addRange() should be called after on()"); + + int line = range.start().line(); + + Preconditions.checkArgument(line == range.end().line(), "Ranges of significant code must be located in a single line"); + Preconditions.checkState(!significantCodePerLine.containsKey(line), "Significant code was already reported for line '%s'. Can only report once per line.", line); + + significantCodePerLine.put(line, range); + return this; + } + + @Override + protected void doSave() { + Preconditions.checkState(inputFile != null, "Call onFile() first"); + storage.store(this); + } + + public InputFile inputFile() { + return inputFile; + } + + public SortedMap significantCodePerLine() { + return significantCodePerLine; + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultStorable.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultStorable.java new file mode 100644 index 00000000000..23b989ca09d --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultStorable.java @@ -0,0 +1,57 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import javax.annotation.Nullable; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.api.batch.sensor.internal.SensorStorage; + +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkState; + +public abstract class DefaultStorable { + + protected final transient SensorStorage storage; + private transient boolean saved = false; + + public DefaultStorable() { + this.storage = null; + } + + public DefaultStorable(@Nullable SensorStorage storage) { + this.storage = storage; + } + + public final void save() { + requireNonNull(this.storage, "No persister on this object"); + checkState(!saved, "This object was already saved"); + doSave(); + this.saved = true; + } + + protected abstract void doSave(); + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSymbolTable.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSymbolTable.java new file mode 100644 index 00000000000..ca8b162f6a4 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSymbolTable.java @@ -0,0 +1,148 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.batch.sensor.symbol.NewSymbol; +import org.sonar.api.batch.sensor.symbol.NewSymbolTable; +import org.sonar.scanner.fs.DefaultInputFile; + +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkArgument; +import static org.sonar.api.utils.Preconditions.checkState; + +public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTable { + + private final Map> referencesBySymbol; + private DefaultInputFile inputFile; + + public DefaultSymbolTable(SensorStorage storage) { + super(storage); + referencesBySymbol = new LinkedHashMap<>(); + } + + public Map> getReferencesBySymbol() { + return referencesBySymbol; + } + + @Override + public DefaultSymbolTable onFile(InputFile inputFile) { + requireNonNull(inputFile, "file can't be null"); + this.inputFile = (DefaultInputFile) inputFile; + return this; + } + + public InputFile inputFile() { + return inputFile; + } + + @Override + public NewSymbol newSymbol(int startLine, int startLineOffset, int endLine, int endLineOffset) { + checkInputFileNotNull(); + TextRange declarationRange; + try { + declarationRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e); + } + return newSymbol(declarationRange); + } + + @Override + public NewSymbol newSymbol(int startOffset, int endOffset) { + checkInputFileNotNull(); + TextRange declarationRange; + try { + declarationRange = inputFile.newRange(startOffset, endOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e); + } + return newSymbol(declarationRange); + } + + @Override + public NewSymbol newSymbol(TextRange range) { + checkInputFileNotNull(); + TreeSet references = new TreeSet<>((o1, o2) -> o1.start().compareTo(o2.start())); + referencesBySymbol.put(range, references); + return new DefaultSymbol(inputFile, range, references); + } + + private static class DefaultSymbol implements NewSymbol { + + private final Collection references; + private final DefaultInputFile inputFile; + private final TextRange declaration; + + public DefaultSymbol(DefaultInputFile inputFile, TextRange declaration, Collection references) { + this.inputFile = inputFile; + this.declaration = declaration; + this.references = references; + } + + @Override + public NewSymbol newReference(int startOffset, int endOffset) { + TextRange referenceRange; + try { + referenceRange = inputFile.newRange(startOffset, endOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e); + } + return newReference(referenceRange); + } + + @Override + public NewSymbol newReference(int startLine, int startLineOffset, int endLine, int endLineOffset) { + TextRange referenceRange; + try { + referenceRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e); + } + return newReference(referenceRange); + } + + @Override + public NewSymbol newReference(TextRange range) { + requireNonNull(range, "Provided range is null"); + checkArgument(!declaration.overlap(range), "Overlapping symbol declaration and reference for symbol at %s", declaration); + references.add(range); + return this; + } + + } + + @Override + protected void doSave() { + checkInputFileNotNull(); + storage.store(this); + } + + private void checkInputFileNotNull() { + checkState(inputFile != null, "Call onFile() first"); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java index 45933fe1730..472537df959 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java @@ -25,9 +25,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; +import org.sonar.api.batch.sensor.code.NewSignificantCode; +import org.sonar.api.batch.sensor.coverage.NewCoverage; +import org.sonar.api.batch.sensor.cpd.NewCpdTokens; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; @@ -35,7 +35,7 @@ import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; +import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import static org.sonar.api.utils.Preconditions.checkArgument; @@ -88,13 +88,15 @@ class InMemorySensorStorage implements SensorStorage { } @Override - public void store(DefaultCoverage defaultCoverage) { + public void store(NewCoverage coverage) { + DefaultCoverage defaultCoverage = (DefaultCoverage) coverage; String fileKey = defaultCoverage.inputFile().key(); coverageByComponent.computeIfAbsent(fileKey, x -> new ArrayList<>()).add(defaultCoverage); } @Override - public void store(DefaultCpdTokens defaultCpdTokens) { + public void store(NewCpdTokens cpdTokens) { + DefaultCpdTokens defaultCpdTokens = (DefaultCpdTokens) cpdTokens; String fileKey = defaultCpdTokens.inputFile().key(); // Emulate duplicate storage check if (cpdTokensByComponent.containsKey(fileKey)) { @@ -104,7 +106,8 @@ class InMemorySensorStorage implements SensorStorage { } @Override - public void store(DefaultSymbolTable symbolTable) { + public void store(NewSymbolTable newSymbolTable) { + DefaultSymbolTable symbolTable = (DefaultSymbolTable) newSymbolTable; String fileKey = symbolTable.inputFile().key(); // Emulate duplicate storage check if (symbolsPerComponent.containsKey(fileKey)) { @@ -131,7 +134,8 @@ class InMemorySensorStorage implements SensorStorage { } @Override - public void store(DefaultSignificantCode significantCode) { + public void store(NewSignificantCode newSignificantCode) { + DefaultSignificantCode significantCode = (DefaultSignificantCode) newSignificantCode; String fileKey = significantCode.inputFile().key(); // Emulate duplicate storage check if (significantCodePerComponent.containsKey(fileKey)) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java index 76aa74d3bf0..1e8f6009f8d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorContext.java @@ -23,11 +23,11 @@ import javax.annotation.concurrent.ThreadSafe; import org.sonar.api.SonarRuntime; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.config.Configuration; import org.sonar.api.config.Settings; +import org.sonar.scanner.fs.DefaultInputProject; @ThreadSafe public class ModuleSensorContext extends ProjectSensorContext { @@ -35,7 +35,7 @@ public class ModuleSensorContext extends ProjectSensorContext { private final InputModule module; public ModuleSensorContext(DefaultInputProject project, InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, - SensorStorage sensorStorage, SonarRuntime sonarRuntime) { + SensorStorage sensorStorage, SonarRuntime sonarRuntime) { super(project, config, mutableSettings, fs, activeRules, sensorStorage, sonarRuntime); this.module = module; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorsExecutor.java index ba78bb1a758..ec3d21f6613 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorsExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ModuleSensorsExecutor.java @@ -23,13 +23,13 @@ import java.util.ArrayList; import java.util.Collection; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.util.logs.Profiler; import org.sonar.scanner.bootstrap.ScannerPluginRepository; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; public class ModuleSensorsExecutor { private static final Logger LOG = Loggers.get(ModuleSensorsExecutor.class); @@ -40,7 +40,7 @@ public class ModuleSensorsExecutor { private final boolean isRoot; public ModuleSensorsExecutor(ModuleSensorExtensionDictionnary selector, DefaultInputModule module, InputModuleHierarchy hierarchy, - SensorStrategy strategy, ScannerPluginRepository pluginRepo) { + SensorStrategy strategy, ScannerPluginRepository pluginRepo) { this.selector = selector; this.strategy = strategy; this.pluginRepo = pluginRepo; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java index 42e8559e83b..8a244510328 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java @@ -25,16 +25,11 @@ import org.sonar.api.SonarRuntime; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.code.NewSignificantCode; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; import org.sonar.api.batch.sensor.coverage.NewCoverage; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; import org.sonar.api.batch.sensor.cpd.NewCpdTokens; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; @@ -43,11 +38,13 @@ import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.rule.NewAdHocRule; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.config.Configuration; import org.sonar.api.config.Settings; import org.sonar.api.scanner.fs.InputProject; import org.sonar.api.utils.Version; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.issue.DefaultIssue; import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError; @ThreadSafe diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java index 785920220ff..e3ffc324ede 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java @@ -39,23 +39,15 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.code.NewSignificantCode; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; import org.sonar.api.batch.sensor.coverage.NewCoverage; -import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; import org.sonar.api.batch.sensor.cpd.NewCpdTokens; -import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens; import org.sonar.api.batch.sensor.cpd.internal.TokensLine; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.error.NewAnalysisError; -import org.sonar.api.batch.sensor.error.internal.DefaultAnalysisError; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.issue.ExternalIssue; @@ -67,7 +59,6 @@ import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.rule.AdHocRule; import org.sonar.api.batch.sensor.rule.NewAdHocRule; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.config.Configuration; import org.sonar.api.config.Settings; import org.sonar.api.config.internal.ConfigurationBridge; @@ -79,6 +70,11 @@ import org.sonar.api.scanner.fs.InputProject; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.issue.DefaultIssue; import org.sonar.scanner.rule.ActiveRulesBuilder; import static java.util.Collections.unmodifiableMap; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java index f549ec6216c..54bf590d758 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java @@ -24,11 +24,11 @@ import org.sonar.api.batch.Phase; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.batch.sensor.coverage.NewCoverage; import org.sonar.api.scanner.sensor.ProjectSensor; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.report.ReportPublisher; @Phase(name = Phase.Name.POST) diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java index d60f344a516..f6e59a75f9a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java @@ -25,12 +25,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.scanner.sensor.DefaultMeasure; import org.sonar.api.measures.CoreMetrics; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultMeasure; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; @@ -151,5 +151,4 @@ public class DefaultFileLinesContextTest { fileLineMeasures.setIntValue(HITS_METRIC_KEY, 1, 2); } - } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java index df848a56006..d625da5f8df 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/analysis/AnalysisTempFolderProviderTest.java @@ -20,13 +20,12 @@ package org.sonar.scanner.analysis; import java.io.File; -import java.io.IOException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.TempFolder; +import org.sonar.scanner.fs.DefaultInputProject; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -47,7 +46,7 @@ public class AnalysisTempFolderProviderTest { } @Test - public void createTempFolder() throws IOException { + public void createTempFolder() { File defaultDir = new File(temp.getRoot(), AnalysisTempFolderProvider.TMP_NAME); TempFolder tempFolder = tempFolderProvider.provide(project); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java index ecc155cd5e5..a649c5e9f24 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java @@ -36,9 +36,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentMatchers; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.util.CloseableIterator; @@ -47,6 +44,9 @@ import org.sonar.duplications.block.ByteArray; import org.sonar.duplications.index.CloneGroup; import org.sonar.duplications.index.ClonePart; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReport.Duplicate; import org.sonar.scanner.protocol.output.ScannerReport.Duplication; import org.sonar.scanner.protocol.output.ScannerReportReader; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java index 627114cce88..2e3e6d2898d 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java @@ -22,8 +22,8 @@ package org.sonar.scanner.cpd; import java.util.Optional; import org.junit.Before; import org.junit.Test; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.config.Configuration; +import org.sonar.scanner.fs.DefaultInputProject; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java index 3d7c7486034..f62bb729def 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java @@ -32,9 +32,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.duplications.block.Block; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java index 596a25f9275..3eaeb9997ad 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java @@ -27,12 +27,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.SensorContextTester; import static java.nio.charset.StandardCharsets.UTF_8; @@ -105,8 +105,8 @@ public class ExternalIssueImporterTest { ReportParser.TextRange input = new ReportParser.TextRange(); input.startLine = 1; input.startColumn = 4; - input.endLine= 2; - input.endColumn= 3; + input.endLine = 2; + input.endColumn = 3; runOn(newIssue(input)); @@ -124,8 +124,8 @@ public class ExternalIssueImporterTest { ReportParser.TextRange input = new ReportParser.TextRange(); input.startLine = 1; input.startColumn = null; - input.endLine= 2; - input.endColumn= null; + input.endLine = 2; + input.endColumn = null; runOn(newIssue(input)); @@ -145,8 +145,8 @@ public class ExternalIssueImporterTest { ReportParser.TextRange input = new ReportParser.TextRange(); input.startLine = 1; input.startColumn = 3; - input.endLine= 2; - input.endColumn= null; + input.endLine = 2; + input.endColumn = null; runOn(newIssue(input)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputDirTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputDirTest.java new file mode 100644 index 00000000000..1679a8df405 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputDirTest.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultInputDirTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void test() throws Exception { + File baseDir = temp.newFolder(); + DefaultInputDir inputDir = new DefaultInputDir("ABCDE", "src") + .setModuleBaseDir(baseDir.toPath()); + + assertThat(inputDir.key()).isEqualTo("ABCDE:src"); + assertThat(inputDir.file().getAbsolutePath()).isEqualTo(new File(baseDir, "src").getAbsolutePath()); + assertThat(inputDir.relativePath()).isEqualTo("src"); + assertThat(new File(inputDir.relativePath())).isRelative(); + assertThat(inputDir.absolutePath()).endsWith("src"); + assertThat(new File(inputDir.absolutePath())).isAbsolute(); + } + + @Test + public void testEqualsAndHashCode() throws Exception { + DefaultInputDir inputDir1 = new DefaultInputDir("ABCDE", "src"); + + DefaultInputDir inputDir2 = new DefaultInputDir("ABCDE", "src"); + + assertThat(inputDir1.equals(inputDir1)).isTrue(); + assertThat(inputDir1.equals(inputDir2)).isTrue(); + assertThat(inputDir1.equals("foo")).isFalse(); + + assertThat(inputDir1.hashCode()).isEqualTo(63545559); + + assertThat(inputDir1.toString()).contains("[moduleKey=ABCDE, relative=src, basedir=null"); + + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputFileTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputFileTest.java new file mode 100644 index 00000000000..6673977bfe4 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputFileTest.java @@ -0,0 +1,315 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.stream.Collectors; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.fs.internal.Metadata; +import org.sonar.api.batch.fs.internal.SensorStrategy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +public class DefaultInputFileTest { + + private static final String PROJECT_RELATIVE_PATH = "module1/src/Foo.php"; + private static final String MODULE_RELATIVE_PATH = "src/Foo.php"; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private DefaultIndexedFile indexedFile; + + private Path baseDir; + private SensorStrategy sensorStrategy; + + @Before + public void prepare() throws IOException { + baseDir = temp.newFolder().toPath(); + sensorStrategy = new SensorStrategy(); + indexedFile = new DefaultIndexedFile(baseDir.resolve(PROJECT_RELATIVE_PATH), "ABCDE", PROJECT_RELATIVE_PATH, MODULE_RELATIVE_PATH, InputFile.Type.TEST, "php", 0, + sensorStrategy); + } + + @Test + public void test() throws Exception { + + Metadata metadata = new Metadata(42, 42, "", new int[0], new int[0], 10); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> f.setMetadata(metadata)) + .setStatus(InputFile.Status.ADDED) + .setCharset(StandardCharsets.ISO_8859_1); + + assertThat(inputFile.absolutePath()).endsWith("Foo.php"); + assertThat(inputFile.filename()).isEqualTo("Foo.php"); + assertThat(inputFile.uri()).hasPath(baseDir.resolve(PROJECT_RELATIVE_PATH).toUri().getPath()); + assertThat(new File(inputFile.absolutePath())).isAbsolute(); + assertThat(inputFile.language()).isEqualTo("php"); + assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED); + assertThat(inputFile.type()).isEqualTo(InputFile.Type.TEST); + assertThat(inputFile.lines()).isEqualTo(42); + assertThat(inputFile.charset()).isEqualTo(StandardCharsets.ISO_8859_1); + + assertThat(inputFile.getModuleRelativePath()).isEqualTo(MODULE_RELATIVE_PATH); + assertThat(inputFile.getProjectRelativePath()).isEqualTo(PROJECT_RELATIVE_PATH); + + sensorStrategy.setGlobal(false); + assertThat(inputFile.relativePath()).isEqualTo(MODULE_RELATIVE_PATH); + assertThat(new File(inputFile.relativePath())).isRelative(); + sensorStrategy.setGlobal(true); + assertThat(inputFile.relativePath()).isEqualTo(PROJECT_RELATIVE_PATH); + assertThat(new File(inputFile.relativePath())).isRelative(); + } + + @Test + public void test_content() throws IOException { + Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH); + Files.createDirectories(testFile.getParent()); + String content = "test é string"; + Files.write(testFile, content.getBytes(StandardCharsets.ISO_8859_1)); + + assertThat(Files.readAllLines(testFile, StandardCharsets.ISO_8859_1).get(0)).hasSize(content.length()); + + Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10); + + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata)) + .setStatus(InputFile.Status.ADDED) + .setCharset(StandardCharsets.ISO_8859_1); + + assertThat(inputFile.contents()).isEqualTo(content); + try (InputStream inputStream = inputFile.inputStream()) { + String result = new BufferedReader(new InputStreamReader(inputStream, inputFile.charset())).lines().collect(Collectors.joining()); + assertThat(result).isEqualTo(content); + } + + } + + @Test + public void test_content_exclude_bom() throws IOException { + Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH); + Files.createDirectories(testFile.getParent()); + try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(testFile.toFile()), StandardCharsets.UTF_8))) { + out.write('\ufeff'); + } + String content = "test é string €"; + Files.write(testFile, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); + + assertThat(Files.readAllLines(testFile, StandardCharsets.UTF_8).get(0)).hasSize(content.length() + 1); + + Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10); + + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata)) + .setStatus(InputFile.Status.ADDED) + .setCharset(StandardCharsets.UTF_8); + + assertThat(inputFile.contents()).isEqualTo(content); + try (InputStream inputStream = inputFile.inputStream()) { + String result = new BufferedReader(new InputStreamReader(inputStream, inputFile.charset())).lines().collect(Collectors.joining()); + assertThat(result).isEqualTo(content); + } + + } + + @Test + public void test_equals_and_hashcode() throws Exception { + DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); + DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); + DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php", null), (f) -> mock(Metadata.class)); + + assertThat(f1).isEqualTo(f1); + assertThat(f1).isEqualTo(f1a); + assertThat(f1).isNotEqualTo(f2); + assertThat(f1.equals("foo")).isFalse(); + assertThat(f1.equals(null)).isFalse(); + + assertThat(f1.hashCode()).isEqualTo(f1.hashCode()); + assertThat(f1.hashCode()).isEqualTo(f1a.hashCode()); + } + + @Test + public void test_toString() throws Exception { + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class)); + assertThat(file.toString()).isEqualTo(MODULE_RELATIVE_PATH); + } + + @Test + public void checkValidPointer() { + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + assertThat(file.newPointer(1, 0).line()).isEqualTo(1); + assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0); + // Don't fail + file.newPointer(1, 9); + file.newPointer(2, 0); + file.newPointer(2, 5); + + try { + file.newPointer(0, 1); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("0 is not a valid line for a file"); + } + try { + file.newPointer(3, 1); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("3 is not a valid line for pointer. File src/Foo.php has 2 line(s)"); + } + try { + file.newPointer(1, -1); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("-1 is not a valid line offset for a file"); + } + try { + file.newPointer(1, 10); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1"); + } + } + + @Test + public void checkValidPointerUsingGlobalOffset() { + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {8, 15}, 16); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + assertThat(file.newPointer(0).line()).isEqualTo(1); + assertThat(file.newPointer(0).lineOffset()).isEqualTo(0); + + assertThat(file.newPointer(9).line()).isEqualTo(1); + // Ignore eol characters + assertThat(file.newPointer(9).lineOffset()).isEqualTo(8); + + assertThat(file.newPointer(10).line()).isEqualTo(2); + assertThat(file.newPointer(10).lineOffset()).isEqualTo(0); + + assertThat(file.newPointer(15).line()).isEqualTo(2); + assertThat(file.newPointer(15).lineOffset()).isEqualTo(5); + + assertThat(file.newPointer(16).line()).isEqualTo(2); + // Ignore eol characters + assertThat(file.newPointer(16).lineOffset()).isEqualTo(5); + + try { + file.newPointer(-1); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("-1 is not a valid offset for a file"); + } + + try { + file.newPointer(17); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("17 is not a valid offset for file src/Foo.php. Max offset is 16"); + } + } + + @Test + public void checkValidRange() { + Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde")); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + + assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isEqualTo(1); + // Don't fail + file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)); + file.newRange(file.newPointer(1, 0), file.newPointer(1, 9)); + file.newRange(file.newPointer(1, 0), file.newPointer(2, 0)); + assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 5))).isEqualTo(file.newRange(0, 15)); + + try { + file.newRange(file.newPointer(1, 0), file.newPointer(1, 0)); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("Start pointer [line=1, lineOffset=0] should be before end pointer [line=1, lineOffset=0]"); + } + try { + file.newRange(file.newPointer(1, 0), file.newPointer(1, 10)); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1"); + } + } + + @Test + public void selectLine() { + Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc")); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + + assertThat(file.selectLine(1).start().line()).isEqualTo(1); + assertThat(file.selectLine(1).start().lineOffset()).isEqualTo(0); + assertThat(file.selectLine(1).end().line()).isEqualTo(1); + assertThat(file.selectLine(1).end().lineOffset()).isEqualTo(9); + + // Don't fail when selecting empty line + assertThat(file.selectLine(3).start().line()).isEqualTo(3); + assertThat(file.selectLine(3).start().lineOffset()).isEqualTo(0); + assertThat(file.selectLine(3).end().line()).isEqualTo(3); + assertThat(file.selectLine(3).end().lineOffset()).isEqualTo(0); + + try { + file.selectLine(5); + fail(); + } catch (Exception e) { + assertThat(e).hasMessage("5 is not a valid line for pointer. File src/Foo.php has 4 line(s)"); + } + } + + @Test + public void checkValidRangeUsingGlobalOffset() { + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + TextRange newRange = file.newRange(10, 13); + assertThat(newRange.start().line()).isEqualTo(2); + assertThat(newRange.start().lineOffset()).isEqualTo(0); + assertThat(newRange.end().line()).isEqualTo(2); + assertThat(newRange.end().lineOffset()).isEqualTo(3); + } + + @Test + public void testRangeOverlap() { + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata)); + // Don't fail + assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)))).isTrue(); + assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isTrue(); + assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 1), file.newPointer(1, 2)))).isFalse(); + assertThat(file.newRange(file.newPointer(1, 2), file.newPointer(1, 3)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isFalse(); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputModuleTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputModuleTest.java new file mode 100644 index 00000000000..02570d36735 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputModuleTest.java @@ -0,0 +1,110 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultInputModuleTest { + + private static final String FILE_1 = "file1"; + private static final String TEST_1 = "test1"; + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void check_getters() throws IOException { + ProjectDefinition def = ProjectDefinition.create(); + def.setKey("moduleKey"); + File baseDir = temp.newFolder(); + Path src = baseDir.toPath().resolve(FILE_1); + Files.createFile(src); + Path test = baseDir.toPath().resolve(TEST_1); + Files.createFile(test); + def.setBaseDir(baseDir); + File workDir = temp.newFolder(); + def.setWorkDir(workDir); + def.setSources(FILE_1); + def.setTests(TEST_1); + DefaultInputModule module = new DefaultInputModule(def); + + assertThat(module.key()).isEqualTo("moduleKey"); + assertThat(module.definition()).isEqualTo(def); + assertThat(module.getBranch()).isNull(); + assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); + assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey"); + assertThat(module.getWorkDir()).isEqualTo(workDir.toPath()); + assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); + assertThat(module.getSourceDirsOrFiles().get()).containsExactlyInAnyOrder(src); + assertThat(module.getTestDirsOrFiles().get()).containsExactlyInAnyOrder(test); + assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); + + assertThat(module.isFile()).isFalse(); + } + + @Test + public void no_sources() throws IOException { + ProjectDefinition def = ProjectDefinition.create(); + def.setKey("moduleKey"); + File baseDir = temp.newFolder(); + Path src = baseDir.toPath().resolve(FILE_1); + Files.createFile(src); + Path test = baseDir.toPath().resolve(TEST_1); + Files.createFile(test); + def.setBaseDir(baseDir); + File workDir = temp.newFolder(); + def.setWorkDir(workDir); + DefaultInputModule module = new DefaultInputModule(def); + + assertThat(module.key()).isEqualTo("moduleKey"); + assertThat(module.definition()).isEqualTo(def); + assertThat(module.getBranch()).isNull(); + assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); + assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey"); + assertThat(module.getWorkDir()).isEqualTo(workDir.toPath()); + assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); + assertThat(module.getSourceDirsOrFiles()).isNotPresent(); + assertThat(module.getTestDirsOrFiles()).isNotPresent(); + assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset()); + + assertThat(module.isFile()).isFalse(); + } + + @Test + public void working_directory_should_be_hidden() throws IOException { + ProjectDefinition def = ProjectDefinition.create(); + File workDir = temp.newFolder(".sonar"); + def.setWorkDir(workDir); + File baseDir = temp.newFolder(); + def.setBaseDir(baseDir); + DefaultInputModule module = new DefaultInputModule(def); + assertThat(workDir.isHidden()).isTrue(); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputProjectTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputProjectTest.java new file mode 100644 index 00000000000..03248472335 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultInputProjectTest.java @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultInputProjectTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void testGetters() throws IOException { + ProjectDefinition def = ProjectDefinition.create(); + def.setKey("projectKey"); + def.setName("projectName"); + File baseDir = temp.newFolder(); + def.setBaseDir(baseDir); + def.setDescription("desc"); + File workDir = temp.newFolder(); + def.setWorkDir(workDir); + def.setSources("file1"); + def.setTests("test1"); + AbstractProjectOrModule project = new DefaultInputProject(def); + + assertThat(project.key()).isEqualTo("projectKey"); + assertThat(project.getName()).isEqualTo("projectName"); + assertThat(project.getOriginalName()).isEqualTo("projectName"); + assertThat(project.definition()).isEqualTo(def); + assertThat(project.getBranch()).isNull(); + assertThat(project.getBaseDir()).isEqualTo(baseDir.toPath()); + assertThat(project.getKeyWithBranch()).isEqualTo("projectKey"); + assertThat(project.getDescription()).isEqualTo("desc"); + assertThat(project.getWorkDir()).isEqualTo(workDir.toPath()); + assertThat(project.getEncoding()).isEqualTo(Charset.defaultCharset()); + + assertThat(project.properties()).hasSize(5); + + assertThat(project.isFile()).isFalse(); + } + + @Test + public void testEncoding() throws IOException { + ProjectDefinition def = ProjectDefinition.create(); + def.setKey("projectKey"); + def.setName("projectName"); + File baseDir = temp.newFolder(); + def.setBaseDir(baseDir); + def.setProjectVersion("version"); + def.setDescription("desc"); + File workDir = temp.newFolder(); + def.setWorkDir(workDir); + def.setSources("file1"); + def.setProperty("sonar.sourceEncoding", "UTF-16"); + AbstractProjectOrModule project = new DefaultInputProject(def); + + assertThat(project.getEncoding()).isEqualTo(StandardCharsets.UTF_16); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java index 826edf9d086..c2665324ebc 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java @@ -23,7 +23,6 @@ import java.io.File; import java.io.FileInputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - import javax.annotation.Nullable; import org.apache.commons.codec.binary.Hex; import org.apache.commons.io.FileUtils; @@ -31,7 +30,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.Metadata; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; @@ -223,7 +221,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, " foo\nb ar\r\nbaz \t", StandardCharsets.UTF_8, true); - org.sonar.api.batch.fs.internal.DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) + DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) .setModuleBaseDir(tempFile.getParentFile().toPath()) .setCharset(StandardCharsets.UTF_8) .build(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/TestInputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/TestInputFileBuilderTest.java new file mode 100644 index 00000000000..2d83007ff13 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/TestInputFileBuilderTest.java @@ -0,0 +1,72 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.fs; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import org.apache.commons.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile.Status; +import org.sonar.api.batch.fs.InputFile.Type; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestInputFileBuilderTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void setContent() throws IOException { + DefaultInputFile file = TestInputFileBuilder.create("module", "invalidPath") + .setContents("my content") + .setCharset(StandardCharsets.UTF_8) + .build(); + assertThat(file.contents()).isEqualTo("my content"); + assertThat(IOUtils.toString(file.inputStream())).isEqualTo("my content"); + } + + @Test + public void testGetters() { + DefaultInputFile file = TestInputFileBuilder.create("module", new File("baseDir"), new File("baseDir", "path")) + .setStatus(Status.SAME) + .setType(Type.MAIN) + .build(); + + assertThat(file.type()).isEqualTo(Type.MAIN); + assertThat(file.status()).isEqualTo(Status.SAME); + assertThat(file.isPublished()).isTrue(); + assertThat(file.type()).isEqualTo(Type.MAIN); + assertThat(file.relativePath()).isEqualTo("path"); + assertThat(file.absolutePath()).isEqualTo("baseDir/path"); + + } + + @Test + public void testCreateInputModule() throws IOException { + File baseDir = temp.newFolder(); + AbstractProjectOrModule module = TestInputFileBuilder.newDefaultInputModule("key", baseDir); + assertThat(module.key()).isEqualTo("key"); + assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath()); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java index b90e6a19dd4..ccd628b0a17 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java @@ -27,8 +27,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java index c9f44cd5b8f..40ac5200719 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java @@ -27,11 +27,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.test.MutableTestCase; import org.sonar.api.test.MutableTestPlan; import org.sonar.api.utils.MessageException; import org.sonar.scanner.deprecated.test.TestPlanBuilder; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.sensor.SensorContextTester; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java index b506b78f074..5250e1aa5d1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/DefaultFilterableIssueTest.java @@ -23,8 +23,8 @@ import java.util.Date; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.ProjectInfo; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.protocol.Constants.Severity; import org.sonar.scanner.protocol.output.ScannerReport.Issue; import org.sonar.scanner.protocol.output.ScannerReport.TextRange; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java index 50c247f5b51..881a3629a04 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java @@ -32,20 +32,18 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.scanner.fs.TestInputFileBuilder; -import org.sonar.scanner.rule.ActiveRulesBuilder; -import org.sonar.scanner.rule.NewActiveRule; -import org.sonar.scanner.rule.RulesBuilder; -import org.sonar.scanner.sensor.DefaultExternalIssue; -import org.sonar.scanner.sensor.DefaultIssue; -import org.sonar.scanner.sensor.DefaultIssueLocation; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.report.ReportPublisher; +import org.sonar.scanner.rule.ActiveRulesBuilder; +import org.sonar.scanner.rule.NewActiveRule; +import org.sonar.scanner.rule.RulesBuilder; +import org.sonar.scanner.sensor.DefaultExternalIssue; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java index 8a9df4a744a..d5a99ff296f 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java @@ -21,10 +21,10 @@ package org.sonar.scanner.issue.ignore; import org.junit.Before; import org.junit.Test; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.rule.RuleKey; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.api.utils.WildcardPattern; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.issue.DefaultFilterableIssue; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java index 6a597ef85b3..94cebe5f0bd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java @@ -27,9 +27,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.notifications.AnalysisWarnings; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.scanner.issue.ignore.pattern.IssuePattern; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java index 07c39d82113..fb4165825e7 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java @@ -34,7 +34,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.FileMetadata; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java index 16154f5ff0c..40695d3529e 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java @@ -30,7 +30,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.FileMetadata; import org.sonar.scanner.mediumtest.AnalysisResult; import org.sonar.scanner.mediumtest.ScannerMediumTester; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java index 627e285af3a..d6f141aa0f8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java @@ -32,8 +32,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.SonarEdition; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.mediumtest.AnalysisResult; import org.sonar.scanner.mediumtest.ScannerMediumTester; import org.sonar.xoo.XooPlugin; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java index 6ae40643542..e64c47b7edb 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java @@ -36,12 +36,12 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.SonarEdition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.PathUtils; import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.mediumtest.AnalysisResult; import org.sonar.scanner.mediumtest.ScannerMediumTester; import org.sonar.xoo.XooPlugin; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java index fe18fdb725f..6bfffc32384 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.ModuleConfiguration; import org.sonar.scanner.scan.filesystem.ModuleCoverageAndDuplicationExclusions; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java index bce232d44f0..d48402ea9ed 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java @@ -26,15 +26,15 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.SensorStrategy; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.sensor.Sensor; -import org.sonar.scanner.sensor.ModuleSensorExtensionDictionnary; import org.sonar.scanner.bootstrap.ScannerPluginRepository; -import org.sonar.scanner.sensor.ModuleSensorsExecutor; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.ModuleSensorExtensionDictionnary; import org.sonar.scanner.sensor.ModuleSensorWrapper; +import org.sonar.scanner.sensor.ModuleSensorsExecutor; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java index b041c6badc8..a225093a650 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.ProjectConfiguration; import org.sonar.scanner.scan.filesystem.ProjectCoverageAndDuplicationExclusions; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java index 22c8528301f..f795cf97408 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/AnalysisContextReportPublisherTest.java @@ -32,14 +32,14 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.GlobalServerSettings; import org.sonar.scanner.bootstrap.ScannerPluginRepository; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.ProjectServerSettings; import org.sonar.scanner.scan.filesystem.InputComponentStore; @@ -147,6 +147,66 @@ public class AnalysisContextReportPublisherTest { " - sonar.projectKey=foo"); } + @Test + public void shouldNotDumpSQPropsInSystemProps() throws Exception { + logTester.setLevel(LoggerLevel.DEBUG); + ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); + Properties props = new Properties(); + props.setProperty(COM_FOO, "bar"); + props.setProperty(SONAR_SKIP, "true"); + when(system2.properties()).thenReturn(props); + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo") + .setProperty(COM_FOO, "bar") + .setProperty(SONAR_SKIP, "true")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); + + publisher.init(writer); + + List lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(lines).containsExactly("Environment variables:", + "System properties:", + " - com.foo=bar", + "SonarQube plugins:", + "Global server settings:", + "Project server settings:", + "Project scanner properties:", + " - sonar.projectKey=foo", + " - sonar.skip=true"); + } + + @Test + public void shouldNotDumpEnvTwice() throws Exception { + logTester.setLevel(LoggerLevel.DEBUG); + ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); + + Map env = new HashMap<>(); + env.put(FOO, "BAR"); + env.put(BIZ, "BAZ"); + when(system2.envVariables()).thenReturn(env); + DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create() + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder()) + .setProperty("sonar.projectKey", "foo") + .setProperty("env." + FOO, "BAR")); + when(store.allModules()).thenReturn(singletonList(rootModule)); + when(hierarchy.root()).thenReturn(rootModule); + publisher.init(writer); + + String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(content).containsOnlyOnce(FOO); + assertThat(content).containsOnlyOnce(BIZ); + assertThat(content).containsSubsequence(BIZ, FOO); + + content = FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8); + assertThat(content).containsOnlyOnce(FOO); + assertThat(content).containsOnlyOnce(BIZ); + assertThat(content).doesNotContain("env." + FOO); + } + @Test public void shouldNotDumpSensitiveModuleProperties() throws Exception { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); @@ -187,7 +247,6 @@ public class AnalysisContextReportPublisherTest { assertThat(writer.getFileStructure().analysisLog()).exists(); - assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8)).containsSubsequence( "sonar.aVeryLongProp=" + StringUtils.repeat("abcde", 199) + "ab...", "sonar.projectBaseDir=" + baseDir.toString(), diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java index 4d4a3476553..18ce32fab0a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java @@ -30,11 +30,11 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java index 36134513be9..b812747c692 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java @@ -31,11 +31,11 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.utils.DateUtils; import org.sonar.scanner.ProjectInfo; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java index 7a66973ec20..3eb07e5e945 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java @@ -39,14 +39,14 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.scanner.ProjectInfo; import org.sonar.scanner.bootstrap.ScannerPlugin; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.cpd.CpdSettings; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; @@ -145,9 +145,9 @@ public class MetadataPublisherTest { .setRulesUpdatedAt(date.getTime()) .build())); assertThat(metadata.getPluginsByKey()).containsOnly(entry("java", org.sonar.scanner.protocol.output.ScannerReport.Metadata.Plugin.newBuilder() - .setKey("java") - .setUpdatedAt(12345) - .build()), + .setKey("java") + .setUpdatedAt(12345) + .build()), entry("php", org.sonar.scanner.protocol.output.ScannerReport.Metadata.Plugin.newBuilder() .setKey("php") .setUpdatedAt(45678) diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java index 4c3699326a0..3c7893722ad 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java @@ -34,8 +34,6 @@ import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.platform.Server; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; @@ -43,6 +41,8 @@ import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.scan.ScanProperties; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonarqube.ws.Ce; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java index 5f6054f81c9..835e423f9ee 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java @@ -27,8 +27,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java index 26bb3a6e1aa..f2888be4c65 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoaderTest.java @@ -29,10 +29,10 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.utils.MessageException; import org.sonar.scanner.WsTestUtil; import org.sonar.scanner.bootstrap.ScannerWsClient; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonarqube.ws.Batch.WsProjectResponse; import org.sonarqube.ws.client.HttpException; import org.sonarqube.ws.client.WsRequest; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java index 87da83b2cd5..aadf37e6a75 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultInputModuleHierarchyTest.java @@ -28,7 +28,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputModule; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java index 8c09090dff4..3c4cb6ffb15 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java @@ -22,8 +22,7 @@ package org.sonar.scanner.scan; import java.util.Arrays; import org.junit.Test; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.scanner.fs.DefaultInputModule; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; @@ -36,7 +35,7 @@ public class ModuleIndexerTest { private DefaultInputModuleHierarchy moduleHierarchy; private InputComponentStore componentStore; - public void createIndexer(DefaultInputProject rootProject) { + public void createIndexer() { componentStore = new InputComponentStore(mock(BranchConfiguration.class)); moduleHierarchy = mock(DefaultInputModuleHierarchy.class); indexer = new ModuleIndexer(componentStore, moduleHierarchy); @@ -69,7 +68,7 @@ public class ModuleIndexerTest { when(mod2.definition()).thenReturn(def); when(mod3.definition()).thenReturn(def); - createIndexer(mock(DefaultInputProject.class)); + createIndexer(); when(moduleHierarchy.root()).thenReturn(root); when(moduleHierarchy.children(root)).thenReturn(Arrays.asList(mod1, mod2, mod3)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java index 4a1b0b5a4a2..12f20933bdb 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectLockTest.java @@ -29,7 +29,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.scanner.fs.DefaultInputProject; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java index 49f1804c550..a2622ae4cbd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ScanPropertiesTest.java @@ -27,9 +27,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.DefaultInputProject; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java index b4497362413..ba5aedb451f 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/WorkDirectoriesInitializerTest.java @@ -26,8 +26,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.InputModuleHierarchy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java index 04490bd02e4..e9365140bd2 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java @@ -32,9 +32,9 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputPath; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java index 9bd732b9287..0682ccaf345 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java @@ -32,9 +32,9 @@ import org.junit.rules.TemporaryFolder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.PathUtils; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.FileMetadata; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java index 2ead8234b68..c624be2c6f1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java @@ -26,8 +26,8 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.SensorStrategy; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.branch.BranchConfiguration; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java index 7e6540f69f1..9f613f48ed7 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java @@ -30,7 +30,7 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultIndexedFile; +import org.sonar.scanner.fs.DefaultIndexedFile; import org.sonar.api.config.internal.MapSettings; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java index ccd56feef74..167b4e33a9c 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java @@ -26,7 +26,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputFile; import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.repository.FileData; import org.sonar.scanner.repository.ProjectRepositoriesSupplier; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java index 4b81bb45f5e..681433767ff 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java @@ -28,9 +28,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; +import org.sonar.scanner.fs.DefaultInputProject; +import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.scan.branch.BranchConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java index a5ca3a8d26e..a8f6ec82940 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java @@ -32,13 +32,13 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.sonar.api.CoreProperties; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.config.Configuration; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.LogTester; import org.sonar.core.config.ScannerProperties; +import org.sonar.scanner.fs.InputModuleHierarchy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.any; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java index ff6ca35bca7..77d29126e44 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmRevisionImplTest.java @@ -24,9 +24,9 @@ import java.util.Map; import java.util.Optional; import javax.annotation.Nullable; import org.junit.Test; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.scanner.bootstrap.RawScannerProperties; import org.sonar.scanner.ci.CiConfiguration; +import org.sonar.scanner.fs.InputModuleHierarchy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -60,7 +60,7 @@ public class ScmRevisionImplTest { public void ignore_failure_if_scm_does_not_support_revisions() { CiConfiguration ciConfiguration = mock(CiConfiguration.class); when(ciConfiguration.getScmRevision()).thenReturn(Optional.empty()); - Map scannerConfiguration = new HashMap<>(); + Map scannerConfiguration = new HashMap<>(); ScmConfiguration scmConfiguration = mock(ScmConfiguration.class, RETURNS_DEEP_STUBS); when(scmConfiguration.provider().revisionId(any())).thenThrow(new UnsupportedOperationException("BOOM")); InputModuleHierarchy moduleHierarchy = mock(InputModuleHierarchy.class, RETURNS_DEEP_STUBS); @@ -73,7 +73,7 @@ public class ScmRevisionImplTest { private Optional testGet(@Nullable String cliValue, @Nullable String ciValue, @Nullable String scmValue) { CiConfiguration ciConfiguration = mock(CiConfiguration.class); when(ciConfiguration.getScmRevision()).thenReturn(Optional.ofNullable(ciValue)); - Map scannerConfiguration = new HashMap<>(); + Map scannerConfiguration = new HashMap<>(); scannerConfiguration.put("sonar.scm.revision", cliValue); ScmConfiguration scmConfiguration = mock(ScmConfiguration.class, RETURNS_DEEP_STUBS); when(scmConfiguration.provider().revisionId(any())).thenReturn(scmValue); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAnalysisErrorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAnalysisErrorTest.java new file mode 100644 index 00000000000..afff924afdf --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAnalysisErrorTest.java @@ -0,0 +1,114 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextPointer; +import org.sonar.api.batch.sensor.error.NewAnalysisError; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +public class DefaultAnalysisErrorTest { + private InputFile inputFile; + private SensorStorage storage; + private TextPointer textPointer; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() { + inputFile = new TestInputFileBuilder("module1", "src/File.java").build(); + textPointer = new DefaultTextPointer(5, 2); + storage = mock(SensorStorage.class); + } + + @Test + public void test_analysis_error() { + DefaultAnalysisError analysisError = new DefaultAnalysisError(storage); + analysisError.onFile(inputFile) + .at(textPointer) + .message("msg"); + + assertThat(analysisError.location()).isEqualTo(textPointer); + assertThat(analysisError.message()).isEqualTo("msg"); + assertThat(analysisError.inputFile()).isEqualTo(inputFile); + } + + @Test + public void test_save() { + DefaultAnalysisError analysisError = new DefaultAnalysisError(storage); + analysisError.onFile(inputFile).save(); + + verify(storage).store(analysisError); + verifyNoMoreInteractions(storage); + } + + @Test + public void test_no_storage() { + exception.expect(NullPointerException.class); + DefaultAnalysisError analysisError = new DefaultAnalysisError(); + analysisError.onFile(inputFile).save(); + } + + @Test + public void test_validation() { + try { + new DefaultAnalysisError(storage).onFile(null); + fail("Expected exception"); + } catch (IllegalArgumentException e) { + // expected + } + + NewAnalysisError error = new DefaultAnalysisError(storage).onFile(inputFile); + try { + error.onFile(inputFile); + fail("Expected exception"); + } catch (IllegalStateException e) { + // expected + } + + error = new DefaultAnalysisError(storage).at(textPointer); + try { + error.at(textPointer); + fail("Expected exception"); + } catch (IllegalStateException e) { + // expected + } + + try { + new DefaultAnalysisError(storage).save(); + fail("Expected exception"); + } catch (NullPointerException e) { + // expected + } + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultCpdTokensTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultCpdTokensTest.java new file mode 100644 index 00000000000..7a559792723 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultCpdTokensTest.java @@ -0,0 +1,170 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import org.junit.Test; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +public class DefaultCpdTokensTest { + private final SensorStorage sensorStorage = mock(SensorStorage.class); + + private final DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .setLines(2) + .setOriginalLineStartOffsets(new int[] {0, 50}) + .setOriginalLineEndOffsets(new int[] {49, 100}) + .setLastValidOffset(101) + .build(); + + @Test + public void save_no_tokens() { + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(inputFile); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.inputFile()).isEqualTo(inputFile); + } + + @Test + public void save_one_token() { + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(inputFile) + .addToken(inputFile.newRange(1, 2, 1, 5), "foo"); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.getTokenLines()).extracting("value", "startLine", "hashCode", "startUnit", "endUnit").containsExactly(tuple("foo", 1, "foo".hashCode(), 1, 1)); + } + + @Test + public void handle_exclusions() { + inputFile.setExcludedForDuplication(true); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(inputFile) + .addToken(inputFile.newRange(1, 2, 1, 5), "foo"); + + tokens.save(); + + verifyZeroInteractions(sensorStorage); + + assertThat(tokens.getTokenLines()).isEmpty(); + } + + @Test + public void dont_save_for_test_files() { + DefaultInputFile testInputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .setLines(2) + .setOriginalLineStartOffsets(new int[] {0, 50}) + .setOriginalLineEndOffsets(new int[] {49, 100}) + .setLastValidOffset(101) + .setType(InputFile.Type.TEST) + .build(); + + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(testInputFile) + .addToken(testInputFile.newRange(1, 2, 1, 5), "foo"); + + tokens.save(); + verifyZeroInteractions(sensorStorage); + assertThat(tokens.getTokenLines()).isEmpty(); + } + + @Test + public void save_many_tokens() { + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(inputFile) + .addToken(inputFile.newRange(1, 2, 1, 5), "foo") + .addToken(inputFile.newRange(1, 6, 1, 10), "bar") + .addToken(inputFile.newRange(1, 20, 1, 25), "biz") + .addToken(inputFile.newRange(2, 1, 2, 10), "next"); + + tokens.save(); + + verify(sensorStorage).store(tokens); + + assertThat(tokens.getTokenLines()) + .extracting("value", "startLine", "hashCode", "startUnit", "endUnit") + .containsExactly( + tuple("foobarbiz", 1, "foobarbiz".hashCode(), 1, 3), + tuple("next", 2, "next".hashCode(), 4, 4)); + } + + @Test + public void basic_validation() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage); + try { + tokens.save(); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Call onFile() first"); + } + try { + tokens.addToken(inputFile.newRange(1, 2, 1, 5), "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Call onFile() first"); + } + try { + tokens.addToken(null, "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Range should not be null"); + } + try { + tokens.addToken(inputFile.newRange(1, 2, 1, 5), null); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Image should not be null"); + } + } + + @Test + public void validate_tokens_order() { + SensorStorage sensorStorage = mock(SensorStorage.class); + DefaultCpdTokens tokens = new DefaultCpdTokens(sensorStorage) + .onFile(inputFile) + .addToken(inputFile.newRange(1, 6, 1, 10), "bar"); + + try { + tokens.addToken(inputFile.newRange(1, 2, 1, 5), "foo"); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e).hasMessage("Tokens of file src/Foo.java should be provided in order.\n" + + "Previous token: Range[from [line=1, lineOffset=6] to [line=1, lineOffset=10]]\n" + + "Last token: Range[from [line=1, lineOffset=2] to [line=1, lineOffset=5]]"); + } + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java index ca91e301cc8..0081480f466 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java @@ -27,13 +27,14 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.issue.DefaultIssueLocation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java index 712703976c2..f70f92dd982 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java @@ -26,9 +26,9 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextRange; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.DefaultTextRange; import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java index 96bd5936b6b..f869f6f17f0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputFile; import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.issue.DefaultIssueLocation; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.rules.ExpectedException.none; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java index 0ab0b99655b..c6659dbc8a1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java @@ -26,14 +26,16 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.rule.RuleKey; +import org.sonar.scanner.fs.DefaultInputDir; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.issue.DefaultIssue; +import org.sonar.scanner.issue.DefaultIssueLocation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java index 43844837e1e..43de69f19d0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java @@ -25,10 +25,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.measures.CoreMetrics; +import org.sonar.scanner.fs.AbstractProjectOrModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java index d0aca624090..d95d44a69ed 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java @@ -29,21 +29,21 @@ import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.measures.CoreMetrics; import org.sonar.core.metric.ScannerMetrics; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.DefaultInputDir; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.issue.DefaultIssue; +import org.sonar.scanner.issue.DefaultIssueLocation; import org.sonar.scanner.issue.IssuePublisher; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSignificantCodeTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSignificantCodeTest.java new file mode 100644 index 00000000000..73a7f1c4299 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSignificantCodeTest.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultSignificantCodeTest { + private SensorStorage sensorStorage = mock(SensorStorage.class); + private DefaultSignificantCode underTest = new DefaultSignificantCode(sensorStorage); + private InputFile inputFile = TestInputFileBuilder.create("module", "file1.xoo") + .setContents("this is\na file\n with some code") + .build(); + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void should_save_ranges() { + underTest.onFile(inputFile) + .addRange(inputFile.selectLine(1)) + .save(); + verify(sensorStorage).store(underTest); + } + + @Test + public void fail_if_save_without_file() { + exception.expect(IllegalStateException.class); + exception.expectMessage("Call onFile() first"); + underTest.save(); + } + + @Test + public void fail_if_add_range_to_same_line_twice() { + underTest.onFile(inputFile); + underTest.addRange(inputFile.selectLine(1)); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Significant code was already reported for line '1'."); + underTest.addRange(inputFile.selectLine(1)); + } + + @Test + public void fail_if_range_includes_many_lines() { + underTest.onFile(inputFile); + + exception.expect(IllegalArgumentException.class); + exception.expectMessage("Ranges of significant code must be located in a single line"); + underTest.addRange(inputFile.newRange(1, 1, 2, 1)); + } + + @Test + public void fail_if_add_range_before_setting_file() { + exception.expect(IllegalStateException.class); + exception.expectMessage("addRange() should be called after on()"); + underTest.addRange(inputFile.selectLine(1)); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSymbolTableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSymbolTableTest.java new file mode 100644 index 00000000000..3339e1d2bed --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSymbolTableTest.java @@ -0,0 +1,73 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * 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 02110-1301, USA. + */ +package org.sonar.scanner.sensor; + +import java.util.Map; +import java.util.Set; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSymbolTable; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class DefaultSymbolTableTest { + + private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") + .setLines(2) + .setOriginalLineStartOffsets(new int[] {0, 50}) + .setOriginalLineEndOffsets(new int[] {49, 100}) + .setLastValidOffset(101) + .build(); + + private Map> referencesPerSymbol; + + @Rule + public ExpectedException throwable = ExpectedException.none(); + + @Before + public void setUpSampleSymbols() { + + DefaultSymbolTable symbolTableBuilder = new DefaultSymbolTable(mock(SensorStorage.class)) + .onFile(INPUT_FILE); + symbolTableBuilder + .newSymbol(0, 10) + .newReference(12, 15) + .newReference(2, 10, 2, 15); + + symbolTableBuilder.newSymbol(1, 12, 1, 15).newReference(52, 55); + + symbolTableBuilder.save(); + + referencesPerSymbol = symbolTableBuilder.getReferencesBySymbol(); + } + + @Test + public void should_register_symbols() { + assertThat(referencesPerSymbol).hasSize(2); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java index 01d3b6046e8..668a050119a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java @@ -28,7 +28,6 @@ import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.internal.SensorStorage; @@ -37,6 +36,7 @@ import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.Version; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputProject; import org.sonar.scanner.rule.ActiveRulesBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java index cf1d452f76a..24e93796c31 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java @@ -28,11 +28,6 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.scanner.fs.DefaultFileSystem; -import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.error.AnalysisError; @@ -46,6 +41,11 @@ import org.sonar.api.config.internal.MapSettings; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; +import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.DefaultInputFile; +import org.sonar.scanner.fs.DefaultInputModule; +import org.sonar.scanner.fs.DefaultTextPointer; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.rule.ActiveRulesBuilder; import org.sonar.scanner.rule.NewActiveRule;