1 /*
   2  * Copyright (c) 2009, 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 import java.io.*;
  24 import java.util.Set;
  25 import java.util.HashSet;
  26 
  27 import javax.annotation.processing.*;
  28 import javax.lang.model.SourceVersion;
  29 import javax.lang.model.element.*;
  30 import javax.lang.model.util.ElementFilter;
  31 
  32 import com.sun.source.util.JavacTask;
  33 import com.sun.source.util.TaskEvent;
  34 import com.sun.source.util.TaskListener;
  35 import com.sun.source.util.TreePath;
  36 import com.sun.tools.javac.main.JavaCompiler;
  37 import com.sun.tools.javac.main.JavaCompiler.CompileState;
  38 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
  39 import com.sun.tools.javac.util.Context;
  40 
  41 /*
  42  * @test
  43  * @summary test that type processors are run when -proc:only is passed.
  44  * This class implements the functionality of a type processor, as previously
  45  * embodied by the AbstractTypeProcessor class.
  46  *
  47  * @author Mahmood Ali
  48  * @author Werner Dietl
  49  */
  50 @SupportedAnnotationTypes("*")
  51 public class TypeProcOnly extends AbstractProcessor {
  52     private static final String INDICATOR = "INDICATOR";
  53 
  54     private final AttributionTaskListener listener = new AttributionTaskListener();
  55     private final Set<Name> elements = new HashSet<Name>();
  56 
  57     @Override
  58     public final void init(ProcessingEnvironment env) {
  59         super.init(env);
  60         JavacTask.instance(env).addTaskListener(listener);
  61         Context ctx = ((JavacProcessingEnvironment)processingEnv).getContext();
  62         JavaCompiler compiler = JavaCompiler.instance(ctx);
  63         compiler.shouldStopPolicyIfNoError = CompileState.max(
  64                 compiler.shouldStopPolicyIfNoError,
  65                 CompileState.FLOW);
  66     }
  67 
  68     @Override
  69     public final boolean process(Set<? extends TypeElement> annotations,
  70             RoundEnvironment roundEnv) {
  71         for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) {
  72             elements.add(elem.getQualifiedName());
  73         }
  74         return false;
  75     }
  76 
  77     @Override
  78     public SourceVersion getSupportedSourceVersion() {
  79         return SourceVersion.latest();
  80     }
  81 
  82     private final class AttributionTaskListener implements TaskListener {
  83         @Override
  84         public void started(TaskEvent e) { }
  85 
  86         @Override
  87         public void finished(TaskEvent e) {
  88             if (e.getKind() != TaskEvent.Kind.ANALYZE)
  89                 return;
  90 
  91             if (!elements.remove(e.getTypeElement().getQualifiedName()))
  92                 return;
  93 
  94             System.out.println(INDICATOR);
  95         }
  96     }
  97 
  98 
  99     private static File writeTestFile() throws IOException {
 100         File f = new File("Test.java");
 101         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
 102         out.println("class Test { }");
 103         out.close();
 104         return f;
 105     }
 106 
 107     public static void main(String[] args) throws Exception {
 108         PrintStream prevOut = System.out;
 109 
 110         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
 111         PrintStream out = new PrintStream(bytes);
 112         System.setOut(out);
 113 
 114         try {
 115             File f = writeTestFile();
 116             com.sun.tools.javac.Main.compile(new String[] {"-proc:only", "-processor", "TypeProcOnly", f.getAbsolutePath()});
 117         } finally {
 118             System.setOut(prevOut);
 119         }
 120 
 121         if (bytes.toString().trim().equals(INDICATOR)) {
 122             System.out.println("PASSED");
 123         } else {
 124             throw new Exception("Processor did not run correctly. Output: " + bytes);
 125         }
 126     }
 127 }