aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java7
-rw-r--r--sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java121
-rw-r--r--sonar-duplications/src/main/java/org/sonar/duplications/block/BlockChunker.java7
-rw-r--r--sonar-duplications/src/main/java/org/sonar/duplications/index/PackedMemoryCloneIndex.java22
-rw-r--r--sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java12
-rw-r--r--sonar-duplications/src/test/java/org/sonar/duplications/block/BlockTest.java22
6 files changed, 143 insertions, 48 deletions
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
index 600c3d3de35..bfd83db3491 100644
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
+++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
@@ -73,7 +73,12 @@ public class DbDuplicationsIndex {
int endLine = unit.getEndLine();
// TODO Godin: in fact we could work directly with id instead of key - this will allow to decrease memory consumption
- Block block = new Block(resourceKey, new ByteArray(hash), indexInFile, startLine, endLine);
+ Block block = Block.builder()
+ .setResourceId(resourceKey)
+ .setBlockHash(new ByteArray(hash))
+ .setIndexInFile(indexInFile)
+ .setLines(startLine, endLine)
+ .build();
// Group blocks by hash
Collection<Block> sameHash = cache.get(block.getBlockHash());
diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java b/sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java
index 1ccc79194ef..822454db205 100644
--- a/sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java
+++ b/sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java
@@ -31,14 +31,92 @@ public final class Block implements CodeFragment {
private final String resourceId;
private final ByteArray blockHash;
private final int indexInFile;
+
private final int startLine;
private final int endLine;
+ private int startUnit;
+ private int endUnit;
+
/**
* Cache for hash code.
*/
private int hash;
+ /**
+ * @since 2.14
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * <p>Instances can be reused - it is safe to call {@link #build}
+ * multiple times to build multiple blocks in series.</p>
+ *
+ * @since 2.14
+ */
+ public static final class Builder {
+
+ private String resourceId;
+ private ByteArray blockHash;
+ private int indexInFile;
+
+ private int startLine;
+ private int endLine;
+
+ private int startUnit;
+ private int endUnit;
+
+ public Builder setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ return this;
+ }
+
+ public Builder setBlockHash(ByteArray blockHash) {
+ this.blockHash = blockHash;
+ return this;
+ }
+
+ public Builder setIndexInFile(int index) {
+ this.indexInFile = index;
+ return this;
+ }
+
+ public Builder setLines(int start, int end) {
+ this.startLine = start;
+ this.endLine = end;
+ return this;
+ }
+
+ @Beta
+ public Builder setUnit(int start, int end) {
+ this.startUnit = start;
+ this.endUnit = end;
+ return this;
+ }
+
+ public Block build() {
+ return new Block(this);
+ }
+ }
+
+ private Block(Builder builder) {
+ this.resourceId = builder.resourceId;
+ this.blockHash = builder.blockHash;
+ this.indexInFile = builder.indexInFile;
+
+ this.startLine = builder.startLine;
+ this.endLine = builder.endLine;
+
+ this.startUnit = builder.startUnit;
+ this.endUnit = builder.endUnit;
+ }
+
+ /**
+ * @deprecated since 2.14 use {@link #builder()}
+ */
+ @Deprecated
public Block(String resourceId, ByteArray blockHash, int indexInFile, int startLine, int endLine) {
this.resourceId = resourceId;
this.blockHash = blockHash;
@@ -47,10 +125,6 @@ public final class Block implements CodeFragment {
this.endLine = endLine;
}
- public Block(int indexInFile, int firstLineNumber, int lastLineNumber, String resourceId, String hash) {
- this(resourceId, new ByteArray(hash), indexInFile, firstLineNumber, lastLineNumber);
- }
-
public String getHashHex() {
return getBlockHash().toString();
}
@@ -67,8 +141,13 @@ public final class Block implements CodeFragment {
return indexInFile;
}
- private int startUnit;
- private int endUnit;
+ public int getStartLine() {
+ return startLine;
+ }
+
+ public int getEndLine() {
+ return endLine;
+ }
/**
* @since 2.14
@@ -86,36 +165,6 @@ public final class Block implements CodeFragment {
return endUnit;
}
- /**
- * TODO get rid of this method, otherwise class is not immutable
- *
- * @see #getStartUnit()
- * @since 2.14
- */
- @Beta
- public void setStartUnit(int startUnit) {
- this.startUnit = startUnit;
- }
-
- /**
- * TODO get rid of this method, otherwise class is not immutable
- *
- * @see #getEndUnit()
- * @since 2.14
- */
- @Beta
- public void setEndUnit(int endUnit) {
- this.endUnit = endUnit;
- }
-
- public int getStartLine() {
- return startLine;
- }
-
- public int getEndLine() {
- return endLine;
- }
-
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Block)) {
diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/block/BlockChunker.java b/sonar-duplications/src/main/java/org/sonar/duplications/block/BlockChunker.java
index 3abc0742493..0851eb21f04 100644
--- a/sonar-duplications/src/main/java/org/sonar/duplications/block/BlockChunker.java
+++ b/sonar-duplications/src/main/java/org/sonar/duplications/block/BlockChunker.java
@@ -66,13 +66,18 @@ public class BlockChunker {
for (; last < blockSize - 1; last++) {
hash = hash * PRIME_BASE + statementsArr[last].getValue().hashCode();
}
+ Block.Builder blockBuilder = Block.builder().setResourceId(resourceId);
for (; last < statementsArr.length; last++, first++) {
Statement firstStatement = statementsArr[first];
Statement lastStatement = statementsArr[last];
// add last statement to hash
hash = hash * PRIME_BASE + lastStatement.getValue().hashCode();
// create block
- blocks.add(new Block(resourceId, new ByteArray(hash), first, firstStatement.getStartLine(), lastStatement.getEndLine()));
+ Block block = blockBuilder.setBlockHash(new ByteArray(hash))
+ .setIndexInFile(first)
+ .setLines(firstStatement.getStartLine(), lastStatement.getEndLine())
+ .build();
+ blocks.add(block);
// remove first statement from hash
hash -= power * firstStatement.getValue().hashCode();
}
diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/index/PackedMemoryCloneIndex.java b/sonar-duplications/src/main/java/org/sonar/duplications/index/PackedMemoryCloneIndex.java
index a2d66e2f0b3..bced97e3433 100644
--- a/sonar-duplications/src/main/java/org/sonar/duplications/index/PackedMemoryCloneIndex.java
+++ b/sonar-duplications/src/main/java/org/sonar/duplications/index/PackedMemoryCloneIndex.java
@@ -66,6 +66,8 @@ public class PackedMemoryCloneIndex extends AbstractCloneIndex {
private int[] resourceIdsIndex;
+ private final Block.Builder blockBuilder = Block.builder();
+
public PackedMemoryCloneIndex() {
this(8, DEFAULT_INITIAL_CAPACITY);
}
@@ -114,9 +116,13 @@ public class PackedMemoryCloneIndex extends AbstractCloneIndex {
int startUnit = blockData[offset++];
int endUnit = blockData[offset];
- Block block = new Block(resourceId, new ByteArray(hash), indexInFile, firstLineNumber, lastLineNumber);
- block.setStartUnit(startUnit);
- block.setEndUnit(endUnit);
+ Block block = blockBuilder
+ .setResourceId(resourceId)
+ .setBlockHash(new ByteArray(hash))
+ .setIndexInFile(indexInFile)
+ .setLines(firstLineNumber, lastLineNumber)
+ .setUnit(startUnit, endUnit)
+ .build();
result.add(block);
index++;
@@ -154,9 +160,13 @@ public class PackedMemoryCloneIndex extends AbstractCloneIndex {
int startUnit = blockData[offset++];
int endUnit = blockData[offset];
- Block block = new Block(resourceId, sequenceHash, indexInFile, firstLineNumber, lastLineNumber);
- block.setStartUnit(startUnit);
- block.setEndUnit(endUnit);
+ Block block = blockBuilder
+ .setResourceId(resourceId)
+ .setBlockHash(sequenceHash)
+ .setIndexInFile(indexInFile)
+ .setLines(firstLineNumber, lastLineNumber)
+ .setUnit(startUnit, endUnit)
+ .build();
result.add(block);
index++;
}
diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java b/sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java
index 81ef62d7b52..7fb3652adc0 100644
--- a/sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java
+++ b/sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java
@@ -29,7 +29,7 @@ import java.util.List;
/**
* Differences with {@link org.sonar.duplications.block.BlockChunker}:
* works with {@link TokensLine},
- * sets {@link Block#setStartUnit(int)} and {@link Block#setEndUnit(int)} - indexes of first and last token for this block.
+ * sets {@link Block#getStartUnit() startUnit} and {@link Block#getEndUnit() endUnit} - indexes of first and last token for this block.
*/
public class PmdBlockChunker {
@@ -60,15 +60,19 @@ public class PmdBlockChunker {
for (; last < blockSize - 1; last++) {
hash = hash * PRIME_BASE + fragmentsArr[last].getHashCode();
}
+ Block.Builder blockBuilder = Block.builder().setResourceId(resourceId);
for (; last < fragmentsArr.length; last++, first++) {
TokensLine firstFragment = fragmentsArr[first];
TokensLine lastFragment = fragmentsArr[last];
// add last statement to hash
hash = hash * PRIME_BASE + lastFragment.getHashCode();
// create block
- Block block = new Block(resourceId, new ByteArray(hash), first, firstFragment.getStartLine(), lastFragment.getEndLine());
- block.setStartUnit(firstFragment.getStartUnit());
- block.setEndUnit(lastFragment.getEndUnit());
+ Block block = blockBuilder
+ .setBlockHash(new ByteArray(hash))
+ .setIndexInFile(first)
+ .setLines(firstFragment.getStartLine(), lastFragment.getEndLine())
+ .setUnit(firstFragment.getStartUnit(), lastFragment.getEndUnit())
+ .build();
blocks.add(block);
// remove first statement from hash
hash -= power * firstFragment.getHashCode();
diff --git a/sonar-duplications/src/test/java/org/sonar/duplications/block/BlockTest.java b/sonar-duplications/src/test/java/org/sonar/duplications/block/BlockTest.java
index bcb8bcfe389..fd86e55c699 100644
--- a/sonar-duplications/src/test/java/org/sonar/duplications/block/BlockTest.java
+++ b/sonar-duplications/src/test/java/org/sonar/duplications/block/BlockTest.java
@@ -27,6 +27,28 @@ import static org.junit.Assert.*;
public class BlockTest {
@Test
+ public void testBuilder() {
+ ByteArray hash = new ByteArray(1);
+ Block block = Block.builder()
+ .setResourceId("resource")
+ .setBlockHash(hash)
+ .setIndexInFile(1)
+ .setLines(2, 3)
+ .setUnit(4, 5)
+ .build();
+
+ assertThat(block.getResourceId(), is("resource"));
+ assertThat(block.getBlockHash(), sameInstance(hash));
+ assertThat(block.getIndexInFile(), is(1));
+
+ assertThat(block.getStartLine(), is(2));
+ assertThat(block.getEndLine(), is(3));
+
+ assertThat(block.getStartUnit(), is(4));
+ assertThat(block.getEndUnit(), is(5));
+ }
+
+ @Test
public void fieldsTest() {
String fileName = "someFile";
int statementIndex = 4;