Source Code Cross Referenced for JavaCompiler.java in  » 6.0-JDK-Modules-com.sun » tools » com » sun » tools » javac » main » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun » tools » com.sun.tools.javac.main 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.tools.javac.main;
0027:
0028:        import java.io.*;
0029:        import java.util.HashSet;
0030:        import java.util.LinkedHashMap;
0031:        import java.util.Map;
0032:        import java.util.MissingResourceException;
0033:        import java.util.ResourceBundle;
0034:        import java.util.Set;
0035:        import java.util.logging.Handler;
0036:        import java.util.logging.Level;
0037:        import java.util.logging.Logger;
0038:
0039:        import javax.tools.JavaFileManager;
0040:        import javax.tools.JavaFileObject;
0041:        import javax.tools.DiagnosticListener;
0042:
0043:        import com.sun.source.util.TaskEvent;
0044:        import com.sun.source.util.TaskListener;
0045:
0046:        import com.sun.tools.javac.util.*;
0047:        import com.sun.tools.javac.code.*;
0048:        import com.sun.tools.javac.tree.*;
0049:        import com.sun.tools.javac.parser.*;
0050:        import com.sun.tools.javac.comp.*;
0051:        import com.sun.tools.javac.jvm.*;
0052:
0053:        import com.sun.tools.javac.code.Symbol.*;
0054:        import com.sun.tools.javac.tree.JCTree.*;
0055:
0056:        import com.sun.tools.javac.processing.*;
0057:        import javax.annotation.processing.Processor;
0058:
0059:        import static javax.tools.StandardLocation.CLASS_OUTPUT;
0060:        import static com.sun.tools.javac.util.ListBuffer.lb;
0061:
0062:        // TEMP, until we have a more efficient way to save doc comment info
0063:        import com.sun.tools.javac.parser.DocCommentScanner;
0064:
0065:        import javax.lang.model.SourceVersion;
0066:
0067:        /** This class could be the main entry point for GJC when GJC is used as a
0068:         *  component in a larger software system. It provides operations to
0069:         *  construct a new compiler, and to run a new compiler on a set of source
0070:         *  files.
0071:         *
0072:         *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
0073:         *  you write code that depends on this, you do so at your own risk.
0074:         *  This code and its internal interfaces are subject to change or
0075:         *  deletion without notice.</b>
0076:         */
0077:        @Version("@(#)JavaCompiler.java	1.117 07/06/14")
0078:        public class JavaCompiler implements  ClassReader.SourceCompleter {
0079:            /** The context key for the compiler. */
0080:            protected static final Context.Key<JavaCompiler> compilerKey = new Context.Key<JavaCompiler>();
0081:
0082:            /** Get the JavaCompiler instance for this context. */
0083:            public static JavaCompiler instance(Context context) {
0084:                JavaCompiler instance = context.get(compilerKey);
0085:                if (instance == null)
0086:                    instance = new JavaCompiler(context);
0087:                return instance;
0088:            }
0089:
0090:            /** The current version number as a string.
0091:             */
0092:            public static String version() {
0093:                return version("release"); // mm.nn.oo[-milestone]
0094:            }
0095:
0096:            /** The current full version number as a string.
0097:             */
0098:            public static String fullVersion() {
0099:                return version("full"); // mm.mm.oo[-milestone]-build
0100:            }
0101:
0102:            private static final String versionRBName = "com.sun.tools.javac.resources.version";
0103:            private static ResourceBundle versionRB;
0104:
0105:            private static String version(String key) {
0106:                if (versionRB == null) {
0107:                    try {
0108:                        versionRB = ResourceBundle.getBundle(versionRBName);
0109:                    } catch (MissingResourceException e) {
0110:                        return Log.getLocalizedString(
0111:                                "version.resource.missing", System
0112:                                        .getProperty("java.version"));
0113:                    }
0114:                }
0115:                try {
0116:                    return versionRB.getString(key);
0117:                } catch (MissingResourceException e) {
0118:                    return Log.getLocalizedString("version.unknown", System
0119:                            .getProperty("java.version"));
0120:                }
0121:            }
0122:
0123:            private static enum CompilePolicy {
0124:                /*
0125:                 * Just attribute the parse trees
0126:                 */
0127:                ATTR_ONLY,
0128:
0129:                /*
0130:                 * Just attribute and do flow analysis on the parse trees.
0131:                 * This should catch most user errors.
0132:                 */
0133:                CHECK_ONLY,
0134:
0135:                /*
0136:                 * Attribute everything, then do flow analysis for everything,
0137:                 * then desugar everything, and only then generate output.
0138:                 * Means nothing is generated if there are any errors in any classes.
0139:                 */
0140:                SIMPLE,
0141:
0142:                /*
0143:                 * After attributing everything and doing flow analysis,
0144:                 * group the work by compilation unit.
0145:                 * Then, process the work for each compilation unit together.
0146:                 * Means nothing is generated for a compilation unit if the are any errors
0147:                 * in the compilation unit  (or in any preceding compilation unit.)
0148:                 */
0149:                BY_FILE,
0150:
0151:                /*
0152:                 * Completely process each entry on the todo list in turn.
0153:                 * -- this is the same for 1.5.
0154:                 * Means output might be generated for some classes in a compilation unit
0155:                 * and not others.
0156:                 */
0157:                BY_TODO;
0158:
0159:                static CompilePolicy decode(String option) {
0160:                    if (option == null)
0161:                        return DEFAULT_COMPILE_POLICY;
0162:                    else if (option.equals("attr"))
0163:                        return ATTR_ONLY;
0164:                    else if (option.equals("check"))
0165:                        return CHECK_ONLY;
0166:                    else if (option.equals("simple"))
0167:                        return SIMPLE;
0168:                    else if (option.equals("byfile"))
0169:                        return BY_FILE;
0170:                    else if (option.equals("bytodo"))
0171:                        return BY_TODO;
0172:                    else
0173:                        return DEFAULT_COMPILE_POLICY;
0174:                }
0175:            }
0176:
0177:            private static CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
0178:
0179:            private static enum ImplicitSourcePolicy {
0180:                /** Don't generate or process implicitly read source files. */
0181:                NONE,
0182:                /** Generate classes for implicitly read source files. */
0183:                CLASS,
0184:                /** Like CLASS, but generate warnings if annotation processing occurs */
0185:                UNSET;
0186:
0187:                static ImplicitSourcePolicy decode(String option) {
0188:                    if (option == null)
0189:                        return UNSET;
0190:                    else if (option.equals("none"))
0191:                        return NONE;
0192:                    else if (option.equals("class"))
0193:                        return CLASS;
0194:                    else
0195:                        return UNSET;
0196:                }
0197:            }
0198:
0199:            /** The log to be used for error reporting.
0200:             */
0201:            public Log log;
0202:
0203:            /** The tree factory module.
0204:             */
0205:            protected TreeMaker make;
0206:
0207:            /** The class reader.
0208:             */
0209:            protected ClassReader reader;
0210:
0211:            /** The class writer.
0212:             */
0213:            protected ClassWriter writer;
0214:
0215:            /** The module for the symbol table entry phases.
0216:             */
0217:            protected Enter enter;
0218:
0219:            /** The symbol table.
0220:             */
0221:            protected Symtab syms;
0222:
0223:            /** The language version.
0224:             */
0225:            protected Source source;
0226:
0227:            /** The module for code generation.
0228:             */
0229:            protected Gen gen;
0230:
0231:            /** The name table.
0232:             */
0233:            protected Name.Table names;
0234:
0235:            /** The attributor.
0236:             */
0237:            protected Attr attr;
0238:
0239:            /** The attributor.
0240:             */
0241:            protected Check chk;
0242:
0243:            /** The flow analyzer.
0244:             */
0245:            protected Flow flow;
0246:
0247:            /** The type eraser.
0248:             */
0249:            TransTypes transTypes;
0250:
0251:            /** The syntactic sugar desweetener.
0252:             */
0253:            Lower lower;
0254:
0255:            /** The annotation annotator.
0256:             */
0257:            protected Annotate annotate;
0258:
0259:            /** Force a completion failure on this name
0260:             */
0261:            protected final Name completionFailureName;
0262:
0263:            /** Type utilities.
0264:             */
0265:            protected Types types;
0266:
0267:            /** Access to file objects.
0268:             */
0269:            protected JavaFileManager fileManager;
0270:
0271:            /** Factory for parsers.
0272:             */
0273:            protected Parser.Factory parserFactory;
0274:
0275:            /** Optional listener for progress events
0276:             */
0277:            protected TaskListener taskListener;
0278:
0279:            /**
0280:             * Annotation processing may require and provide a new instance
0281:             * of the compiler to be used for the analyze and generate phases.
0282:             */
0283:            protected JavaCompiler delegateCompiler;
0284:
0285:            /**
0286:             * Flag set if any annotation processing occurred.
0287:             **/
0288:            protected boolean annotationProcessingOccurred;
0289:
0290:            /**
0291:             * Flag set if any implicit source files read.
0292:             **/
0293:            protected boolean implicitSourceFilesRead;
0294:
0295:            protected Context context;
0296:
0297:            /** Construct a new compiler using a shared context.
0298:             */
0299:            public JavaCompiler(final Context context) {
0300:                this .context = context;
0301:                context.put(compilerKey, this );
0302:
0303:                // if fileManager not already set, register the JavacFileManager to be used
0304:                if (context.get(JavaFileManager.class) == null)
0305:                    JavacFileManager.preRegister(context);
0306:
0307:                names = Name.Table.instance(context);
0308:                log = Log.instance(context);
0309:                reader = ClassReader.instance(context);
0310:                make = TreeMaker.instance(context);
0311:                writer = ClassWriter.instance(context);
0312:                enter = Enter.instance(context);
0313:                todo = Todo.instance(context);
0314:
0315:                fileManager = context.get(JavaFileManager.class);
0316:                parserFactory = Parser.Factory.instance(context);
0317:
0318:                try {
0319:                    // catch completion problems with predefineds
0320:                    syms = Symtab.instance(context);
0321:                } catch (CompletionFailure ex) {
0322:                    // inlined Check.completionError as it is not initialized yet
0323:                    log.error("cant.access", ex.sym, ex.errmsg);
0324:                    if (ex instanceof  ClassReader.BadClassFile)
0325:                        throw new Abort();
0326:                }
0327:                source = Source.instance(context);
0328:                attr = Attr.instance(context);
0329:                chk = Check.instance(context);
0330:                gen = Gen.instance(context);
0331:                flow = Flow.instance(context);
0332:                transTypes = TransTypes.instance(context);
0333:                lower = Lower.instance(context);
0334:                annotate = Annotate.instance(context);
0335:                types = Types.instance(context);
0336:                taskListener = context.get(TaskListener.class);
0337:
0338:                reader.sourceCompleter = this ;
0339:
0340:                Options options = Options.instance(context);
0341:
0342:                verbose = options.get("-verbose") != null;
0343:                sourceOutput = options.get("-printsource") != null; // used to be -s
0344:                stubOutput = options.get("-stubs") != null;
0345:                relax = options.get("-relax") != null;
0346:                printFlat = options.get("-printflat") != null;
0347:                attrParseOnly = options.get("-attrparseonly") != null;
0348:                encoding = options.get("-encoding");
0349:                lineDebugInfo = options.get("-g:") == null
0350:                        || options.get("-g:lines") != null;
0351:                genEndPos = options.get("-Xjcov") != null
0352:                        || context.get(DiagnosticListener.class) != null;
0353:                devVerbose = options.get("dev") != null;
0354:                processPcks = options.get("process.packages") != null;
0355:
0356:                verboseCompilePolicy = options.get("verboseCompilePolicy") != null;
0357:
0358:                if (attrParseOnly)
0359:                    compilePolicy = CompilePolicy.ATTR_ONLY;
0360:                else
0361:                    compilePolicy = CompilePolicy.decode(options
0362:                            .get("compilePolicy"));
0363:
0364:                implicitSourcePolicy = ImplicitSourcePolicy.decode(options
0365:                        .get("-implicit"));
0366:
0367:                completionFailureName = (options.get("failcomplete") != null) ? names
0368:                        .fromString(options.get("failcomplete"))
0369:                        : null;
0370:            }
0371:
0372:            /* Switches:
0373:             */
0374:
0375:            /** Verbose output.
0376:             */
0377:            public boolean verbose;
0378:
0379:            /** Emit plain Java source files rather than class files.
0380:             */
0381:            public boolean sourceOutput;
0382:
0383:            /** Emit stub source files rather than class files.
0384:             */
0385:            public boolean stubOutput;
0386:
0387:            /** Generate attributed parse tree only.
0388:             */
0389:            public boolean attrParseOnly;
0390:
0391:            /** Switch: relax some constraints for producing the jsr14 prototype.
0392:             */
0393:            boolean relax;
0394:
0395:            /** Debug switch: Emit Java sources after inner class flattening.
0396:             */
0397:            public boolean printFlat;
0398:
0399:            /** The encoding to be used for source input.
0400:             */
0401:            public String encoding;
0402:
0403:            /** Generate code with the LineNumberTable attribute for debugging
0404:             */
0405:            public boolean lineDebugInfo;
0406:
0407:            /** Switch: should we store the ending positions?
0408:             */
0409:            public boolean genEndPos;
0410:
0411:            /** Switch: should we debug ignored exceptions
0412:             */
0413:            protected boolean devVerbose;
0414:
0415:            /** Switch: should we (annotation) process packages as well
0416:             */
0417:            protected boolean processPcks;
0418:
0419:            /** Switch: is annotation processing requested explitly via
0420:             * CompilationTask.setProcessors?
0421:             */
0422:            protected boolean explicitAnnotationProcessingRequested = false;
0423:
0424:            /**
0425:             * The policy for the order in which to perform the compilation
0426:             */
0427:            protected CompilePolicy compilePolicy;
0428:
0429:            /**
0430:             * The policy for what to do with implicitly read source files
0431:             */
0432:            protected ImplicitSourcePolicy implicitSourcePolicy;
0433:
0434:            /**
0435:             * Report activity related to compilePolicy
0436:             */
0437:            public boolean verboseCompilePolicy;
0438:
0439:            /** A queue of all as yet unattributed classes.
0440:             */
0441:            public Todo todo;
0442:
0443:            private Set<Env<AttrContext>> deferredSugar = new HashSet<Env<AttrContext>>();
0444:
0445:            /** The set of currently compiled inputfiles, needed to ensure
0446:             *  we don't accidentally overwrite an input file when -s is set.
0447:             *  initialized by `compile'.
0448:             */
0449:            protected Set<JavaFileObject> inputFiles = new HashSet<JavaFileObject>();
0450:
0451:            /** The number of errors reported so far.
0452:             */
0453:            public int errorCount() {
0454:                if (delegateCompiler != null && delegateCompiler != this )
0455:                    return delegateCompiler.errorCount();
0456:                else
0457:                    return log.nerrors;
0458:            }
0459:
0460:            protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) {
0461:                if (errorCount() == 0)
0462:                    return listBuffer.toList();
0463:                else
0464:                    return List.nil();
0465:            }
0466:
0467:            protected final <T> List<T> stopIfError(List<T> list) {
0468:                if (errorCount() == 0)
0469:                    return list;
0470:                else
0471:                    return List.nil();
0472:            }
0473:
0474:            /** The number of warnings reported so far.
0475:             */
0476:            public int warningCount() {
0477:                if (delegateCompiler != null && delegateCompiler != this )
0478:                    return delegateCompiler.warningCount();
0479:                else
0480:                    return log.nwarnings;
0481:            }
0482:
0483:            /** Whether or not any parse errors have occurred.
0484:             */
0485:            public boolean parseErrors() {
0486:                return parseErrors;
0487:            }
0488:
0489:            protected Scanner.Factory getScannerFactory() {
0490:                return Scanner.Factory.instance(context);
0491:            }
0492:
0493:            /** Try to open input stream with given name.
0494:             *  Report an error if this fails.
0495:             *  @param filename   The file name of the input stream to be opened.
0496:             */
0497:            public CharSequence readSource(JavaFileObject filename) {
0498:                try {
0499:                    inputFiles.add(filename);
0500:                    return filename.getCharContent(false);
0501:                } catch (IOException e) {
0502:                    log.error("error.reading.file", filename, e
0503:                            .getLocalizedMessage());
0504:                    return null;
0505:                }
0506:            }
0507:
0508:            /** Parse contents of input stream.
0509:             *  @param filename     The name of the file from which input stream comes.
0510:             *  @param input        The input stream to be parsed.
0511:             */
0512:            protected JCCompilationUnit parse(JavaFileObject filename,
0513:                    CharSequence content) {
0514:                long msec = now();
0515:                JCCompilationUnit tree = make
0516:                        .TopLevel(List.<JCTree.JCAnnotation> nil(), null, List
0517:                                .<JCTree> nil());
0518:                if (content != null) {
0519:                    if (verbose) {
0520:                        printVerbose("parsing.started", filename);
0521:                    }
0522:                    if (taskListener != null) {
0523:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE,
0524:                                filename);
0525:                        taskListener.started(e);
0526:                    }
0527:                    int initialErrorCount = log.nerrors;
0528:                    Scanner scanner = getScannerFactory().newScanner(content);
0529:                    Parser parser = parserFactory.newParser(scanner,
0530:                            keepComments(), genEndPos);
0531:                    tree = parser.compilationUnit();
0532:                    parseErrors |= (log.nerrors > initialErrorCount);
0533:                    if (lineDebugInfo) {
0534:                        tree.lineMap = scanner.getLineMap();
0535:                    }
0536:                    if (verbose) {
0537:                        printVerbose("parsing.done", Long
0538:                                .toString(elapsed(msec)));
0539:                    }
0540:                }
0541:
0542:                tree.sourcefile = filename;
0543:
0544:                if (content != null && taskListener != null) {
0545:                    TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
0546:                    taskListener.finished(e);
0547:                }
0548:
0549:                return tree;
0550:            }
0551:
0552:            // where
0553:            public boolean keepComments = false;
0554:
0555:            protected boolean keepComments() {
0556:                return keepComments || sourceOutput || stubOutput;
0557:            }
0558:
0559:            /** Parse contents of file.
0560:             *  @param filename     The name of the file to be parsed.
0561:             */
0562:            @Deprecated
0563:            public JCTree.JCCompilationUnit parse(String filename)
0564:                    throws IOException {
0565:                JavacFileManager fm = (JavacFileManager) fileManager;
0566:                return parse(fm
0567:                        .getJavaFileObjectsFromStrings(List.of(filename))
0568:                        .iterator().next());
0569:            }
0570:
0571:            /** Parse contents of file.
0572:             *  @param filename     The name of the file to be parsed.
0573:             */
0574:            public JCTree.JCCompilationUnit parse(JavaFileObject filename) {
0575:                JavaFileObject prev = log.useSource(filename);
0576:                try {
0577:                    JCTree.JCCompilationUnit t = parse(filename,
0578:                            readSource(filename));
0579:                    if (t.endPositions != null)
0580:                        log.setEndPosTable(filename, t.endPositions);
0581:                    return t;
0582:                } finally {
0583:                    log.useSource(prev);
0584:                }
0585:            }
0586:
0587:            /** Resolve an identifier.
0588:             * @param name      The identifier to resolve
0589:             */
0590:            public Symbol resolveIdent(String name) {
0591:                if (name.equals(""))
0592:                    return syms.errSymbol;
0593:                JavaFileObject prev = log.useSource(null);
0594:                try {
0595:                    JCExpression tree = null;
0596:                    for (String s : name.split("\\.", -1)) {
0597:                        if (!SourceVersion.isIdentifier(s)) // TODO: check for keywords
0598:                            return syms.errSymbol;
0599:                        tree = (tree == null) ? make.Ident(names.fromString(s))
0600:                                : make.Select(tree, names.fromString(s));
0601:                    }
0602:                    JCCompilationUnit toplevel = make.TopLevel(List
0603:                            .<JCTree.JCAnnotation> nil(), null, List
0604:                            .<JCTree> nil());
0605:                    toplevel.packge = syms.unnamedPackage;
0606:                    return attr.attribIdent(tree, toplevel);
0607:                } finally {
0608:                    log.useSource(prev);
0609:                }
0610:            }
0611:
0612:            /** Emit plain Java source for a class.
0613:             *  @param env    The attribution environment of the outermost class
0614:             *                containing this class.
0615:             *  @param cdef   The class definition to be printed.
0616:             */
0617:            JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef)
0618:                    throws IOException {
0619:                JavaFileObject outFile = fileManager.getJavaFileForOutput(
0620:                        CLASS_OUTPUT, cdef.sym.flatname.toString(),
0621:                        JavaFileObject.Kind.SOURCE, null);
0622:                if (inputFiles.contains(outFile)) {
0623:                    log.error(cdef.pos(), "source.cant.overwrite.input.file",
0624:                            outFile);
0625:                    return null;
0626:                } else {
0627:                    BufferedWriter out = new BufferedWriter(outFile
0628:                            .openWriter());
0629:                    try {
0630:                        new Pretty(out, true).printUnit(env.toplevel, cdef);
0631:                        if (verbose)
0632:                            printVerbose("wrote.file", outFile);
0633:                    } finally {
0634:                        out.close();
0635:                    }
0636:                    return outFile;
0637:                }
0638:            }
0639:
0640:            /** Generate code and emit a class file for a given class
0641:             *  @param env    The attribution environment of the outermost class
0642:             *                containing this class.
0643:             *  @param cdef   The class definition from which code is generated.
0644:             */
0645:            JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef)
0646:                    throws IOException {
0647:                try {
0648:                    if (gen.genClass(env, cdef))
0649:                        return writer.writeClass(cdef.sym);
0650:                } catch (ClassWriter.PoolOverflow ex) {
0651:                    log.error(cdef.pos(), "limit.pool");
0652:                } catch (ClassWriter.StringOverflow ex) {
0653:                    log.error(cdef.pos(), "limit.string.overflow", ex.value
0654:                            .substring(0, 20));
0655:                } catch (CompletionFailure ex) {
0656:                    chk.completionError(cdef.pos(), ex);
0657:                }
0658:                return null;
0659:            }
0660:
0661:            /** Complete compiling a source file that has been accessed
0662:             *  by the class file reader.
0663:             *  @param c          The class the source file of which needs to be compiled.
0664:             *  @param filename   The name of the source file.
0665:             *  @param f          An input stream that reads the source file.
0666:             */
0667:            public void complete(ClassSymbol c) throws CompletionFailure {
0668:                //      System.err.println("completing " + c);//DEBUG
0669:                if (completionFailureName == c.fullname) {
0670:                    throw new CompletionFailure(c,
0671:                            "user-selected completion failure by class name");
0672:                }
0673:                JCCompilationUnit tree;
0674:                JavaFileObject filename = c.classfile;
0675:                JavaFileObject prev = log.useSource(filename);
0676:
0677:                try {
0678:                    tree = parse(filename, filename.getCharContent(false));
0679:                } catch (IOException e) {
0680:                    log.error("error.reading.file", filename, e);
0681:                    tree = make.TopLevel(List.<JCTree.JCAnnotation> nil(),
0682:                            null, List.<JCTree> nil());
0683:                } finally {
0684:                    log.useSource(prev);
0685:                }
0686:
0687:                if (taskListener != null) {
0688:                    TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
0689:                    taskListener.started(e);
0690:                }
0691:
0692:                enter.complete(List.of(tree), c);
0693:
0694:                if (taskListener != null) {
0695:                    TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
0696:                    taskListener.finished(e);
0697:                }
0698:
0699:                if (enter.getEnv(c) == null) {
0700:                    boolean isPkgInfo = tree.sourcefile.isNameCompatible(
0701:                            "package-info", JavaFileObject.Kind.SOURCE);
0702:                    if (isPkgInfo) {
0703:                        if (enter.getEnv(tree.packge) == null) {
0704:                            String msg = log.getLocalizedString(
0705:                                    "file.does.not.contain.package", c
0706:                                            .location());
0707:                            throw new ClassReader.BadClassFile(c, filename, msg);
0708:                        }
0709:                    } else {
0710:                        throw new ClassReader.BadClassFile(c, filename,
0711:                                log
0712:                                        .getLocalizedString(
0713:                                                "file.doesnt.contain.class",
0714:                                                c.fullname));
0715:                    }
0716:                }
0717:
0718:                implicitSourceFilesRead = true;
0719:            }
0720:
0721:            /** Track when the JavaCompiler has been used to compile something. */
0722:            private boolean hasBeenUsed = false;
0723:            private long start_msec = 0;
0724:            public long elapsed_msec = 0;
0725:
0726:            /** Track whether any errors occurred while parsing source text. */
0727:            private boolean parseErrors = false;
0728:
0729:            public void compile(List<JavaFileObject> sourceFileObject)
0730:                    throws Throwable {
0731:                compile(sourceFileObject, List.<String> nil(), null);
0732:            }
0733:
0734:            /**
0735:             * Main method: compile a list of files, return all compiled classes
0736:             *
0737:             * @param sourceFileObjects file objects to be compiled
0738:             * @param classnames class names to process for annotations
0739:             * @param processors user provided annotation processors to bypass
0740:             * discovery, {@code null} means that no processors were provided
0741:             */
0742:            public void compile(List<JavaFileObject> sourceFileObjects,
0743:                    List<String> classnames,
0744:                    Iterable<? extends Processor> processors)
0745:                    throws IOException // TODO: temp, from JavacProcessingEnvironment
0746:            {
0747:                if (processors != null && processors.iterator().hasNext())
0748:                    explicitAnnotationProcessingRequested = true;
0749:                // as a JavaCompiler can only be used once, throw an exception if
0750:                // it has been used before.
0751:                if (hasBeenUsed)
0752:                    throw new AssertionError("attempt to reuse JavaCompiler");
0753:                hasBeenUsed = true;
0754:
0755:                start_msec = now();
0756:                try {
0757:                    initProcessAnnotations(processors);
0758:
0759:                    // These method calls must be chained to avoid memory leaks
0760:                    delegateCompiler = processAnnotations(
0761:                            enterTrees(stopIfError(parseFiles(sourceFileObjects))),
0762:                            classnames);
0763:
0764:                    delegateCompiler.compile2();
0765:                    delegateCompiler.close();
0766:                    elapsed_msec = delegateCompiler.elapsed_msec;
0767:                } catch (Abort ex) {
0768:                    if (devVerbose)
0769:                        ex.printStackTrace();
0770:                }
0771:            }
0772:
0773:            /**
0774:             * The phases following annotation processing: attribution,
0775:             * desugar, and finally code generation.
0776:             */
0777:            private void compile2() {
0778:                try {
0779:                    switch (compilePolicy) {
0780:                    case ATTR_ONLY:
0781:                        attribute(todo);
0782:                        break;
0783:
0784:                    case CHECK_ONLY:
0785:                        flow(attribute(todo));
0786:                        break;
0787:
0788:                    case SIMPLE:
0789:                        generate(desugar(flow(attribute(todo))));
0790:                        break;
0791:
0792:                    case BY_FILE:
0793:                        for (List<Env<AttrContext>> list : groupByFile(
0794:                                flow(attribute(todo))).values())
0795:                            generate(desugar(list));
0796:                        break;
0797:
0798:                    case BY_TODO:
0799:                        while (todo.nonEmpty())
0800:                            generate(desugar(flow(attribute(todo.next()))));
0801:                        break;
0802:
0803:                    default:
0804:                        assert false : "unknown compile policy";
0805:                    }
0806:                } catch (Abort ex) {
0807:                    if (devVerbose)
0808:                        ex.printStackTrace();
0809:                }
0810:
0811:                if (verbose) {
0812:                    elapsed_msec = elapsed(start_msec);
0813:                    ;
0814:                    printVerbose("total", Long.toString(elapsed_msec));
0815:                }
0816:
0817:                reportDeferredDiagnostics();
0818:
0819:                if (!log.hasDiagnosticListener()) {
0820:                    printCount("error", errorCount());
0821:                    printCount("warn", warningCount());
0822:                }
0823:            }
0824:
0825:            private List<JCClassDecl> rootClasses;
0826:
0827:            /**
0828:             * Parses a list of files.
0829:             */
0830:            public List<JCCompilationUnit> parseFiles(
0831:                    List<JavaFileObject> fileObjects) throws IOException {
0832:                if (errorCount() > 0)
0833:                    return List.nil();
0834:
0835:                //parse all files
0836:                ListBuffer<JCCompilationUnit> trees = lb();
0837:                for (JavaFileObject fileObject : fileObjects)
0838:                    trees.append(parse(fileObject));
0839:                return trees.toList();
0840:            }
0841:
0842:            /**
0843:             * Enter the symbols found in a list of parse trees.
0844:             * As a side-effect, this puts elements on the "todo" list.
0845:             * Also stores a list of all top level classes in rootClasses.
0846:             */
0847:            public List<JCCompilationUnit> enterTrees(
0848:                    List<JCCompilationUnit> roots) {
0849:                //enter symbols for all files
0850:                if (taskListener != null) {
0851:                    for (JCCompilationUnit unit : roots) {
0852:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
0853:                        taskListener.started(e);
0854:                    }
0855:                }
0856:
0857:                enter.main(roots);
0858:
0859:                if (taskListener != null) {
0860:                    for (JCCompilationUnit unit : roots) {
0861:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
0862:                        taskListener.finished(e);
0863:                    }
0864:                }
0865:
0866:                //If generating source, remember the classes declared in
0867:                //the original compilation units listed on the command line.
0868:                if (sourceOutput || stubOutput) {
0869:                    ListBuffer<JCClassDecl> cdefs = lb();
0870:                    for (JCCompilationUnit unit : roots) {
0871:                        for (List<JCTree> defs = unit.defs; defs.nonEmpty(); defs = defs.tail) {
0872:                            if (defs.head instanceof  JCClassDecl)
0873:                                cdefs.append((JCClassDecl) defs.head);
0874:                        }
0875:                    }
0876:                    rootClasses = cdefs.toList();
0877:                }
0878:                return roots;
0879:            }
0880:
0881:            /**
0882:             * Set to true to enable skeleton annotation processing code.
0883:             * Currently, we assume this variable will be replaced more
0884:             * advanced logic to figure out if annotation processing is
0885:             * needed.
0886:             */
0887:            boolean processAnnotations = false;
0888:
0889:            /**
0890:             * Object to handle annotation processing.
0891:             */
0892:            JavacProcessingEnvironment procEnvImpl = null;
0893:
0894:            /**
0895:             * Check if we should process annotations.
0896:             * If so, and if no scanner is yet registered, then set up the DocCommentScanner
0897:             * to catch doc comments, and set keepComments so the parser records them in
0898:             * the compilation unit.
0899:             *
0900:             * @param processors user provided annotation processors to bypass
0901:             * discovery, {@code null} means that no processors were provided
0902:             */
0903:            public void initProcessAnnotations(
0904:                    Iterable<? extends Processor> processors) {
0905:                // Process annotations if processing is not disabled and there
0906:                // is at least one Processor available.
0907:                Options options = Options.instance(context);
0908:                if (options.get("-proc:none") != null) {
0909:                    processAnnotations = false;
0910:                } else if (procEnvImpl == null) {
0911:                    procEnvImpl = new JavacProcessingEnvironment(context,
0912:                            processors);
0913:                    processAnnotations = procEnvImpl.atLeastOneProcessor();
0914:
0915:                    if (processAnnotations) {
0916:                        if (context.get(Scanner.Factory.scannerFactoryKey) == null)
0917:                            DocCommentScanner.Factory.preRegister(context);
0918:                        options.put("save-parameter-names",
0919:                                "save-parameter-names");
0920:                        reader.saveParameterNames = true;
0921:                        keepComments = true;
0922:                        if (taskListener != null)
0923:                            taskListener.started(new TaskEvent(
0924:                                    TaskEvent.Kind.ANNOTATION_PROCESSING));
0925:
0926:                    } else { // free resources
0927:                        procEnvImpl.close();
0928:                    }
0929:                }
0930:            }
0931:
0932:            // TODO: called by JavacTaskImpl
0933:            public JavaCompiler processAnnotations(List<JCCompilationUnit> roots)
0934:                    throws IOException {
0935:                return processAnnotations(roots, List.<String> nil());
0936:            }
0937:
0938:            /**
0939:             * Process any anotations found in the specifed compilation units.
0940:             * @param roots a list of compilation units
0941:             * @return an instance of the compiler in which to complete the compilation
0942:             */
0943:            public JavaCompiler processAnnotations(
0944:                    List<JCCompilationUnit> roots, List<String> classnames)
0945:                    throws IOException { // TODO: see TEMP note in JavacProcessingEnvironment
0946:                if (errorCount() != 0) {
0947:                    // Errors were encountered.  If todo is empty, then the
0948:                    // encountered errors were parse errors.  Otherwise, the
0949:                    // errors were found during the enter phase which should
0950:                    // be ignored when processing annotations.
0951:
0952:                    if (todo.isEmpty())
0953:                        return this ;
0954:                }
0955:
0956:                // ASSERT: processAnnotations and procEnvImpl should have been set up by
0957:                // by initProcessAnnotations
0958:
0959:                // NOTE: The !classnames.isEmpty() checks should be refactored to Main.
0960:
0961:                if (!processAnnotations) {
0962:                    // If there are no annotation processors present, and
0963:                    // annotation processing is to occur with compilation,
0964:                    // emit a warning.
0965:                    Options options = Options.instance(context);
0966:                    if (options.get("-proc:only") != null) {
0967:                        log.warning("proc.proc-only.requested.no.procs");
0968:                        todo.clear();
0969:                    }
0970:                    // If not processing annotations, classnames must be empty
0971:                    if (!classnames.isEmpty()) {
0972:                        log
0973:                                .error(
0974:                                        "proc.no.explicit.annotation.processing.requested",
0975:                                        classnames);
0976:                    }
0977:                    return this ; // continue regular compilation
0978:                }
0979:
0980:                try {
0981:                    List<ClassSymbol> classSymbols = List.nil();
0982:                    List<PackageSymbol> pckSymbols = List.nil();
0983:                    if (!classnames.isEmpty()) {
0984:                        // Check for explicit request for annotation
0985:                        // processing
0986:                        if (!explicitAnnotationProcessingRequested()) {
0987:                            log
0988:                                    .error(
0989:                                            "proc.no.explicit.annotation.processing.requested",
0990:                                            classnames);
0991:                            return this ; // TODO: Will this halt compilation?
0992:                        } else {
0993:                            boolean errors = false;
0994:                            for (String nameStr : classnames) {
0995:                                Symbol sym = resolveIdent(nameStr);
0996:                                if (sym == null
0997:                                        || (sym.kind == Kinds.PCK && !processPcks)) {
0998:                                    log.error("proc.cant.find.class", nameStr);
0999:                                    errors = true;
1000:                                    continue;
1001:                                }
1002:                                try {
1003:                                    if (sym.kind == Kinds.PCK)
1004:                                        sym.complete();
1005:                                    if (sym.exists()) {
1006:                                        Name name = names.fromString(nameStr);
1007:                                        if (sym.kind == Kinds.PCK)
1008:                                            pckSymbols = pckSymbols
1009:                                                    .prepend((PackageSymbol) sym);
1010:                                        else
1011:                                            classSymbols = classSymbols
1012:                                                    .prepend((ClassSymbol) sym);
1013:                                        continue;
1014:                                    }
1015:                                    assert sym.kind == Kinds.PCK;
1016:                                    log.warning("proc.package.does.not.exist",
1017:                                            nameStr);
1018:                                    pckSymbols = pckSymbols
1019:                                            .prepend((PackageSymbol) sym);
1020:                                } catch (CompletionFailure e) {
1021:                                    log.error("proc.cant.find.class", nameStr);
1022:                                    errors = true;
1023:                                    continue;
1024:                                }
1025:                            }
1026:                            if (errors)
1027:                                return this ;
1028:                        }
1029:                    }
1030:                    JavaCompiler c = procEnvImpl.doProcessing(context, roots,
1031:                            classSymbols, pckSymbols);
1032:                    if (c != this )
1033:                        annotationProcessingOccurred = c.annotationProcessingOccurred = true;
1034:                    return c;
1035:                } catch (CompletionFailure ex) {
1036:                    log.error("cant.access", ex.sym, ex.errmsg);
1037:                    return this ;
1038:
1039:                }
1040:            }
1041:
1042:            boolean explicitAnnotationProcessingRequested() {
1043:                Options options = Options.instance(context);
1044:                return explicitAnnotationProcessingRequested
1045:                        || options.get("-processor") != null
1046:                        || options.get("-processorpath") != null
1047:                        || options.get("-proc:only") != null
1048:                        || options.get("-Xprint") != null;
1049:            }
1050:
1051:            /**
1052:             * Attribute a list of parse trees, such as found on the "todo" list.
1053:             * Note that attributing classes may cause additional files to be
1054:             * parsed and entered via the SourceCompleter.
1055:             * Attribution of the entries in the list does not stop if any errors occur.
1056:             * @returns a list of environments for attributd classes.
1057:             */
1058:            public List<Env<AttrContext>> attribute(
1059:                    ListBuffer<Env<AttrContext>> envs) {
1060:                ListBuffer<Env<AttrContext>> results = lb();
1061:                while (envs.nonEmpty())
1062:                    results.append(attribute(envs.next()));
1063:                return results.toList();
1064:            }
1065:
1066:            /**
1067:             * Attribute a parse tree.
1068:             * @returns the attributed parse tree
1069:             */
1070:            public Env<AttrContext> attribute(Env<AttrContext> env) {
1071:                if (verboseCompilePolicy)
1072:                    log.printLines(log.noticeWriter, "[attribute "
1073:                            + env.enclClass.sym + "]");
1074:                if (verbose)
1075:                    printVerbose("checking.attribution", env.enclClass.sym);
1076:
1077:                if (taskListener != null) {
1078:                    TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE,
1079:                            env.toplevel, env.enclClass.sym);
1080:                    taskListener.started(e);
1081:                }
1082:
1083:                JavaFileObject prev = log
1084:                        .useSource(env.enclClass.sym.sourcefile != null ? env.enclClass.sym.sourcefile
1085:                                : env.toplevel.sourcefile);
1086:                try {
1087:                    attr.attribClass(env.tree.pos(), env.enclClass.sym);
1088:                } finally {
1089:                    log.useSource(prev);
1090:                }
1091:
1092:                return env;
1093:            }
1094:
1095:            /**
1096:             * Perform dataflow checks on attributed parse trees.
1097:             * These include checks for definite assignment and unreachable statements.
1098:             * If any errors occur, an empty list will be returned.
1099:             * @returns the list of attributed parse trees
1100:             */
1101:            public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) {
1102:                ListBuffer<Env<AttrContext>> results = lb();
1103:                for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) {
1104:                    flow(l.head, results);
1105:                }
1106:                return stopIfError(results);
1107:            }
1108:
1109:            /**
1110:             * Perform dataflow checks on an attributed parse tree.
1111:             */
1112:            public List<Env<AttrContext>> flow(Env<AttrContext> env) {
1113:                ListBuffer<Env<AttrContext>> results = lb();
1114:                flow(env, results);
1115:                return stopIfError(results);
1116:            }
1117:
1118:            /**
1119:             * Perform dataflow checks on an attributed parse tree.
1120:             */
1121:            protected void flow(Env<AttrContext> env,
1122:                    ListBuffer<Env<AttrContext>> results) {
1123:                try {
1124:                    if (errorCount() > 0)
1125:                        return;
1126:
1127:                    if (relax || deferredSugar.contains(env)) {
1128:                        results.append(env);
1129:                        return;
1130:                    }
1131:
1132:                    if (verboseCompilePolicy)
1133:                        log.printLines(log.noticeWriter, "[flow "
1134:                                + env.enclClass.sym + "]");
1135:                    JavaFileObject prev = log
1136:                            .useSource(env.enclClass.sym.sourcefile != null ? env.enclClass.sym.sourcefile
1137:                                    : env.toplevel.sourcefile);
1138:                    try {
1139:                        make.at(Position.FIRSTPOS);
1140:                        TreeMaker localMake = make.forToplevel(env.toplevel);
1141:                        flow.analyzeTree(env.tree, localMake);
1142:
1143:                        if (errorCount() > 0)
1144:                            return;
1145:
1146:                        results.append(env);
1147:                    } finally {
1148:                        log.useSource(prev);
1149:                    }
1150:                } finally {
1151:                    if (taskListener != null) {
1152:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE,
1153:                                env.toplevel, env.enclClass.sym);
1154:                        taskListener.finished(e);
1155:                    }
1156:                }
1157:            }
1158:
1159:            /**
1160:             * Prepare attributed parse trees, in conjunction with their attribution contexts,
1161:             * for source or code generation.
1162:             * If any errors occur, an empty list will be returned.
1163:             * @returns a list containing the classes to be generated
1164:             */
1165:            public List<Pair<Env<AttrContext>, JCClassDecl>> desugar(
1166:                    List<Env<AttrContext>> envs) {
1167:                ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb();
1168:                for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail)
1169:                    desugar(l.head, results);
1170:                return stopIfError(results);
1171:            }
1172:
1173:            /**
1174:             * Prepare attributed parse trees, in conjunction with their attribution contexts,
1175:             * for source or code generation. If the file was not listed on the command line,
1176:             * the current implicitSourcePolicy is taken into account.
1177:             * The preparation stops as soon as an error is found.
1178:             */
1179:            protected void desugar(Env<AttrContext> env,
1180:                    ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results) {
1181:                if (errorCount() > 0)
1182:                    return;
1183:
1184:                if (implicitSourcePolicy == ImplicitSourcePolicy.NONE
1185:                        && !inputFiles.contains(env.toplevel.sourcefile)) {
1186:                    return;
1187:                }
1188:
1189:                if (desugarLater(env)) {
1190:                    if (verboseCompilePolicy)
1191:                        log.printLines(log.noticeWriter, "[defer "
1192:                                + env.enclClass.sym + "]");
1193:                    todo.append(env);
1194:                    return;
1195:                }
1196:                deferredSugar.remove(env);
1197:
1198:                if (verboseCompilePolicy)
1199:                    log.printLines(log.noticeWriter, "[desugar "
1200:                            + env.enclClass.sym + "]");
1201:
1202:                JavaFileObject prev = log
1203:                        .useSource(env.enclClass.sym.sourcefile != null ? env.enclClass.sym.sourcefile
1204:                                : env.toplevel.sourcefile);
1205:                try {
1206:                    //save tree prior to rewriting
1207:                    JCTree untranslated = env.tree;
1208:
1209:                    make.at(Position.FIRSTPOS);
1210:                    TreeMaker localMake = make.forToplevel(env.toplevel);
1211:
1212:                    if (env.tree instanceof  JCCompilationUnit) {
1213:                        if (!(stubOutput || sourceOutput || printFlat)) {
1214:                            List<JCTree> pdef = lower.translateTopLevelClass(
1215:                                    env, env.tree, localMake);
1216:                            if (pdef.head != null) {
1217:                                assert pdef.tail.isEmpty();
1218:                                results
1219:                                        .append(new Pair<Env<AttrContext>, JCClassDecl>(
1220:                                                env, (JCClassDecl) pdef.head));
1221:                            }
1222:                        }
1223:                        return;
1224:                    }
1225:
1226:                    if (stubOutput) {
1227:                        //emit stub Java source file, only for compilation
1228:                        //units enumerated explicitly on the command line
1229:                        JCClassDecl cdef = (JCClassDecl) env.tree;
1230:                        if (untranslated instanceof  JCClassDecl
1231:                                && rootClasses
1232:                                        .contains((JCClassDecl) untranslated)
1233:                                && ((cdef.mods.flags & (Flags.PROTECTED | Flags.PUBLIC)) != 0 || cdef.sym
1234:                                        .packge().getQualifiedName() == names.java_lang)) {
1235:                            results
1236:                                    .append(new Pair<Env<AttrContext>, JCClassDecl>(
1237:                                            env, removeMethodBodies(cdef)));
1238:                        }
1239:                        return;
1240:                    }
1241:
1242:                    env.tree = transTypes.translateTopLevelClass(env.tree,
1243:                            localMake);
1244:
1245:                    if (errorCount() != 0)
1246:                        return;
1247:
1248:                    if (sourceOutput) {
1249:                        //emit standard Java source file, only for compilation
1250:                        //units enumerated explicitly on the command line
1251:                        JCClassDecl cdef = (JCClassDecl) env.tree;
1252:                        if (untranslated instanceof  JCClassDecl
1253:                                && rootClasses
1254:                                        .contains((JCClassDecl) untranslated)) {
1255:                            results
1256:                                    .append(new Pair<Env<AttrContext>, JCClassDecl>(
1257:                                            env, cdef));
1258:                        }
1259:                        return;
1260:                    }
1261:
1262:                    //translate out inner classes
1263:                    List<JCTree> cdefs = lower.translateTopLevelClass(env,
1264:                            env.tree, localMake);
1265:
1266:                    if (errorCount() != 0)
1267:                        return;
1268:
1269:                    //generate code for each class
1270:                    for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1271:                        JCClassDecl cdef = (JCClassDecl) l.head;
1272:                        results.append(new Pair<Env<AttrContext>, JCClassDecl>(
1273:                                env, cdef));
1274:                    }
1275:                } finally {
1276:                    log.useSource(prev);
1277:                }
1278:
1279:            }
1280:
1281:            /**
1282:             * Determine if a class needs to be desugared later.  As erasure
1283:             * (TransTypes) destroys information needed in flow analysis, we
1284:             * need to ensure that supertypes are translated before derived
1285:             * types are translated.
1286:             */
1287:            public boolean desugarLater(final Env<AttrContext> env) {
1288:                if (compilePolicy == CompilePolicy.BY_FILE)
1289:                    return false;
1290:                if (!devVerbose && deferredSugar.contains(env))
1291:                    // guarantee that compiler terminates
1292:                    return false;
1293:                class ScanNested extends TreeScanner {
1294:                    Set<Symbol> externalSupers = new HashSet<Symbol>();
1295:
1296:                    public void visitClassDef(JCClassDecl node) {
1297:                        Type st = types.super type(node.sym.type);
1298:                        if (st.tag == TypeTags.CLASS) {
1299:                            ClassSymbol c = st.tsym.outermostClass();
1300:                            Env<AttrContext> stEnv = enter.getEnv(c);
1301:                            if (stEnv != null && env != stEnv)
1302:                                externalSupers.add(st.tsym);
1303:                        }
1304:                        super .visitClassDef(node);
1305:                    }
1306:                }
1307:                ScanNested scanner = new ScanNested();
1308:                scanner.scan(env.tree);
1309:                if (scanner.externalSupers.isEmpty())
1310:                    return false;
1311:                if (!deferredSugar.add(env) && devVerbose) {
1312:                    throw new AssertionError(env.enclClass.sym
1313:                            + " was deferred, "
1314:                            + "second time has these external super types "
1315:                            + scanner.externalSupers);
1316:                }
1317:                return true;
1318:            }
1319:
1320:            /** Generates the source or class file for a list of classes.
1321:             * The decision to generate a source file or a class file is
1322:             * based upon the compiler's options.
1323:             * Generation stops if an error occurs while writing files.
1324:             */
1325:            public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) {
1326:                generate(list, null);
1327:            }
1328:
1329:            public void generate(
1330:                    List<Pair<Env<AttrContext>, JCClassDecl>> list,
1331:                    ListBuffer<JavaFileObject> results) {
1332:                boolean usePrintSource = (stubOutput || sourceOutput || printFlat);
1333:
1334:                for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l
1335:                        .nonEmpty(); l = l.tail) {
1336:                    Pair<Env<AttrContext>, JCClassDecl> x = l.head;
1337:                    Env<AttrContext> env = x.fst;
1338:                    JCClassDecl cdef = x.snd;
1339:
1340:                    if (verboseCompilePolicy) {
1341:                        log.printLines(log.noticeWriter, "[generate "
1342:                                + (usePrintSource ? " source" : "code") + " "
1343:                                + env.enclClass.sym + "]");
1344:                    }
1345:
1346:                    if (taskListener != null) {
1347:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE,
1348:                                env.toplevel, cdef.sym);
1349:                        taskListener.started(e);
1350:                    }
1351:
1352:                    JavaFileObject prev = log
1353:                            .useSource(env.enclClass.sym.sourcefile != null ? env.enclClass.sym.sourcefile
1354:                                    : env.toplevel.sourcefile);
1355:                    try {
1356:                        JavaFileObject file;
1357:                        if (usePrintSource)
1358:                            file = printSource(env, cdef);
1359:                        else
1360:                            file = genCode(env, cdef);
1361:                        if (results != null && file != null)
1362:                            results.append(file);
1363:                    } catch (IOException ex) {
1364:                        log.error(cdef.pos(), "class.cant.write", cdef.sym, ex
1365:                                .getMessage());
1366:                        return;
1367:                    } finally {
1368:                        log.useSource(prev);
1369:                    }
1370:
1371:                    if (taskListener != null) {
1372:                        TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE,
1373:                                env.toplevel, cdef.sym);
1374:                        taskListener.finished(e);
1375:                    }
1376:                }
1377:            }
1378:
1379:            // where
1380:            Map<JCCompilationUnit, List<Env<AttrContext>>> groupByFile(
1381:                    List<Env<AttrContext>> list) {
1382:                // use a LinkedHashMap to preserve the order of the original list as much as possible
1383:                Map<JCCompilationUnit, List<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, List<Env<AttrContext>>>();
1384:                Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>();
1385:                for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) {
1386:                    Env<AttrContext> env = l.head;
1387:                    List<Env<AttrContext>> sublist = map.get(env.toplevel);
1388:                    if (sublist == null)
1389:                        sublist = List.of(env);
1390:                    else {
1391:                        // this builds the list for the file in reverse order, so make a note
1392:                        // to reverse the list before returning.
1393:                        sublist = sublist.prepend(env);
1394:                        fixupSet.add(env.toplevel);
1395:                    }
1396:                    map.put(env.toplevel, sublist);
1397:                }
1398:                // fixup any lists that need reversing back to the correct order
1399:                for (JCTree.JCCompilationUnit tree : fixupSet)
1400:                    map.put(tree, map.get(tree).reverse());
1401:                return map;
1402:            }
1403:
1404:            JCClassDecl removeMethodBodies(JCClassDecl cdef) {
1405:                final boolean isInterface = (cdef.mods.flags & Flags.INTERFACE) != 0;
1406:                class MethodBodyRemover extends TreeTranslator {
1407:                    public void visitMethodDef(JCMethodDecl tree) {
1408:                        tree.mods.flags &= ~Flags.SYNCHRONIZED;
1409:                        for (JCVariableDecl vd : tree.params)
1410:                            vd.mods.flags &= ~Flags.FINAL;
1411:                        tree.body = null;
1412:                        super .visitMethodDef(tree);
1413:                    }
1414:
1415:                    public void visitVarDef(JCVariableDecl tree) {
1416:                        if (tree.init != null
1417:                                && tree.init.type.constValue() == null)
1418:                            tree.init = null;
1419:                        super .visitVarDef(tree);
1420:                    }
1421:
1422:                    public void visitClassDef(JCClassDecl tree) {
1423:                        ListBuffer<JCTree> newdefs = lb();
1424:                        for (List<JCTree> it = tree.defs; it.tail != null; it = it.tail) {
1425:                            JCTree t = it.head;
1426:                            switch (t.getTag()) {
1427:                            case JCTree.CLASSDEF:
1428:                                if (isInterface
1429:                                        || (((JCClassDecl) t).mods.flags & (Flags.PROTECTED | Flags.PUBLIC)) != 0
1430:                                        || (((JCClassDecl) t).mods.flags & (Flags.PRIVATE)) == 0
1431:                                        && ((JCClassDecl) t).sym.packge()
1432:                                                .getQualifiedName() == names.java_lang)
1433:                                    newdefs.append(t);
1434:                                break;
1435:                            case JCTree.METHODDEF:
1436:                                if (isInterface
1437:                                        || (((JCMethodDecl) t).mods.flags & (Flags.PROTECTED | Flags.PUBLIC)) != 0
1438:                                        || ((JCMethodDecl) t).sym.name == names.init
1439:                                        || (((JCMethodDecl) t).mods.flags & (Flags.PRIVATE)) == 0
1440:                                        && ((JCMethodDecl) t).sym.packge()
1441:                                                .getQualifiedName() == names.java_lang)
1442:                                    newdefs.append(t);
1443:                                break;
1444:                            case JCTree.VARDEF:
1445:                                if (isInterface
1446:                                        || (((JCVariableDecl) t).mods.flags & (Flags.PROTECTED | Flags.PUBLIC)) != 0
1447:                                        || (((JCVariableDecl) t).mods.flags & (Flags.PRIVATE)) == 0
1448:                                        && ((JCVariableDecl) t).sym.packge()
1449:                                                .getQualifiedName() == names.java_lang)
1450:                                    newdefs.append(t);
1451:                                break;
1452:                            default:
1453:                                break;
1454:                            }
1455:                        }
1456:                        tree.defs = newdefs.toList();
1457:                        super .visitClassDef(tree);
1458:                    }
1459:                }
1460:                MethodBodyRemover r = new MethodBodyRemover();
1461:                return r.translate(cdef);
1462:            }
1463:
1464:            public void reportDeferredDiagnostics() {
1465:                if (annotationProcessingOccurred && implicitSourceFilesRead
1466:                        && implicitSourcePolicy == ImplicitSourcePolicy.UNSET) {
1467:                    if (explicitAnnotationProcessingRequested())
1468:                        log.warning("proc.use.implicit");
1469:                    else
1470:                        log.warning("proc.use.proc.or.implicit");
1471:                }
1472:                chk.reportDeferredDiagnostics();
1473:            }
1474:
1475:            /** Close the compiler, flushing the logs
1476:             */
1477:            public void close() {
1478:                close(true);
1479:            }
1480:
1481:            private void close(boolean disposeNames) {
1482:                rootClasses = null;
1483:                reader = null;
1484:                make = null;
1485:                writer = null;
1486:                enter = null;
1487:                if (todo != null)
1488:                    todo.clear();
1489:                todo = null;
1490:                parserFactory = null;
1491:                syms = null;
1492:                source = null;
1493:                attr = null;
1494:                chk = null;
1495:                gen = null;
1496:                flow = null;
1497:                transTypes = null;
1498:                lower = null;
1499:                annotate = null;
1500:                types = null;
1501:
1502:                log.flush();
1503:                try {
1504:                    fileManager.flush();
1505:                } catch (IOException e) {
1506:                    throw new Abort(e);
1507:                } finally {
1508:                    if (names != null && disposeNames)
1509:                        names.dispose();
1510:                    names = null;
1511:                }
1512:            }
1513:
1514:            /** Output for "-verbose" option.
1515:             *  @param key The key to look up the correct internationalized string.
1516:             *  @param arg An argument for substitution into the output string.
1517:             */
1518:            protected void printVerbose(String key, Object arg) {
1519:                Log.printLines(log.noticeWriter, log.getLocalizedString(
1520:                        "verbose." + key, arg));
1521:            }
1522:
1523:            /** Print numbers of errors and warnings.
1524:             */
1525:            protected void printCount(String kind, int count) {
1526:                if (count != 0) {
1527:                    String text;
1528:                    if (count == 1)
1529:                        text = log.getLocalizedString("count." + kind, String
1530:                                .valueOf(count));
1531:                    else
1532:                        text = log.getLocalizedString("count." + kind
1533:                                + ".plural", String.valueOf(count));
1534:                    Log.printLines(log.errWriter, text);
1535:                    log.errWriter.flush();
1536:                }
1537:            }
1538:
1539:            private static long now() {
1540:                return System.currentTimeMillis();
1541:            }
1542:
1543:            private static long elapsed(long then) {
1544:                return now() - then;
1545:            }
1546:
1547:            public void initRound(JavaCompiler prev) {
1548:                keepComments = prev.keepComments;
1549:                start_msec = prev.start_msec;
1550:                hasBeenUsed = true;
1551:            }
1552:
1553:            public static void enableLogging() {
1554:                Logger logger = Logger.getLogger(com.sun.tools.javac.Main.class
1555:                        .getPackage().getName());
1556:                logger.setLevel(Level.ALL);
1557:                for (Handler h : logger.getParent().getHandlers()) {
1558:                    h.setLevel(Level.ALL);
1559:                }
1560:
1561:            }
1562:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.