diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2017-01-11 17:49:34 +0100 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2017-01-27 16:26:30 +0100 |
commit | 7b3024ee784a83f274a8bcc76475cf2a91219283 (patch) | |
tree | cf3256f9164e5df584b41b244396c3d2f617cf7e /sonar-plugin-api | |
parent | 6840dc54995084e8410b5b6903353a94034cad34 (diff) | |
download | sonarqube-7b3024ee784a83f274a8bcc76475cf2a91219283.tar.gz sonarqube-7b3024ee784a83f274a8bcc76475cf2a91219283.zip |
SONAR-8622 Lazily generate metadata for input files
Diffstat (limited to 'sonar-plugin-api')
40 files changed, 799 insertions, 458 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java index 4007b74d145..045b2fd5319 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java @@ -29,6 +29,6 @@ public interface FilePredicate { /** * Test if provided file is valid for this predicate */ - boolean apply(InputFile inputFile); + boolean apply(IndexedFile inputFile); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java index 33b22cb4402..72614539fad 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java @@ -108,8 +108,6 @@ public interface FilePredicates { FilePredicate hasLanguages(String... languages); - FilePredicate hasStatus(InputFile.Status status); - FilePredicate hasType(InputFile.Type type); FilePredicate not(FilePredicate p); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java new file mode 100644 index 00000000000..89381593298 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/IndexedFile.java @@ -0,0 +1,100 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.annotation.CheckForNull; + +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputPath; + +/** + * @since 6.3 + */ +public interface IndexedFile extends InputPath { + /** + * Path relative to module base directory. Path is unique and identifies file + * within given <code>{@link FileSystem}</code>. File separator is the forward + * slash ('/'), even on Microsoft Windows. + * <br> + * Returns <code>src/main/java/com/Foo.java</code> if module base dir is + * <code>/path/to/module</code> and if file is + * <code>/path/to/module/src/main/java/com/Foo.java</code>. + * <br> + * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo'). + */ + @Override + String relativePath(); + + /** + * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows. + * <br> + * This is not canonical path. Symbolic links are not resolved. For example if /project/src links + * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use + * {@code file().getCanonicalPath()} to resolve symbolic link. + */ + @Override + String absolutePath(); + + /** + * The underlying absolute {@link java.io.File}. It should not be used to read the file in the filesystem. + * @see #contents() + * @see #inputStream() + */ + @Override + File file(); + + /** + * The underlying absolute {@link Path}. + * It should not be used to read the file in the filesystem. + * @see #contents() + * @see #inputStream() + * @since 5.1 + */ + @Override + Path path(); + + /** + * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file. + */ + @CheckForNull + String language(); + + /** + * Does it contain main or test code ? + */ + InputFile.Type type(); + + /** + * Creates a stream of the file's contents. Depending on the runtime context, the source might be a file in a physical or virtual filesystem. + * Typically, it won't be buffered. <b>The stream must be closed by the caller</b>. + * Note that there is a default implementation. + * @since 6.2 + */ + default InputStream inputStream() throws IOException { + return Files.newInputStream(path()); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java index 923575d7fee..299fc006406 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java @@ -41,7 +41,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; * * @since 4.2 */ -public interface InputFile extends InputPath { +public interface InputFile extends IndexedFile, InputPath { enum Type { MAIN, TEST @@ -100,11 +100,13 @@ public interface InputFile extends InputPath { * Language, for example "java" or "php". Can be null if indexation of all files is enabled and no language claims to support the file. */ @CheckForNull + @Override String language(); /** * Does it contain main or test code ? */ + @Override Type type(); /** @@ -113,6 +115,7 @@ public interface InputFile extends InputPath { * Note that there is a default implementation. * @since 6.2 */ + @Override default InputStream inputStream() throws IOException { return Files.newInputStream(path()); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java index 740e8dd68cc..49f0654a797 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFileFilter.java @@ -28,6 +28,7 @@ import org.sonar.api.batch.ScannerSide; */ @ScannerSide @ExtensionPoint +@FunctionalInterface public interface InputFileFilter { boolean accept(InputFile f); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java index 2e5362c1943..b6e549d28ad 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbsolutePathPredicate.java @@ -20,6 +20,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.PathUtils; @@ -43,7 +44,7 @@ class AbsolutePathPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return path.equals(f.absolutePath()); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java index e7afc7600a3..e000fd1a1b6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java @@ -22,6 +22,7 @@ package org.sonar.api.batch.fs.internal; import com.google.common.annotations.VisibleForTesting; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import java.util.ArrayList; @@ -60,7 +61,7 @@ class AndPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { for (OptimizedFilePredicate predicate : predicates) { if (!predicate.apply(f)) { return false; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java index b0b384c004d..864fde37b8e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java @@ -146,11 +146,6 @@ public class DefaultFilePredicates implements FilePredicates { } @Override - public FilePredicate hasStatus(InputFile.Status status) { - return new StatusPredicate(status); - } - - @Override public FilePredicate hasType(InputFile.Type type) { return new TypePredicate(type); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java index c7339ed1b2b..b6a8d3aaa7e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java @@ -32,6 +32,8 @@ import java.util.Iterator; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; +import java.util.stream.StreamSupport; + import javax.annotation.Nullable; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FilePredicates; @@ -52,7 +54,7 @@ public class DefaultFileSystem implements FileSystem { private Path workDir; private Charset encoding; protected final FilePredicates predicates; - private FilePredicate defaultPredicate; + private InputFilePredicate defaultPredicate; /** * Only for testing @@ -107,7 +109,7 @@ public class DefaultFileSystem implements FileSystem { return this; } - public DefaultFileSystem setDefaultPredicate(@Nullable FilePredicate predicate) { + public DefaultFileSystem setDefaultPredicate(@Nullable InputFilePredicate predicate) { this.defaultPredicate = predicate; return this; } @@ -155,11 +157,12 @@ public class DefaultFileSystem implements FileSystem { @Override public Iterable<InputFile> inputFiles(FilePredicate predicate) { doPreloadFiles(); - FilePredicate combinedPredicate = predicate; + Iterable<InputFile> iterable = OptimizedFilePredicateAdapter.create(predicate).get(cache); if (defaultPredicate != null) { - combinedPredicate = predicates().and(defaultPredicate, predicate); + return StreamSupport.stream(iterable.spliterator(), false) + .filter(defaultPredicate::apply)::iterator; } - return OptimizedFilePredicateAdapter.create(combinedPredicate).get(cache); + return iterable; } @Override @@ -183,15 +186,7 @@ public class DefaultFileSystem implements FileSystem { return cache.inputDir(relativePath); } - /** - * Adds InputFile to the list and registers its language, if present. - * Synchronized because PersistIt Exchange is not concurrent - */ - public synchronized DefaultFileSystem add(DefaultInputFile inputFile) { - if (this.baseDir == null) { - throw new IllegalStateException("Please set basedir on filesystem before adding files"); - } - inputFile.setModuleBaseDir(this.baseDir); + public DefaultFileSystem add(InputFile inputFile) { cache.add(inputFile); String language = inputFile.language(); if (language != null) { @@ -200,22 +195,14 @@ public class DefaultFileSystem implements FileSystem { return this; } - /** - * Adds InputDir to the list. - * Synchronized because PersistIt Exchange is not concurrent - */ - public synchronized DefaultFileSystem add(DefaultInputDir inputDir) { - if (this.baseDir == null) { - throw new IllegalStateException("Please set basedir on filesystem before adding dirs"); - } - inputDir.setModuleBaseDir(this.baseDir); + public DefaultFileSystem add(DefaultInputDir inputDir) { cache.add(inputDir); return this; } /** * Adds a language to the list. To be used only for unit tests that need to use {@link #languages()} without - * using {@link #add(DefaultInputFile)}. + * using {@link #add(InputFile)}. */ public DefaultFileSystem addLanguages(String language, String... others) { languages.add(language); 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 new file mode 100644 index 00000000000..e3a1107e28f --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java @@ -0,0 +1,126 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import org.sonar.api.batch.fs.IndexedFile; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.utils.PathUtils; + +public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile { + private final String relativePath; + private final String moduleKey; + private final Path moduleBaseDir; + private String language; + private final Type type; + + public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath) { + this(moduleKey, moduleBaseDir, relativePath, Type.MAIN); + } + + public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, Type type) { + this.moduleKey = moduleKey; + this.relativePath = PathUtils.sanitize(relativePath); + this.moduleBaseDir = moduleBaseDir.normalize(); + this.type = type; + } + + public DefaultIndexedFile setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + @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() { + return moduleBaseDir.resolve(relativePath); + } + + @CheckForNull + @Override + public String language() { + return language; + } + + @Override + public Type type() { + return type; + } + + /** + * Component key. + */ + @Override + public String key() { + return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString(); + } + + public String moduleKey() { + return moduleKey; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof DefaultIndexedFile)) { + return false; + } + + DefaultIndexedFile that = (DefaultIndexedFile) 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 boolean isFile() { + return true; + } +} 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 index a3d4de28654..b6c644e9cb6 100644 --- 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 @@ -21,91 +21,67 @@ package org.sonar.api.batch.fs.internal; import com.google.common.base.Preconditions; import java.io.File; -import java.io.StringReader; import java.nio.charset.Charset; import java.nio.file.Path; import java.util.Arrays; +import java.util.function.Function; + import javax.annotation.CheckForNull; -import javax.annotation.Nullable; 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.FileMetadata.Metadata; -import org.sonar.api.utils.PathUtils; /** * @since 4.2 */ public class DefaultInputFile extends DefaultInputComponent implements InputFile { - - private final String relativePath; - private final String moduleKey; - private Path moduleBaseDir; - private String language; - private Type type = Type.MAIN; + private final DefaultIndexedFile indexedFile; + private final Function<DefaultInputFile, Metadata> metadataGenerator; private Status status; - private int lines = -1; private Charset charset; - private int lastValidOffset = -1; - private String hash; - private int nonBlankLines; - private int[] originalLineOffsets; + private Metadata metadata; - public DefaultInputFile(String moduleKey, String relativePath) { - this.moduleKey = moduleKey; - this.relativePath = PathUtils.sanitize(relativePath); + public DefaultInputFile(DefaultIndexedFile indexedFile, Function<DefaultInputFile, Metadata> metadataGenerator) { + this.indexedFile = indexedFile; + this.metadataGenerator = metadataGenerator; + this.metadata = null; + } + + private void checkMetadata() { + if (metadata == null) { + setMetadata(metadataGenerator.apply(this)); + } } @Override public String relativePath() { - return relativePath; + return indexedFile.relativePath(); } @Override public String absolutePath() { - return PathUtils.sanitize(path().toString()); + return indexedFile.absolutePath(); } @Override public File file() { - return path().toFile(); + return indexedFile.file(); } @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); + return indexedFile.path(); } @CheckForNull @Override public String language() { - return language; + return indexedFile.language(); } @Override public Type type() { - return type; - } - - /** - * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)} - */ - @Override - public Status status() { - return status; - } - - @Override - public int lines() { - return lines; - } - - @Override - public boolean isEmpty() { - return lastValidOffset == 0; + return indexedFile.type(); } /** @@ -113,119 +89,88 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile */ @Override public String key() { - return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString(); + return indexedFile.key(); } public String moduleKey() { - return moduleKey; + return indexedFile.moduleKey(); } @Override - public Charset charset() { - return charset; - } - - /** - * For testing purpose. Will be automaticall set when file is added to {@link DefaultFileSystem} - */ - public DefaultInputFile setModuleBaseDir(Path moduleBaseDir) { - this.moduleBaseDir = moduleBaseDir.normalize(); - return this; + public int hashCode() { + return indexedFile.hashCode(); } - public DefaultInputFile setLanguage(@Nullable String language) { - this.language = language; - return this; + @Override + public String toString() { + return indexedFile.toString(); } - public DefaultInputFile setType(Type type) { - this.type = type; - return this; + /** + * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)} + */ + @Override + public Status status() { + checkMetadata(); + return status; } - public DefaultInputFile setStatus(Status status) { - this.status = status; - return this; + @Override + public int lines() { + checkMetadata(); + return metadata.lines(); } - public DefaultInputFile setLines(int lines) { - this.lines = lines; - return this; + @Override + public boolean isEmpty() { + checkMetadata(); + return metadata.lastValidOffset() == 0; } - public DefaultInputFile setCharset(Charset charset) { - this.charset = charset; - return this; + @Override + public Charset charset() { + checkMetadata(); + return charset; } public int lastValidOffset() { - Preconditions.checkState(lastValidOffset >= 0, "InputFile is not properly initialized. Please set 'lastValidOffset' property."); - return lastValidOffset; - } - - public DefaultInputFile setLastValidOffset(int lastValidOffset) { - this.lastValidOffset = lastValidOffset; - return this; + checkMetadata(); + Preconditions.checkState(metadata.lastValidOffset() >= 0, "InputFile is not properly initialized."); + return metadata.lastValidOffset(); } /** * Digest hash of the file. */ public String hash() { - return hash; + checkMetadata(); + return metadata.hash(); } public int nonBlankLines() { - return nonBlankLines; + checkMetadata(); + return metadata.nonBlankLines(); } public int[] originalLineOffsets() { - Preconditions.checkState(originalLineOffsets != null, "InputFile is not properly initialized. Please set 'originalLineOffsets' property."); - Preconditions.checkState(originalLineOffsets.length == lines, "InputFile is not properly initialized. 'originalLineOffsets' property length should be equal to 'lines'"); - return originalLineOffsets; - } - - public DefaultInputFile setHash(String hash) { - this.hash = hash; - return this; - } - - public DefaultInputFile setNonBlankLines(int nonBlankLines) { - this.nonBlankLines = nonBlankLines; - return this; - } - - public DefaultInputFile setOriginalLineOffsets(int[] originalLineOffsets) { - this.originalLineOffsets = originalLineOffsets; - return this; + checkMetadata(); + Preconditions.checkState(metadata.originalLineOffsets() != null, "InputFile is not properly initialized."); + Preconditions.checkState(metadata.originalLineOffsets().length == metadata.lines(), + "InputFile is not properly initialized. 'originalLineOffsets' property length should be equal to 'lines'"); + return metadata.originalLineOffsets(); } @Override public TextPointer newPointer(int line, int lineOffset) { + checkMetadata(); DefaultTextPointer textPointer = new DefaultTextPointer(line, lineOffset); checkValid(textPointer, "pointer"); return textPointer; } - private void checkValid(TextPointer pointer, String owner) { - Preconditions.checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line()); - Preconditions.checkArgument(pointer.line() <= this.lines, "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, lines); - Preconditions.checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset()); - int lineLength = lineLength(pointer.line()); - Preconditions.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 lastValidGlobalOffsetForLine(line) - originalLineOffsets()[line - 1]; - } - - private int lastValidGlobalOffsetForLine(int line) { - return line < this.lines ? (originalLineOffsets()[line] - 1) : lastValidOffset(); - } - @Override public TextRange newRange(TextPointer start, TextPointer end) { + checkMetadata(); checkValid(start, "start pointer"); checkValid(end, "end pointer"); return newRangeValidPointers(start, end, false); @@ -233,6 +178,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile @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); @@ -240,30 +186,28 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile @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"); } - private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) { - Preconditions.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); - } - /** * 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(); Preconditions.checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset); Preconditions.checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset()); int line = findLine(globalOffset); @@ -271,24 +215,46 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile return new DefaultTextPointer(line, globalOffset - startLineOffset); } - private int findLine(int globalOffset) { - return Math.abs(Arrays.binarySearch(originalLineOffsets(), globalOffset) + 1); + public DefaultInputFile setStatus(Status status) { + this.status = status; + return this; } - public DefaultInputFile initMetadata(Metadata metadata) { - this.setLines(metadata.lines); - this.setLastValidOffset(metadata.lastValidOffset); - this.setNonBlankLines(metadata.nonBlankLines); - this.setHash(metadata.hash); - this.setOriginalLineOffsets(metadata.originalLineOffsets); + public DefaultInputFile setCharset(Charset charset) { + this.charset = charset; return this; } - /** - * For testing purpose - */ - public DefaultInputFile initMetadata(String content) { - return initMetadata(new FileMetadata().readMetadata(new StringReader(content))); + private void checkValid(TextPointer pointer, String owner) { + Preconditions.checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line()); + Preconditions.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()); + Preconditions.checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset()); + int lineLength = lineLength(pointer.line()); + Preconditions.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 lastValidGlobalOffsetForLine(line) - originalLineOffsets()[line - 1]; + } + + private int lastValidGlobalOffsetForLine(int line) { + return line < this.metadata.lines() ? (originalLineOffsets()[line] - 1) : lastValidOffset(); + } + + private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) { + Preconditions.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(originalLineOffsets(), globalOffset) + 1); + } + + private DefaultInputFile setMetadata(Metadata metadata) { + this.metadata = metadata; + return this; } @Override @@ -303,17 +269,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile } DefaultInputFile that = (DefaultInputFile) 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 + "]"; + return this.moduleKey().equals(that.moduleKey()) && this.relativePath().equals(that.relativePath()); } @Override diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java index 3fac4b9e6ef..1acaf7b2df3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FalsePredicate.java @@ -21,6 +21,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import java.util.Collections; @@ -30,7 +31,7 @@ class FalsePredicate extends AbstractFilePredicate { static final FilePredicate FALSE = new FalsePredicate(); @Override - public boolean apply(InputFile inputFile) { + public boolean apply(IndexedFile inputFile) { return false; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java index 9a196396462..64d4205080c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java @@ -41,6 +41,7 @@ import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.input.BOMInputStream; import org.sonar.api.CoreProperties; import org.sonar.api.batch.ScannerSide; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -351,22 +352,6 @@ public class FileMetadata { } } - public static class Metadata { - final int lines; - final int nonBlankLines; - final String hash; - final int[] originalLineOffsets; - final int lastValidOffset; - - private Metadata(int lines, int nonBlankLines, String hash, int[] originalLineOffsets, int lastValidOffset) { - this.lines = lines; - this.nonBlankLines = nonBlankLines; - this.hash = hash; - this.originalLineOffsets = originalLineOffsets; - this.lastValidOffset = lastValidOffset; - } - } - @FunctionalInterface public interface LineHashConsumer { @@ -377,7 +362,7 @@ public class FileMetadata { /** * Compute a MD5 hash of each line of the file after removing of all blank chars */ - public static void computeLineHashesForIssueTracking(DefaultInputFile f, LineHashConsumer consumer) { + public static void computeLineHashesForIssueTracking(InputFile f, LineHashConsumer consumer) { readFile(f.file(), f.charset(), new LineHashComputer(consumer, f.file())); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputFilePredicate.java index daa4b23d5e5..eacd05b625c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputFilePredicate.java @@ -21,20 +21,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.InputFile; -/** - * @since 4.2 - */ -class StatusPredicate extends AbstractFilePredicate { - - private final InputFile.Status status; - - StatusPredicate(InputFile.Status status) { - this.status = status; - } - - @Override - public boolean apply(InputFile f) { - return status == f.status(); - } - +@FunctionalInterface +public interface InputFilePredicate { + boolean apply(InputFile inputFile); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java index b7f7c78fd4c..52930c6e2b6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/LanguagePredicate.java @@ -19,7 +19,7 @@ */ package org.sonar.api.batch.fs.internal; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; /** * @since 4.2 @@ -32,7 +32,7 @@ class LanguagePredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return language.equals(f.language()); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java new file mode 100644 index 00000000000..37880243be4 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java @@ -0,0 +1,57 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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; + +public class Metadata { + private final int lines; + private final int nonBlankLines; + private final String hash; + private final int[] originalLineOffsets; + private final int lastValidOffset; + + public Metadata(int lines, int nonBlankLines, String hash, int[] originalLineOffsets, int lastValidOffset) { + this.lines = lines; + this.nonBlankLines = nonBlankLines; + this.hash = hash; + this.originalLineOffsets = originalLineOffsets; + this.lastValidOffset = lastValidOffset; + } + + public int lines() { + return lines; + } + + public int nonBlankLines() { + return nonBlankLines; + } + + public String hash() { + return hash; + } + + public int[] originalLineOffsets() { + return originalLineOffsets; + } + + public int lastValidOffset() { + return lastValidOffset; + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java index 2a179713f9b..d51f79d2e13 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java @@ -20,7 +20,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; /** * @since 4.2 @@ -34,7 +34,7 @@ class NotPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return !predicate.apply(f); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java index 636ac426067..35fa0a183f3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OptimizedFilePredicateAdapter.java @@ -20,7 +20,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; class OptimizedFilePredicateAdapter extends AbstractFilePredicate { @@ -31,7 +31,7 @@ class OptimizedFilePredicateAdapter extends AbstractFilePredicate { } @Override - public boolean apply(InputFile inputFile) { + public boolean apply(IndexedFile inputFile) { return unoptimizedPredicate.apply(inputFile); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java index 644c33b8224..e539d05a83d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java @@ -21,7 +21,7 @@ package org.sonar.api.batch.fs.internal; import com.google.common.annotations.VisibleForTesting; import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; import java.util.ArrayList; import java.util.Collection; @@ -56,7 +56,7 @@ class OrPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { for (FilePredicate predicate : predicates) { if (predicate.apply(f)) { return true; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java index 010601ac395..5d73f9ceb4a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java @@ -21,7 +21,7 @@ package org.sonar.api.batch.fs.internal; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.utils.WildcardPattern; public abstract class PathPattern { @@ -32,9 +32,9 @@ public abstract class PathPattern { this.pattern = WildcardPattern.create(pattern); } - public abstract boolean match(InputFile inputFile); + public abstract boolean match(IndexedFile inputFile); - public abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension); + public abstract boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension); public static PathPattern create(String s) { String trimmed = StringUtils.trim(s); @@ -58,12 +58,12 @@ public abstract class PathPattern { } @Override - public boolean match(InputFile inputFile) { + public boolean match(IndexedFile inputFile) { return match(inputFile, true); } @Override - public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) { + public boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension) { String path = inputFile.absolutePath(); if (!caseSensitiveFileExtension) { String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName())); @@ -90,12 +90,12 @@ public abstract class PathPattern { } @Override - public boolean match(InputFile inputFile) { + public boolean match(IndexedFile inputFile) { return match(inputFile, true); } @Override - public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) { + public boolean match(IndexedFile inputFile, boolean caseSensitiveFileExtension) { String path = inputFile.relativePath(); if (!caseSensitiveFileExtension) { String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName())); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java index 86cd285f74c..45766537a8b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPatternPredicate.java @@ -19,6 +19,7 @@ */ package org.sonar.api.batch.fs.internal; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; /** @@ -33,7 +34,7 @@ class PathPatternPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return pattern.match(f); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java index 155a8b6a3ab..f7e727f45b5 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/RelativePathPredicate.java @@ -20,6 +20,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.utils.PathUtils; @@ -42,7 +43,7 @@ public class RelativePathPredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return path.equals(f.relativePath()); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java new file mode 100644 index 00000000000..fe4bb6d74d3 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java @@ -0,0 +1,125 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.StringReader; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; + +import javax.annotation.Nullable; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.utils.PathUtils; + +/** + * @since 4.2 + */ +public class TestInputFileBuilder { + private final String relativePath; + private final String moduleKey; + private Path moduleBaseDir; + private String language; + private InputFile.Type type = InputFile.Type.MAIN; + private InputFile.Status status; + private int lines = -1; + private Charset charset; + private int lastValidOffset = -1; + private String hash; + private int nonBlankLines; + private int[] originalLineOffsets; + + public TestInputFileBuilder(String moduleKey, String relativePath) { + this.moduleKey = moduleKey; + this.moduleBaseDir = Paths.get(moduleKey); + this.relativePath = PathUtils.sanitize(relativePath); + } + + public TestInputFileBuilder setModuleBaseDir(Path moduleBaseDir) { + this.moduleBaseDir = moduleBaseDir.normalize(); + return this; + } + + public TestInputFileBuilder setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + public TestInputFileBuilder setType(InputFile.Type type) { + this.type = type; + return this; + } + + public TestInputFileBuilder setStatus(InputFile.Status status) { + this.status = status; + return this; + } + + public TestInputFileBuilder setLines(int lines) { + this.lines = lines; + return this; + } + + public TestInputFileBuilder setCharset(Charset charset) { + this.charset = charset; + return this; + } + + public TestInputFileBuilder setLastValidOffset(int lastValidOffset) { + this.lastValidOffset = lastValidOffset; + return this; + } + + public TestInputFileBuilder setHash(String hash) { + this.hash = hash; + return this; + } + + public TestInputFileBuilder setNonBlankLines(int nonBlankLines) { + this.nonBlankLines = nonBlankLines; + return this; + } + + public TestInputFileBuilder setOriginalLineOffsets(int[] originalLineOffsets) { + this.originalLineOffsets = originalLineOffsets; + return this; + } + + public TestInputFileBuilder setMetadata(Metadata metadata) { + this.setLines(metadata.lines()); + this.setLastValidOffset(metadata.lastValidOffset()); + this.setNonBlankLines(metadata.nonBlankLines()); + this.setHash(metadata.hash()); + this.setOriginalLineOffsets(metadata.originalLineOffsets()); + return this; + } + + public TestInputFileBuilder initMetadata(String content) { + return setMetadata(new FileMetadata().readMetadata(new StringReader(content))); + } + + public DefaultInputFile build() { + DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type); + indexedFile.setLanguage(language); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> new Metadata(lines, nonBlankLines, hash, originalLineOffsets, lastValidOffset)); + inputFile.setStatus(status); + inputFile.setCharset(charset); + return inputFile; + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java index c8ca4d9163b..c7a58946749 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TruePredicate.java @@ -21,6 +21,7 @@ package org.sonar.api.batch.fs.internal; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; class TruePredicate extends AbstractFilePredicate { @@ -28,7 +29,7 @@ class TruePredicate extends AbstractFilePredicate { static final FilePredicate TRUE = new TruePredicate(); @Override - public boolean apply(InputFile inputFile) { + public boolean apply(IndexedFile inputFile) { return true; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java index 36fefb2fd29..c3d9fbf0bc1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TypePredicate.java @@ -19,6 +19,7 @@ */ package org.sonar.api.batch.fs.internal; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; /** @@ -33,7 +34,7 @@ class TypePredicate extends AbstractFilePredicate { } @Override - public boolean apply(InputFile f) { + public boolean apply(IndexedFile f) { return type == f.type(); } 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 index fc84bd2fc5e..a32e6423196 100644 --- 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 @@ -24,7 +24,6 @@ import java.util.Collections; import java.util.SortedMap; 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; @@ -35,7 +34,7 @@ import static com.google.common.base.Preconditions.checkState; public class DefaultCoverage extends DefaultStorable implements NewCoverage { - private DefaultInputFile inputFile; + private InputFile inputFile; private CoverageType type; private int totalCoveredLines = 0; private int totalConditions = 0; @@ -54,7 +53,7 @@ public class DefaultCoverage extends DefaultStorable implements NewCoverage { @Override public DefaultCoverage onFile(InputFile inputFile) { - this.inputFile = (DefaultInputFile) inputFile; + this.inputFile = inputFile; return this; } 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 index 16d8be19e08..cdec0c7971a 100644 --- 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 @@ -25,7 +25,6 @@ import java.util.List; import org.sonar.api.CoreProperties; 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.fs.internal.PathPattern; import org.sonar.api.batch.sensor.cpd.NewCpdTokens; import org.sonar.api.batch.sensor.internal.DefaultStorable; @@ -37,7 +36,7 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { private final Settings settings; private final ImmutableList.Builder<TokensLine> result = ImmutableList.builder(); - private DefaultInputFile inputFile; + private InputFile inputFile; private int startLine = Integer.MIN_VALUE; private int startIndex = 0; private int currentIndex = 0; @@ -53,7 +52,7 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens { @Override public DefaultCpdTokens onFile(InputFile inputFile) { Preconditions.checkNotNull(inputFile, "file can't be null"); - this.inputFile = (DefaultInputFile) inputFile; + this.inputFile = inputFile; String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS); for (PathPattern cpdExclusion : PathPattern.create(cpdExclusions)) { if (cpdExclusion.match(inputFile)) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java index 5ce491477cf..e06847c27e3 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java @@ -25,10 +25,12 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; @@ -39,16 +41,21 @@ public class DefaultFilePredicatesTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - DefaultInputFile javaFile; + private Path moduleBasePath; + + @Before + public void setUp() throws IOException { + moduleBasePath = temp.newFolder().toPath(); + } + + IndexedFile javaFile; FilePredicates predicates; @Before public void before() throws IOException { predicates = new DefaultFilePredicates(temp.newFolder().toPath()); - javaFile = new DefaultInputFile("foo", "src/main/java/struts/Action.java") - .setModuleBaseDir(temp.newFolder().toPath()) - .setLanguage("java") - .setStatus(InputFile.Status.ADDED); + javaFile = new DefaultIndexedFile("foo", moduleBasePath, "src/main/java/struts/Action.java") + .setLanguage("java"); } @Test @@ -151,12 +158,6 @@ public class DefaultFilePredicatesTest { } @Test - public void has_status() { - assertThat(predicates.hasStatus(InputFile.Status.ADDED).apply(javaFile)).isTrue(); - assertThat(predicates.hasStatus(InputFile.Status.CHANGED).apply(javaFile)).isFalse(); - } - - @Test public void has_type() { assertThat(predicates.hasType(InputFile.Type.MAIN).apply(javaFile)).isTrue(); assertThat(predicates.hasType(InputFile.Type.TEST).apply(javaFile)).isFalse(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java index 81d517ab71f..5656d232821 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java @@ -81,12 +81,12 @@ public class DefaultFileSystemTest { public void files() { assertThat(fs.inputFiles(fs.predicates().all())).isEmpty(); - fs.add(new DefaultInputFile("foo", "src/Foo.php").setLanguage("php")); - fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java")); - fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java")); + fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); // no language - fs.add(new DefaultInputFile("foo", "src/readme.txt")); + fs.add(new TestInputFileBuilder("foo", "src/readme.txt").build()); assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNotNull(); assertThat(fs.inputFile(fs.predicates().hasRelativePath("does/not/exist"))).isNull(); @@ -118,15 +118,15 @@ public class DefaultFileSystemTest { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("expected one element"); - fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java")); - fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java")); + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); fs.inputFile(fs.predicates().all()); } @Test public void input_file_supports_non_indexed_predicates() { - fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java")); + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); // it would fail if more than one java file assertThat(fs.inputFile(fs.predicates().hasLanguage("java"))).isNotNull(); 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 index 5fd96320fec..ae1aed402ce 100644 --- 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 @@ -24,9 +24,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +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.util.stream.Collectors; import org.junit.Rule; @@ -37,6 +39,7 @@ import org.sonar.api.batch.fs.TextRange; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; public class DefaultInputFileTest { @@ -46,12 +49,11 @@ public class DefaultInputFileTest { @Test public void test() throws Exception { Path baseDir = temp.newFolder().toPath(); - DefaultInputFile inputFile = new DefaultInputFile("ABCDE", "src/Foo.php") - .setModuleBaseDir(baseDir) - .setLines(42) - .setLanguage("php") + + Metadata metadata = new Metadata(42, 42, "", new int[0], 0); + DefaultIndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST).setLanguage("php"); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> metadata) .setStatus(InputFile.Status.ADDED) - .setType(InputFile.Type.TEST) .setCharset(StandardCharsets.ISO_8859_1); assertThat(inputFile.relativePath()).isEqualTo("src/Foo.php"); @@ -71,13 +73,12 @@ public class DefaultInputFileTest { Path testFile = baseDir.resolve("src").resolve("Foo.php"); Files.createDirectories(testFile.getParent()); Files.write(testFile, "test string".getBytes(StandardCharsets.UTF_8)); - DefaultInputFile inputFile = new DefaultInputFile("ABCDE", "src/Foo.php") - .setModuleBaseDir(baseDir) - .setLines(42) - .setLanguage("php") - .setStatus(InputFile.Status.ADDED) - .setType(InputFile.Type.TEST) - .setCharset(StandardCharsets.ISO_8859_1); + Metadata metadata = new Metadata(42, 30, "", new int[0], 0); + + DefaultInputFile inputFile = new DefaultInputFile(new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST) + .setLanguage("php"), f -> metadata) + .setStatus(InputFile.Status.ADDED) + .setCharset(StandardCharsets.ISO_8859_1); assertThat(inputFile.contents()).isEqualTo("test string"); try (InputStream inputStream = inputFile.inputStream()) { @@ -89,9 +90,9 @@ public class DefaultInputFileTest { @Test public void test_equals_and_hashcode() throws Exception { - DefaultInputFile f1 = new DefaultInputFile("ABCDE", "src/Foo.php"); - DefaultInputFile f1a = new DefaultInputFile("ABCDE", "src/Foo.php"); - DefaultInputFile f2 = new DefaultInputFile("ABCDE", "src/Bar.php"); + DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class)); + DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class)); + DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php"), (f) -> mock(Metadata.class)); assertThat(f1).isEqualTo(f1); assertThat(f1).isEqualTo(f1a); @@ -105,16 +106,14 @@ public class DefaultInputFileTest { @Test public void test_toString() throws Exception { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, basedir=null]"); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> mock(Metadata.class)); + assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, basedir=module]"); } @Test public void checkValidPointer() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.setLines(2); - file.setOriginalLineOffsets(new int[] {0, 10}); - file.setLastValidOffset(15); + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata); assertThat(file.newPointer(1, 0).line()).isEqualTo(1); assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0); // Don't fail @@ -132,7 +131,7 @@ public class DefaultInputFileTest { file.newPointer(3, 1); fail(); } catch (Exception e) { - assertThat(e).hasMessage("3 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 2 line(s)"); + assertThat(e).hasMessage("3 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 2 line(s)"); } try { file.newPointer(1, -1); @@ -144,16 +143,14 @@ public class DefaultInputFileTest { file.newPointer(1, 10); fail(); } catch (Exception e) { - assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 9 character(s) at line 1"); + assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1"); } } @Test public void checkValidPointerUsingGlobalOffset() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.setLines(2); - file.setOriginalLineOffsets(new int[] {0, 10}); - file.setLastValidOffset(15); + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata); assertThat(file.newPointer(0).line()).isEqualTo(1); assertThat(file.newPointer(0).lineOffset()).isEqualTo(0); @@ -177,14 +174,15 @@ public class DefaultInputFileTest { file.newPointer(16); fail(); } catch (Exception e) { - assertThat(e).hasMessage("16 is not a valid offset for file [moduleKey=ABCDE, relative=src/Foo.php, basedir=null]. Max offset is 15"); + assertThat(e).hasMessage("16 is not a valid offset for file [moduleKey=ABCDE, relative=src/Foo.php, basedir=module]. Max offset is 15"); } } @Test public void checkValidRange() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.initMetadata("bla bla a\nabcde"); + Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde")); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> 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)); @@ -202,14 +200,15 @@ public class DefaultInputFileTest { 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 [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 9 character(s) at line 1"); + assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1"); } } @Test public void selectLine() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.initMetadata("bla bla a\nabcde\n\nabc"); + Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc")); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> 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); @@ -225,16 +224,14 @@ public class DefaultInputFileTest { file.selectLine(5); fail(); } catch (Exception e) { - assertThat(e).hasMessage("5 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=null] has 4 line(s)"); + assertThat(e).hasMessage("5 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 4 line(s)"); } } @Test public void checkValidRangeUsingGlobalOffset() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.setLines(2); - file.setOriginalLineOffsets(new int[] {0, 10}); - file.setLastValidOffset(15); + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata); TextRange newRange = file.newRange(10, 13); assertThat(newRange.start().line()).isEqualTo(2); assertThat(newRange.start().lineOffset()).isEqualTo(0); @@ -244,10 +241,8 @@ public class DefaultInputFileTest { @Test public void testRangeOverlap() { - DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php"); - file.setLines(2); - file.setOriginalLineOffsets(new int[] {0, 10}); - file.setLastValidOffset(15); + Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15); + DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> 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(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java index 0b8fd1ebf79..daa153f72d3 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java @@ -53,12 +53,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.touch(tempFile); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(1); - assertThat(metadata.nonBlankLines).isEqualTo(0); - assertThat(metadata.hash).isNotEmpty(); - assertThat(metadata.originalLineOffsets).containsOnly(0); - assertThat(metadata.lastValidOffset).isEqualTo(0); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(1); + assertThat(metadata.nonBlankLines()).isEqualTo(0); + assertThat(metadata.hash()).isNotEmpty(); + assertThat(metadata.originalLineOffsets()).containsOnly(0); + assertThat(metadata.lastValidOffset()).isEqualTo(0); } @Test @@ -66,12 +66,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(3); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10); - assertThat(metadata.lastValidOffset).isEqualTo(13); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10); + assertThat(metadata.lastValidOffset()).isEqualTo(13); } @Test @@ -79,10 +79,10 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "marker´s\n", Charset.forName("cp1252")); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(2); - assertThat(metadata.hash).isEqualTo(md5Hex("marker\ufffds\n")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 9); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(2); + assertThat(metadata.hash()).isEqualTo(md5Hex("marker\ufffds\n")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 9); } @Test @@ -90,22 +90,22 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10, 18); } @Test public void non_ascii_utf_16() throws Exception { File tempFile = temp.newFile(); FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_16, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_16); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8))); - assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_16); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8))); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 5, 10, 18); } @Test @@ -113,12 +113,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\nbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(3); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8); - assertThat(metadata.lastValidOffset).isEqualTo(11); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8); + assertThat(metadata.lastValidOffset()).isEqualTo(11); } @Test @@ -126,12 +126,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\nbaz\n", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8, 12); - assertThat(metadata.lastValidOffset).isEqualTo(12); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8, 12); + assertThat(metadata.lastValidOffset()).isEqualTo(12); } @Test @@ -139,12 +139,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\rbar\rbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(3); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8); - assertThat(metadata.lastValidOffset).isEqualTo(11); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8); + assertThat(metadata.lastValidOffset()).isEqualTo(11); } @Test @@ -152,12 +152,12 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\rbar\rbaz\r", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 8, 12); - assertThat(metadata.lastValidOffset).isEqualTo(12); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 8, 12); + assertThat(metadata.lastValidOffset()).isEqualTo(12); } @Test @@ -165,11 +165,11 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9, 13); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9, 13); } @Test @@ -177,11 +177,11 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\n\n\nbar", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(2); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\n\n\nbar")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 5, 6); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(2); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\n\n\nbar")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 5, 6); } @Test @@ -189,11 +189,11 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(3); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9); } @Test @@ -201,11 +201,11 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "\nfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(4); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("\nfoo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 1, 5, 10); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("\nfoo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 1, 5, 10); } @Test @@ -213,11 +213,11 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "\uFEFFfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(3); - assertThat(metadata.nonBlankLines).isEqualTo(3); - assertThat(metadata.hash).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineOffsets).containsOnly(0, 4, 9); + Metadata metadata = new FileMetadata().readMetadata(tempFile, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineOffsets()).containsOnly(0, 4, 9); } @Test @@ -225,9 +225,10 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, " foo\nb ar\r\nbaz \t", StandardCharsets.UTF_8, true); - DefaultInputFile f = new DefaultInputFile("foo", tempFile.getName()); - f.setModuleBaseDir(tempFile.getParentFile().toPath()); - f.setCharset(StandardCharsets.UTF_8); + DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) + .setModuleBaseDir(tempFile.getParentFile().toPath()) + .setCharset(StandardCharsets.UTF_8) + .build(); FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() { @Override @@ -254,9 +255,10 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "", StandardCharsets.UTF_8, true); - DefaultInputFile f = new DefaultInputFile("foo", tempFile.getName()); - f.setModuleBaseDir(tempFile.getParentFile().toPath()); - f.setCharset(StandardCharsets.UTF_8); + DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) + .setModuleBaseDir(tempFile.getParentFile().toPath()) + .setCharset(StandardCharsets.UTF_8) + .build(); FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() { @Override @@ -295,9 +297,9 @@ public class FileMetadataTest { File file2 = temp.newFile(); FileUtils.write(file2, "foo\nbar", StandardCharsets.UTF_8, true); - String hash1 = new FileMetadata().readMetadata(file1, StandardCharsets.UTF_8).hash; - String hash1a = new FileMetadata().readMetadata(file1a, StandardCharsets.UTF_8).hash; - String hash2 = new FileMetadata().readMetadata(file2, StandardCharsets.UTF_8).hash; + String hash1 = new FileMetadata().readMetadata(file1, StandardCharsets.UTF_8).hash(); + String hash1a = new FileMetadata().readMetadata(file1a, StandardCharsets.UTF_8).hash(); + String hash2 = new FileMetadata().readMetadata(file2, StandardCharsets.UTF_8).hash(); assertThat(hash1).isEqualTo(hash1a); assertThat(hash1).isNotEqualTo(hash2); } @@ -306,10 +308,10 @@ public class FileMetadataTest { public void binary_file_with_unmappable_character() throws Exception { File woff = new File(this.getClass().getResource("glyphicons-halflings-regular.woff").toURI()); - FileMetadata.Metadata metadata = new FileMetadata().readMetadata(woff, StandardCharsets.UTF_8); - assertThat(metadata.lines).isEqualTo(135); - assertThat(metadata.nonBlankLines).isEqualTo(133); - assertThat(metadata.hash).isNotEmpty(); + Metadata metadata = new FileMetadata().readMetadata(woff, StandardCharsets.UTF_8); + assertThat(metadata.lines()).isEqualTo(135); + assertThat(metadata.nonBlankLines()).isEqualTo(133); + assertThat(metadata.hash()).isNotEmpty(); assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains("Invalid character encountered in file"); assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains( 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 82f9542844e..f6111ea24e4 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 @@ -19,11 +19,13 @@ */ package org.sonar.api.batch.fs.internal; +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.IndexedFile; +import java.io.IOException; import java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThat; @@ -31,33 +33,38 @@ import static org.assertj.core.api.Assertions.assertThat; public class PathPatternTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); + private Path moduleBasePath; + + @Before + public void setUp() throws IOException { + moduleBasePath = temp.newFolder().toPath(); + } @Test public void match_relative_path() { PathPattern pattern = PathPattern.create("**/*Foo.java"); assertThat(pattern.toString()).isEqualTo("**/*Foo.java"); - InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java"); - assertThat(pattern.match(inputFile)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java"); + assertThat(pattern.match(indexedFile)).isTrue(); // case sensitive by default - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA"); - assertThat(pattern.match(inputFile)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA"); + assertThat(pattern.match(indexedFile)).isFalse(); - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java"); - assertThat(pattern.match(inputFile)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java"); + assertThat(pattern.match(indexedFile)).isFalse(); } @Test public void match_relative_path_and_insensitive_file_extension() throws Exception { PathPattern pattern = PathPattern.create("**/*Foo.java"); - Path moduleBaseDir = temp.newFolder().toPath(); - InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile, false)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA"); + assertThat(pattern.match(indexedFile, false)).isTrue(); - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile, false)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java"); + assertThat(pattern.match(indexedFile, false)).isFalse(); } @Test @@ -65,16 +72,15 @@ public class PathPatternTest { PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java"); assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java"); - Path moduleBaseDir = temp.newFolder().toPath(); - InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java"); + assertThat(pattern.match(indexedFile)).isTrue(); // case sensitive by default - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA"); + assertThat(pattern.match(indexedFile)).isFalse(); - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java"); + assertThat(pattern.match(indexedFile)).isFalse(); } @Test @@ -82,12 +88,11 @@ public class PathPatternTest { PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java"); assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java"); - Path moduleBaseDir = temp.newFolder().toPath(); - InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile, false)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA"); + assertThat(pattern.match(indexedFile, false)).isTrue(); - inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.JAVA").setModuleBaseDir(moduleBaseDir); - assertThat(pattern.match(inputFile, false)).isFalse(); + indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.JAVA"); + assertThat(pattern.match(indexedFile, false)).isFalse(); } @Test 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 index c5772e3b349..e28256d2849 100644 --- 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 @@ -20,7 +20,8 @@ package org.sonar.api.batch.sensor.cpd.internal; import org.junit.Test; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; @@ -34,11 +35,11 @@ import static org.mockito.Mockito.verifyZeroInteractions; public class DefaultCpdTokensTest { - private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java") + private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") .setLines(2) - .setLanguage("java") .setOriginalLineOffsets(new int[] {0, 50}) - .setLastValidOffset(100); + .setLastValidOffset(100) + .build(); @Test public void save_no_tokens() { @@ -145,7 +146,7 @@ public class DefaultCpdTokensTest { tokens.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo"); fail("Expected exception"); } catch (Exception e) { - assertThat(e).hasMessage("Tokens of file [moduleKey=foo, relative=src/Foo.java, basedir=null] should be provided in order.\n" + + assertThat(e).hasMessage("Tokens of file [moduleKey=foo, relative=src/Foo.java, basedir=foo] 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 index cb67b294f54..4be93eb9c5d 100644 --- 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 @@ -29,8 +29,8 @@ 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.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultTextPointer; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.internal.SensorStorage; import static org.assertj.core.api.Assertions.assertThat; @@ -46,7 +46,7 @@ public class DefaultAnalysisErrorTest { @Before public void setUp() { - inputFile = new DefaultInputFile("module1", "src/File.java"); + inputFile = new TestInputFileBuilder("module1", "src/File.java").build(); textPointer = new DefaultTextPointer(5, 2); storage = mock(SensorStorage.class); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java index bd3766962f4..2aea77143a7 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java @@ -24,10 +24,11 @@ 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.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.fs.internal.DefaultTextRange; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import static org.assertj.core.api.Assertions.assertThat; @@ -38,10 +39,11 @@ import static org.sonar.api.batch.sensor.highlighting.TypeOfText.KEYWORD; public class DefaultHighlightingTest { - private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java") + private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") .setLines(2) .setOriginalLineOffsets(new int[] {0, 50}) - .setLastValidOffset(100); + .setLastValidOffset(100) + .build(); private Collection<SyntaxHighlightingRule> highlightingRules; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java index 4acdbc92dc2..fb95b469016 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java @@ -20,7 +20,6 @@ package org.sonar.api.batch.sensor.internal; import java.io.File; -import java.io.StringReader; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -31,7 +30,7 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem; 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.api.batch.fs.internal.FileMetadata; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.error.AnalysisError; @@ -93,12 +92,12 @@ public class SensorContextTesterTest { assertThat(tester.allIssues()).isEmpty(); NewIssue newIssue = tester.newIssue(); newIssue - .at(newIssue.newLocation().on(new DefaultInputFile("foo", "src/Foo.java"))) + .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) .forRule(RuleKey.of("repo", "rule")) .save(); newIssue = tester.newIssue(); newIssue - .at(newIssue.newLocation().on(new DefaultInputFile("foo", "src/Foo.java"))) + .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) .forRule(RuleKey.of("repo", "rule")) .save(); assertThat(tester.allIssues()).hasSize(2); @@ -109,7 +108,7 @@ public class SensorContextTesterTest { assertThat(tester.allAnalysisErrors()).isEmpty(); NewAnalysisError newAnalysisError = tester.newAnalysisError(); - InputFile file = new DefaultInputFile("foo", "src/Foo.java"); + InputFile file = new TestInputFileBuilder("foo", "src/Foo.java").build(); newAnalysisError.onFile(file) .message("error") .at(new DefaultTextPointer(5, 2)) @@ -129,14 +128,14 @@ public class SensorContextTesterTest { assertThat(tester.measures("foo:src/Foo.java")).isEmpty(); assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull(); tester.<Integer>newMeasure() - .on(new DefaultInputFile("foo", "src/Foo.java")) + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) .forMetric(CoreMetrics.NCLOC) .withValue(2) .save(); assertThat(tester.measures("foo:src/Foo.java")).hasSize(1); assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); tester.<Integer>newMeasure() - .on(new DefaultInputFile("foo", "src/Foo.java")) + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) .forMetric(CoreMetrics.LINES) .withValue(4) .save(); @@ -155,12 +154,12 @@ public class SensorContextTesterTest { @Test(expected = SonarException.class) public void duplicateMeasures() { tester.<Integer>newMeasure() - .on(new DefaultInputFile("foo", "src/Foo.java")) + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) .forMetric(CoreMetrics.NCLOC) .withValue(2) .save(); tester.<Integer>newMeasure() - .on(new DefaultInputFile("foo", "src/Foo.java")) + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) .forMetric(CoreMetrics.NCLOC) .withValue(2) .save(); @@ -170,7 +169,7 @@ public class SensorContextTesterTest { public void testHighlighting() { assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).isEmpty(); tester.newHighlighting() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) .highlight(8, 10, TypeOfText.CONSTANT) .highlight(9, 10, TypeOfText.COMMENT) @@ -182,11 +181,11 @@ public class SensorContextTesterTest { @Test(expected = UnsupportedOperationException.class) public void duplicateHighlighting() { tester.newHighlighting() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) .save(); tester.newHighlighting() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) .save(); } @@ -196,7 +195,7 @@ public class SensorContextTesterTest { assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull(); NewSymbolTable symbolTable = tester.newSymbolTable() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))); + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); symbolTable .newSymbol(1, 8, 1, 10); @@ -216,14 +215,14 @@ public class SensorContextTesterTest { @Test(expected = UnsupportedOperationException.class) public void duplicateSymbolReferences() { NewSymbolTable symbolTable = tester.newSymbolTable() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))); + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); symbolTable .newSymbol(1, 8, 1, 10); symbolTable.save(); symbolTable = tester.newSymbolTable() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))); + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); symbolTable .newSymbol(1, 8, 1, 10); @@ -237,7 +236,7 @@ public class SensorContextTesterTest { exception.expect(IllegalStateException.class); tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) .lineHits(0, 3); } @@ -248,7 +247,7 @@ public class SensorContextTesterTest { exception.expect(IllegalStateException.class); tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) .lineHits(4, 3); } @@ -257,7 +256,7 @@ public class SensorContextTesterTest { assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) .lineHits(1, 2) .lineHits(2, 3) .save(); @@ -267,12 +266,12 @@ public class SensorContextTesterTest { public void multipleCoverage() { tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) .lineHits(1, 2) .conditions(3, 4, 2) .save(); tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasdas")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) .lineHits(1, 2) .conditions(3, 4, 3) .save(); @@ -286,7 +285,9 @@ public class SensorContextTesterTest { assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull(); assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull(); tester.newCoverage() - .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar\nasd\nasdas\nasdfas")))) + .onFile(new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("annot dsf fds foo bar\nasd\nasdas\nasdfas") + .build()) .conditions(1, 4, 2) .save(); assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4); @@ -296,7 +297,9 @@ public class SensorContextTesterTest { @Test public void testCpdTokens() { assertThat(tester.cpdTokens("foo:src/Foo.java")).isNull(); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("public class Foo {\n\n}"))); + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("public class Foo {\n\n}") + .build(); tester.newCpdTokens() .onFile(inputFile) .addToken(inputFile.newRange(0, 6), "public") @@ -313,7 +316,9 @@ public class SensorContextTesterTest { @Test(expected = UnsupportedOperationException.class) public void duplicateCpdTokens() { - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("public class Foo {\n\n}"))); + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("public class Foo {\n\n}") + .build(); tester.newCpdTokens() .onFile(inputFile) .addToken(inputFile.newRange(0, 6), "public") diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java index 2f54035a1ee..967b8b8e9d7 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java @@ -19,13 +19,12 @@ */ package org.sonar.api.batch.sensor.issue.internal; -import java.io.StringReader; import org.apache.commons.lang.StringUtils; 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.batch.fs.internal.FileMetadata; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +33,9 @@ public class DefaultIssueLocationTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php").initMetadata(new FileMetadata().readMetadata(new StringReader("Foo\nBar\n"))); + private InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("Foo\nBar\n") + .build(); @Test public void not_allowed_to_call_on_twice() { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java index 6b380a0c6b7..72a8d672473 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java @@ -19,12 +19,11 @@ */ package org.sonar.api.batch.sensor.issue.internal; -import java.io.StringReader; import org.junit.Test; 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.FileMetadata; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.rule.RuleKey; @@ -35,7 +34,9 @@ import static org.mockito.Mockito.verify; public class DefaultIssueTest { - private DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php").initMetadata(new FileMetadata().readMetadata(new StringReader("Foo\nBar\n"))); + private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("Foo\nBar\n") + .build(); @Test public void build_file_issue() { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java index 15023eb803c..8443c8b401f 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.measures.CoreMetrics; @@ -41,10 +42,10 @@ public class DefaultMeasureTest { SensorStorage storage = mock(SensorStorage.class); DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage) .forMetric(CoreMetrics.LINES) - .on(new DefaultInputFile("foo", "src/Foo.php")) + .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) .withValue(3); - assertThat(newMeasure.inputComponent()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php")); + assertThat(newMeasure.inputComponent()).isEqualTo(new TestInputFileBuilder("foo", "src/Foo.php").build()); assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES); assertThat(newMeasure.value()).isEqualTo(3); @@ -77,7 +78,7 @@ public class DefaultMeasureTest { thrown.expectMessage("on() already called"); new DefaultMeasure<Integer>() .on(new DefaultInputModule("foo")) - .on(new DefaultInputFile("foo", "src/Foo.php")) + .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) .withValue(3) .save(); } 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 index ee7ba4c0b20..65706305e79 100644 --- 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 @@ -25,8 +25,9 @@ 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.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import static org.assertj.core.api.Assertions.assertThat; @@ -34,10 +35,11 @@ import static org.mockito.Mockito.mock; public class DefaultSymbolTableTest { - private static final DefaultInputFile INPUT_FILE = new DefaultInputFile("foo", "src/Foo.java") + private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") .setLines(2) .setOriginalLineOffsets(new int[] {0, 50}) - .setLastValidOffset(100); + .setLastValidOffset(100) + .build(); private Map<TextRange, Set<TextRange>> referencesPerSymbol; |