< prev index next >

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

Print this page
rev 2973 : 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.*;


 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.JCDiagnostic;
  73 import com.sun.tools.javac.util.JavacMessages;
  74 import com.sun.tools.javac.util.List;
  75 import com.sun.tools.javac.util.Log;
  76 import com.sun.tools.javac.util.MatchingUtils;
  77 import com.sun.tools.javac.util.Name;
  78 import com.sun.tools.javac.util.Names;
  79 import com.sun.tools.javac.util.Options;
  80 import com.sun.tools.javac.util.ServiceLoader;
  81 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
  82 import static com.sun.tools.javac.code.Kinds.Kind.*;


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


 501         Set<String> keySet = options.keySet();
 502         Map<String, String> tempOptions = new LinkedHashMap<>();
 503 
 504         for(String key : keySet) {
 505             if (key.startsWith("-A") && key.length() > 2) {
 506                 int sepIndex = key.indexOf('=');
 507                 String candidateKey = null;
 508                 String candidateValue = null;
 509 
 510                 if (sepIndex == -1)
 511                     candidateKey = key.substring(2);
 512                 else if (sepIndex >= 3) {
 513                     candidateKey = key.substring(2, sepIndex);
 514                     candidateValue = (sepIndex < key.length()-1)?
 515                         key.substring(sepIndex+1) : null;
 516                 }
 517                 tempOptions.put(candidateKey, candidateValue);
 518             }
 519         }
 520 
 521         PlatformProvider platformProvider = context.get(PlatformProvider.class);
 522 
 523         if (platformProvider != null) {
 524             for (PluginInfo<Processor> ap : platformProvider.getAnnotationProcessors()) {
 525                 tempOptions.putAll(ap.getOptions());
 526             }
 527         }
 528 
 529         return Collections.unmodifiableMap(tempOptions);
 530     }
 531 
 532     private Set<String> initUnmatchedProcessorOptions() {
 533         Set<String> unmatchedProcessorOptions = new HashSet<>();
 534         unmatchedProcessorOptions.addAll(processorOptions.keySet());
 535         return unmatchedProcessorOptions;
 536     }
 537 
 538     /**
 539      * State about how a processor has been used by the tool.  If a
 540      * processor has been used on a prior round, its process method is
 541      * called on all subsequent rounds, perhaps with an empty set of
 542      * annotations to process.  The {@code annotationSupported} method
 543      * caches the supported annotation information from the first (and
 544      * only) getSupportedAnnotationTypes call to the processor.
 545      */
 546     static class ProcessorState {
 547         public Processor processor;
 548         public boolean   contributed;


< prev index next >