use of org.sonar.duplications.block.Block in project sonarqube by SonarSource.
the class DetectorTestCase method same_lines_but_different_indexes.
/**
* Given file with two lines, containing following statements:
* <pre>
* 0: A,B,A,B
* 1: A,B,A
* </pre>
* with block size 5 each block will span both lines, and hashes will be:
* <pre>
* A,B,A,B,A=1
* B,A,B,A,B=2
* A,B,A,B,A=1
* </pre>
* Expected: one clone with two parts, which contain exactly the same lines
*/
@Test
public void same_lines_but_different_indexes() {
CloneIndex cloneIndex = createIndex();
Block.Builder block = Block.builder().setResourceId("a").setLines(0, 1);
Block[] fileBlocks = new Block[] { block.setBlockHash(new ByteArray("1".getBytes())).setIndexInFile(0).build(), block.setBlockHash(new ByteArray("2".getBytes())).setIndexInFile(1).build(), block.setBlockHash(new ByteArray("1".getBytes())).setIndexInFile(2).build() };
List<CloneGroup> clones = detect(cloneIndex, fileBlocks);
print(clones);
assertThat(clones.size(), is(1));
Iterator<CloneGroup> clonesIterator = clones.iterator();
CloneGroup clone = clonesIterator.next();
assertThat(clone.getCloneUnitLength(), is(1));
assertThat(clone.getCloneParts().size(), is(2));
assertThat(clone.getOriginPart(), is(new ClonePart("a", 0, 0, 1)));
assertThat(clone.getCloneParts(), hasItem(new ClonePart("a", 0, 0, 1)));
assertThat(clone.getCloneParts(), hasItem(new ClonePart("a", 2, 0, 1)));
}
use of org.sonar.duplications.block.Block in project sonarqube by SonarSource.
the class DetectorTestCase method newBlocks.
protected static Block[] newBlocks(String resourceId, String hashes) {
List<Block> result = new ArrayList<>();
int indexInFile = 0;
for (int i = 0; i < hashes.length(); i += 2) {
Block block = newBlock(resourceId, new ByteArray("0" + hashes.charAt(i)), indexInFile);
result.add(block);
indexInFile++;
}
return result.toArray(new Block[result.size()]);
}
use of org.sonar.duplications.block.Block in project sonarqube by SonarSource.
the class PmdBlockChunker method chunk.
/**
* @return ArrayList as we need a serializable object
*/
public List<Block> chunk(String resourceId, List<TokensLine> fragments) {
List<TokensLine> filtered = new ArrayList<>();
int i = 0;
while (i < fragments.size()) {
TokensLine first = fragments.get(i);
int j = i + 1;
while (j < fragments.size() && fragments.get(j).getValue().equals(first.getValue())) {
j++;
}
filtered.add(fragments.get(i));
if (i < j - 1) {
filtered.add(fragments.get(j - 1));
}
i = j;
}
fragments = filtered;
if (fragments.size() < blockSize) {
return new ArrayList<>();
}
TokensLine[] fragmentsArr = fragments.toArray(new TokensLine[fragments.size()]);
List<Block> blocks = new ArrayList<>(fragmentsArr.length - blockSize + 1);
long hash = 0;
int first = 0;
int last = 0;
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 = 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();
}
return blocks;
}
use of org.sonar.duplications.block.Block in project sonarqube by SonarSource.
the class BlocksGroup method subsumedBy.
/**
* One group is subsumed by another group, when each block from first group has corresponding block from second group
* with same resource id and with corrected index.
*/
private static boolean subsumedBy(BlocksGroup group1, BlocksGroup group2, int indexCorrection) {
List<Block> list1 = group1.blocks;
List<Block> list2 = group2.blocks;
int i = 0;
int j = 0;
while (i < list1.size() && j < list2.size()) {
Block block1 = list1.get(i);
Block block2 = list2.get(j);
int c = RESOURCE_ID_COMPARATOR.compare(block1.getResourceId(), block2.getResourceId());
if (c != 0) {
j++;
continue;
}
c = block1.getIndexInFile() - indexCorrection - block2.getIndexInFile();
if (c < 0) {
// list1[i] < list2[j]
break;
}
if (c != 0) {
// list1[i] != list2[j]
j++;
}
if (c == 0) {
// list1[i] == list2[j]
i++;
j++;
}
}
return i == list1.size();
}
use of org.sonar.duplications.block.Block in project sonarqube by SonarSource.
the class OriginalCloneDetectionAlgorithm method reportClones.
private void reportClones(BlocksGroup beginGroup, BlocksGroup endGroup, int cloneLength) {
List<Block[]> pairs = beginGroup.pairs(endGroup, cloneLength);
ClonePart origin = null;
List<ClonePart> parts = new ArrayList<>();
for (int i = 0; i < pairs.size(); i++) {
Block[] pair = pairs.get(i);
Block firstBlock = pair[0];
Block lastBlock = pair[1];
ClonePart part = new ClonePart(firstBlock.getResourceId(), firstBlock.getIndexInFile(), firstBlock.getStartLine(), lastBlock.getEndLine());
if (originResourceId.equals(part.getResourceId())) {
if (origin == null || part.getUnitStart() < origin.getUnitStart()) {
origin = part;
}
}
parts.add(part);
}
filter.add(CloneGroup.builder().setLength(cloneLength).setOrigin(origin).setParts(parts).build());
}
Aggregations