@VisibleForTesting final void saveDuplications(final DefaultInputComponent component, List<CloneGroup> duplications) { if (duplications.size() > MAX_CLONE_GROUP_PER_FILE) { LOG.warn("Too many duplication groups on file {}. Keep only the first {} groups.", component, MAX_CLONE_GROUP_PER_FILE); } Iterable<ScannerReport.Duplication> reportDuplications = duplications.stream() .limit(MAX_CLONE_GROUP_PER_FILE) .map( new Function<CloneGroup, Duplication>() { private final ScannerReport.Duplication.Builder dupBuilder = ScannerReport.Duplication.newBuilder(); private final ScannerReport.Duplicate.Builder blockBuilder = ScannerReport.Duplicate.newBuilder(); @Override public ScannerReport.Duplication apply(CloneGroup input) { return toReportDuplication(component, dupBuilder, blockBuilder, input); } })::iterator; publisher.getWriter().writeComponentDuplications(component.scannerId(), reportDuplications); }
assertThat(cloneGroupFile1.getOriginPosition().getEndLine()).isEqualTo(17); assertThat(cloneGroupFile1.getDuplicateList()).hasSize(1); assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile2).getRef()); assertThat(cloneGroupFile2.getOriginPosition().getEndLine()).isEqualTo(17); assertThat(cloneGroupFile2.getDuplicateList()).hasSize(1); assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile1).getRef());
@Test public void testIntraFileDuplications() throws IOException { File srcDir = new File(baseDir, "src"); srcDir.mkdir(); String content = "Sample xoo\ncontent\nfoo\nbar\nSample xoo\ncontent\n"; File xooFile = new File(srcDir, "sample.xoo"); FileUtils.write(xooFile, content); AnalysisResult result = tester.newAnalysis() .properties(builder .put("sonar.sources", "src") .put("sonar.cpd.xoo.minimumTokens", "2") .put("sonar.cpd.xoo.minimumLines", "2") .put("sonar.verbose", "true") .build()) .execute(); InputFile inputFile = result.inputFile("src/sample.xoo"); // One clone group List<ScannerReport.Duplication> duplicationGroups = result.duplicationsFor(inputFile); assertThat(duplicationGroups).hasSize(1); ScannerReport.Duplication cloneGroup = duplicationGroups.get(0); assertThat(cloneGroup.getOriginPosition().getStartLine()).isEqualTo(1); assertThat(cloneGroup.getOriginPosition().getEndLine()).isEqualTo(2); assertThat(cloneGroup.getDuplicateList()).hasSize(1); assertThat(cloneGroup.getDuplicate(0).getRange().getStartLine()).isEqualTo(5); assertThat(cloneGroup.getDuplicate(0).getRange().getEndLine()).isEqualTo(6); }
@VisibleForTesting final void saveDuplications(final DefaultInputComponent component, List<CloneGroup> duplications) { if (duplications.size() > MAX_CLONE_GROUP_PER_FILE) { LOG.warn("Too many duplication groups on file {}. Keep only the first {} groups.", component, MAX_CLONE_GROUP_PER_FILE); } Iterable<ScannerReport.Duplication> reportDuplications = duplications.stream() .limit(MAX_CLONE_GROUP_PER_FILE) .map( new Function<CloneGroup, Duplication>() { private final ScannerReport.Duplication.Builder dupBuilder = ScannerReport.Duplication.newBuilder(); private final ScannerReport.Duplicate.Builder blockBuilder = ScannerReport.Duplicate.newBuilder(); @Override public ScannerReport.Duplication apply(CloneGroup input) { return toReportDuplication(component, dupBuilder, blockBuilder, input); } })::iterator; publisher.getWriter().writeComponentDuplications(component.scannerId(), reportDuplications); }
@Override @Nonnull public Duplicate apply(@Nonnull ScannerReport.Duplicate input) { if (input.getOtherFileRef() != 0) { checkArgument(input.getOtherFileRef() != file.getReportAttributes().getRef(), "file and otherFile references can not be the same"); return new InProjectDuplicate( treeRootHolder.getComponentByRef(input.getOtherFileRef()), convert(input.getRange())); } return new InnerDuplicate(convert(input.getRange())); } }
assertThat(cloneGroupFile1.getOriginPosition().getEndLine()).isEqualTo(17); assertThat(cloneGroupFile1.getDuplicateList()).hasSize(1); assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile2).getRef()); assertThat(cloneGroupFile2.getOriginPosition().getEndLine()).isEqualTo(17); assertThat(cloneGroupFile2.getDuplicateList()).hasSize(1); assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile1).getRef());
@Test public void read_duplications() { ScannerReportWriter writer = new ScannerReportWriter(dir); writer.writeMetadata(ScannerReport.Metadata.newBuilder() .setRootComponentRef(1).build()); writer.writeComponent(ScannerReport.Component.newBuilder() .setRef(1).build()); ScannerReport.Duplication duplication = ScannerReport.Duplication.newBuilder() .setOriginPosition(ScannerReport.TextRange.newBuilder() .setStartLine(1) .setEndLine(5) .build()) .addDuplicate(ScannerReport.Duplicate.newBuilder() .setOtherFileRef(2) .setRange(ScannerReport.TextRange.newBuilder() .setStartLine(6) .setEndLine(10) .build()) .build()) .build(); writer.writeComponentDuplications(1, asList(duplication)); ScannerReportReader sut = new ScannerReportReader(dir); assertThat(sut.readComponentDuplications(1)).hasSize(1); }
@Test public void write_duplications() { assertThat(underTest.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isFalse(); ScannerReport.Duplication duplication = ScannerReport.Duplication.newBuilder() .setOriginPosition(ScannerReport.TextRange.newBuilder() .setStartLine(1) .setEndLine(5) .build()) .addDuplicate(ScannerReport.Duplicate.newBuilder() .setOtherFileRef(2) .setRange(ScannerReport.TextRange.newBuilder() .setStartLine(6) .setEndLine(10) .build()) .build()) .build(); underTest.writeComponentDuplications(1, asList(duplication)); assertThat(underTest.hasComponentData(FileStructure.Domain.DUPLICATIONS, 1)).isTrue(); File file = underTest.getFileStructure().fileFor(FileStructure.Domain.DUPLICATIONS, 1); assertThat(file).exists().isFile(); try (CloseableIterator<ScannerReport.Duplication> duplications = Protobuf.readStream(file, ScannerReport.Duplication.parser())) { ScannerReport.Duplication dup = duplications.next(); assertThat(dup.getOriginPosition()).isNotNull(); assertThat(dup.getDuplicateList()).hasSize(1); } }
@Override @Nonnull public Duplicate apply(@Nonnull ScannerReport.Duplicate input) { if (input.getOtherFileRef() != 0) { checkArgument(input.getOtherFileRef() != file.getReportAttributes().getRef(), "file and otherFile references can not be the same"); Component otherComponent = treeRootHolder.getReportTreeComponentByRef(input.getOtherFileRef()); if ((analysisMetadataHolder.isShortLivingBranch() || analysisMetadataHolder.isPullRequest()) && otherComponent.getStatus() == Component.Status.SAME) { return new InExtendedProjectDuplicate(otherComponent, convert(input.getRange())); } else { return new InProjectDuplicate(otherComponent, convert(input.getRange())); } } return new InnerDuplicate(convert(input.getRange())); }
private static ScannerReport.Duplicate createInProjectDuplicate(int componentRef, int line) { return ScannerReport.Duplicate.newBuilder() .setOtherFileRef(componentRef) .setRange(singleLineTextRange(line)) .build(); }
private static ScannerReport.Duplicate createInnerDuplicate(int line) { return ScannerReport.Duplicate.newBuilder() .setRange(singleLineTextRange(line)) .build(); }
private void assertDuplication(Duplication d, int originStartLine, int originEndLine, @Nullable Integer otherFileRef, int rangeStartLine, int rangeEndLine) { assertThat(d.getOriginPosition().getStartLine()).isEqualTo(originStartLine); assertThat(d.getOriginPosition().getEndLine()).isEqualTo(originEndLine); assertThat(d.getDuplicateList()).hasSize(1); if (otherFileRef != null) { assertThat(d.getDuplicate(0).getOtherFileRef()).isEqualTo(otherFileRef); } else { assertThat(d.getDuplicate(0).getOtherFileRef()).isEqualTo(0); } assertThat(d.getDuplicate(0).getRange().getStartLine()).isEqualTo(rangeStartLine); assertThat(d.getDuplicate(0).getRange().getEndLine()).isEqualTo(rangeEndLine); }
private void assertDuplicate(Duplicate d, int otherFileRef, int rangeStartLine, int rangeEndLine) { assertThat(d.getOtherFileRef()).isEqualTo(otherFileRef); assertThat(d.getRange().getStartLine()).isEqualTo(rangeStartLine); assertThat(d.getRange().getEndLine()).isEqualTo(rangeEndLine); }