use of org.revapi.Element in project revapi by revapi.
the class ClassFilterTest method testWith.
static void testWith(ArchiveAndCompilationPath archive, String configJSON, Set<String> expectedResults) throws Exception {
try {
JavaApiAnalyzer apiAnalyzer = new JavaApiAnalyzer(Collections.emptyList());
Revapi r = new Revapi(singleton(JavaApiAnalyzer.class), emptySet(), emptySet(), emptySet());
AnalysisContext ctx = AnalysisContext.builder(r).withConfigurationFromJSON(configJSON).build();
AnalysisContext analyzerCtx = r.prepareAnalysis(ctx).getFirstConfigurationOrNull(JavaApiAnalyzer.class);
apiAnalyzer.initialize(analyzerCtx);
ArchiveAnalyzer archiveAnalyzer = apiAnalyzer.getArchiveAnalyzer(new API(Collections.singletonList(new ShrinkwrapArchive(archive.archive)), null));
ElementForest forest = archiveAnalyzer.analyze();
List<Element> results = forest.search(Element.class, true, new AcceptingFilter(), null);
((JavaArchiveAnalyzer) archiveAnalyzer).getCompilationValve().removeCompiledResults();
List<String> expected = new ArrayList<>(expectedResults);
List<String> actual = results.stream().filter(e -> {
if (e.getArchive() == null) {
return false;
}
if (!(e instanceof JavaModelElement)) {
// exclude annotations
return false;
}
JavaModelElement el = (JavaModelElement) e;
return !el.isInherited();
}).map(Element::getFullHumanReadableString).collect(toList());
Collections.sort(expected);
Collections.sort(actual);
Assert.assertEquals(expected, actual);
} finally {
deleteDir(archive.compilationPath);
}
}
use of org.revapi.Element in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testPreventRecursionWhenConstructingInheritedMembers.
@Test
public void testPreventRecursionWhenConstructingInheritedMembers() throws Exception {
ArchiveAndCompilationPath archive = createCompiledJar("a.jar", "misc/MemberInheritsOwner.java");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(archive.archive)), null), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
forest.getRoots();
Assert.assertEquals(1, forest.getRoots().size());
Predicate<Element> findMethod = c -> "method void MemberInheritsOwner::method()".equals(c.getFullHumanReadableString());
Predicate<Element> findMember1 = c -> "interface MemberInheritsOwner.Member1".equals(c.getFullHumanReadableString());
Predicate<Element> findMember2 = c -> "interface MemberInheritsOwner.Member2".equals(c.getFullHumanReadableString());
Element root = forest.getRoots().first();
Assert.assertEquals(3, root.getChildren().size());
Assert.assertTrue(root.getChildren().stream().anyMatch(findMethod));
Assert.assertTrue(root.getChildren().stream().anyMatch(findMember1));
Assert.assertTrue(root.getChildren().stream().anyMatch(findMember2));
Assert.assertEquals(1, root.getChildren().stream().filter(findMember1).findFirst().get().getChildren().size());
Assert.assertEquals(1, root.getChildren().stream().filter(findMember2).findFirst().get().getChildren().size());
} finally {
deleteDir(archive.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
use of org.revapi.Element in project revapi by revapi.
the class AbstractIncludeExcludeFilter method decide.
@SuppressWarnings("ConstantConditions")
private boolean decide(@Nullable Object element) {
// we don't exclude anything that we don't handle...
if (doNothing || !(element instanceof JavaElement)) {
return true;
}
InclusionState ret = elementResults.get(element);
if (ret != null) {
return ret.toBoolean();
}
JavaElement el = (JavaElement) element;
// exploit the fact that parent elements are always filtered before the children
Element parent = el.getParent();
InclusionState parentInclusionState = parent == null ? InclusionState.UNDECIDED : elementResults.get(parent);
// if we have no record of the parent inclusion, then this is a top-level class. Assume it wants to be included.
if (parentInclusionState == null) {
parentInclusionState = InclusionState.UNDECIDED;
}
// this is a java element, but not a model-based element - i.e. this is an annotation.
if (!(element instanceof JavaModelElement)) {
return decideAnnotation((JavaAnnotationElement) element, parentInclusionState);
}
JavaModelElement javaElement = (JavaModelElement) element;
Stream<String> tested = getTestedElementRepresentations(javaElement);
// let's first assume we're going to inherit the parent's inclusion state
ret = parentInclusionState;
// now see if we need to change that assumption
switch(parentInclusionState) {
case INCLUDED:
// on this element should be excluded
if (excludeTest != null) {
if (tested.anyMatch(s -> excludeTest.test(s))) {
ret = InclusionState.EXCLUDED;
}
}
break;
case EXCLUDED:
if (!canBeReIncluded(javaElement)) {
break;
}
// i.e. this fall-through is intentional.
case UNDECIDED:
// ok, the parent is undecided. This means we have to do the full checks on this element.
List<String> testedList = null;
if (includeTest != null && excludeTest != null) {
testedList = tested.collect(toList());
tested = testedList.stream();
}
if (includeTest != null) {
// ok, there is an include test but the parent is undecided. This means that the parent actually
// didn't match the include test. Let's check with this element.
ret = tested.anyMatch(s -> includeTest.test(s)) ? InclusionState.INCLUDED : InclusionState.EXCLUDED;
}
if (excludeTest != null) {
if (testedList != null) {
tested = testedList.stream();
}
if (tested.anyMatch(s -> excludeTest.test(s))) {
ret = InclusionState.EXCLUDED;
}
}
break;
}
elementResults.put(element, ret);
return ret.toBoolean();
}
use of org.revapi.Element in project revapi by revapi.
the class ReportMojo method reportDifferences.
private void reportDifferences(List<ReportTimeReporter.DifferenceReport> diffs, Sink sink, ResourceBundle bundle, String typeKey) {
if (diffs == null || diffs.isEmpty()) {
return;
}
sink.section3();
sink.sectionTitle3();
sink.text(bundle.getString(typeKey));
sink.sectionTitle3_();
sink.table();
sink.tableRow();
sink.tableHeaderCell();
sink.text(bundle.getString("report.revapi.difference.code"));
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text(bundle.getString("report.revapi.difference.element"));
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text(bundle.getString("report.revapi.difference.description"));
sink.tableHeaderCell_();
sink.tableRow_();
diffs.sort((d1, d2) -> {
String c1 = d1.difference.code;
String c2 = d2.difference.code;
int cmp = c1.compareTo(c2);
if (cmp != 0) {
return cmp;
}
Element e1 = d1.newElement == null ? d1.oldElement : d1.newElement;
Element e2 = d2.newElement == null ? d2.oldElement : d2.newElement;
cmp = e1.getClass().getName().compareTo(e2.getClass().getName());
if (cmp != 0) {
return cmp;
}
return e1.getFullHumanReadableString().compareTo(e2.getFullHumanReadableString());
});
for (ReportTimeReporter.DifferenceReport d : diffs) {
String element = d.oldElement == null ? (d.newElement.getFullHumanReadableString()) : d.oldElement.getFullHumanReadableString();
sink.tableRow();
sink.tableCell();
sink.monospaced();
sink.text(d.difference.code);
sink.monospaced_();
sink.tableCell_();
sink.tableCell();
sink.monospaced();
sink.bold();
sink.text(element);
sink.bold_();
sink.monospaced_();
sink.tableCell();
sink.text(d.difference.description);
sink.tableCell_();
sink.tableRow_();
}
sink.table_();
sink.section3_();
}
use of org.revapi.Element in project revapi by revapi.
the class BuildTimeReporterTest method testJSONEscapedInIgnoreHint.
@Test
public void testJSONEscapedInIgnoreHint() {
BuildTimeReporter reporter = new BuildTimeReporter();
API oldApi = API.builder().build();
API newApi = API.builder().build();
AnalysisContext ctx = AnalysisContext.builder().withOldAPI(oldApi).withNewAPI(newApi).withData(BuildTimeReporter.BREAKING_SEVERITY_KEY, DifferenceSeverity.EQUIVALENT).build();
reporter.initialize(ctx);
Element oldEl = new SimpleElement() {
@Nonnull
@Override
public API getApi() {
return oldApi;
}
@Nullable
@Override
public Archive getArchive() {
return null;
}
@Override
public int compareTo(Element o) {
return 0;
}
@Override
public String toString() {
return "old element";
}
};
Element newEl = new SimpleElement() {
@Nonnull
@Override
public API getApi() {
return newApi;
}
@Nullable
@Override
public Archive getArchive() {
return null;
}
@Override
public int compareTo(Element o) {
return 0;
}
@Override
public String toString() {
return "new element";
}
};
Report report = Report.builder().withNew(newEl).withOld(oldEl).addProblem().withCode("diffs\\myDiff").withDescription("the problem").addClassification(CompatibilityType.BINARY, DifferenceSeverity.BREAKING).addAttachment("shouldBeEscaped", "{\"a\", \"b\"}").done().build();
reporter.report(report);
String resultMessage = reporter.getAllProblemsMessage();
Assert.assertNotNull(resultMessage);
int start = resultMessage.indexOf('{');
int end = resultMessage.lastIndexOf('}');
String json = resultMessage.substring(start, end + 1);
json = json.replace("<<<<< ADD YOUR EXPLANATION FOR THE NECESSITY OF THIS CHANGE >>>>>", "\"\"");
ModelNode parsed = ModelNode.fromJSONString(json);
Assert.assertEquals("diffs\\myDiff", parsed.get("code").asString());
Assert.assertEquals("{\"a\", \"b\"}", parsed.get("shouldBeEscaped").asString());
}
Aggregations