javacompiler.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,491 行 · 第 1/4 页

JAVA
1,491
字号
    public boolean verbose;    /** Emit plain Java source files rather than class files.     */    public boolean sourceOutput;    /** Emit stub source files rather than class files.     */    public boolean stubOutput;    /** Generate attributed parse tree only.     */    public boolean attrParseOnly;    /** Switch: relax some constraints for producing the jsr14 prototype.     */    boolean relax;    /** Debug switch: Emit Java sources after inner class flattening.     */    public boolean printFlat;    /** The encoding to be used for source input.     */    public String encoding;    /** Generate code with the LineNumberTable attribute for debugging     */    public boolean lineDebugInfo;    /** Switch: should we store the ending positions?     */    public boolean genEndPos;    /** Switch: should we debug ignored exceptions     */    protected boolean devVerbose;    /** Switch: should we (annotation) process packages as well     */    protected boolean processPcks;    /** Switch: is annotation processing requested explitly via     * CompilationTask.setProcessors?     */    protected boolean explicitAnnotationProcessingRequested = false;    /**     * The policy for the order in which to perform the compilation     */    protected CompilePolicy compilePolicy;        /**     * The policy for what to do with implicitly read source files     */    protected ImplicitSourcePolicy implicitSourcePolicy;    /**     * Report activity related to compilePolicy     */    public boolean verboseCompilePolicy;    /** A queue of all as yet unattributed classes.     */    public Todo todo;    private Set<Env<AttrContext>> deferredSugar = new HashSet<Env<AttrContext>>();    /** The set of currently compiled inputfiles, needed to ensure     *  we don't accidentally overwrite an input file when -s is set.     *  initialized by `compile'.     */    protected Set<JavaFileObject> inputFiles = new HashSet<JavaFileObject>();    /** The number of errors reported so far.     */    public int errorCount() {        if (delegateCompiler != null && delegateCompiler != this)            return delegateCompiler.errorCount();        else            return log.nerrors;    }    protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) {        if (errorCount() == 0)            return listBuffer.toList();        else            return List.nil();    }    protected final <T> List<T> stopIfError(List<T> list) {        if (errorCount() == 0)            return list;        else            return List.nil();    }    /** The number of warnings reported so far.     */    public int warningCount() {        if (delegateCompiler != null && delegateCompiler != this)            return delegateCompiler.warningCount();        else            return log.nwarnings;    }        /** Whether or not any parse errors have occurred.     */    public boolean parseErrors() {	return parseErrors;    }    protected Scanner.Factory getScannerFactory() {        return Scanner.Factory.instance(context);    }    /** Try to open input stream with given name.     *  Report an error if this fails.     *  @param filename   The file name of the input stream to be opened.     */    public CharSequence readSource(JavaFileObject filename) {        try {            inputFiles.add(filename);            return filename.getCharContent(false);        } catch (IOException e) {            log.error("error.reading.file", filename, e.getLocalizedMessage());            return null;        }    }    /** Parse contents of input stream.     *  @param filename     The name of the file from which input stream comes.     *  @param input        The input stream to be parsed.     */    protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {        long msec = now();        JCCompilationUnit tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(),                                      null, List.<JCTree>nil());        if (content != null) {            if (verbose) {                printVerbose("parsing.started", filename);            }            if (taskListener != null) {                TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);                taskListener.started(e);            }	    int initialErrorCount = log.nerrors;            Scanner scanner = getScannerFactory().newScanner(content);            Parser parser = parserFactory.newParser(scanner, keepComments(), genEndPos);            tree = parser.compilationUnit();	    parseErrors |= (log.nerrors > initialErrorCount);            if (lineDebugInfo) {                tree.lineMap = scanner.getLineMap();            }            if (verbose) {                printVerbose("parsing.done", Long.toString(elapsed(msec)));            }        }        tree.sourcefile = filename;        if (content != null && taskListener != null) {            TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);            taskListener.finished(e);        }        return tree;    }    // where        public boolean keepComments = false;        protected boolean keepComments() {            return keepComments || sourceOutput || stubOutput;        }    /** Parse contents of file.     *  @param filename     The name of the file to be parsed.     */    @Deprecated    public JCTree.JCCompilationUnit parse(String filename) throws IOException {	JavacFileManager fm = (JavacFileManager)fileManager;        return parse(fm.getJavaFileObjectsFromStrings(List.of(filename)).iterator().next());    }    /** Parse contents of file.     *  @param filename     The name of the file to be parsed.     */    public JCTree.JCCompilationUnit parse(JavaFileObject filename) {        JavaFileObject prev = log.useSource(filename);        try {            JCTree.JCCompilationUnit t = parse(filename, readSource(filename));            if (t.endPositions != null)                log.setEndPosTable(filename, t.endPositions);            return t;        } finally {            log.useSource(prev);        }    }    /** Resolve an identifier.     * @param name      The identifier to resolve     */    public Symbol resolveIdent(String name) {        if (name.equals(""))            return syms.errSymbol;        JavaFileObject prev = log.useSource(null);        try {            JCExpression tree = null;            for (String s : name.split("\\.", -1)) {                if (!SourceVersion.isIdentifier(s)) // TODO: check for keywords                    return syms.errSymbol;                tree = (tree == null) ? make.Ident(names.fromString(s))                                      : make.Select(tree, names.fromString(s));            }            JCCompilationUnit toplevel =                make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());            toplevel.packge = syms.unnamedPackage;            return attr.attribIdent(tree, toplevel);        } finally {            log.useSource(prev);        }    }    /** Emit plain Java source for a class.     *  @param env    The attribution environment of the outermost class     *                containing this class.     *  @param cdef   The class definition to be printed.     */    JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {        JavaFileObject outFile            = fileManager.getJavaFileForOutput(CLASS_OUTPUT,					       cdef.sym.flatname.toString(),					       JavaFileObject.Kind.SOURCE,					       null);        if (inputFiles.contains(outFile)) {            log.error(cdef.pos(), "source.cant.overwrite.input.file", outFile);            return null;        } else {            BufferedWriter out = new BufferedWriter(outFile.openWriter());            try {                new Pretty(out, true).printUnit(env.toplevel, cdef);                if (verbose)                    printVerbose("wrote.file", outFile);            } finally {                out.close();            }            return outFile;        }    }    /** Generate code and emit a class file for a given class     *  @param env    The attribution environment of the outermost class     *                containing this class.     *  @param cdef   The class definition from which code is generated.     */    JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {        try {            if (gen.genClass(env, cdef))                 return writer.writeClass(cdef.sym);        } catch (ClassWriter.PoolOverflow ex) {            log.error(cdef.pos(), "limit.pool");        } catch (ClassWriter.StringOverflow ex) {            log.error(cdef.pos(), "limit.string.overflow",                      ex.value.substring(0, 20));        } catch (CompletionFailure ex) {            chk.completionError(cdef.pos(), ex);        }        return null;    }    /** Complete compiling a source file that has been accessed     *  by the class file reader.     *  @param c          The class the source file of which needs to be compiled.     *  @param filename   The name of the source file.     *  @param f          An input stream that reads the source file.     */    public void complete(ClassSymbol c) throws CompletionFailure {//      System.err.println("completing " + c);//DEBUG        if (completionFailureName == c.fullname) {            throw new CompletionFailure(c, "user-selected completion failure by class name");        }        JCCompilationUnit tree;        JavaFileObject filename = c.classfile;        JavaFileObject prev = log.useSource(filename);        try {            tree = parse(filename, filename.getCharContent(false));        } catch (IOException e) {            log.error("error.reading.file", filename, e);            tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());        } finally {            log.useSource(prev);        }        if (taskListener != null) {            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);            taskListener.started(e);        }        enter.complete(List.of(tree), c);        if (taskListener != null) {            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);            taskListener.finished(e);        }        if (enter.getEnv(c) == null) {            boolean isPkgInfo =                tree.sourcefile.isNameCompatible("package-info",                                                 JavaFileObject.Kind.SOURCE);            if (isPkgInfo) {                if (enter.getEnv(tree.packge) == null) {                    String msg                        = log.getLocalizedString("file.does.not.contain.package",                                                 c.location());                    throw new ClassReader.BadClassFile(c, filename, msg);                }            } else {                throw new                    ClassReader.BadClassFile(c, filename, log.                                             getLocalizedString("file.doesnt.contain.class",                                                                c.fullname));            }        }                implicitSourceFilesRead = true;    }    /** Track when the JavaCompiler has been used to compile something. */    private boolean hasBeenUsed = false;    private long start_msec = 0;    public long elapsed_msec = 0;    /** Track whether any errors occurred while parsing source text. */    private boolean parseErrors = false;    public void compile(List<JavaFileObject> sourceFileObject)        throws Throwable {        compile(sourceFileObject, List.<String>nil(), null);    }    /**     * Main method: compile a list of files, return all compiled classes     *     * @param sourceFileObjects file objects to be compiled     * @param classnames class names to process for annotations     * @param processors user provided annotation processors to bypass     * discovery, {@code null} means that no processors were provided     */    public void compile(List<JavaFileObject> sourceFileObjects,                        List<String> classnames,			Iterable<? extends Processor> processors)        throws IOException // TODO: temp, from JavacProcessingEnvironment    {        if (processors != null && processors.iterator().hasNext())            explicitAnnotationProcessingRequested = true;        // as a JavaCompiler can only be used once, throw an exception if        // it has been used before.        if (hasBeenUsed)	    throw new AssertionError("attempt to reuse JavaCompiler");        hasBeenUsed = true;        start_msec = now();        try {            initProcessAnnotations(processors);            // These method calls must be chained to avoid memory leaks            delegateCompiler = processAnnotations(enterTrees(stopIfError(parseFiles(sourceFileObjects))),                                                  classnames);            delegateCompiler.compile2();	    delegateCompiler.close();	    elapsed_msec = delegateCompiler.elapsed_msec;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?