Search in sources :

Example 1 with Difference

use of org.revapi.Difference in project revapi by revapi.

the class JavaElementDifferenceAnalyzer method endAnalysis.

@Override
public Report endAnalysis(@Nullable Element oldElement, @Nullable Element newElement) {
    if (oldElement == nonExistenceOldRoot && newElement == nonExistenceNewRoot) {
        nonExistenceMode = false;
        nonExistenceOldRoot = null;
        nonExistenceNewRoot = null;
    }
    if (conforms(oldElement, newElement, AnnotationElement.class)) {
        // the annotations are always reported at the parent element
        return new Report(Collections.emptyList(), oldElement, newElement);
    }
    List<Difference> differences = new ArrayList<>();
    CheckType lastInterest = checkTypeStack.pop();
    if (lastInterest.isConcrete()) {
        for (Check c : checksStack.pop()) {
            List<Difference> p = c.visitEnd();
            if (p != null) {
                differences.addAll(p);
            }
        }
    }
    if (lastAnnotationResults != null && !lastAnnotationResults.isEmpty()) {
        differences.addAll(lastAnnotationResults);
        lastAnnotationResults.clear();
    }
    if (!differences.isEmpty()) {
        LOG.trace("Detected following problems: {}", differences);
    }
    Timing.LOG.trace("Ended analysis of {} and {}.", oldElement, newElement);
    ListIterator<Difference> it = differences.listIterator();
    while (it.hasNext()) {
        Difference d = it.next();
        if (analysisConfiguration.reportUseForAllDifferences() || analysisConfiguration.getUseReportingCodes().contains(d.code)) {
            StringBuilder oldUseChain = null;
            StringBuilder newUseChain = null;
            if (oldElement != null) {
                oldUseChain = new StringBuilder();
                appendUses(oldEnvironment, oldElement, oldUseChain);
            }
            if (newElement != null) {
                newUseChain = new StringBuilder();
                appendUses(newEnvironment, newElement, newUseChain);
            }
            Map<String, String> atts = new HashMap<>(d.attachments);
            if (oldUseChain != null) {
                atts.put("exampleUseChainInOldApi", oldUseChain.toString());
            }
            if (newUseChain != null) {
                atts.put("exampleUseChainInNewApi", newUseChain.toString());
            }
            d = Difference.builder().addAttachments(atts).addClassifications(d.classification).withCode(d.code).withName(d.name).withDescription(d.description).build();
        }
        it.set(d);
    }
    return new Report(differences, oldElement, newElement);
}
Also used : Report(org.revapi.Report) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Check(org.revapi.java.spi.Check) Difference(org.revapi.Difference)

Example 2 with Difference

use of org.revapi.Difference in project revapi by revapi.

the class AttributeValueChanged method doVisitAnnotation.

@Override
protected List<Difference> doVisitAnnotation(JavaAnnotationElement oldElement, JavaAnnotationElement newElement) {
    if (oldElement == null || newElement == null || !isAccessible(newElement.getParent())) {
        return null;
    }
    AnnotationMirror oldAnnotation = oldElement.getAnnotation();
    AnnotationMirror newAnnotation = newElement.getAnnotation();
    List<Difference> result = new ArrayList<>();
    Map<String, Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> oldAttrs = Util.keyAnnotationAttributesByName(oldAnnotation.getElementValues());
    Map<String, Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> newAttrs = Util.keyAnnotationAttributesByName(newAnnotation.getElementValues());
    for (Map.Entry<String, Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> oldE : oldAttrs.entrySet()) {
        String name = oldE.getKey();
        Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> oldValue = oldE.getValue();
        Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> newValue = newAttrs.get(name);
        if (newValue == null) {
            result.add(createDifference(Code.ANNOTATION_ATTRIBUTE_REMOVED, Code.attachmentsFor(oldElement.getParent(), newElement.getParent(), "annotationType", Util.toHumanReadableString(newElement.getAnnotation().getAnnotationType()), "annotation", Util.toHumanReadableString(newElement.getAnnotation()), "attribute", name, "value", Util.toHumanReadableString(oldValue.getValue()))));
        } else if (!Util.isEqual(oldValue.getValue(), newValue.getValue())) {
            result.add(createDifference(Code.ANNOTATION_ATTRIBUTE_VALUE_CHANGED, Code.attachmentsFor(oldElement.getParent(), newElement.getParent(), "annotationType", Util.toHumanReadableString(newElement.getAnnotation().getAnnotationType()), "annotation", Util.toHumanReadableString(newElement.getAnnotation()), "attribute", name, "oldValue", Util.toHumanReadableString(oldValue.getValue()), "newValue", Util.toHumanReadableString(newValue.getValue()))));
        }
        newAttrs.remove(name);
    }
    for (Map.Entry<String, Map.Entry<? extends ExecutableElement, ? extends AnnotationValue>> newE : newAttrs.entrySet()) {
        String name = newE.getKey();
        Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> newValue = newE.getValue();
        Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> oldValue = oldAttrs.get(name);
        if (oldValue == null) {
            result.add(createDifference(Code.ANNOTATION_ATTRIBUTE_ADDED, Code.attachmentsFor(oldElement.getParent(), newElement.getParent(), "annotationType", Util.toHumanReadableString(newElement.getAnnotation().getAnnotationType()), "annotation", Util.toHumanReadableString(newElement.getAnnotation()), "attribute", name, "value", Util.toHumanReadableString(newValue.getValue()))));
        }
    }
    return result.isEmpty() ? null : result;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) AnnotationValue(javax.lang.model.element.AnnotationValue) Difference(org.revapi.Difference) Map(java.util.Map)

Example 3 with Difference

use of org.revapi.Difference in project revapi by revapi.

the class Added method doEnd.

@Override
protected List<Difference> doEnd() {
    ActiveElements<JavaTypeElement> types = popIfActive();
    if (types != null) {
        TypeElement typeInOld = getOldTypeEnvironment().getElementUtils().getTypeElement(types.newElement.getDeclaringElement().getQualifiedName());
        String[] attachments = Code.attachmentsFor(types.oldElement, types.newElement);
        Difference difference = typeInOld == null ? createDifference(Code.CLASS_ADDED, attachments) : createDifference(Code.CLASS_EXTERNAL_CLASS_EXPOSED_IN_API, attachments);
        return Collections.singletonList(difference);
    }
    return null;
}
Also used : JavaTypeElement(org.revapi.java.spi.JavaTypeElement) TypeElement(javax.lang.model.element.TypeElement) Difference(org.revapi.Difference) JavaTypeElement(org.revapi.java.spi.JavaTypeElement)

Example 4 with Difference

use of org.revapi.Difference in project revapi by revapi.

the class KindChanged method doEnd.

@Override
protected List<Difference> doEnd() {
    ActiveElements<JavaTypeElement> types = popIfActive();
    if (types != null) {
        TypeElement o = types.oldElement.getDeclaringElement();
        TypeElement n = types.newElement.getDeclaringElement();
        if (o.getKind() != n.getKind()) {
            Difference p = createDifference(Code.CLASS_KIND_CHANGED, Code.attachmentsFor(types.oldElement, types.newElement, "oldKind", kind(o), "newKind", kind(n)));
            return Collections.singletonList(p);
        }
    }
    return null;
}
Also used : JavaTypeElement(org.revapi.java.spi.JavaTypeElement) TypeElement(javax.lang.model.element.TypeElement) Difference(org.revapi.Difference) JavaTypeElement(org.revapi.java.spi.JavaTypeElement)

Example 5 with Difference

use of org.revapi.Difference in project revapi by revapi.

the class AntReporter method report.

@Override
public void report(@Nonnull Report report) {
    Element element = report.getOldElement();
    if (element == null) {
        element = report.getNewElement();
    }
    if (element == null) {
        throw new IllegalStateException("This should not ever happen. Both elements in a report were null.");
    }
    for (Difference difference : report.getDifferences()) {
        DifferenceSeverity maxSeverity = DifferenceSeverity.NON_BREAKING;
        for (Map.Entry<CompatibilityType, DifferenceSeverity> e : difference.classification.entrySet()) {
            if (e.getValue().compareTo(maxSeverity) >= 0) {
                maxSeverity = e.getValue();
            }
        }
        if (maxSeverity.compareTo(minSeverity) < 0) {
            continue;
        }
        StringBuilder message = new StringBuilder();
        message.append(element.getFullHumanReadableString()).append(": ").append(difference.code).append(": ").append(difference.description).append(" [");
        for (Map.Entry<CompatibilityType, DifferenceSeverity> e : difference.classification.entrySet()) {
            message.append(e.getKey()).append(": ").append(e.getValue()).append(", ");
        }
        message.replace(message.length() - 2, message.length(), "]");
        logger.log(message.toString(), Project.MSG_ERR);
    }
}
Also used : DifferenceSeverity(org.revapi.DifferenceSeverity) CompatibilityType(org.revapi.CompatibilityType) Element(org.revapi.Element) Difference(org.revapi.Difference) Map(java.util.Map)

Aggregations

Difference (org.revapi.Difference)22 ArrayList (java.util.ArrayList)7 Test (org.junit.Test)6 AnalysisContext (org.revapi.AnalysisContext)6 JavaTypeElement (org.revapi.java.spi.JavaTypeElement)6 TypeElement (javax.lang.model.element.TypeElement)5 Map (java.util.Map)4 TypeMirror (javax.lang.model.type.TypeMirror)4 Report (org.revapi.Report)4 List (java.util.List)3 JavaMethodElement (org.revapi.java.spi.JavaMethodElement)3 Nullable (javax.annotation.Nullable)2 AnnotationValue (javax.lang.model.element.AnnotationValue)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 CoIterator (org.revapi.CoIterator)2 DifferenceSeverity (org.revapi.DifferenceSeverity)2 Element (org.revapi.Element)2 Util (org.revapi.java.spi.Util)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1