Search in sources :

Example 1 with QualifiedNameable

use of javax.lang.model.element.QualifiedNameable 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 2 with QualifiedNameable

use of javax.lang.model.element.QualifiedNameable in project auto by google.

the class TypeSimplifier method ambiguousNames.

private static Set<String> ambiguousNames(Types typeUtils, Set<TypeMirror> types) {
    Set<String> ambiguous = new HashSet<>();
    Map<String, Name> simpleNamesToQualifiedNames = new HashMap<>();
    for (TypeMirror type : types) {
        if (type.getKind() == TypeKind.ERROR) {
            throw new MissingTypeException(MoreTypes.asError(type));
        }
        String simpleName = typeUtils.asElement(type).getSimpleName().toString();
        /*
       * Compare by qualified names, because in Eclipse JDT, if Java 8 type annotations are used,
       * the same (unannotated) type may appear multiple times in the Set<TypeMirror>.
       * TODO(emcmanus): investigate further, because this might cause problems elsewhere.
       */
        Name qualifiedName = ((QualifiedNameable) typeUtils.asElement(type)).getQualifiedName();
        Name previous = simpleNamesToQualifiedNames.put(simpleName, qualifiedName);
        if (previous != null && !previous.equals(qualifiedName)) {
            ambiguous.add(simpleName);
        }
    }
    return ambiguous;
}
Also used : MissingTypeException(com.google.auto.value.processor.MissingTypes.MissingTypeException) HashMap(java.util.HashMap) TypeMirror(javax.lang.model.type.TypeMirror) QualifiedNameable(javax.lang.model.element.QualifiedNameable) HashSet(java.util.HashSet) Name(javax.lang.model.element.Name)

Aggregations

HashSet (java.util.HashSet)2 QualifiedNameable (javax.lang.model.element.QualifiedNameable)2 BuckTracing (com.facebook.buck.event.api.BuckTracing)1 MissingTypeException (com.google.auto.value.processor.MissingTypes.MissingTypeException)1 TreePath (com.sun.source.util.TreePath)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Set (java.util.Set)1 Element (javax.lang.model.element.Element)1 Name (javax.lang.model.element.Name)1 PackageElement (javax.lang.model.element.PackageElement)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1 TypeMirror (javax.lang.model.type.TypeMirror)1