Search in sources :

Example 1 with ServiceProvider

use of org.graalvm.compiler.serviceprovider.ServiceProvider in project graal by oracle.

the class ServiceProviderProcessor method processElement.

private void processElement(TypeElement serviceProvider) {
    if (processed.contains(serviceProvider)) {
        return;
    }
    processed.add(serviceProvider);
    ServiceProvider annotation = serviceProvider.getAnnotation(ServiceProvider.class);
    if (annotation != null) {
        try {
            annotation.value();
        } catch (MirroredTypeException ex) {
            TypeMirror service = ex.getTypeMirror();
            if (verifyAnnotation(service, serviceProvider)) {
                if (serviceProvider.getNestingKind().isNested()) {
                    /*
                         * This is a simplifying constraint that means we don't have to process the
                         * qualified name to insert '$' characters at the relevant positions.
                         */
                    String msg = String.format("Service provider class %s must be a top level class", serviceProvider.getSimpleName());
                    processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
                } else {
                    /*
                         * Since the definition of the service class is not necessarily modifiable,
                         * we need to support a non-top-level service class and ensure its name is
                         * properly expressed with '$' separating nesting levels instead of '.'.
                         */
                    TypeElement serviceElement = (TypeElement) processingEnv.getTypeUtils().asElement(service);
                    String serviceName = serviceElement.getSimpleName().toString();
                    Element enclosing = serviceElement.getEnclosingElement();
                    while (enclosing != null) {
                        final ElementKind kind = enclosing.getKind();
                        if (kind == ElementKind.PACKAGE) {
                            serviceName = ((PackageElement) enclosing).getQualifiedName().toString() + "." + serviceName;
                            break;
                        } else if (kind == ElementKind.CLASS || kind == ElementKind.INTERFACE) {
                            serviceName = ((TypeElement) enclosing).getSimpleName().toString() + "$" + serviceName;
                            enclosing = enclosing.getEnclosingElement();
                        } else {
                            String msg = String.format("Cannot generate provider descriptor for service class %s as it is not nested in a package, class or interface", serviceElement.getQualifiedName());
                            processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
                            return;
                        }
                    }
                    serviceProviders.put(serviceProvider, serviceName);
                }
            }
        }
    }
}
Also used : MirroredTypeException(javax.lang.model.type.MirroredTypeException) ElementKind(javax.lang.model.element.ElementKind) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) ServiceProvider(org.graalvm.compiler.serviceprovider.ServiceProvider) PackageElement(javax.lang.model.element.PackageElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement)

Aggregations

Element (javax.lang.model.element.Element)1 ElementKind (javax.lang.model.element.ElementKind)1 PackageElement (javax.lang.model.element.PackageElement)1 TypeElement (javax.lang.model.element.TypeElement)1 MirroredTypeException (javax.lang.model.type.MirroredTypeException)1 TypeMirror (javax.lang.model.type.TypeMirror)1 ServiceProvider (org.graalvm.compiler.serviceprovider.ServiceProvider)1