< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java

Print this page
rev 48841 : [mq]: 8187950


  35 import java.nio.file.Path;
  36 import java.util.*;
  37 import java.util.Map.Entry;
  38 import java.util.regex.*;
  39 import java.util.stream.Collectors;
  40 
  41 import javax.annotation.processing.*;
  42 import javax.lang.model.SourceVersion;
  43 import javax.lang.model.element.*;
  44 import javax.lang.model.util.*;
  45 import javax.tools.JavaFileManager;
  46 import javax.tools.JavaFileObject;
  47 import javax.tools.JavaFileObject.Kind;
  48 import javax.tools.StandardJavaFileManager;
  49 
  50 import static javax.tools.StandardLocation.*;
  51 
  52 import com.sun.source.util.TaskEvent;
  53 import com.sun.tools.javac.api.MultiTaskListener;
  54 import com.sun.tools.javac.code.*;

  55 import com.sun.tools.javac.code.Scope.WriteableScope;
  56 import com.sun.tools.javac.code.Source.Feature;
  57 import com.sun.tools.javac.code.Symbol.*;
  58 import com.sun.tools.javac.code.Type.ClassType;
  59 import com.sun.tools.javac.code.Types;
  60 import com.sun.tools.javac.comp.AttrContext;
  61 import com.sun.tools.javac.comp.Check;
  62 import com.sun.tools.javac.comp.Enter;
  63 import com.sun.tools.javac.comp.Env;
  64 import com.sun.tools.javac.comp.Modules;
  65 import com.sun.tools.javac.file.JavacFileManager;
  66 import com.sun.tools.javac.main.JavaCompiler;
  67 import com.sun.tools.javac.main.Option;
  68 import com.sun.tools.javac.model.JavacElements;
  69 import com.sun.tools.javac.model.JavacTypes;
  70 import com.sun.tools.javac.platform.PlatformDescription;
  71 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
  72 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  73 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  74 import com.sun.tools.javac.tree.*;


 160     JCDiagnostic.Factory diags;
 161 
 162     /**
 163      * Source level of the compile.
 164      */
 165     Source source;
 166 
 167     private ClassLoader processorClassLoader;
 168     private ServiceLoader<Processor> serviceLoader;
 169     private SecurityException processorLoaderException;
 170 
 171     private final JavaFileManager fileManager;
 172 
 173     /**
 174      * JavacMessages object used for localization
 175      */
 176     private JavacMessages messages;
 177 
 178     private MultiTaskListener taskListener;
 179     private final Symtab symtab;

 180     private final Names names;
 181     private final Enter enter;
 182     private final Completer initialCompleter;
 183     private final Check chk;
 184 
 185     private final Context context;
 186 
 187     /** Get the JavacProcessingEnvironment instance for this context. */
 188     public static JavacProcessingEnvironment instance(Context context) {
 189         JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
 190         if (instance == null)
 191             instance = new JavacProcessingEnvironment(context);
 192         return instance;
 193     }
 194 
 195     protected JavacProcessingEnvironment(Context context) {
 196         this.context = context;
 197         context.put(JavacProcessingEnvironment.class, this);
 198         log = Log.instance(context);
 199         source = Source.instance(context);


 210         fatalErrors = options.isSet("fatalEnterError");
 211         showResolveErrors = options.isSet("showResolveErrors");
 212         werror = options.isSet(Option.WERROR);
 213         fileManager = context.get(JavaFileManager.class);
 214         platformAnnotations = initPlatformAnnotations();
 215 
 216         // Initialize services before any processors are initialized
 217         // in case processors use them.
 218         filer = new JavacFiler(context);
 219         messager = new JavacMessager(context, this);
 220         elementUtils = JavacElements.instance(context);
 221         typeUtils = JavacTypes.instance(context);
 222         modules = Modules.instance(context);
 223         types = Types.instance(context);
 224         annotate = Annotate.instance(context);
 225         processorOptions = initProcessorOptions();
 226         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
 227         messages = JavacMessages.instance(context);
 228         taskListener = MultiTaskListener.instance(context);
 229         symtab = Symtab.instance(context);

 230         names = Names.instance(context);
 231         enter = Enter.instance(context);
 232         initialCompleter = ClassFinder.instance(context).getCompleter();
 233         chk = Check.instance(context);
 234         initProcessorLoader();
 235     }
 236 
 237     public void setProcessors(Iterable<? extends Processor> processors) {
 238         Assert.checkNull(discoveredProcs);
 239         initProcessorIterator(processors);
 240     }
 241 
 242     private Set<String> initPlatformAnnotations() {
 243         Set<String> platformAnnotations = new HashSet<>();
 244         platformAnnotations.add("java.lang.Deprecated");
 245         platformAnnotations.add("java.lang.Override");
 246         platformAnnotations.add("java.lang.SuppressWarnings");
 247         platformAnnotations.add("java.lang.annotation.Documented");
 248         platformAnnotations.add("java.lang.annotation.Inherited");
 249         platformAnnotations.add("java.lang.annotation.Retention");


 648     private Set<String> initUnmatchedProcessorOptions() {
 649         Set<String> unmatchedProcessorOptions = new HashSet<>();
 650         unmatchedProcessorOptions.addAll(processorOptions.keySet());
 651         return unmatchedProcessorOptions;
 652     }
 653 
 654     /**
 655      * State about how a processor has been used by the tool.  If a
 656      * processor has been used on a prior round, its process method is
 657      * called on all subsequent rounds, perhaps with an empty set of
 658      * annotations to process.  The {@code annotationSupported} method
 659      * caches the supported annotation information from the first (and
 660      * only) getSupportedAnnotationTypes call to the processor.
 661      */
 662     static class ProcessorState {
 663         public Processor processor;
 664         public boolean   contributed;
 665         private ArrayList<Pattern> supportedAnnotationPatterns;
 666         private ArrayList<String>  supportedOptionNames;
 667 
 668         ProcessorState(Processor p, Log log, Source source, boolean allowModules, ProcessingEnvironment env) {

 669             processor = p;
 670             contributed = false;
 671 

 672             try {
 673                 processor.init(env);
 674 
 675                 checkSourceVersionCompatibility(source, log);
 676 
 677                 supportedAnnotationPatterns = new ArrayList<>();
 678                 for (String importString : processor.getSupportedAnnotationTypes()) {
 679                     supportedAnnotationPatterns.add(importStringToPattern(allowModules,
 680                                                                           importString,
 681                                                                           processor,
 682                                                                           log));
 683                 }
 684 
 685                 supportedOptionNames = new ArrayList<>();
 686                 for (String optionName : processor.getSupportedOptions() ) {
 687                     if (checkOptionName(optionName, log))
 688                         supportedOptionNames.add(optionName);
 689                 }
 690 
 691             } catch (ClientCodeException e) {
 692                 throw e;
 693             } catch (Throwable t) {
 694                 throw new AnnotationProcessingError(t);


 695             }
 696         }
 697 
 698         /**
 699          * Checks whether or not a processor's source version is
 700          * compatible with the compilation source version.  The
 701          * processor's source version needs to be greater than or
 702          * equal to the source version of the compile.
 703          */
 704         private void checkSourceVersionCompatibility(Source source, Log log) {
 705             SourceVersion procSourceVersion = processor.getSupportedSourceVersion();
 706 
 707             if (procSourceVersion.compareTo(Source.toSourceVersion(source)) < 0 )  {
 708                 log.warning(Warnings.ProcProcessorIncompatibleSourceVersion(procSourceVersion,
 709                                                                             processor.getClass().getName(),
 710                                                                             source.name));
 711             }
 712         }
 713 
 714         private boolean checkOptionName(String optionName, Log log) {


 750             DiscoveredProcessors psi;
 751             Iterator<ProcessorState> innerIter;
 752             boolean onProcInterator;
 753 
 754             ProcessorStateIterator(DiscoveredProcessors psi) {
 755                 this.psi = psi;
 756                 this.innerIter = psi.procStateList.iterator();
 757                 this.onProcInterator = false;
 758             }
 759 
 760             public ProcessorState next() {
 761                 if (!onProcInterator) {
 762                     if (innerIter.hasNext())
 763                         return innerIter.next();
 764                     else
 765                         onProcInterator = true;
 766                 }
 767 
 768                 if (psi.processorIterator.hasNext()) {
 769                     ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
 770                                                            log, source, Feature.MODULES.allowedInSource(source),

 771                                                            JavacProcessingEnvironment.this);
 772                     psi.procStateList.add(ps);
 773                     return ps;
 774                 } else
 775                     throw new NoSuchElementException();
 776             }
 777 
 778             public boolean hasNext() {
 779                 if (onProcInterator)
 780                     return  psi.processorIterator.hasNext();
 781                 else
 782                     return innerIter.hasNext() || psi.processorIterator.hasNext();
 783             }
 784 
 785             public void remove () {
 786                 throw new UnsupportedOperationException();
 787             }
 788 
 789             /**
 790              * Run all remaining processors on the procStateList that


 942         }
 943 
 944         void addAnnotations(Element e, Set<TypeElement> p) {
 945             for (AnnotationMirror annotationMirror :
 946                      elements.getAllAnnotationMirrors(e) ) {
 947                 Element e2 = annotationMirror.getAnnotationType().asElement();
 948                 p.add((TypeElement) e2);
 949             }
 950         }
 951 
 952         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 953         public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
 954             addAnnotations(e, p);
 955             return super.scan(e, p);
 956         }
 957     }
 958 
 959     private boolean callProcessor(Processor proc,
 960                                          Set<? extends TypeElement> tes,
 961                                          RoundEnvironment renv) {

 962         try {
 963             return proc.process(tes, renv);
 964         } catch (ClassFinder.BadClassFile ex) {
 965             log.error(Errors.ProcCantAccess1(ex.sym, ex.getDetailValue()));
 966             return false;
 967         } catch (CompletionFailure ex) {
 968             StringWriter out = new StringWriter();
 969             ex.printStackTrace(new PrintWriter(out));
 970             log.error(Errors.ProcCantAccess(ex.sym, ex.getDetailValue(), out.toString()));
 971             return false;
 972         } catch (ClientCodeException e) {
 973             throw e;
 974         } catch (Throwable t) {
 975             throw new AnnotationProcessingError(t);


 976         }
 977     }
 978 
 979     /**
 980      * Helper object for a single round of annotation processing.
 981      */
 982     class Round {
 983         /** The round number. */
 984         final int number;
 985         /** The diagnostic handler for the round. */
 986         final Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
 987 
 988         /** The ASTs to be compiled. */
 989         List<JCCompilationUnit> roots;
 990         /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */
 991         Set<JCCompilationUnit> treesToClean;
 992         /** The classes to be compiler that have were generated. */
 993         Map<ModuleSymbol, Map<String, JavaFileObject>> genClassFiles;
 994 
 995         /** The set of annotations to be processed this round. */




  35 import java.nio.file.Path;
  36 import java.util.*;
  37 import java.util.Map.Entry;
  38 import java.util.regex.*;
  39 import java.util.stream.Collectors;
  40 
  41 import javax.annotation.processing.*;
  42 import javax.lang.model.SourceVersion;
  43 import javax.lang.model.element.*;
  44 import javax.lang.model.util.*;
  45 import javax.tools.JavaFileManager;
  46 import javax.tools.JavaFileObject;
  47 import javax.tools.JavaFileObject.Kind;
  48 import javax.tools.StandardJavaFileManager;
  49 
  50 import static javax.tools.StandardLocation.*;
  51 
  52 import com.sun.source.util.TaskEvent;
  53 import com.sun.tools.javac.api.MultiTaskListener;
  54 import com.sun.tools.javac.code.*;
  55 import com.sun.tools.javac.code.DeferredCompletionFailureHandler.Handler;
  56 import com.sun.tools.javac.code.Scope.WriteableScope;
  57 import com.sun.tools.javac.code.Source.Feature;
  58 import com.sun.tools.javac.code.Symbol.*;
  59 import com.sun.tools.javac.code.Type.ClassType;
  60 import com.sun.tools.javac.code.Types;
  61 import com.sun.tools.javac.comp.AttrContext;
  62 import com.sun.tools.javac.comp.Check;
  63 import com.sun.tools.javac.comp.Enter;
  64 import com.sun.tools.javac.comp.Env;
  65 import com.sun.tools.javac.comp.Modules;
  66 import com.sun.tools.javac.file.JavacFileManager;
  67 import com.sun.tools.javac.main.JavaCompiler;
  68 import com.sun.tools.javac.main.Option;
  69 import com.sun.tools.javac.model.JavacElements;
  70 import com.sun.tools.javac.model.JavacTypes;
  71 import com.sun.tools.javac.platform.PlatformDescription;
  72 import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
  73 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  74 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  75 import com.sun.tools.javac.tree.*;


 161     JCDiagnostic.Factory diags;
 162 
 163     /**
 164      * Source level of the compile.
 165      */
 166     Source source;
 167 
 168     private ClassLoader processorClassLoader;
 169     private ServiceLoader<Processor> serviceLoader;
 170     private SecurityException processorLoaderException;
 171 
 172     private final JavaFileManager fileManager;
 173 
 174     /**
 175      * JavacMessages object used for localization
 176      */
 177     private JavacMessages messages;
 178 
 179     private MultiTaskListener taskListener;
 180     private final Symtab symtab;
 181     private final DeferredCompletionFailureHandler dcfh;
 182     private final Names names;
 183     private final Enter enter;
 184     private final Completer initialCompleter;
 185     private final Check chk;
 186 
 187     private final Context context;
 188 
 189     /** Get the JavacProcessingEnvironment instance for this context. */
 190     public static JavacProcessingEnvironment instance(Context context) {
 191         JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
 192         if (instance == null)
 193             instance = new JavacProcessingEnvironment(context);
 194         return instance;
 195     }
 196 
 197     protected JavacProcessingEnvironment(Context context) {
 198         this.context = context;
 199         context.put(JavacProcessingEnvironment.class, this);
 200         log = Log.instance(context);
 201         source = Source.instance(context);


 212         fatalErrors = options.isSet("fatalEnterError");
 213         showResolveErrors = options.isSet("showResolveErrors");
 214         werror = options.isSet(Option.WERROR);
 215         fileManager = context.get(JavaFileManager.class);
 216         platformAnnotations = initPlatformAnnotations();
 217 
 218         // Initialize services before any processors are initialized
 219         // in case processors use them.
 220         filer = new JavacFiler(context);
 221         messager = new JavacMessager(context, this);
 222         elementUtils = JavacElements.instance(context);
 223         typeUtils = JavacTypes.instance(context);
 224         modules = Modules.instance(context);
 225         types = Types.instance(context);
 226         annotate = Annotate.instance(context);
 227         processorOptions = initProcessorOptions();
 228         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
 229         messages = JavacMessages.instance(context);
 230         taskListener = MultiTaskListener.instance(context);
 231         symtab = Symtab.instance(context);
 232         dcfh = DeferredCompletionFailureHandler.instance(context);
 233         names = Names.instance(context);
 234         enter = Enter.instance(context);
 235         initialCompleter = ClassFinder.instance(context).getCompleter();
 236         chk = Check.instance(context);
 237         initProcessorLoader();
 238     }
 239 
 240     public void setProcessors(Iterable<? extends Processor> processors) {
 241         Assert.checkNull(discoveredProcs);
 242         initProcessorIterator(processors);
 243     }
 244 
 245     private Set<String> initPlatformAnnotations() {
 246         Set<String> platformAnnotations = new HashSet<>();
 247         platformAnnotations.add("java.lang.Deprecated");
 248         platformAnnotations.add("java.lang.Override");
 249         platformAnnotations.add("java.lang.SuppressWarnings");
 250         platformAnnotations.add("java.lang.annotation.Documented");
 251         platformAnnotations.add("java.lang.annotation.Inherited");
 252         platformAnnotations.add("java.lang.annotation.Retention");


 651     private Set<String> initUnmatchedProcessorOptions() {
 652         Set<String> unmatchedProcessorOptions = new HashSet<>();
 653         unmatchedProcessorOptions.addAll(processorOptions.keySet());
 654         return unmatchedProcessorOptions;
 655     }
 656 
 657     /**
 658      * State about how a processor has been used by the tool.  If a
 659      * processor has been used on a prior round, its process method is
 660      * called on all subsequent rounds, perhaps with an empty set of
 661      * annotations to process.  The {@code annotationSupported} method
 662      * caches the supported annotation information from the first (and
 663      * only) getSupportedAnnotationTypes call to the processor.
 664      */
 665     static class ProcessorState {
 666         public Processor processor;
 667         public boolean   contributed;
 668         private ArrayList<Pattern> supportedAnnotationPatterns;
 669         private ArrayList<String>  supportedOptionNames;
 670 
 671         ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh,
 672                        boolean allowModules, ProcessingEnvironment env) {
 673             processor = p;
 674             contributed = false;
 675 
 676             Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler);
 677             try {
 678                 processor.init(env);
 679 
 680                 checkSourceVersionCompatibility(source, log);
 681 
 682                 supportedAnnotationPatterns = new ArrayList<>();
 683                 for (String importString : processor.getSupportedAnnotationTypes()) {
 684                     supportedAnnotationPatterns.add(importStringToPattern(allowModules,
 685                                                                           importString,
 686                                                                           processor,
 687                                                                           log));
 688                 }
 689 
 690                 supportedOptionNames = new ArrayList<>();
 691                 for (String optionName : processor.getSupportedOptions() ) {
 692                     if (checkOptionName(optionName, log))
 693                         supportedOptionNames.add(optionName);
 694                 }
 695 
 696             } catch (ClientCodeException e) {
 697                 throw e;
 698             } catch (Throwable t) {
 699                 throw new AnnotationProcessingError(t);
 700             } finally {
 701                 dcfh.setHandler(prevDeferredHandler);
 702             }
 703         }
 704 
 705         /**
 706          * Checks whether or not a processor's source version is
 707          * compatible with the compilation source version.  The
 708          * processor's source version needs to be greater than or
 709          * equal to the source version of the compile.
 710          */
 711         private void checkSourceVersionCompatibility(Source source, Log log) {
 712             SourceVersion procSourceVersion = processor.getSupportedSourceVersion();
 713 
 714             if (procSourceVersion.compareTo(Source.toSourceVersion(source)) < 0 )  {
 715                 log.warning(Warnings.ProcProcessorIncompatibleSourceVersion(procSourceVersion,
 716                                                                             processor.getClass().getName(),
 717                                                                             source.name));
 718             }
 719         }
 720 
 721         private boolean checkOptionName(String optionName, Log log) {


 757             DiscoveredProcessors psi;
 758             Iterator<ProcessorState> innerIter;
 759             boolean onProcInterator;
 760 
 761             ProcessorStateIterator(DiscoveredProcessors psi) {
 762                 this.psi = psi;
 763                 this.innerIter = psi.procStateList.iterator();
 764                 this.onProcInterator = false;
 765             }
 766 
 767             public ProcessorState next() {
 768                 if (!onProcInterator) {
 769                     if (innerIter.hasNext())
 770                         return innerIter.next();
 771                     else
 772                         onProcInterator = true;
 773                 }
 774 
 775                 if (psi.processorIterator.hasNext()) {
 776                     ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
 777                                                            log, source, dcfh,
 778                                                            Feature.MODULES.allowedInSource(source),
 779                                                            JavacProcessingEnvironment.this);
 780                     psi.procStateList.add(ps);
 781                     return ps;
 782                 } else
 783                     throw new NoSuchElementException();
 784             }
 785 
 786             public boolean hasNext() {
 787                 if (onProcInterator)
 788                     return  psi.processorIterator.hasNext();
 789                 else
 790                     return innerIter.hasNext() || psi.processorIterator.hasNext();
 791             }
 792 
 793             public void remove () {
 794                 throw new UnsupportedOperationException();
 795             }
 796 
 797             /**
 798              * Run all remaining processors on the procStateList that


 950         }
 951 
 952         void addAnnotations(Element e, Set<TypeElement> p) {
 953             for (AnnotationMirror annotationMirror :
 954                      elements.getAllAnnotationMirrors(e) ) {
 955                 Element e2 = annotationMirror.getAnnotationType().asElement();
 956                 p.add((TypeElement) e2);
 957             }
 958         }
 959 
 960         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 961         public Set<TypeElement> scan(Element e, Set<TypeElement> p) {
 962             addAnnotations(e, p);
 963             return super.scan(e, p);
 964         }
 965     }
 966 
 967     private boolean callProcessor(Processor proc,
 968                                          Set<? extends TypeElement> tes,
 969                                          RoundEnvironment renv) {
 970         Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler);
 971         try {
 972             return proc.process(tes, renv);
 973         } catch (ClassFinder.BadClassFile ex) {
 974             log.error(Errors.ProcCantAccess1(ex.sym, ex.getDetailValue()));
 975             return false;
 976         } catch (CompletionFailure ex) {
 977             StringWriter out = new StringWriter();
 978             ex.printStackTrace(new PrintWriter(out));
 979             log.error(Errors.ProcCantAccess(ex.sym, ex.getDetailValue(), out.toString()));
 980             return false;
 981         } catch (ClientCodeException e) {
 982             throw e;
 983         } catch (Throwable t) {
 984             throw new AnnotationProcessingError(t);
 985         } finally {
 986             dcfh.setHandler(prevDeferredHandler);
 987         }
 988     }
 989 
 990     /**
 991      * Helper object for a single round of annotation processing.
 992      */
 993     class Round {
 994         /** The round number. */
 995         final int number;
 996         /** The diagnostic handler for the round. */
 997         final Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
 998 
 999         /** The ASTs to be compiled. */
1000         List<JCCompilationUnit> roots;
1001         /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */
1002         Set<JCCompilationUnit> treesToClean;
1003         /** The classes to be compiler that have were generated. */
1004         Map<ModuleSymbol, Map<String, JavaFileObject>> genClassFiles;
1005 
1006         /** The set of annotations to be processed this round. */


< prev index next >