javacompiler.java
来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,491 行 · 第 1/4 页
JAVA
1,491 行
/* * Copyright 1999-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.main;import java.io.*;import java.util.HashSet;import java.util.LinkedHashMap;import java.util.Map;import java.util.MissingResourceException;import java.util.ResourceBundle;import java.util.Set;import java.util.logging.Handler;import java.util.logging.Level;import java.util.logging.Logger;import javax.tools.JavaFileManager;import javax.tools.JavaFileObject;import javax.tools.DiagnosticListener;import com.sun.source.util.TaskEvent;import com.sun.source.util.TaskListener;import com.sun.tools.javac.util.*;import com.sun.tools.javac.code.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.parser.*;import com.sun.tools.javac.comp.*;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.tree.JCTree.*;import com.sun.tools.javac.processing.*;import javax.annotation.processing.Processor;import static javax.tools.StandardLocation.CLASS_OUTPUT;import static com.sun.tools.javac.util.ListBuffer.lb;// TEMP, until we have a more efficient way to save doc comment infoimport com.sun.tools.javac.parser.DocCommentScanner;import javax.lang.model.SourceVersion;/** This class could be the main entry point for GJC when GJC is used as a * component in a larger software system. It provides operations to * construct a new compiler, and to run a new compiler on a set of source * files. * * <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 JavaCompiler implements ClassReader.SourceCompleter { /** The context key for the compiler. */ protected static final Context.Key<JavaCompiler> compilerKey = new Context.Key<JavaCompiler>(); /** Get the JavaCompiler instance for this context. */ public static JavaCompiler instance(Context context) { JavaCompiler instance = context.get(compilerKey); if (instance == null) instance = new JavaCompiler(context); return instance; } /** The current version number as a string. */ public static String version() { return version("release"); // mm.nn.oo[-milestone] } /** The current full version number as a string. */ public static String fullVersion() { return version("full"); // mm.mm.oo[-milestone]-build } private static final String versionRBName = "com.sun.tools.javac.resources.version"; private static ResourceBundle versionRB; private static String version(String key) { if (versionRB == null) { try { versionRB = ResourceBundle.getBundle(versionRBName); } catch (MissingResourceException e) { return Log.getLocalizedString("version.resource.missing", System.getProperty("java.version")); } } try { return versionRB.getString(key); } catch (MissingResourceException e) { return Log.getLocalizedString("version.unknown", System.getProperty("java.version")); } } private static enum CompilePolicy { /* * Just attribute the parse trees */ ATTR_ONLY, /* * Just attribute and do flow analysis on the parse trees. * This should catch most user errors. */ CHECK_ONLY, /* * Attribute everything, then do flow analysis for everything, * then desugar everything, and only then generate output. * Means nothing is generated if there are any errors in any classes. */ SIMPLE, /* * After attributing everything and doing flow analysis, * group the work by compilation unit. * Then, process the work for each compilation unit together. * Means nothing is generated for a compilation unit if the are any errors * in the compilation unit (or in any preceding compilation unit.) */ BY_FILE, /* * Completely process each entry on the todo list in turn. * -- this is the same for 1.5. * Means output might be generated for some classes in a compilation unit * and not others. */ BY_TODO; static CompilePolicy decode(String option) { if (option == null) return DEFAULT_COMPILE_POLICY; else if (option.equals("attr")) return ATTR_ONLY; else if (option.equals("check")) return CHECK_ONLY; else if (option.equals("simple")) return SIMPLE; else if (option.equals("byfile")) return BY_FILE; else if (option.equals("bytodo")) return BY_TODO; else return DEFAULT_COMPILE_POLICY; } } private static CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO; private static enum ImplicitSourcePolicy { /** Don't generate or process implicitly read source files. */ NONE, /** Generate classes for implicitly read source files. */ CLASS, /** Like CLASS, but generate warnings if annotation processing occurs */ UNSET; static ImplicitSourcePolicy decode(String option) { if (option == null) return UNSET; else if (option.equals("none")) return NONE; else if (option.equals("class")) return CLASS; else return UNSET; } } /** The log to be used for error reporting. */ public Log log; /** The tree factory module. */ protected TreeMaker make; /** The class reader. */ protected ClassReader reader; /** The class writer. */ protected ClassWriter writer; /** The module for the symbol table entry phases. */ protected Enter enter; /** The symbol table. */ protected Symtab syms; /** The language version. */ protected Source source; /** The module for code generation. */ protected Gen gen; /** The name table. */ protected Name.Table names; /** The attributor. */ protected Attr attr; /** The attributor. */ protected Check chk; /** The flow analyzer. */ protected Flow flow; /** The type eraser. */ TransTypes transTypes; /** The syntactic sugar desweetener. */ Lower lower; /** The annotation annotator. */ protected Annotate annotate; /** Force a completion failure on this name */ protected final Name completionFailureName; /** Type utilities. */ protected Types types; /** Access to file objects. */ protected JavaFileManager fileManager; /** Factory for parsers. */ protected Parser.Factory parserFactory; /** Optional listener for progress events */ protected TaskListener taskListener; /** * Annotation processing may require and provide a new instance * of the compiler to be used for the analyze and generate phases. */ protected JavaCompiler delegateCompiler; /** * Flag set if any annotation processing occurred. **/ protected boolean annotationProcessingOccurred; /** * Flag set if any implicit source files read. **/ protected boolean implicitSourceFilesRead; protected Context context; /** Construct a new compiler using a shared context. */ public JavaCompiler(final Context context) { this.context = context; context.put(compilerKey, this); // if fileManager not already set, register the JavacFileManager to be used if (context.get(JavaFileManager.class) == null) JavacFileManager.preRegister(context); names = Name.Table.instance(context); log = Log.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); enter = Enter.instance(context); todo = Todo.instance(context); fileManager = context.get(JavaFileManager.class); parserFactory = Parser.Factory.instance(context); try { // catch completion problems with predefineds syms = Symtab.instance(context); } catch (CompletionFailure ex) { // inlined Check.completionError as it is not initialized yet log.error("cant.access", ex.sym, ex.errmsg); if (ex instanceof ClassReader.BadClassFile) throw new Abort(); } source = Source.instance(context); attr = Attr.instance(context); chk = Check.instance(context); gen = Gen.instance(context); flow = Flow.instance(context); transTypes = TransTypes.instance(context); lower = Lower.instance(context); annotate = Annotate.instance(context); types = Types.instance(context); taskListener = context.get(TaskListener.class); reader.sourceCompleter = this; Options options = Options.instance(context); verbose = options.get("-verbose") != null; sourceOutput = options.get("-printsource") != null; // used to be -s stubOutput = options.get("-stubs") != null; relax = options.get("-relax") != null; printFlat = options.get("-printflat") != null; attrParseOnly = options.get("-attrparseonly") != null; encoding = options.get("-encoding"); lineDebugInfo = options.get("-g:") == null || options.get("-g:lines") != null; genEndPos = options.get("-Xjcov") != null || context.get(DiagnosticListener.class) != null; devVerbose = options.get("dev") != null; processPcks = options.get("process.packages") != null; verboseCompilePolicy = options.get("verboseCompilePolicy") != null; if (attrParseOnly) compilePolicy = CompilePolicy.ATTR_ONLY; else compilePolicy = CompilePolicy.decode(options.get("compilePolicy")); implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit")); completionFailureName = (options.get("failcomplete") != null) ? names.fromString(options.get("failcomplete")) : null; } /* Switches: */ /** Verbose output. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?