< prev index next >

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

Print this page
rev 2988 : JDK-8058150


  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.processing;
  27 
  28 import java.io.Closeable;
  29 import java.io.File;
  30 import java.io.PrintWriter;
  31 import java.io.StringWriter;
  32 import java.net.MalformedURLException;
  33 import java.net.URL;
  34 import java.util.*;
  35 import java.util.regex.*;

  36 
  37 import javax.annotation.processing.*;
  38 import javax.lang.model.SourceVersion;
  39 import javax.lang.model.element.*;
  40 import javax.lang.model.util.*;
  41 import javax.tools.JavaFileManager;
  42 import javax.tools.JavaFileObject;
  43 import javax.tools.StandardJavaFileManager;
  44 import static javax.tools.StandardLocation.*;
  45 
  46 import com.sun.source.util.TaskEvent;
  47 import com.sun.tools.javac.api.MultiTaskListener;
  48 import com.sun.tools.javac.code.*;
  49 import com.sun.tools.javac.code.Symbol.*;
  50 import com.sun.tools.javac.code.Type.ClassType;
  51 import com.sun.tools.javac.code.Types;
  52 import com.sun.tools.javac.comp.AttrContext;
  53 import com.sun.tools.javac.comp.Check;
  54 import com.sun.tools.javac.comp.Enter;
  55 import com.sun.tools.javac.comp.Env;
  56 import com.sun.tools.javac.file.JavacFileManager;
  57 import com.sun.tools.javac.main.JavaCompiler;
  58 import com.sun.tools.javac.model.JavacElements;
  59 import com.sun.tools.javac.model.JavacTypes;


  60 import com.sun.tools.javac.tree.*;
  61 import com.sun.tools.javac.tree.JCTree.*;
  62 import com.sun.tools.javac.util.Abort;
  63 import com.sun.tools.javac.util.Assert;
  64 import com.sun.tools.javac.util.ClientCodeException;
  65 import com.sun.tools.javac.util.Context;
  66 import com.sun.tools.javac.util.Convert;
  67 import com.sun.tools.javac.util.DefinedBy;
  68 import com.sun.tools.javac.util.DefinedBy.Api;

  69 import com.sun.tools.javac.util.JCDiagnostic;
  70 import com.sun.tools.javac.util.JavacMessages;
  71 import com.sun.tools.javac.util.List;
  72 import com.sun.tools.javac.util.Log;
  73 import com.sun.tools.javac.util.MatchingUtils;
  74 import com.sun.tools.javac.util.Name;
  75 import com.sun.tools.javac.util.Names;
  76 import com.sun.tools.javac.util.Options;
  77 import com.sun.tools.javac.util.ServiceLoader;
  78 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
  79 import static com.sun.tools.javac.code.Kinds.Kind.*;
  80 import static com.sun.tools.javac.main.Option.*;
  81 import static com.sun.tools.javac.comp.CompileStates.CompileState;
  82 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
  83 
  84 /**
  85  * Objects of this class hold and manage the state needed to support
  86  * annotation processing.
  87  *
  88  * <p><b>This is NOT part of any supported API.


 265                  * If the "-processor" option is used, search the appropriate
 266                  * path for the named class.  Otherwise, use a service
 267                  * provider mechanism to create the processor iterator.
 268                  */
 269                 if (processorNames != null) {
 270                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
 271                 } else {
 272                     processorIterator = new ServiceIterator(processorClassLoader, log);
 273                 }
 274             } else {
 275                 /*
 276                  * A security exception will occur if we can't create a classloader.
 277                  * Ignore the exception if, with hindsight, we didn't need it anyway
 278                  * (i.e. no processor was specified either explicitly, or implicitly,
 279                  * in service configuration file.) Otherwise, we cannot continue.
 280                  */
 281                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
 282                         processorClassLoaderException);
 283             }
 284         }
 285         discoveredProcs = new DiscoveredProcessors(processorIterator);












 286     }
 287 
 288     /**
 289      * Returns an empty processor iterator if no processors are on the
 290      * relevant path, otherwise if processors are present, logs an
 291      * error.  Called when a service loader is unavailable for some
 292      * reason, either because a service loader class cannot be found
 293      * or because a security policy prevents class loaders from being
 294      * created.
 295      *
 296      * @param key The resource key to use to log an error message
 297      * @param e   If non-null, pass this exception to Abort
 298      */
 299     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
 300         JavaFileManager fileManager = context.get(JavaFileManager.class);
 301 
 302         if (fileManager instanceof JavacFileManager) {
 303             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
 304             Iterable<? extends File> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 305                 ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH)


 464         Set<String> keySet = options.keySet();
 465         Map<String, String> tempOptions = new LinkedHashMap<>();
 466 
 467         for(String key : keySet) {
 468             if (key.startsWith("-A") && key.length() > 2) {
 469                 int sepIndex = key.indexOf('=');
 470                 String candidateKey = null;
 471                 String candidateValue = null;
 472 
 473                 if (sepIndex == -1)
 474                     candidateKey = key.substring(2);
 475                 else if (sepIndex >= 3) {
 476                     candidateKey = key.substring(2, sepIndex);
 477                     candidateValue = (sepIndex < key.length()-1)?
 478                         key.substring(sepIndex+1) : null;
 479                 }
 480                 tempOptions.put(candidateKey, candidateValue);
 481             }
 482         }
 483 








 484         return Collections.unmodifiableMap(tempOptions);
 485     }
 486 
 487     private Set<String> initUnmatchedProcessorOptions() {
 488         Set<String> unmatchedProcessorOptions = new HashSet<>();
 489         unmatchedProcessorOptions.addAll(processorOptions.keySet());
 490         return unmatchedProcessorOptions;
 491     }
 492 
 493     /**
 494      * State about how a processor has been used by the tool.  If a
 495      * processor has been used on a prior round, its process method is
 496      * called on all subsequent rounds, perhaps with an empty set of
 497      * annotations to process.  The {@code annotationSupported} method
 498      * caches the supported annotation information from the first (and
 499      * only) getSupportedAnnotationTypes call to the processor.
 500      */
 501     static class ProcessorState {
 502         public Processor processor;
 503         public boolean   contributed;




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.processing;
  27 
  28 import java.io.Closeable;
  29 import java.io.File;
  30 import java.io.PrintWriter;
  31 import java.io.StringWriter;
  32 import java.net.MalformedURLException;
  33 import java.net.URL;
  34 import java.util.*;
  35 import java.util.regex.*;
  36 import java.util.stream.Collectors;
  37 
  38 import javax.annotation.processing.*;
  39 import javax.lang.model.SourceVersion;
  40 import javax.lang.model.element.*;
  41 import javax.lang.model.util.*;
  42 import javax.tools.JavaFileManager;
  43 import javax.tools.JavaFileObject;
  44 import javax.tools.StandardJavaFileManager;
  45 import static javax.tools.StandardLocation.*;
  46 
  47 import com.sun.source.util.TaskEvent;
  48 import com.sun.tools.javac.api.MultiTaskListener;
  49 import com.sun.tools.javac.code.*;
  50 import com.sun.tools.javac.code.Symbol.*;
  51 import com.sun.tools.javac.code.Type.ClassType;
  52 import com.sun.tools.javac.code.Types;
  53 import com.sun.tools.javac.comp.AttrContext;
  54 import com.sun.tools.javac.comp.Check;
  55 import com.sun.tools.javac.comp.Enter;
  56 import com.sun.tools.javac.comp.Env;
  57 import com.sun.tools.javac.file.JavacFileManager;
  58 import com.sun.tools.javac.main.JavaCompiler;
  59 import com.sun.tools.javac.model.JavacElements;
  60 import com.sun.tools.javac.model.JavacTypes;
  61 import com.sun.tools.javac.platform.PlatformProvider;
  62 import com.sun.tools.javac.platform.PlatformProvider.PluginInfo;
  63 import com.sun.tools.javac.tree.*;
  64 import com.sun.tools.javac.tree.JCTree.*;
  65 import com.sun.tools.javac.util.Abort;
  66 import com.sun.tools.javac.util.Assert;
  67 import com.sun.tools.javac.util.ClientCodeException;
  68 import com.sun.tools.javac.util.Context;
  69 import com.sun.tools.javac.util.Convert;
  70 import com.sun.tools.javac.util.DefinedBy;
  71 import com.sun.tools.javac.util.DefinedBy.Api;
  72 import com.sun.tools.javac.util.Iterators;
  73 import com.sun.tools.javac.util.JCDiagnostic;
  74 import com.sun.tools.javac.util.JavacMessages;
  75 import com.sun.tools.javac.util.List;
  76 import com.sun.tools.javac.util.Log;
  77 import com.sun.tools.javac.util.MatchingUtils;
  78 import com.sun.tools.javac.util.Name;
  79 import com.sun.tools.javac.util.Names;
  80 import com.sun.tools.javac.util.Options;
  81 import com.sun.tools.javac.util.ServiceLoader;
  82 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
  83 import static com.sun.tools.javac.code.Kinds.Kind.*;
  84 import static com.sun.tools.javac.main.Option.*;
  85 import static com.sun.tools.javac.comp.CompileStates.CompileState;
  86 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
  87 
  88 /**
  89  * Objects of this class hold and manage the state needed to support
  90  * annotation processing.
  91  *
  92  * <p><b>This is NOT part of any supported API.


 269                  * If the "-processor" option is used, search the appropriate
 270                  * path for the named class.  Otherwise, use a service
 271                  * provider mechanism to create the processor iterator.
 272                  */
 273                 if (processorNames != null) {
 274                     processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
 275                 } else {
 276                     processorIterator = new ServiceIterator(processorClassLoader, log);
 277                 }
 278             } else {
 279                 /*
 280                  * A security exception will occur if we can't create a classloader.
 281                  * Ignore the exception if, with hindsight, we didn't need it anyway
 282                  * (i.e. no processor was specified either explicitly, or implicitly,
 283                  * in service configuration file.) Otherwise, we cannot continue.
 284                  */
 285                 processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
 286                         processorClassLoaderException);
 287             }
 288         }
 289         PlatformProvider platformProvider = context.get(PlatformProvider.class);
 290         java.util.List<Processor> platformProcessors = Collections.emptyList();
 291         if (platformProvider != null) {
 292             platformProcessors = platformProvider.getAnnotationProcessors()
 293                                                  .stream()
 294                                                  .map(ap -> ap.getPlugin())
 295                                                  .collect(Collectors.toList());
 296         }
 297         List<Iterator<? extends Processor>> iterators = List.of(processorIterator,
 298                                                                 platformProcessors.iterator());
 299         Iterator<? extends Processor> compoundIterator =
 300                 Iterators.createCompoundIterator(iterators, i -> i);
 301         discoveredProcs = new DiscoveredProcessors(compoundIterator);
 302     }
 303 
 304     /**
 305      * Returns an empty processor iterator if no processors are on the
 306      * relevant path, otherwise if processors are present, logs an
 307      * error.  Called when a service loader is unavailable for some
 308      * reason, either because a service loader class cannot be found
 309      * or because a security policy prevents class loaders from being
 310      * created.
 311      *
 312      * @param key The resource key to use to log an error message
 313      * @param e   If non-null, pass this exception to Abort
 314      */
 315     private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
 316         JavaFileManager fileManager = context.get(JavaFileManager.class);
 317 
 318         if (fileManager instanceof JavacFileManager) {
 319             StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
 320             Iterable<? extends File> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
 321                 ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH)


 480         Set<String> keySet = options.keySet();
 481         Map<String, String> tempOptions = new LinkedHashMap<>();
 482 
 483         for(String key : keySet) {
 484             if (key.startsWith("-A") && key.length() > 2) {
 485                 int sepIndex = key.indexOf('=');
 486                 String candidateKey = null;
 487                 String candidateValue = null;
 488 
 489                 if (sepIndex == -1)
 490                     candidateKey = key.substring(2);
 491                 else if (sepIndex >= 3) {
 492                     candidateKey = key.substring(2, sepIndex);
 493                     candidateValue = (sepIndex < key.length()-1)?
 494                         key.substring(sepIndex+1) : null;
 495                 }
 496                 tempOptions.put(candidateKey, candidateValue);
 497             }
 498         }
 499 
 500         PlatformProvider platformProvider = context.get(PlatformProvider.class);
 501 
 502         if (platformProvider != null) {
 503             for (PluginInfo<Processor> ap : platformProvider.getAnnotationProcessors()) {
 504                 tempOptions.putAll(ap.getOptions());
 505             }
 506         }
 507 
 508         return Collections.unmodifiableMap(tempOptions);
 509     }
 510 
 511     private Set<String> initUnmatchedProcessorOptions() {
 512         Set<String> unmatchedProcessorOptions = new HashSet<>();
 513         unmatchedProcessorOptions.addAll(processorOptions.keySet());
 514         return unmatchedProcessorOptions;
 515     }
 516 
 517     /**
 518      * State about how a processor has been used by the tool.  If a
 519      * processor has been used on a prior round, its process method is
 520      * called on all subsequent rounds, perhaps with an empty set of
 521      * annotations to process.  The {@code annotationSupported} method
 522      * caches the supported annotation information from the first (and
 523      * only) getSupportedAnnotationTypes call to the processor.
 524      */
 525     static class ProcessorState {
 526         public Processor processor;
 527         public boolean   contributed;


< prev index next >