Search in sources :

Example 1 with Element

use of javax.lang.model.element.Element in project buck by facebook.

the class TreeContextScanner method scan.

@Override
@Nullable
public R scan(Tree tree, @Nullable P p) {
    if (tree == null) {
        return null;
    }
    TreePath previousPath = currentPath;
    Element previousEnclosingElement = enclosingElement;
    currentPath = new TreePath(currentPath, tree);
    switch(tree.getKind()) {
        case ANNOTATION_TYPE:
        case CLASS:
        case COMPILATION_UNIT:
        case ENUM:
        case INTERFACE:
        case METHOD:
        case VARIABLE:
        case TYPE_PARAMETER:
            enclosingElement = Preconditions.checkNotNull(trees.getElement(currentPath));
            break;
        // $CASES-OMITTED$
        default:
            break;
    }
    try {
        // This super call will actually visit the tree, now with all the context set up
        return super.scan(tree, p);
    } finally {
        currentPath = previousPath;
        enclosingElement = previousEnclosingElement;
    }
}
Also used : TreePath(com.sun.source.util.TreePath) Element(javax.lang.model.element.Element) Nullable(com.facebook.buck.util.liteinfersupport.Nullable)

Example 2 with Element

use of javax.lang.model.element.Element in project buck by facebook.

the class TypeElementsReader method addTypeElements.

private void addTypeElements(Element rootElement, Map<Path, TypeElement> typeElements) {
    if (!rootElement.getKind().isClass() && !rootElement.getKind().isInterface()) {
        return;
    }
    TypeElement typeElement = (TypeElement) rootElement;
    typeElements.put(getRelativePath(typeElement), typeElement);
    for (Element enclosed : typeElement.getEnclosedElements()) {
        addTypeElements(enclosed, typeElements);
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement)

Example 3 with Element

use of javax.lang.model.element.Element in project buck by facebook.

the class InterfaceValidator method validate.

public void validate(List<? extends CompilationUnitTree> compilationUnits) {
    try (BuckTracing.TraceSection trace = BUCK_TRACING.traceSection("buck.abi.validate")) {
        new InterfaceTypeAndConstantReferenceFinder(trees, new InterfaceTypeAndConstantReferenceFinder.Listener() {

            private final Set<Element> importedTypes = new HashSet<>();

            @Override
            public void onTypeImported(TypeElement type) {
                importedTypes.add(type);
            }

            @Override
            public void onTypeReferenceFound(TypeElement referencedType, TreePath path, Element enclosingElement) {
                PackageElement enclosingPackage = getPackageElement(enclosingElement);
                if (typeWillBeAvailable(referencedType) || referenceIsLegalForMissingTypes(path, enclosingPackage, referencedType)) {
                    // All good!
                    return;
                }
                String minimalQualifiedName = findMinimalQualifiedName(path, enclosingPackage, referencedType);
                // TODO(jkeljo): Clearer message
                trees.printMessage(messageKind, String.format("Must qualify the name: %s", minimalQualifiedName), path.getLeaf(), path.getCompilationUnit());
            }

            @Override
            public void onConstantReferenceFound(VariableElement constant, TreePath path, Element enclosingElement) {
                TypeElement constantEnclosingType = (TypeElement) constant.getEnclosingElement();
                if (typeWillBeAvailable(constantEnclosingType)) {
                    // All good!
                    return;
                }
                // TODO(jkeljo): Clearer message
                trees.printMessage(messageKind, String.format("Must inline the constant value: %s", constant.getConstantValue()), path.getLeaf(), path.getCompilationUnit());
            }

            private boolean typeWillBeAvailable(TypeElement type) {
                return isCompiledInCurrentRun(type) || isOnBootClasspath(type);
            }

            private boolean isCompiledInCurrentRun(TypeElement typeElement) {
                return trees.getPath(typeElement) != null;
            }

            private boolean isOnBootClasspath(TypeElement typeElement) {
                return bootClasspathOracle.isOnBootClasspath(elements.getBinaryName(typeElement).toString());
            }

            private boolean referenceIsLegalForMissingTypes(TreePath path, PackageElement enclosingPackage, TypeElement referencedTypeElement) {
                return isImported(referencedTypeElement) || isTopLevelTypeInPackage(referencedTypeElement, enclosingPackage) || isFullyQualified(path, referencedTypeElement);
            }

            private boolean isImported(TypeElement referencedTypeElement) {
                return importedTypes.contains(referencedTypeElement);
            }

            private boolean isTopLevelTypeInPackage(TypeElement referencedTypeElement, PackageElement enclosingPackage) {
                return enclosingPackage == referencedTypeElement.getEnclosingElement();
            }

            private boolean isFullyQualified(TreePath path, TypeElement referencedTypeElement) {
                return referencedTypeElement.getQualifiedName().contentEquals(TreeBackedTrees.treeToName(path.getLeaf()));
            }

            private String findMinimalQualifiedName(TreePath path, PackageElement enclosingPackage, TypeElement typeElement) {
                List<QualifiedNameable> enclosingElements = new ArrayList<>();
                QualifiedNameable walker = typeElement;
                while (walker.getKind() != ElementKind.PACKAGE && !referenceIsLegalForMissingTypes(path, enclosingPackage, (TypeElement) walker)) {
                    enclosingElements.add(walker);
                    walker = (QualifiedNameable) walker.getEnclosingElement();
                }
                enclosingElements.add(walker);
                StringBuilder resultBuilder = new StringBuilder();
                for (int i = enclosingElements.size() - 1; i >= 0; i--) {
                    QualifiedNameable element = enclosingElements.get(i);
                    if (element.getKind() == ElementKind.PACKAGE) {
                        resultBuilder.append(element.getQualifiedName());
                    } else {
                        resultBuilder.append(element.getSimpleName());
                    }
                    if (i > 0) {
                        resultBuilder.append(".");
                    }
                }
                return resultBuilder.toString();
            }
        }).findReferences(compilationUnits);
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) TypeElement(javax.lang.model.element.TypeElement) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) BuckTracing(com.facebook.buck.event.api.BuckTracing) TreePath(com.sun.source.util.TreePath) QualifiedNameable(javax.lang.model.element.QualifiedNameable) PackageElement(javax.lang.model.element.PackageElement)

Example 4 with Element

use of javax.lang.model.element.Element in project buck by facebook.

the class DescriptorAndSignatureFactoryTestBase method findErrors.

private void findErrors(TypeElement typeElement, Function<FieldNode, String> fieldNodeExpectedValueGetter, Function<MethodNode, String> methodNodeExpectedValueGetter, Function<ClassNode, String> classNodeExpectedValueGetter, Function<Element, String> elementActualValueGetter) throws IOException {
    ClassNode typeNode = getClassNode(elements.getBinaryName(typeElement).toString());
    for (Element enclosedElement : typeElement.getEnclosedElements()) {
        Name elementName = enclosedElement.getSimpleName();
        String actual = elementActualValueGetter.apply(enclosedElement);
        switch(enclosedElement.getKind()) {
            case FIELD:
                checkValue("Field", elementName, fieldNodeExpectedValueGetter.apply(getFieldNode(typeNode, elementName)), actual);
                break;
            case CONSTRUCTOR:
            case METHOD:
                checkValue("Method", elementName, methodNodeExpectedValueGetter.apply(getMethodNode(typeNode, elementName)), actual);
                break;
            case ANNOTATION_TYPE:
            case CLASS:
            case ENUM:
            case INTERFACE:
                ClassNode innerTypeNode = getClassNode(elements.getBinaryName((TypeElement) enclosedElement).toString());
                checkValue("Class", elementName, classNodeExpectedValueGetter.apply(innerTypeNode), actual);
                findErrors((TypeElement) enclosedElement, fieldNodeExpectedValueGetter, methodNodeExpectedValueGetter, classNodeExpectedValueGetter, elementActualValueGetter);
                break;
            // $CASES-OMITTED$
            default:
                fail(String.format("Didn't implement testing for element kind %s", enclosedElement.getKind()));
                continue;
        }
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) Name(javax.lang.model.element.Name)

Example 5 with Element

use of javax.lang.model.element.Element in project buck by facebook.

the class TreeBackedTypeElementTest method testEnclosedClasses.

@Test
public void testEnclosedClasses() throws IOException {
    compile(Joiner.on('\n').join("class Foo {", "  class Bar { }", "}"));
    TypeElement fooElement = elements.getTypeElement("Foo");
    TypeElement barElement = elements.getTypeElement("Foo.Bar");
    List<Element> enclosedElements = new ArrayList<>(fooElement.getEnclosedElements());
    assertThat(enclosedElements, Matchers.hasItems(barElement));
    assertSame(fooElement, barElement.getEnclosingElement());
}
Also used : TypeElement(javax.lang.model.element.TypeElement) PackageElement(javax.lang.model.element.PackageElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

Element (javax.lang.model.element.Element)286 TypeElement (javax.lang.model.element.TypeElement)227 ExecutableElement (javax.lang.model.element.ExecutableElement)148 VariableElement (javax.lang.model.element.VariableElement)96 TypeMirror (javax.lang.model.type.TypeMirror)68 PackageElement (javax.lang.model.element.PackageElement)48 ArrayList (java.util.ArrayList)39 DeclaredType (javax.lang.model.type.DeclaredType)30 IOException (java.io.IOException)29 Map (java.util.Map)26 HashSet (java.util.HashSet)23 LinkedHashSet (java.util.LinkedHashSet)22 List (java.util.List)22 Set (java.util.Set)22 Test (org.junit.Test)21 ElementKind (javax.lang.model.element.ElementKind)20 AnnotationMirror (javax.lang.model.element.AnnotationMirror)19 Elements (javax.lang.model.util.Elements)18 HashMap (java.util.HashMap)16 LinkedHashMap (java.util.LinkedHashMap)15