Search in sources :

Example 1 with Util

use of org.revapi.java.spi.Util in project revapi by revapi.

the class SerialVersionUidChecker method computeStructuralId.

public static long computeStructuralId(TypeElement type, TypeEnvironment environment) {
    Predicate<Element> serializableFields = e -> {
        Set<Modifier> mods = e.getModifiers();
        return !mods.contains(Modifier.TRANSIENT) && !mods.contains(Modifier.STATIC);
    };
    Comparator<Element> bySimpleName = Comparator.comparing(e -> e.getSimpleName().toString());
    List<TypeMirror> fields = ElementFilter.fieldsIn(type.getEnclosedElements()).stream().filter(serializableFields).sorted(bySimpleName).map(Element::asType).collect(Collectors.toList());
    Types types = environment.getTypeUtils();
    for (TypeMirror st : Util.getAllSuperClasses(types, type.asType())) {
        Element ste = types.asElement(st);
        ElementFilter.fieldsIn(ste.getEnclosedElements()).stream().filter(serializableFields).sorted(bySimpleName).map(e -> types.asMemberOf((DeclaredType) st, e)).forEach(fields::add);
    }
    String data = fields.stream().map(Util::toUniqueString).collect(Collectors.joining());
    try {
        byte[] bytes = data.getBytes("UTF-8");
        MessageDigest md = MessageDigest.getInstance("SHA");
        byte[] hashBytes = md.digest(bytes);
        long hash = 0;
        for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
            hash = (hash << 8) | (hashBytes[i] & 0xFF);
        }
        return hash;
    } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
        throw new IllegalStateException("Could not compute structural ID of a type " + type.getQualifiedName().toString(), e);
    }
}
Also used : Arrays(java.util.Arrays) SimpleTypeVisitor7(javax.lang.model.util.SimpleTypeVisitor7) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Modifier(javax.lang.model.element.Modifier) MessageDigest(java.security.MessageDigest) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) CheckBase(org.revapi.java.spi.CheckBase) ArrayList(java.util.ArrayList) JavaFieldElement(org.revapi.java.spi.JavaFieldElement) DataOutputStream(java.io.DataOutputStream) Charset(java.nio.charset.Charset) Util(org.revapi.java.spi.Util) DeclaredType(javax.lang.model.type.DeclaredType) ElementFilter(javax.lang.model.util.ElementFilter) Nonnull(javax.annotation.Nonnull) EnumSet(java.util.EnumSet) Nullable(javax.annotation.Nullable) ArrayType(javax.lang.model.type.ArrayType) Code(org.revapi.java.spi.Code) ElementKind(javax.lang.model.element.ElementKind) ExecutableType(javax.lang.model.type.ExecutableType) AnalysisContext(org.revapi.AnalysisContext) NoType(javax.lang.model.type.NoType) Predicate(java.util.function.Predicate) ExecutableElement(javax.lang.model.element.ExecutableElement) Set(java.util.Set) IOException(java.io.IOException) Element(javax.lang.model.element.Element) Reader(java.io.Reader) Types(javax.lang.model.util.Types) TypeEnvironment(org.revapi.java.spi.TypeEnvironment) InputStreamReader(java.io.InputStreamReader) Collectors(java.util.stream.Collectors) Difference(org.revapi.Difference) TypeKind(javax.lang.model.type.TypeKind) Objects(java.util.Objects) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) PrimitiveType(javax.lang.model.type.PrimitiveType) ModelNode(org.jboss.dmr.ModelNode) Comparator(java.util.Comparator) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Collections(java.util.Collections) Types(javax.lang.model.util.Types) EnumSet(java.util.EnumSet) Set(java.util.Set) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) JavaFieldElement(org.revapi.java.spi.JavaFieldElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) UnsupportedEncodingException(java.io.UnsupportedEncodingException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) TypeMirror(javax.lang.model.type.TypeMirror) MessageDigest(java.security.MessageDigest)

Example 2 with Util

use of org.revapi.java.spi.Util 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;
}
Also used : CoIterator(org.revapi.CoIterator) ArrayList(java.util.ArrayList) Util(org.revapi.java.spi.Util) Difference(org.revapi.Difference) Code(org.revapi.java.spi.Code) JavaTypeElement(org.revapi.java.spi.JavaTypeElement) TypeMirror(javax.lang.model.type.TypeMirror) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with Util

use of org.revapi.java.spi.Util in project revapi by revapi.

the class ExceptionsThrownChanged method doEnd.

@Nullable
@Override
protected List<Difference> doEnd() {
    ActiveElements<JavaMethodElement> methods = popIfActive();
    if (methods == null) {
        return null;
    }
    List<? extends TypeMirror> oldExceptions = new ArrayList<>(methods.oldElement.getModelRepresentation().getThrownTypes());
    List<? extends TypeMirror> newExceptions = new ArrayList<>(methods.newElement.getModelRepresentation().getThrownTypes());
    Comparator<TypeMirror> byClassName = Comparator.comparing(Util::toUniqueString);
    Collections.sort(oldExceptions, byClassName);
    Collections.sort(newExceptions, byClassName);
    CoIterator<TypeMirror> it = new CoIterator<>(oldExceptions.iterator(), newExceptions.iterator(), byClassName);
    List<String> removedRuntimeExceptions = new ArrayList<>();
    List<String> addedRuntimeExceptions = new ArrayList<>();
    List<String> removedCheckedExceptions = new ArrayList<>();
    List<String> addedCheckedExceptions = new ArrayList<>();
    boolean reportSomething = false;
    while (it.hasNext()) {
        it.next();
        TypeMirror oldType = it.getLeft();
        TypeMirror newType = it.getRight();
        if (oldType != null && newType != null) {
            // they match, so move on, nothing to report here
            continue;
        }
        reportSomething = true;
        TypeElement oldException = oldType == null ? null : oldType.accept(CONVERT_TO_ELEMENT, null);
        TypeElement newException = newType == null ? null : newType.accept(CONVERT_TO_ELEMENT, null);
        if (oldException != null) {
            if (isRuntimeException(oldException)) {
                removedRuntimeExceptions.add(oldException.getQualifiedName().toString());
            } else {
                removedCheckedExceptions.add(oldException.getQualifiedName().toString());
            }
        } else if (newException != null) {
            if (isRuntimeException(newException)) {
                addedRuntimeExceptions.add(newException.getQualifiedName().toString());
            } else {
                addedCheckedExceptions.add(newException.getQualifiedName().toString());
            }
        }
    }
    if (!reportSomething) {
        return null;
    }
    List<Difference> ret = new ArrayList<>();
    if (!removedRuntimeExceptions.isEmpty()) {
        removedRuntimeExceptions.forEach(ex -> ret.add(createDifference(Code.METHOD_RUNTIME_EXCEPTION_REMOVED, Code.attachmentsFor(methods.oldElement, methods.newElement, "exception", ex))));
    }
    if (!addedRuntimeExceptions.isEmpty()) {
        addedRuntimeExceptions.forEach(ex -> ret.add(createDifference(Code.METHOD_RUNTIME_EXCEPTION_ADDED, Code.attachmentsFor(methods.oldElement, methods.newElement, "exception", ex))));
    }
    if (!addedCheckedExceptions.isEmpty()) {
        addedCheckedExceptions.forEach(ex -> ret.add(createDifference(Code.METHOD_CHECKED_EXCEPTION_ADDED, Code.attachmentsFor(methods.oldElement, methods.newElement, "exception", ex))));
    }
    if (!removedCheckedExceptions.isEmpty()) {
        removedCheckedExceptions.forEach(ex -> ret.add(createDifference(Code.METHOD_CHECKED_EXCEPTION_REMOVED, Code.attachmentsFor(methods.oldElement, methods.newElement, "exception", ex))));
    }
    return ret;
}
Also used : CoIterator(org.revapi.CoIterator) JavaMethodElement(org.revapi.java.spi.JavaMethodElement) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) Util(org.revapi.java.spi.Util) Difference(org.revapi.Difference) TypeMirror(javax.lang.model.type.TypeMirror) Nullable(javax.annotation.Nullable)

Aggregations

ArrayList (java.util.ArrayList)3 TypeMirror (javax.lang.model.type.TypeMirror)3 Difference (org.revapi.Difference)3 List (java.util.List)2 Nullable (javax.annotation.Nullable)2 TypeElement (javax.lang.model.element.TypeElement)2 CoIterator (org.revapi.CoIterator)2 Util (org.revapi.java.spi.Util)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataOutputStream (java.io.DataOutputStream)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Charset (java.nio.charset.Charset)1 MessageDigest (java.security.MessageDigest)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1