Search in sources :

Example 1 with SimpleElementVisitor6

use of javax.lang.model.util.SimpleElementVisitor6 in project goci by EBISPOT.

the class SpiProcessor method process.

/**
   * Process @ServiceProvider annotations.  This will generate appropriate
   * entries in the META-INF/services file, making classes discoverable at
   * runtime for anything handling these annotations.
   */
public boolean process(Set<? extends TypeElement> typeElements, RoundEnvironment roundEnv) {
    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "There are " + roundEnv.getElementsAnnotatedWith(Spi.class).size() + " Spi interfaces and " + roundEnv.getElementsAnnotatedWith(ServiceProvider.class).size() + " ServiceProvider implementations");
    // setup output options
    Map<String, PrintWriter> outputs = new HashMap<>();
    // check all elements annotated with @ServiceProvider
    for (Element element : roundEnv.getElementsAnnotatedWith(ServiceProvider.class)) {
        ElementVisitor<Void, Void> visitor = new SimpleElementVisitor6<Void, Void>() {

            public Void visitType(TypeElement e, Void aVoid) {
                typeElement = e;
                return super.visitType(e, aVoid);
            }
        };
        element.accept(visitor, null);
        // visiting this type - work out the superclass (i.e. the @Spi)
        Name result = findSpiAnnotation(typeElement);
        if (result != null) {
            Name spiName = findSpiAnnotation(typeElement);
            if (spiName == null) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Type annotated with @ServiceProvider but this type does not " + "implement an SPI");
            } else {
                // found the SPI, insert the service file
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating service entry for " + typeElement.getQualifiedName() + " for service " + spiName);
                String spiNameStr = spiName.toString();
                PrintWriter pw = outputs.get(spiNameStr);
                // lazily instantiate pw if it is null
                if (pw == null) {
                    try {
                        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating service file for " + spiName);
                        FileObject fo = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/" + spiName);
                        pw = new PrintWriter(fo.openWriter());
                        outputs.put(spiNameStr, pw);
                    } catch (IOException e) {
                        e.printStackTrace();
                        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Problem creating services file for " + spiName);
                    }
                }
                // pw should now have defo be non-null, unless something went wrong
                if (pw != null) {
                    pw.println(typeElement.getQualifiedName());
                }
            }
        } else {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, typeElement.getQualifiedName() + ": Classes annotated with " + ServiceProvider.class.getName() + " " + "MUST implement an interface marked with an " + Spi.class.getName() + " annotation");
            return false;
        }
    }
    // done all elements, so make sure all writers are closed
    for (PrintWriter pw : outputs.values()) {
        pw.close();
    }
    return true;
}
Also used : SimpleElementVisitor6(javax.lang.model.util.SimpleElementVisitor6) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) IOException(java.io.IOException) Name(javax.lang.model.element.Name) FileObject(javax.tools.FileObject) PrintWriter(java.io.PrintWriter)

Example 2 with SimpleElementVisitor6

use of javax.lang.model.util.SimpleElementVisitor6 in project robolectric by robolectric.

the class RobolectricModel method prepare.

/**
   * Prepares the various derived parts of the model based on the class mappings
   * that have been registered to date.
   */
public void prepare() {
    for (Map.Entry<TypeElement, TypeElement> entry : getVisibleShadowTypes().entrySet()) {
        final TypeElement shadowType = entry.getKey();
        registerType(shadowType);
        final TypeElement solidType = entry.getValue();
        registerType(solidType);
    }
    for (Map.Entry<TypeElement, TypeElement> entry : getResetterShadowTypes().entrySet()) {
        final TypeElement shadowType = entry.getKey();
        registerType(shadowType);
    }
    while (!typeMap.isEmpty()) {
        final HashMultimap<String, TypeElement> nextRound = HashMultimap.create();
        for (Map.Entry<String, Set<TypeElement>> referents : Multimaps.asMap(typeMap).entrySet()) {
            final Set<TypeElement> c = referents.getValue();
            // name, then
            if (c.size() == 1) {
                final TypeElement type = c.iterator().next();
                referentMap.put(type, referents.getKey());
            } else {
                for (TypeElement type : c) {
                    SimpleElementVisitor6<Void, TypeElement> visitor = new SimpleElementVisitor6<Void, TypeElement>() {

                        @Override
                        public Void visitType(TypeElement parent, TypeElement type) {
                            nextRound.put(parent.getSimpleName() + "." + type.getSimpleName(), type);
                            importMap.put(type, parent);
                            return null;
                        }

                        @Override
                        public Void visitPackage(PackageElement parent, TypeElement type) {
                            referentMap.put(type, type.getQualifiedName().toString());
                            importMap.remove(type);
                            return null;
                        }
                    };
                    visitor.visit(importMap.get(type).getEnclosingElement(), type);
                }
            }
        }
        typeMap = nextRound;
    }
    for (TypeElement imp : importMap.values()) {
        if (imp.getModifiers().contains(Modifier.PUBLIC) && !JAVA_LANG.equals(imp.getEnclosingElement())) {
            imports.add(imp.getQualifiedName().toString());
        }
    }
    // Other imports that the generated class needs
    imports.add("java.util.Map");
    imports.add("java.util.HashMap");
    imports.add("javax.annotation.Generated");
    imports.add("org.robolectric.internal.ShadowExtractor");
    imports.add("org.robolectric.internal.ShadowProvider");
}
Also used : TreeSet(java.util.TreeSet) Sets.newTreeSet(com.google.common.collect.Sets.newTreeSet) Set(java.util.Set) SimpleElementVisitor6(javax.lang.model.util.SimpleElementVisitor6) TypeElement(javax.lang.model.element.TypeElement) PackageElement(javax.lang.model.element.PackageElement) HashMap(java.util.HashMap) Map(java.util.Map) Maps.newTreeMap(com.google.common.collect.Maps.newTreeMap) Maps.newHashMap(com.google.common.collect.Maps.newHashMap) TreeMap(java.util.TreeMap)

Aggregations

HashMap (java.util.HashMap)2 TypeElement (javax.lang.model.element.TypeElement)2 SimpleElementVisitor6 (javax.lang.model.util.SimpleElementVisitor6)2 Maps.newHashMap (com.google.common.collect.Maps.newHashMap)1 Maps.newTreeMap (com.google.common.collect.Maps.newTreeMap)1 Sets.newTreeSet (com.google.common.collect.Sets.newTreeSet)1 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 Map (java.util.Map)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 Element (javax.lang.model.element.Element)1 Name (javax.lang.model.element.Name)1 PackageElement (javax.lang.model.element.PackageElement)1 FileObject (javax.tools.FileObject)1