Search in sources :

Example 1 with JavaModelElement

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;
    }
}
Also used : JavaModelElement(org.revapi.java.spi.JavaModelElement) JavaTypeElement(org.revapi.java.spi.JavaTypeElement) TypeElement(org.revapi.java.model.TypeElement) UseSite(org.revapi.java.spi.UseSite) Nullable(javax.annotation.Nullable) DeclaredType(javax.lang.model.type.DeclaredType)

Example 2 with JavaModelElement

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);
    }
}
Also used : ElementForest(org.revapi.ElementForest) Revapi(org.revapi.Revapi) JavaModelElement(org.revapi.java.spi.JavaModelElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) Element(org.revapi.Element) ArrayList(java.util.ArrayList) ArchiveAnalyzer(org.revapi.ArchiveAnalyzer) AnalysisContext(org.revapi.AnalysisContext) API(org.revapi.API)

Example 3 with JavaModelElement

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);
}
Also used : ProbingEnvironment(org.revapi.java.compilation.ProbingEnvironment) JavaTypeElement(org.revapi.java.spi.JavaTypeElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableElement(javax.lang.model.element.VariableElement) Set(java.util.Set) Element(javax.lang.model.element.Element) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) FlatFilter(org.revapi.java.FlatFilter) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) Util(org.revapi.java.spi.Util) DeclaredType(javax.lang.model.type.DeclaredType) Archive(org.revapi.Archive) ClassPathUseSite(org.revapi.java.compilation.ClassPathUseSite) UseSite(org.revapi.java.spi.UseSite) SimpleElementVisitor8(javax.lang.model.util.SimpleElementVisitor8) Collections(java.util.Collections) Nonnull(javax.annotation.Nonnull) JavaModelElement(org.revapi.java.spi.JavaModelElement) JavaTypeElement(org.revapi.java.spi.JavaTypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) JavaTypeElement(org.revapi.java.spi.JavaTypeElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableElement(javax.lang.model.element.VariableElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) List(java.util.List)

Example 4 with JavaModelElement

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();
}
Also used : JavaElement(org.revapi.java.spi.JavaElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) Element(org.revapi.Element) JavaElement(org.revapi.java.spi.JavaElement) JavaAnnotationElement(org.revapi.java.spi.JavaAnnotationElement)

Example 5 with JavaModelElement

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());
}
Also used : API(org.revapi.API) ShrinkWrap(org.jboss.shrinkwrap.api.ShrinkWrap) Code(org.revapi.java.spi.Code) AnalysisContext(org.revapi.AnalysisContext) Report(org.revapi.Report) JavaModelElement(org.revapi.java.spi.JavaModelElement) AnalysisResult(org.revapi.AnalysisResult) Test(org.junit.Test) Revapi(org.revapi.Revapi) List(java.util.List) JavaArchive(org.jboss.shrinkwrap.api.spec.JavaArchive) After(org.junit.After) Assert(org.junit.Assert) Before(org.junit.Before) Revapi(org.revapi.Revapi) Report(org.revapi.Report) JavaModelElement(org.revapi.java.spi.JavaModelElement) JavaModelElement(org.revapi.java.spi.JavaModelElement) AnalysisContext(org.revapi.AnalysisContext) AnalysisResult(org.revapi.AnalysisResult) Test(org.junit.Test)

Aggregations

JavaModelElement (org.revapi.java.spi.JavaModelElement)8 List (java.util.List)3 Nullable (javax.annotation.Nullable)3 ArrayList (java.util.ArrayList)2 DeclaredType (javax.lang.model.type.DeclaredType)2 API (org.revapi.API)2 AnalysisContext (org.revapi.AnalysisContext)2 Element (org.revapi.Element)2 Revapi (org.revapi.Revapi)2 Code (org.revapi.java.spi.Code)2 JavaTypeElement (org.revapi.java.spi.JavaTypeElement)2 UseSite (org.revapi.java.spi.UseSite)2 Collections (java.util.Collections)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 Nonnull (javax.annotation.Nonnull)1 Element (javax.lang.model.element.Element)1