1 /* 2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.replacements.verifier; 24 25 import java.lang.annotation.Annotation; 26 import java.util.ArrayList; 27 import java.util.HashSet; 28 import java.util.List; 29 import java.util.Set; 30 31 import javax.annotation.processing.AbstractProcessor; 32 import javax.annotation.processing.ProcessingEnvironment; 33 import javax.annotation.processing.RoundEnvironment; 34 import javax.lang.model.SourceVersion; 35 import javax.lang.model.element.AnnotationMirror; 36 import javax.lang.model.element.Element; 37 import javax.lang.model.element.TypeElement; 38 import javax.lang.model.type.DeclaredType; 39 40 public class VerifierAnnotationProcessor extends AbstractProcessor { 41 42 private List<AbstractVerifier> verifiers; 43 44 @Override 45 public SourceVersion getSupportedSourceVersion() { 46 return SourceVersion.latest(); 47 } 48 49 @Override 50 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 51 if (!roundEnv.processingOver()) { 52 PluginGenerator generator = new PluginGenerator(); 53 for (AbstractVerifier verifier : getVerifiers()) { 54 Class<? extends Annotation> annotationClass = verifier.getAnnotationClass(); 55 for (Element e : roundEnv.getElementsAnnotatedWith(annotationClass)) { 56 AnnotationMirror annotationMirror = findAnnotationMirror(processingEnv, e.getAnnotationMirrors(), annotationClass); 57 if (annotationMirror == null) { 58 assert false : "Annotation mirror always expected."; 59 continue; 60 } 61 verifier.verify(e, annotationMirror, generator); 62 } 63 } 64 65 generator.generateAll(processingEnv); 66 } 67 return false; 68 } 69 70 public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List<? extends AnnotationMirror> mirrors, Class<?> annotationClass) { 71 TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName()); 72 for (AnnotationMirror mirror : mirrors) { 73 DeclaredType annotationType = mirror.getAnnotationType(); 74 TypeElement actualAnnotationType = (TypeElement) annotationType.asElement(); 75 if (actualAnnotationType.equals(expectedAnnotationType)) { 76 return mirror; 77 } 78 } 79 return null; 80 } 81 82 public List<AbstractVerifier> getVerifiers() { 83 /* 84 * Initialized lazily to fail(CNE) when the processor is invoked and not when it is created. 85 */ 86 if (verifiers == null) { 87 assert this.processingEnv != null : "ProcessingEnv must be initialized before calling getVerifiers."; 88 verifiers = new ArrayList<>(); 89 verifiers.add(new ClassSubstitutionVerifier(this.processingEnv)); 90 verifiers.add(new MethodSubstitutionVerifier(this.processingEnv)); 91 verifiers.add(new NodeIntrinsicVerifier(this.processingEnv)); 92 verifiers.add(new FoldVerifier(this.processingEnv)); 93 } 94 return verifiers; 95 } 96 97 @Override 98 public Set<String> getSupportedAnnotationTypes() { 99 Set<String> annotationTypes = new HashSet<>(); 100 for (AbstractVerifier verifier : getVerifiers()) { 101 annotationTypes.add(verifier.getAnnotationClass().getCanonicalName()); 102 } 103 return annotationTypes; 104 } 105 106 }