javacompiler.java

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

JAVA
1,491
字号
        } catch (Abort ex) {            if (devVerbose)                ex.printStackTrace();        }    }    /**     * The phases following annotation processing: attribution,     * desugar, and finally code generation.     */    private void compile2() {        try {            switch (compilePolicy) {            case ATTR_ONLY:                attribute(todo);                break;            case CHECK_ONLY:                flow(attribute(todo));                break;            case SIMPLE:                generate(desugar(flow(attribute(todo))));                break;            case BY_FILE:                for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values())                    generate(desugar(list));                break;            case BY_TODO:                while (todo.nonEmpty())                    generate(desugar(flow(attribute(todo.next()))));                break;            default:                assert false: "unknown compile policy";            }        } catch (Abort ex) {            if (devVerbose)                ex.printStackTrace();        }        if (verbose) {	    elapsed_msec = elapsed(start_msec);;            printVerbose("total", Long.toString(elapsed_msec));	}        reportDeferredDiagnostics();        if (!log.hasDiagnosticListener()) {            printCount("error", errorCount());            printCount("warn", warningCount());        }    }    private List<JCClassDecl> rootClasses;    /**     * Parses a list of files.     */   public List<JCCompilationUnit> parseFiles(List<JavaFileObject> fileObjects) throws IOException {       if (errorCount() > 0)       	   return List.nil();        //parse all files        ListBuffer<JCCompilationUnit> trees = lb();        for (JavaFileObject fileObject : fileObjects)            trees.append(parse(fileObject));        return trees.toList();    }    /**     * Enter the symbols found in a list of parse trees.     * As a side-effect, this puts elements on the "todo" list.     * Also stores a list of all top level classes in rootClasses.     */    public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {        //enter symbols for all files        if (taskListener != null) {            for (JCCompilationUnit unit: roots) {                TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);                taskListener.started(e);            }        }                enter.main(roots);                if (taskListener != null) {            for (JCCompilationUnit unit: roots) {                TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);                taskListener.finished(e);            }        }        //If generating source, remember the classes declared in        //the original compilation units listed on the command line.        if (sourceOutput || stubOutput) {            ListBuffer<JCClassDecl> cdefs = lb();            for (JCCompilationUnit unit : roots) {                for (List<JCTree> defs = unit.defs;                     defs.nonEmpty();                     defs = defs.tail) {                    if (defs.head instanceof JCClassDecl)                        cdefs.append((JCClassDecl)defs.head);                }            }            rootClasses = cdefs.toList();        }        return roots;    }    /**     * Set to true to enable skeleton annotation processing code.     * Currently, we assume this variable will be replaced more     * advanced logic to figure out if annotation processing is     * needed.     */    boolean processAnnotations = false;    /**     * Object to handle annotation processing.     */    JavacProcessingEnvironment procEnvImpl = null;    /**     * Check if we should process annotations.     * If so, and if no scanner is yet registered, then set up the DocCommentScanner     * to catch doc comments, and set keepComments so the parser records them in     * the compilation unit.     *     * @param processors user provided annotation processors to bypass     * discovery, {@code null} means that no processors were provided     */    public void initProcessAnnotations(Iterable<? extends Processor> processors) {        // Process annotations if processing is not disabled and there        // is at least one Processor available.        Options options = Options.instance(context);        if (options.get("-proc:none") != null) {            processAnnotations = false;        } else if (procEnvImpl == null) {            procEnvImpl = new JavacProcessingEnvironment(context, processors);            processAnnotations = procEnvImpl.atLeastOneProcessor();            if (processAnnotations) {                if (context.get(Scanner.Factory.scannerFactoryKey) == null)                    DocCommentScanner.Factory.preRegister(context);                options.put("save-parameter-names", "save-parameter-names");                reader.saveParameterNames = true;		keepComments = true;		if (taskListener != null)		    taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));            } else { // free resources                procEnvImpl.close();	    }        }    }    // TODO: called by JavacTaskImpl    public JavaCompiler processAnnotations(List<JCCompilationUnit> roots) throws IOException {        return processAnnotations(roots, List.<String>nil());    }    /**     * Process any anotations found in the specifed compilation units.     * @param roots a list of compilation units     * @return an instance of the compiler in which to complete the compilation     */    public JavaCompiler processAnnotations(List<JCCompilationUnit> roots,                                           List<String> classnames)        throws IOException  { // TODO: see TEMP note in JavacProcessingEnvironment        if (errorCount() != 0) {            // Errors were encountered.  If todo is empty, then the            // encountered errors were parse errors.  Otherwise, the            // errors were found during the enter phase which should            // be ignored when processing annotations.            if (todo.isEmpty())                return this;        }        // ASSERT: processAnnotations and procEnvImpl should have been set up by        // by initProcessAnnotations        // NOTE: The !classnames.isEmpty() checks should be refactored to Main.        if (!processAnnotations) {	    // If there are no annotation processors present, and	    // annotation processing is to occur with compilation,	    // emit a warning.	    Options options = Options.instance(context);	    if (options.get("-proc:only") != null) {		log.warning("proc.proc-only.requested.no.procs");		todo.clear();	    }            // If not processing annotations, classnames must be empty            if (!classnames.isEmpty()) {                log.error("proc.no.explicit.annotation.processing.requested",                          classnames);            }            return this; // continue regular compilation        }                 try {            List<ClassSymbol> classSymbols = List.nil();            List<PackageSymbol> pckSymbols = List.nil();            if (!classnames.isEmpty()) {                 // Check for explicit request for annotation                 // processing                if (!explicitAnnotationProcessingRequested()) {                    log.error("proc.no.explicit.annotation.processing.requested",                              classnames);                    return this; // TODO: Will this halt compilation?                } else {                    boolean errors = false;                    for (String nameStr : classnames) {                        Symbol sym = resolveIdent(nameStr);                        if (sym == null || (sym.kind == Kinds.PCK && !processPcks)) {                            log.error("proc.cant.find.class", nameStr);                            errors = true;                            continue;                        }                        try {                            if (sym.kind == Kinds.PCK)                                sym.complete();                            if (sym.exists()) {                                Name name = names.fromString(nameStr);                                if (sym.kind == Kinds.PCK)                                    pckSymbols = pckSymbols.prepend((PackageSymbol)sym);                                else                                    classSymbols = classSymbols.prepend((ClassSymbol)sym);                                continue;                            }                            assert sym.kind == Kinds.PCK;                            log.warning("proc.package.does.not.exist", nameStr);                            pckSymbols = pckSymbols.prepend((PackageSymbol)sym);                        } catch (CompletionFailure e) {                            log.error("proc.cant.find.class", nameStr);                            errors = true;                            continue;                        }                    }                    if (errors)                        return this;                }            }            JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols);            if (c != this)                 annotationProcessingOccurred = c.annotationProcessingOccurred = true;            return c;        } catch (CompletionFailure ex) {	    log.error("cant.access", ex.sym, ex.errmsg);            return this;                    }    }    boolean explicitAnnotationProcessingRequested() {        Options options = Options.instance(context);        return            explicitAnnotationProcessingRequested ||            options.get("-processor") != null ||            options.get("-processorpath") != null ||            options.get("-proc:only") != null ||            options.get("-Xprint") != null;    }    /**     * Attribute a list of parse trees, such as found on the "todo" list.     * Note that attributing classes may cause additional files to be     * parsed and entered via the SourceCompleter.     * Attribution of the entries in the list does not stop if any errors occur.     * @returns a list of environments for attributd classes.     */    public List<Env<AttrContext>> attribute(ListBuffer<Env<AttrContext>> envs) {        ListBuffer<Env<AttrContext>> results = lb();        while (envs.nonEmpty())            results.append(attribute(envs.next()));        return results.toList();    }    /**     * Attribute a parse tree.     * @returns the attributed parse tree     */    public Env<AttrContext> attribute(Env<AttrContext> env) {        if (verboseCompilePolicy)            log.printLines(log.noticeWriter, "[attribute " + env.enclClass.sym + "]");        if (verbose)            printVerbose("checking.attribution", env.enclClass.sym);        if (taskListener != null) {            TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);            taskListener.started(e);        }        JavaFileObject prev = log.useSource(                                  env.enclClass.sym.sourcefile != null ?                                  env.enclClass.sym.sourcefile :                                  env.toplevel.sourcefile);        try {            attr.attribClass(env.tree.pos(), env.enclClass.sym);        }        finally {            log.useSource(prev);        }        return env;    }    /**     * Perform dataflow checks on attributed parse trees.     * These include checks for definite assignment and unreachable statements.     * If any errors occur, an empty list will be returned.     * @returns the list of attributed parse trees     */    public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) {        ListBuffer<Env<AttrContext>> results = lb();        for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) {            flow(l.head, results);        }        return stopIfError(results);    }    /**     * Perform dataflow checks on an attributed parse tree.     */    public List<Env<AttrContext>> flow(Env<AttrContext> env) {        ListBuffer<Env<AttrContext>> results = lb();        flow(env, results);        return stopIfError(results);    }    /**     * Perform dataflow checks on an attributed parse tree.     */    protected void flow(Env<AttrContext> env, ListBuffer<Env<AttrContext>> results) {        try {            if (errorCount() > 0)                return;            if (relax || deferredSugar.contains(env)) {                results.append(env);                return;            }            if (verboseCompilePolicy)                log.printLines(log.noticeWriter, "[flow " + env.enclClass.sym + "]");            JavaFileObject prev = log.useSource(                                                env.enclClass.sym.sourcefile != null ?                                                env.enclClass.sym.sourcefile :                                                env.toplevel.sourcefile);            try {                make.at(Position.FIRSTPOS);                TreeMaker localMake = make.forToplevel(env.toplevel);                flow.analyzeTree(env.tree, localMake);                if (errorCount() > 0)                    return;                results.append(env);            }            finally {                log.useSource(prev);            }        }        finally {            if (taskListener != null) {                TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);                taskListener.finished(e);            }

⌨️ 快捷键说明

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