private static Iterable<Duplicate> convertClonePartsToDuplicates(final Component file, CloneGroup duplication) { final ClonePart originPart = duplication.getOriginPart(); return from(duplication.getCloneParts()) .filter(new DoesNotMatchSameComponentKey(originPart.getResourceId())) .filter(new DuplicateLimiter(file, originPart)) .transform(ClonePartToCrossProjectDuplicate.INSTANCE); }
@Test public void testDuplicationInSingleFile() throws IOException { File file = new File("test-resources/org/sonar/duplications/cpd/CPDTest/CPDFile3.java"); addToIndex(file); List<CloneGroup> duplications = detect(file); assertThat(duplications.size()).isEqualTo(1); CloneGroup duplication = duplications.get(0); assertThat(duplication.getOriginPart().getResourceId()).isEqualTo(file.getAbsolutePath()); assertThat(duplication.getCloneParts().size()).isEqualTo(2); assertThat(duplication.getLengthInUnits()).as("length in tokens").isEqualTo(157); ClonePart part = duplication.getCloneParts().get(0); assertThat(part.getResourceId()).isEqualTo(file.getAbsolutePath()); assertThat(part.getStartLine()).isEqualTo(30); assertThat(part.getEndLine()).isEqualTo(44); }
@Test public void testNumberOfUnitsNotLessThan() { Predicate<CloneGroup> predicate = DuplicationPredicates.numberOfUnitsNotLessThan(5); assertThat(predicate.test(CloneGroup.builder().setLengthInUnits(6).build())).isTrue(); assertThat(predicate.test(CloneGroup.builder().setLengthInUnits(5).build())).isTrue(); assertThat(predicate.test(CloneGroup.builder().setLengthInUnits(4).build())).isFalse(); }
if (first.getCloneUnitLength() > second.getCloneUnitLength()) { return false; List<ClonePart> firstParts = first.getCloneParts(); List<ClonePart> secondParts = second.getCloneParts(); return SortedListsUtils.contains(secondParts, firstParts, new ContainsInComparator(second.getCloneUnitLength(), first.getCloneUnitLength())) && SortedListsUtils.contains(firstParts, secondParts, ContainsInComparator.RESOURCE_ID_COMPARATOR);
@Override public boolean matchesSafely(CloneGroup cloneGroup) { // Check length if (expectedLen != cloneGroup.getCloneUnitLength()) { return false; } // Check number of parts if (expectedParts.length != cloneGroup.getCloneParts().size()) { return false; } // Check origin if (!expectedParts[0].equals(cloneGroup.getOriginPart())) { return false; } // Check parts for (ClonePart expectedPart : expectedParts) { boolean matched = false; for (ClonePart part : cloneGroup.getCloneParts()) { if (part.equals(expectedPart)) { matched = true; break; } } if (!matched) { return false; } } return true; }
public static Predicate<CloneGroup> numberOfUnitsNotLessThan(int min) { return input -> input != null && input.getLengthInUnits() >= min; } }
private void addDuplication(Component file, CloneGroup duplication) { ClonePart originPart = duplication.getOriginPart(); Iterable<Duplicate> duplicates = convertClonePartsToDuplicates(file, duplication); if (!Iterables.isEmpty(duplicates)) { duplicationRepository.add( file, new Duplication(new TextBlock(originPart.getStartLine(), originPart.getEndLine()), duplicates)); } }
/** * Given: * <pre> * c1: a[0-2] * c2: a[0-0] * </pre> * Expected: * <pre> * c1 not in c2 * </pre> */ @Test public void length_of_C1_bigger_than_length_of_C2() { CloneGroup c1 = spy(newCloneGroup(3, newClonePart("a", 0))); CloneGroup c2 = spy(newCloneGroup(1, newClonePart("a", 0))); assertThat(Filter.containsIn(c1, c2), is(false)); // containsIn method should check only origin and length - no need to compare all parts verify(c1).getCloneUnitLength(); verify(c2).getCloneUnitLength(); verifyNoMoreInteractions(c1); verifyNoMoreInteractions(c2); }
public CloneGroup build() { return new CloneGroup(this); } }
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)));
List<ClonePart> firstParts = first.getCloneParts(); List<ClonePart> secondParts = second.getCloneParts(); return SortedListsUtils.contains(secondParts, firstParts, new ContainsInComparator(second.getCloneUnitLength(), first.getCloneUnitLength())) && SortedListsUtils.contains(firstParts, secondParts, ContainsInComparator.RESOURCE_ID_COMPARATOR);
@Override public boolean apply(@Nonnull CloneGroup input) { return input.getLengthInUnits() >= min; } }
@Test public void type1() { String fragment0 = source( "if (a >= b) {", " c = d + b; // Comment1", " d = d + 1;}", "else", " c = d - a; // Comment2"); String fragment1 = source( "if (a>=b) {", " // Comment1", " c=d+b;", " d=d+1;", "} else // Comment2", " c=d-a;"); List<CloneGroup> duplications = detect2(fragment0, fragment1); assertThat(duplications.size(), is(1)); ClonePart part = duplications.get(0).getOriginPart(); assertThat(part.getStartLine(), is(1)); assertThat(part.getEndLine(), is(5)); }
public CloneGroup build() { return new CloneGroup(this); } }
private Duplication toReportDuplication(InputComponent component, Duplication.Builder dupBuilder, Duplicate.Builder blockBuilder, CloneGroup input) { dupBuilder.clear(); ClonePart originBlock = input.getOriginPart(); blockBuilder.clear(); dupBuilder.setOriginPosition(ScannerReport.TextRange.newBuilder() .build()); int clonePartCount = 0; for (ClonePart duplicate : input.getCloneParts()) { if (!duplicate.equals(originBlock)) { clonePartCount++;
@Test public void testDuplicationBetweenTwoFiles() throws IOException { File file1 = new File("test-resources/org/sonar/duplications/cpd/CPDTest/CPDFile1.java"); File file2 = new File("test-resources/org/sonar/duplications/cpd/CPDTest/CPDFile2.java"); addToIndex(file1); addToIndex(file2); List<CloneGroup> duplications = detect(file1); assertThat(duplications.size()).isEqualTo(1); CloneGroup duplication = duplications.get(0); assertThat(duplication.getOriginPart().getResourceId()).isEqualTo(file1.getAbsolutePath()); ClonePart part1 = new ClonePart(file1.getAbsolutePath(), 1, 18, 41); ClonePart part2 = new ClonePart(file2.getAbsolutePath(), 1, 18, 41); assertThat(duplication.getCloneParts()).containsOnly(part1, part2); assertThat(duplication.getLengthInUnits()).as("length in tokens").isEqualTo(115); }
if (first.getCloneUnitLength() > second.getCloneUnitLength()) { return false; List<ClonePart> firstParts = first.getCloneParts(); List<ClonePart> secondParts = second.getCloneParts(); return SortedListsUtils.contains(secondParts, firstParts, new ContainsInComparator(second.getCloneUnitLength(), first.getCloneUnitLength())) && SortedListsUtils.contains(firstParts, secondParts, ContainsInComparator.RESOURCE_ID_COMPARATOR);
public static Predicate<CloneGroup> numberOfUnitsNotLessThan(int min) { return input -> input != null && input.getLengthInUnits() >= min; } }
/** * Supports only subset of Type 2. * * @see #type2 * @see #literalsNormalization() */ @Test public void type2_literals() { String fragment0 = source( "if (a >= b) {", " c = b + 1; // Comment1", " d = '1';}", "else", " c = d - a; // Comment2"); String fragment1 = source( "if (a >= b) {", " c = b + 2; // Comment1", " d = '2';}", "else", " c = d - a; // Comment2"); List<CloneGroup> duplications = detect2(fragment0, fragment1); assertThat(duplications.size(), is(1)); ClonePart part = duplications.get(0).getOriginPart(); assertThat(part.getStartLine(), is(1)); assertThat(part.getEndLine(), is(5)); }
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()); }