📄 javacprocessingenvironment.java
字号:
/* * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.processing;import com.sun.source.util.TaskEvent;import com.sun.source.util.TaskListener;import com.sun.tools.javac.api.JavacTaskImpl;import com.sun.tools.javac.util.List;import com.sun.tools.javac.util.*;import com.sun.tools.javac.code.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.comp.*;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.parser.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.model.JavacElements;import com.sun.tools.javac.model.JavacTypes;import com.sun.tools.javac.tree.JCTree.*;import com.sun.tools.javac.main.JavaCompiler;import java.io.StringWriter;import javax.annotation.processing.*;import javax.lang.model.SourceVersion;import javax.lang.model.element.AnnotationMirror;import javax.lang.model.element.Element;import javax.lang.model.element.TypeElement;import javax.lang.model.element.PackageElement;import javax.lang.model.util.*;import javax.tools.JavaFileManager;import javax.tools.StandardJavaFileManager;import javax.tools.JavaFileObject;import javax.tools.DiagnosticListener;import static javax.tools.StandardLocation.*;import java.lang.reflect.*;import java.util.*;import java.util.regex.*;import java.net.URLClassLoader;import java.net.URL;import java.io.Closeable;import java.io.File;import java.io.PrintWriter;import java.io.IOException;import java.net.MalformedURLException;/** * Objects of this class hold and manage the state needed to support * annotation processing. * * <p><b>This is NOT part of any API supported by Sun Microsystems. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice.</b> */public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable { Options options; private final boolean printProcessorInfo; private final boolean printRounds; private final boolean verbose; private final boolean lint; private final boolean procOnly; private final boolean fatalErrors; private final JavacFiler filer; private final JavacMessager messager; private final JavacElements elementUtils; private final JavacTypes typeUtils; /** * Holds relevant state history of which processors have been * used. */ private DiscoveredProcessors discoveredProcs; /** * Map of processor-specific options. */ private final Map<String, String> processorOptions; /** */ private final Set<String> unmatchedProcessorOptions; /** * Annotations implicitly processed and claimed by javac. */ private final Set<String> platformAnnotations; /** * Set of packages given on command line. */ private Set<PackageSymbol> specifiedPackages = Collections.emptySet(); /** The log to be used for error reporting. */ Log log; /** * Source level of the compile. */ Source source; private Context context; public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) { options = Options.instance(context); this.context = context; log = Log.instance(context); source = Source.instance(context); printProcessorInfo = options.get("-XprintProcessorInfo") != null; printRounds = options.get("-XprintRounds") != null; verbose = options.get("-verbose") != null; lint = options.lint("processing"); procOnly = options.get("-proc:only") != null || options.get("-Xprint") != null; fatalErrors = options.get("fatalEnterError") != null; platformAnnotations = initPlatformAnnotations(); // Initialize services before any processors are initialzied // in case processors use them. filer = new JavacFiler(context); messager = new JavacMessager(context, this); elementUtils = new JavacElements(context); typeUtils = new JavacTypes(context); processorOptions = initProcessorOptions(context); unmatchedProcessorOptions = initUnmatchedProcessorOptions(); initProcessorIterator(context, processors); } private Set<String> initPlatformAnnotations() { Set<String> platformAnnotations = new HashSet<String>(); platformAnnotations.add("java.lang.Deprecated"); platformAnnotations.add("java.lang.Override"); platformAnnotations.add("java.lang.SuppressWarnings"); platformAnnotations.add("java.lang.annotation.Documented"); platformAnnotations.add("java.lang.annotation.Inherited"); platformAnnotations.add("java.lang.annotation.Retention"); platformAnnotations.add("java.lang.annotation.Target"); return Collections.unmodifiableSet(platformAnnotations); } private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) { Paths paths = Paths.instance(context); Log log = Log.instance(context); Iterator<? extends Processor> processorIterator; if (options.get("-Xprint") != null) { try { Processor processor = PrintingProcessor.class.newInstance(); processorIterator = List.of(processor).iterator(); } catch (Throwable t) { AssertionError assertError = new AssertionError("Problem instantiating PrintingProcessor."); assertError.initCause(t); throw assertError; } } else if (processors != null) { processorIterator = processors.iterator(); } else { String processorNames = options.get("-processor"); JavaFileManager fileManager = context.get(JavaFileManager.class); try { // If processorpath is not explicitly set, use the classpath. ClassLoader processorCL = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) : fileManager.getClassLoader(CLASS_PATH); /* * If the "-processor" option is used, search the appropriate * path for the named class. Otherwise, use a service * provider mechanism to create the processor iterator. */ if (processorNames != null) { processorIterator = new NameProcessIterator(processorNames, processorCL, log); } else { processorIterator = new ServiceIterator(processorCL, log); } } catch (SecurityException e) { /* * A security exception will occur if we can't create a classloader. * Ignore the exception if, with hindsight, we didn't need it anyway * (i.e. no processor was specified either explicitly, or implicitly, * in service configuration file.) Otherwise, we cannot continue. */ processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", e); } } discoveredProcs = new DiscoveredProcessors(processorIterator); } /** * Returns an empty processor iterator if no processors are on the * relevant path, otherwise if processors are present, logs an * error. Called when a service loader is unavailable for some * reason, either because a service loader class cannot be found * or because a security policy prevents class loaders from being * created. * * @param key The resource key to use to log an error message * @param e If non-null, pass this exception to Abort */ private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) { JavaFileManager fileManager = context.get(JavaFileManager.class); if (fileManager instanceof JavacFileManager) { StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager; Iterable<? extends File> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH) : standardFileManager.getLocation(CLASS_PATH); if (needClassLoader(options.get("-processor"), workingPath) ) handleException(key, e); } else { handleException(key, e); } java.util.List<Processor> pl = Collections.emptyList(); return pl.iterator(); } /** * Handle a security exception thrown during initializing the * Processor iterator. */ private void handleException(String key, Exception e) { if (e != null) { log.error(key, e.getLocalizedMessage()); throw new Abort(e); } else { log.error(key); throw new Abort(); } } /** * Use a service loader appropriate for the platform to provide an * iterator over annotations processors. If * java.util.ServiceLoader is present use it, otherwise, use * sun.misc.Service, otherwise fail if a loader is needed. */ private class ServiceIterator implements Iterator<Processor> { // The to-be-wrapped iterator. private Iterator<?> iterator; private Log log; ServiceIterator(ClassLoader classLoader, Log log) { Class<?> loaderClass; String loadMethodName; boolean jusl; this.log = log; try { try { loaderClass = Class.forName("java.util.ServiceLoader"); loadMethodName = "load"; jusl = true; } catch (ClassNotFoundException cnfe) { try { loaderClass = Class.forName("sun.misc.Service"); loadMethodName = "providers"; jusl = false; } catch (ClassNotFoundException cnfe2) { // Fail softly if a loader is not actually needed. this.iterator = handleServiceLoaderUnavailability("proc.no.service", null); return; } } // java.util.ServiceLoader.load or sun.misc.Service.providers Method loadMethod = loaderClass.getMethod(loadMethodName, Class.class, ClassLoader.class); Object result = loadMethod.invoke(null, Processor.class, classLoader); // For java.util.ServiceLoader, we have to call another // method to get the iterator. if (jusl) { Method m = loaderClass.getMethod("iterator"); result = m.invoke(result); // serviceLoader.iterator(); } // The result should now be an iterator. this.iterator = (Iterator<?>) result; } catch (Throwable t) { log.error("proc.service.problem"); throw new Abort(t); } } public boolean hasNext() { try { return iterator.hasNext(); } catch (Throwable t) { if ("ServiceConfigurationError". equals(t.getClass().getSimpleName())) { log.error("proc.bad.config.file", t.getLocalizedMessage()); } throw new Abort(t); } } public Processor next() { try { return (Processor)(iterator.next()); } catch (Throwable t) { if ("ServiceConfigurationError". equals(t.getClass().getSimpleName())) { log.error("proc.bad.config.file", t.getLocalizedMessage()); } else { log.error("proc.processor.constructor.error", t.getLocalizedMessage()); } throw new Abort(t); } } public void remove() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -