use of org.revapi.java.spi.Code in project revapi by revapi.
the class InheritanceChainChanged method doEnd.
@Override
protected List<Difference> doEnd() {
ActiveElements<JavaTypeElement> types = popIfActive();
if (types != null) {
List<Difference> ret = new ArrayList<>();
@SuppressWarnings("unchecked") List<TypeMirror> oldSuperClasses = (List<TypeMirror>) types.context[0];
@SuppressWarnings("unchecked") List<TypeMirror> newSuperClasses = (List<TypeMirror>) types.context[1];
Comparator<TypeMirror> typeNameComparator = Comparator.comparing(Util::toUniqueString);
List<TypeMirror> removedSuperClasses = new ArrayList<>();
List<TypeMirror> addedSuperClasses = new ArrayList<>();
oldSuperClasses.sort(typeNameComparator);
newSuperClasses.sort(typeNameComparator);
CoIterator<TypeMirror> iterator = new CoIterator<>(oldSuperClasses.iterator(), newSuperClasses.iterator(), typeNameComparator);
while (iterator.hasNext()) {
iterator.next();
TypeMirror oldType = iterator.getLeft();
TypeMirror newType = iterator.getRight();
if (oldType == null) {
addedSuperClasses.add(newType);
} else if (newType == null) {
removedSuperClasses.add(oldType);
}
}
// this will give us the equivalent of removed/added superclasses but ordered by the inheritance chain
// not by name
removedSuperClasses = retainInCopy(oldSuperClasses, removedSuperClasses);
addedSuperClasses = retainInCopy(newSuperClasses, addedSuperClasses);
Iterator<TypeMirror> removedIt = removedSuperClasses.iterator();
Iterator<TypeMirror> addedIt = addedSuperClasses.iterator();
// always report the most concrete classes
if (removedIt.hasNext()) {
removedIt.next();
}
if (addedIt.hasNext()) {
addedIt.next();
}
// ok, now we only have super types left of the most concrete removed/added super class.
// we are only going to report those that changed their inheritance hierarchy in the other version of the API.
removeClassesWithEquivalentSuperClassChain(removedIt, getOldTypeEnvironment(), getNewTypeEnvironment());
removeClassesWithEquivalentSuperClassChain(addedIt, getNewTypeEnvironment(), getOldTypeEnvironment());
for (TypeMirror t : removedSuperClasses) {
String str = Util.toHumanReadableString(t);
ret.add(createDifference(Code.CLASS_NO_LONGER_INHERITS_FROM_CLASS, Code.attachmentsFor(types.oldElement, types.newElement, "superClass", str)));
}
for (TypeMirror t : addedSuperClasses) {
String str = Util.toHumanReadableString(t);
Code code = types.oldElement.getDeclaringElement().getModifiers().contains(Modifier.FINAL) ? Code.CLASS_FINAL_CLASS_INHERITS_FROM_NEW_CLASS : Code.CLASS_NON_FINAL_CLASS_INHERITS_FROM_NEW_CLASS;
ret.add(createDifference(code, Code.attachmentsFor(types.oldElement, types.newElement, "superClass", str)));
// additionally add a difference about checked exceptions
if (changedToCheckedException(getNewTypeEnvironment().getTypeUtils(), t, oldSuperClasses)) {
ret.add(createDifference(Code.CLASS_NOW_CHECKED_EXCEPTION, Code.attachmentsFor(types.oldElement, types.newElement)));
}
}
return ret;
}
return null;
}
use of org.revapi.java.spi.Code in project revapi by revapi.
the class ReturnTypeChanged method doEnd.
@Nullable
@Override
protected List<Difference> doEnd() {
ActiveElements<JavaMethodElement> methods = popIfActive();
if (methods == null) {
return null;
}
TypeMirror oldReturnType = methods.oldElement.getModelRepresentation().getReturnType();
TypeMirror newReturnType = methods.newElement.getModelRepresentation().getReturnType();
TypeMirror erasedOldType = getOldTypeEnvironment().getTypeUtils().erasure(oldReturnType);
TypeMirror erasedNewType = getNewTypeEnvironment().getTypeUtils().erasure(newReturnType);
String oldR = Util.toUniqueString(oldReturnType);
String newR = Util.toUniqueString(newReturnType);
String oldER = Util.toUniqueString(erasedOldType);
String newER = Util.toUniqueString(erasedNewType);
Code code = null;
if (!oldER.equals(newER)) {
// we need to check if the returned type changed covariantly or not.
if (isPrimitiveOrVoid(erasedOldType) || isPrimitiveOrVoid(erasedNewType)) {
code = Code.METHOD_RETURN_TYPE_CHANGED;
} else if (isCovariant(erasedOldType, erasedNewType)) {
code = Code.METHOD_RETURN_TYPE_CHANGED_COVARIANTLY;
} else {
code = Code.METHOD_RETURN_TYPE_CHANGED;
}
} else {
if (!oldR.equals(newR)) {
code = Code.METHOD_RETURN_TYPE_TYPE_PARAMETERS_CHANGED;
}
}
String oldHR = Util.toHumanReadableString(oldReturnType);
String newHR = Util.toHumanReadableString(newReturnType);
return code == null ? null : Collections.singletonList(createDifference(code, Code.attachmentsFor(methods.oldElement, methods.newElement, "oldType", oldHR, "newType", newHR)));
}
use of org.revapi.java.spi.Code in project revapi by revapi.
the class MovedInHierarchy method doEnd.
@Nullable
@Override
protected List<Difference> doEnd() {
ActiveElements<JavaModelElement> els = popIfActive();
if (els == null) {
return null;
}
String oldType = Util.toHumanReadableString(els.oldElement.getDeclaringElement().getEnclosingElement().asType());
String newType = Util.toHumanReadableString(els.newElement.getDeclaringElement().getEnclosingElement().asType());
// we know that oldEl.isInherited() != newEl.isInherited(), so it's enough to just check for the old
Code code = els.oldElement.isInherited() ? moveDown : moveUp;
return Collections.singletonList(createDifference(code, Code.attachmentsFor(els.oldElement, els.newElement, "oldClass", oldType, "newClass", newType)));
}
Aggregations