src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider.processor/src/org/graalvm/compiler/serviceprovider/processor/ServiceProviderProcessor.java
changeset 48861 47f19ff9903c
parent 47216 71c04702a3d5
child 50330 2cbc42a5764b
equal deleted inserted replaced
48860:5bce1b7e7800 48861:47f19ff9903c
    35 import javax.annotation.processing.FilerException;
    35 import javax.annotation.processing.FilerException;
    36 import javax.annotation.processing.RoundEnvironment;
    36 import javax.annotation.processing.RoundEnvironment;
    37 import javax.annotation.processing.SupportedAnnotationTypes;
    37 import javax.annotation.processing.SupportedAnnotationTypes;
    38 import javax.lang.model.SourceVersion;
    38 import javax.lang.model.SourceVersion;
    39 import javax.lang.model.element.Element;
    39 import javax.lang.model.element.Element;
       
    40 import javax.lang.model.element.ElementKind;
       
    41 import javax.lang.model.element.PackageElement;
    40 import javax.lang.model.element.TypeElement;
    42 import javax.lang.model.element.TypeElement;
    41 import javax.lang.model.type.MirroredTypeException;
    43 import javax.lang.model.type.MirroredTypeException;
    42 import javax.lang.model.type.TypeMirror;
    44 import javax.lang.model.type.TypeMirror;
    43 import javax.tools.Diagnostic.Kind;
    45 import javax.tools.Diagnostic.Kind;
    44 import javax.tools.FileObject;
    46 import javax.tools.FileObject;
    82         ServiceProvider annotation = serviceProvider.getAnnotation(ServiceProvider.class);
    84         ServiceProvider annotation = serviceProvider.getAnnotation(ServiceProvider.class);
    83         if (annotation != null) {
    85         if (annotation != null) {
    84             try {
    86             try {
    85                 annotation.value();
    87                 annotation.value();
    86             } catch (MirroredTypeException ex) {
    88             } catch (MirroredTypeException ex) {
    87                 TypeMirror serviceInterface = ex.getTypeMirror();
    89                 TypeMirror service = ex.getTypeMirror();
    88                 if (verifyAnnotation(serviceInterface, serviceProvider)) {
    90                 if (verifyAnnotation(service, serviceProvider)) {
    89                     if (serviceProvider.getNestingKind().isNested()) {
    91                     if (serviceProvider.getNestingKind().isNested()) {
    90                         /*
    92                         /*
    91                          * This is a simplifying constraint that means we don't have to process the
    93                          * This is a simplifying constraint that means we don't have to process the
    92                          * qualified name to insert '$' characters at the relevant positions.
    94                          * qualified name to insert '$' characters at the relevant positions.
    93                          */
    95                          */
    94                         String msg = String.format("Service provider class %s must be a top level class", serviceProvider.getSimpleName());
    96                         String msg = String.format("Service provider class %s must be a top level class", serviceProvider.getSimpleName());
    95                         processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
    97                         processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
    96                     } else {
    98                     } else {
    97                         serviceProviders.put(serviceProvider, ex.getTypeMirror().toString());
    99                         /*
       
   100                          * Since the definition of the service class is not necessarily modifiable,
       
   101                          * we need to support a non-top-level service class and ensure its name is
       
   102                          * properly expressed with '$' separating nesting levels instead of '.'.
       
   103                          */
       
   104                         TypeElement serviceElement = (TypeElement) processingEnv.getTypeUtils().asElement(service);
       
   105                         String serviceName = serviceElement.getSimpleName().toString();
       
   106                         Element enclosing = serviceElement.getEnclosingElement();
       
   107                         while (enclosing != null) {
       
   108                             final ElementKind kind = enclosing.getKind();
       
   109                             if (kind == ElementKind.PACKAGE) {
       
   110                                 serviceName = ((PackageElement) enclosing).getQualifiedName().toString() + "." + serviceName;
       
   111                                 break;
       
   112                             } else if (kind == ElementKind.CLASS || kind == ElementKind.INTERFACE) {
       
   113                                 serviceName = ((TypeElement) enclosing).getSimpleName().toString() + "$" + serviceName;
       
   114                                 enclosing = enclosing.getEnclosingElement();
       
   115                             } else {
       
   116                                 String msg = String.format("Cannot generate provider descriptor for service class %s as it is not nested in a package, class or interface",
       
   117                                                 serviceElement.getQualifiedName());
       
   118                                 processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
       
   119                                 return;
       
   120                             }
       
   121                         }
       
   122                         serviceProviders.put(serviceProvider, serviceName);
    98                     }
   123                     }
    99                 }
   124                 }
   100             }
   125             }
   101         }
   126         }
   102     }
   127     }