use of org.revapi.java.model.TypeElement in project revapi by revapi.
the class JavaApiAnalyzer method getCorrespondenceDeducer.
@Override
@Nonnull
public CorrespondenceComparatorDeducer getCorrespondenceDeducer() {
return (l1, l2) -> {
if (l1.isEmpty() || l2.isEmpty()) {
return Comparator.naturalOrder();
}
// quickly peek inside to see if there even can be methods in the lists - all of the elements in either list
// will have a common parent and parents of both lists will have the same type or be both null.
Element parent = l1.get(0).getParent();
if (!(parent instanceof TypeElement)) {
return Comparator.naturalOrder();
}
IdentityHashMap<MethodElement, Integer> c1MethodOrder = new IdentityHashMap<>(l1.size());
IdentityHashMap<MethodElement, Integer> c2MethodOrder = new IdentityHashMap<>(l2.size());
// this will reorder the methods in the lists and will also fill in the method order indices in the maps
// so that they can be used for comparisons below
determineOrder(l1, l2, c1MethodOrder, c2MethodOrder);
// and return a comparator
return (e1, e2) -> {
int ret = JavaElementFactory.compareByType(e1, e2);
if (ret != 0) {
return ret;
}
// let's just look that up.
if (e1 instanceof MethodElement && e2 instanceof MethodElement) {
MethodElement m1 = (MethodElement) e1;
MethodElement m2 = (MethodElement) e2;
return c1MethodOrder.get(m1) - c2MethodOrder.get(m2);
} else {
return e1.compareTo(e2);
}
};
};
}
use of org.revapi.java.model.TypeElement 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.model.TypeElement in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testTypeParametersDragIntoAPI.
@Test
public void testTypeParametersDragIntoAPI() throws Exception {
ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "misc/Generics.java", "misc/GenericsParams.java");
JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("Generics.class").toFile(), "Generics.class");
JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("GenericsParams.class").toFile(), "GenericsParams.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeParam.class").toFile(), "GenericsParams$TypeParam.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$ExtendsBound.class").toFile(), "GenericsParams$ExtendsBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$SuperBound.class").toFile(), "GenericsParams$SuperBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVar.class").toFile(), "GenericsParams$TypeVar.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarIface.class").toFile(), "GenericsParams$TypeVarIface.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarImpl.class").toFile(), "GenericsParams$TypeVarImpl.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$Unused.class").toFile(), "GenericsParams$Unused.class");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
Set<TypeElement> roots = forest.getRoots();
Assert.assertEquals(7, roots.size());
Assert.assertTrue(roots.stream().anyMatch(hasName("class Generics<T extends GenericsParams.TypeVar, GenericsParams.TypeVarIface, U extends Generics<GenericsParams.TypeVarImpl, ?>>")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.ExtendsBound")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.SuperBound")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeParam")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVar")));
Assert.assertTrue(roots.stream().anyMatch(hasName("interface GenericsParams.TypeVarIface")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVarImpl")));
Assert.assertFalse(roots.stream().anyMatch(hasName("class GenericsParams.Unused")));
} finally {
deleteDir(compRes.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
use of org.revapi.java.model.TypeElement in project revapi by revapi.
the class JavaElementDifferenceAnalyzer method beginAnalysis.
@Override
public void beginAnalysis(@Nullable Element oldElement, @Nullable Element newElement) {
Timing.LOG.trace("Beginning analysis of {} and {}.", oldElement, newElement);
Check.Type elementsType = getCheckType(oldElement, newElement);
Collection<Check> possibleChecks = nonExistenceMode ? descendingChecksByTypes.getOrDefault(elementsType, emptySet()) : checksByInterest.get(elementsType);
if (conforms(oldElement, newElement, TypeElement.class)) {
checkTypeStack.push(CheckType.CLASS);
checksStack.push(possibleChecks);
lastAnnotationResults = null;
for (Check c : possibleChecks) {
Stats.of(c.getClass().getName()).start();
c.visitClass(oldElement == null ? null : (TypeElement) oldElement, newElement == null ? null : (TypeElement) newElement);
Stats.of(c.getClass().getName()).end(oldElement, newElement);
}
} else if (conforms(oldElement, newElement, AnnotationElement.class)) {
// treat them a bit differently
if (lastAnnotationResults == null) {
lastAnnotationResults = new ArrayList<>(4);
}
// Annotations are handled differently and this would lead to the stack corruption and missed problems!!!
for (Check c : possibleChecks) {
Stats.of(c.getClass().getName()).start();
List<Difference> cps = c.visitAnnotation(oldElement == null ? null : (AnnotationElement) oldElement, newElement == null ? null : (AnnotationElement) newElement);
if (cps != null) {
lastAnnotationResults.addAll(cps);
}
Stats.of(c.getClass().getName()).end(oldElement, newElement);
}
} else if (conforms(oldElement, newElement, FieldElement.class)) {
doRestrictedCheck((FieldElement) oldElement, (FieldElement) newElement, CheckType.FIELD, possibleChecks);
} else if (conforms(oldElement, newElement, MethodElement.class)) {
doRestrictedCheck((MethodElement) oldElement, (MethodElement) newElement, CheckType.METHOD, possibleChecks);
} else if (conforms(oldElement, newElement, MethodParameterElement.class)) {
doRestrictedCheck((MethodParameterElement) oldElement, (MethodParameterElement) newElement, CheckType.METHOD_PARAMETER, possibleChecks);
}
if (!nonExistenceMode && (oldElement == null || newElement == null)) {
nonExistenceMode = true;
nonExistenceOldRoot = oldElement;
nonExistenceNewRoot = newElement;
}
}
use of org.revapi.java.model.TypeElement in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testWithSupplementary.
@Test
public void testWithSupplementary() throws Exception {
ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "v1/supplementary/a/A.java", "v1/supplementary/b/B.java", "v1/supplementary/a/C.java");
JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("A.class").toFile(), "A.class");
JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("B.class").toFile(), "B.class").addAsResource(compRes.compilationPath.resolve("B$T$1.class").toFile(), "B$T$1.class").addAsResource(compRes.compilationPath.resolve("B$T$1$TT$1.class").toFile(), "B$T$1$TT$1.class").addAsResource(compRes.compilationPath.resolve("B$T$2.class").toFile(), "B$T$2.class").addAsResource(compRes.compilationPath.resolve("C.class").toFile(), "C.class").addAsResource(compRes.compilationPath.resolve("B$UsedByIgnoredClass.class").toFile(), "B$UsedByIgnoredClass.class").addAsResource(compRes.compilationPath.resolve("A$PrivateEnum.class").toFile(), "A$PrivateEnum.class");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
Assert.assertEquals(3, forest.getRoots().size());
Iterator<TypeElement> roots = forest.getRoots().iterator();
TypeElement A = roots.next();
TypeElement B_T$1 = roots.next();
TypeElement B_T$2 = roots.next();
Assert.assertEquals("A", A.getCanonicalName());
Assert.assertEquals("A", A.getDeclaringElement().getQualifiedName().toString());
Assert.assertEquals("B.T$1", B_T$1.getCanonicalName());
Assert.assertEquals("B.T$1", B_T$1.getDeclaringElement().getQualifiedName().toString());
Assert.assertEquals("B.T$2", B_T$2.getCanonicalName());
Assert.assertEquals("B.T$2", B_T$2.getDeclaringElement().getQualifiedName().toString());
} finally {
deleteDir(compRes.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
Aggregations