use of org.revapi.java.spi.JavaModelElement in project revapi by revapi.
the class JavaElementDifferenceAnalyzer method appendUseType.
private boolean appendUseType(ProbingEnvironment env, JavaTypeElement ut, List<TypeAndUseSite> path, JavaTypeElement usedType, DeclaredType type, UseSite currentUse, Set<javax.lang.model.element.TypeElement> visitedTypes) {
javax.lang.model.element.TypeElement useType = ut.getDeclaringElement();
if (visitedTypes.contains(useType)) {
return false;
}
visitedTypes.add(useType);
if (ut.isInAPI() && !ut.isInApiThroughUse() && !ut.equals(usedType)) {
// the class is in the primary API
path.add(0, new TypeAndUseSite(type, currentUse));
return true;
} else {
Boolean ret = ut.visitUseSites(new UseSite.Visitor<Boolean, Void>() {
@Nullable
@Override
public Boolean visit(@Nonnull DeclaredType visitedType, @Nonnull UseSite use, @Nullable Void parameter) {
if (traverseToApi(env, usedType, visitedType, use, path, visitedTypes)) {
path.add(0, new TypeAndUseSite(type, currentUse));
return true;
}
return null;
}
@Nullable
@Override
public Boolean end(DeclaredType type, @Nullable Void parameter) {
return null;
}
}, null);
if (ret == null) {
Set<javax.lang.model.element.TypeElement> derivedUseTypes = env.getDerivedTypes(useType);
for (javax.lang.model.element.TypeElement dut : derivedUseTypes) {
TypeElement model = env.getTypeMap().get(dut);
if (model == null) {
continue;
}
JavaModelElement derivedUseElement = findSameDeclarationUnder(currentUse.getSite(), model);
if (derivedUseElement == null) {
continue;
}
UseSite derivedUse = new UseSite(currentUse.getUseType(), derivedUseElement);
if (appendUseType(env, model, path, usedType, type, derivedUse, visitedTypes)) {
ret = true;
break;
}
}
}
return ret == null ? false : ret;
}
}
use of org.revapi.java.spi.JavaModelElement 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.java.spi.JavaModelElement in project revapi by revapi.
the class TypeElement method getModel.
private JavaModelElement getModel(Element element, int indexInParent) {
return element.accept(new SimpleElementVisitor8<JavaModelElement, Void>() {
@Override
public JavaModelElement visitVariable(VariableElement e, Void ignored) {
if (e.getEnclosingElement() instanceof javax.lang.model.element.TypeElement) {
// this is a field
TypeElement type = environment.getTypeMap().get(e.getEnclosingElement());
if (type == null) {
return null;
}
List<FieldElement> fs = type.searchChildren(FieldElement.class, false, FlatFilter.by(f -> f.getDeclaringElement().equals(e)));
return fs.get(0);
} else if (e.getEnclosingElement() instanceof javax.lang.model.element.ExecutableElement) {
// this is a method parameter
Element methodEl = e.getEnclosingElement();
TypeElement type = environment.getTypeMap().get(methodEl.getEnclosingElement());
if (type == null) {
return null;
}
List<MethodElement> ms = type.searchChildren(MethodElement.class, false, FlatFilter.by(m -> m.getDeclaringElement().equals(methodEl)));
MethodElement method = ms.get(0);
// now look for the parameter
List<MethodParameterElement> params = method.searchChildren(MethodParameterElement.class, false, FlatFilter.by(p -> true));
return params.get(indexInParent);
} else {
return null;
}
}
@Override
public JavaModelElement visitType(javax.lang.model.element.TypeElement e, Void ignored) {
return environment.getTypeMap().get(e);
}
@Override
public JavaModelElement visitExecutable(ExecutableElement e, Void ignored) {
TypeElement type = environment.getTypeMap().get(e.getEnclosingElement());
if (type == null) {
return null;
}
List<MethodElement> ms = type.searchChildren(MethodElement.class, false, FlatFilter.by(m -> m.getDeclaringElement().equals(e)));
return ms.get(0);
}
}, null);
}
use of org.revapi.java.spi.JavaModelElement 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.java.spi.JavaModelElement in project revapi by revapi.
the class SupplementaryJarsTest method testSupplementaryJarsAreTakenIntoAccountWhenComputingAPI.
@Test
public void testSupplementaryJarsAreTakenIntoAccountWhenComputingAPI() throws Exception {
List<Report> allReports;
Revapi revapi = createRevapi(CollectingReporter.class);
AnalysisContext ctx = AnalysisContext.builder(revapi).withOldAPI(API.of(new ShrinkwrapArchive(apiV1)).supportedBy(new ShrinkwrapArchive(supV1)).build()).withNewAPI(API.of(new ShrinkwrapArchive(apiV2)).supportedBy(new ShrinkwrapArchive(supV2)).build()).build();
try (AnalysisResult res = revapi.analyze(ctx)) {
Assert.assertTrue(res.isSuccess());
allReports = res.getExtensions().getFirstExtension(CollectingReporter.class, null).getReports();
}
// 11 removed methods when kind of class changes to interface
Assert.assertEquals(8 + 11, allReports.size());
Assert.assertTrue(containsDifference(allReports, null, "class B.T$1.Private", Code.CLASS_NON_PUBLIC_PART_OF_API.code()));
Assert.assertTrue(containsDifference(allReports, null, "field B.T$2.f2", Code.FIELD_ADDED.code()));
Assert.assertTrue(containsDifference(allReports, null, "field A.f3", Code.FIELD_ADDED.code()));
Assert.assertTrue(containsDifference(allReports, "class B.T$2", "class B.T$2", Code.CLASS_NOW_FINAL.code()));
Assert.assertTrue(containsDifference(allReports, null, "class B.T$3", Code.CLASS_ADDED.code()));
Assert.assertTrue(containsDifference(allReports, null, "class B.PrivateUsedClass", Code.CLASS_NON_PUBLIC_PART_OF_API.code()));
Assert.assertTrue(containsDifference(allReports, "class B.UsedByIgnoredClass", "interface B.UsedByIgnoredClass", Code.CLASS_KIND_CHANGED.code()));
Assert.assertTrue(containsDifference(allReports, "method void B.UsedByIgnoredClass::<init>()", null, Code.METHOD_REMOVED.code()));
// eleven methods removed when kind changed, because interface doesn't have the methods of Object
Assert.assertEquals(11, allReports.stream().filter(r -> {
javax.lang.model.element.TypeElement oldType = null;
if (r.getOldElement() == null || !(r.getOldElement() instanceof JavaModelElement)) {
return false;
}
javax.lang.model.element.Element old = ((JavaModelElement) r.getOldElement()).getDeclaringElement();
do {
if (old instanceof javax.lang.model.element.TypeElement) {
oldType = (javax.lang.model.element.TypeElement) old;
break;
}
old = old.getEnclosingElement();
} while (old != null);
if (oldType == null) {
return false;
}
return oldType.getQualifiedName().contentEquals("java.lang.Object");
}).flatMap(r -> r.getDifferences().stream()).count());
}
Aggregations