langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
changeset 864 b1cf6afb8244
parent 735 372aa565a221
child 936 1d395a623f16
equal deleted inserted replaced
863:3113c955a388 864:b1cf6afb8244
    61 import static com.sun.tools.javac.util.ListBuffer.lb;
    61 import static com.sun.tools.javac.util.ListBuffer.lb;
    62 
    62 
    63 // TEMP, until we have a more efficient way to save doc comment info
    63 // TEMP, until we have a more efficient way to save doc comment info
    64 import com.sun.tools.javac.parser.DocCommentScanner;
    64 import com.sun.tools.javac.parser.DocCommentScanner;
    65 
    65 
       
    66 import java.util.Queue;
    66 import javax.lang.model.SourceVersion;
    67 import javax.lang.model.SourceVersion;
    67 
    68 
    68 /** This class could be the main entry point for GJC when GJC is used as a
    69 /** This class could be the main entry point for GJC when GJC is used as a
    69  *  component in a larger software system. It provides operations to
    70  *  component in a larger software system. It provides operations to
    70  *  construct a new compiler, and to run a new compiler on a set of source
    71  *  construct a new compiler, and to run a new compiler on a set of source
   458             return delegateCompiler.errorCount();
   459             return delegateCompiler.errorCount();
   459         else
   460         else
   460             return log.nerrors;
   461             return log.nerrors;
   461     }
   462     }
   462 
   463 
   463     protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) {
   464     protected final <T> Queue<T> stopIfError(Queue<T> queue) {
   464         if (errorCount() == 0)
   465         if (errorCount() == 0)
   465             return listBuffer.toList();
   466             return queue;
   466         else
   467         else
   467             return List.nil();
   468             return ListBuffer.lb();
   468     }
   469     }
   469 
   470 
   470     protected final <T> List<T> stopIfError(List<T> list) {
   471     protected final <T> List<T> stopIfError(List<T> list) {
   471         if (errorCount() == 0)
   472         if (errorCount() == 0)
   472             return list;
   473             return list;
   774             case SIMPLE:
   775             case SIMPLE:
   775                 generate(desugar(flow(attribute(todo))));
   776                 generate(desugar(flow(attribute(todo))));
   776                 break;
   777                 break;
   777 
   778 
   778             case BY_FILE:
   779             case BY_FILE:
   779                 for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values())
   780                 for (Queue<Env<AttrContext>> queue : groupByFile(flow(attribute(todo))).values())
   780                     generate(desugar(list));
   781                     generate(desugar(queue));
   781                 break;
   782                 break;
   782 
   783 
   783             case BY_TODO:
   784             case BY_TODO:
   784                 while (todo.nonEmpty())
   785                 while (todo.nonEmpty())
   785                     generate(desugar(flow(attribute(todo.next()))));
   786                     generate(desugar(flow(attribute(todo.next()))));
   792             if (devVerbose)
   793             if (devVerbose)
   793                 ex.printStackTrace();
   794                 ex.printStackTrace();
   794         }
   795         }
   795 
   796 
   796         if (verbose) {
   797         if (verbose) {
   797             elapsed_msec = elapsed(start_msec);;
   798             elapsed_msec = elapsed(start_msec);
   798             printVerbose("total", Long.toString(elapsed_msec));
   799             printVerbose("total", Long.toString(elapsed_msec));
   799         }
   800         }
   800 
   801 
   801         reportDeferredDiagnostics();
   802         reportDeferredDiagnostics();
   802 
   803 
  1024      * Note that attributing classes may cause additional files to be
  1025      * Note that attributing classes may cause additional files to be
  1025      * parsed and entered via the SourceCompleter.
  1026      * parsed and entered via the SourceCompleter.
  1026      * Attribution of the entries in the list does not stop if any errors occur.
  1027      * Attribution of the entries in the list does not stop if any errors occur.
  1027      * @returns a list of environments for attributd classes.
  1028      * @returns a list of environments for attributd classes.
  1028      */
  1029      */
  1029     public List<Env<AttrContext>> attribute(ListBuffer<Env<AttrContext>> envs) {
  1030     public Queue<Env<AttrContext>> attribute(Queue<Env<AttrContext>> envs) {
  1030         ListBuffer<Env<AttrContext>> results = lb();
  1031         ListBuffer<Env<AttrContext>> results = lb();
  1031         while (envs.nonEmpty())
  1032         while (!envs.isEmpty())
  1032             results.append(attribute(envs.next()));
  1033             results.append(attribute(envs.remove()));
  1033         return results.toList();
  1034         return results;
  1034     }
  1035     }
  1035 
  1036 
  1036     /**
  1037     /**
  1037      * Attribute a parse tree.
  1038      * Attribute a parse tree.
  1038      * @returns the attributed parse tree
  1039      * @returns the attributed parse tree
  1066      * Perform dataflow checks on attributed parse trees.
  1067      * Perform dataflow checks on attributed parse trees.
  1067      * These include checks for definite assignment and unreachable statements.
  1068      * These include checks for definite assignment and unreachable statements.
  1068      * If any errors occur, an empty list will be returned.
  1069      * If any errors occur, an empty list will be returned.
  1069      * @returns the list of attributed parse trees
  1070      * @returns the list of attributed parse trees
  1070      */
  1071      */
  1071     public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) {
  1072     public Queue<Env<AttrContext>> flow(Queue<Env<AttrContext>> envs) {
  1072         ListBuffer<Env<AttrContext>> results = lb();
  1073         ListBuffer<Env<AttrContext>> results = lb();
  1073         for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) {
  1074         for (Env<AttrContext> env: envs) {
  1074             flow(l.head, results);
  1075             flow(env, results);
  1075         }
  1076         }
  1076         return stopIfError(results);
  1077         return stopIfError(results);
  1077     }
  1078     }
  1078 
  1079 
  1079     /**
  1080     /**
  1080      * Perform dataflow checks on an attributed parse tree.
  1081      * Perform dataflow checks on an attributed parse tree.
  1081      */
  1082      */
  1082     public List<Env<AttrContext>> flow(Env<AttrContext> env) {
  1083     public Queue<Env<AttrContext>> flow(Env<AttrContext> env) {
  1083         ListBuffer<Env<AttrContext>> results = lb();
  1084         ListBuffer<Env<AttrContext>> results = lb();
  1084         flow(env, results);
  1085         flow(env, results);
  1085         return stopIfError(results);
  1086         return stopIfError(results);
  1086     }
  1087     }
  1087 
  1088 
  1130      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1131      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1131      * for source or code generation.
  1132      * for source or code generation.
  1132      * If any errors occur, an empty list will be returned.
  1133      * If any errors occur, an empty list will be returned.
  1133      * @returns a list containing the classes to be generated
  1134      * @returns a list containing the classes to be generated
  1134      */
  1135      */
  1135     public List<Pair<Env<AttrContext>, JCClassDecl>> desugar(List<Env<AttrContext>> envs) {
  1136     public Queue<Pair<Env<AttrContext>, JCClassDecl>> desugar(Queue<Env<AttrContext>> envs) {
  1136         ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb();
  1137         ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb();
  1137         for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail)
  1138         for (Env<AttrContext> env: envs)
  1138             desugar(l.head, results);
  1139             desugar(env, results);
  1139         return stopIfError(results);
  1140         return stopIfError(results);
  1140     }
  1141     }
  1141 
  1142 
  1142     /**
  1143     /**
  1143      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1144      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1144      * for source or code generation. If the file was not listed on the command line,
  1145      * for source or code generation. If the file was not listed on the command line,
  1145      * the current implicitSourcePolicy is taken into account.
  1146      * the current implicitSourcePolicy is taken into account.
  1146      * The preparation stops as soon as an error is found.
  1147      * The preparation stops as soon as an error is found.
  1147      */
  1148      */
  1148     protected void desugar(Env<AttrContext> env, ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results) {
  1149     protected void desugar(Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
  1149         if (errorCount() > 0)
  1150         if (errorCount() > 0)
  1150             return;
  1151             return;
  1151 
  1152 
  1152         if (implicitSourcePolicy == ImplicitSourcePolicy.NONE
  1153         if (implicitSourcePolicy == ImplicitSourcePolicy.NONE
  1153                 && !inputFiles.contains(env.toplevel.sourcefile)) {
  1154                 && !inputFiles.contains(env.toplevel.sourcefile)) {
  1178             if (env.tree instanceof JCCompilationUnit) {
  1179             if (env.tree instanceof JCCompilationUnit) {
  1179                 if (!(stubOutput || sourceOutput || printFlat)) {
  1180                 if (!(stubOutput || sourceOutput || printFlat)) {
  1180                     List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
  1181                     List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
  1181                     if (pdef.head != null) {
  1182                     if (pdef.head != null) {
  1182                         assert pdef.tail.isEmpty();
  1183                         assert pdef.tail.isEmpty();
  1183                         results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head));
  1184                         results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head));
  1184                     }
  1185                     }
  1185                 }
  1186                 }
  1186                 return;
  1187                 return;
  1187             }
  1188             }
  1188 
  1189 
  1192                 JCClassDecl cdef = (JCClassDecl)env.tree;
  1193                 JCClassDecl cdef = (JCClassDecl)env.tree;
  1193                 if (untranslated instanceof JCClassDecl &&
  1194                 if (untranslated instanceof JCClassDecl &&
  1194                     rootClasses.contains((JCClassDecl)untranslated) &&
  1195                     rootClasses.contains((JCClassDecl)untranslated) &&
  1195                     ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
  1196                     ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
  1196                      cdef.sym.packge().getQualifiedName() == names.java_lang)) {
  1197                      cdef.sym.packge().getQualifiedName() == names.java_lang)) {
  1197                     results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef)));
  1198                     results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef)));
  1198                 }
  1199                 }
  1199                 return;
  1200                 return;
  1200             }
  1201             }
  1201 
  1202 
  1202             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
  1203             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
  1208                 //emit standard Java source file, only for compilation
  1209                 //emit standard Java source file, only for compilation
  1209                 //units enumerated explicitly on the command line
  1210                 //units enumerated explicitly on the command line
  1210                 JCClassDecl cdef = (JCClassDecl)env.tree;
  1211                 JCClassDecl cdef = (JCClassDecl)env.tree;
  1211                 if (untranslated instanceof JCClassDecl &&
  1212                 if (untranslated instanceof JCClassDecl &&
  1212                     rootClasses.contains((JCClassDecl)untranslated)) {
  1213                     rootClasses.contains((JCClassDecl)untranslated)) {
  1213                     results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
  1214                     results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
  1214                 }
  1215                 }
  1215                 return;
  1216                 return;
  1216             }
  1217             }
  1217 
  1218 
  1218             //translate out inner classes
  1219             //translate out inner classes
  1222                 return;
  1223                 return;
  1223 
  1224 
  1224             //generate code for each class
  1225             //generate code for each class
  1225             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
  1226             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
  1226                 JCClassDecl cdef = (JCClassDecl)l.head;
  1227                 JCClassDecl cdef = (JCClassDecl)l.head;
  1227                 results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
  1228                 results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
  1228             }
  1229             }
  1229         }
  1230         }
  1230         finally {
  1231         finally {
  1231             log.useSource(prev);
  1232             log.useSource(prev);
  1232         }
  1233         }
  1273     /** Generates the source or class file for a list of classes.
  1274     /** Generates the source or class file for a list of classes.
  1274      * The decision to generate a source file or a class file is
  1275      * The decision to generate a source file or a class file is
  1275      * based upon the compiler's options.
  1276      * based upon the compiler's options.
  1276      * Generation stops if an error occurs while writing files.
  1277      * Generation stops if an error occurs while writing files.
  1277      */
  1278      */
  1278     public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) {
  1279     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
  1279         generate(list, null);
  1280         generate(queue, null);
  1280     }
  1281     }
  1281 
  1282 
  1282     public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list, ListBuffer<JavaFileObject> results) {
  1283     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, ListBuffer<JavaFileObject> results) {
  1283         boolean usePrintSource = (stubOutput || sourceOutput || printFlat);
  1284         boolean usePrintSource = (stubOutput || sourceOutput || printFlat);
  1284 
  1285 
  1285         for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l.nonEmpty(); l = l.tail) {
  1286         for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
  1286             Pair<Env<AttrContext>, JCClassDecl> x = l.head;
       
  1287             Env<AttrContext> env = x.fst;
  1287             Env<AttrContext> env = x.fst;
  1288             JCClassDecl cdef = x.snd;
  1288             JCClassDecl cdef = x.snd;
  1289 
  1289 
  1290             if (verboseCompilePolicy) {
  1290             if (verboseCompilePolicy) {
  1291                 log.printLines(log.noticeWriter, "[generate "
  1291                 log.printLines(log.noticeWriter, "[generate "
  1323             }
  1323             }
  1324         }
  1324         }
  1325     }
  1325     }
  1326 
  1326 
  1327         // where
  1327         // where
  1328         Map<JCCompilationUnit, List<Env<AttrContext>>> groupByFile(List<Env<AttrContext>> list) {
  1328         Map<JCCompilationUnit, Queue<Env<AttrContext>>> groupByFile(Queue<Env<AttrContext>> envs) {
  1329             // use a LinkedHashMap to preserve the order of the original list as much as possible
  1329             // use a LinkedHashMap to preserve the order of the original list as much as possible
  1330             Map<JCCompilationUnit, List<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, List<Env<AttrContext>>>();
  1330             Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, Queue<Env<AttrContext>>>();
  1331             Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>();
  1331             for (Env<AttrContext> env: envs) {
  1332             for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) {
  1332                 Queue<Env<AttrContext>> sublist = map.get(env.toplevel);
  1333                 Env<AttrContext> env = l.head;
  1333                 if (sublist == null) {
  1334                 List<Env<AttrContext>> sublist = map.get(env.toplevel);
  1334                     sublist = new ListBuffer<Env<AttrContext>>();
  1335                 if (sublist == null)
  1335                     map.put(env.toplevel, sublist);
  1336                     sublist = List.of(env);
       
  1337                 else {
       
  1338                     // this builds the list for the file in reverse order, so make a note
       
  1339                     // to reverse the list before returning.
       
  1340                     sublist = sublist.prepend(env);
       
  1341                     fixupSet.add(env.toplevel);
       
  1342                 }
  1336                 }
  1343                 map.put(env.toplevel, sublist);
  1337                 sublist.add(env);
  1344             }
  1338             }
  1345             // fixup any lists that need reversing back to the correct order
       
  1346             for (JCTree.JCCompilationUnit tree: fixupSet)
       
  1347                 map.put(tree, map.get(tree).reverse());
       
  1348             return map;
  1339             return map;
  1349         }
  1340         }
  1350 
  1341 
  1351         JCClassDecl removeMethodBodies(JCClassDecl cdef) {
  1342         JCClassDecl removeMethodBodies(JCClassDecl cdef) {
  1352             final boolean isInterface = (cdef.mods.flags & Flags.INTERFACE) != 0;
  1343             final boolean isInterface = (cdef.mods.flags & Flags.INTERFACE) != 0;