857 * Processors for round n have run to completion. Prepare
858 * for round (n+1) by checked for errors raised by
859 * annotation processors and then checking for syntax
860 * errors on any generated source files.
861 */
862 if (messager.errorRaised()) {
863 errorStatus = true;
864 break runAround;
865 } else {
866 if (moreToDo()) {
867 // annotationsPresentInSource = List.nil();
868 annotationsPresent = new LinkedHashSet<TypeElement>();
869 topLevelClasses = List.nil();
870 packageInfoFiles = List.nil();
871
872 compiler.close(false);
873 currentContext = contextForNextRound(currentContext, true);
874
875 JavaFileManager fileManager = currentContext.get(JavaFileManager.class);
876
877 List<JavaFileObject> fileObjects = List.nil();
878 for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
879 fileObjects = fileObjects.prepend(jfo);
880 }
881
882
883 compiler = JavaCompiler.instance(currentContext);
884 List<JCCompilationUnit> parsedFiles = compiler.parseFiles(fileObjects);
885 roots = cleanTrees(roots).reverse();
886
887
888 for (JCCompilationUnit unit : parsedFiles)
889 roots = roots.prepend(unit);
890 roots = roots.reverse();
891
892 // Check for errors after parsing
893 if (compiler.parseErrors()) {
894 errorStatus = true;
895 break runAround;
896 } else {
897 List<ClassSymbol> newClasses = enterNewClassFiles(currentContext);
898 compiler.enterTrees(roots);
899
900 // annotationsPresentInSource =
901 // collector.findAnnotations(parsedFiles);
902 ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>();
903 tlc.appendList(getTopLevelClasses(parsedFiles));
904 tlc.appendList(getTopLevelClassesFromClasses(newClasses));
905 topLevelClasses = tlc.toList();
906
907 ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>();
908 pif.appendList(getPackageInfoFiles(parsedFiles));
909 pif.appendList(getPackageInfoFilesFromClasses(newClasses));
910 packageInfoFiles = pif.toList();
911
912 annotationsPresent = new LinkedHashSet<TypeElement>();
913 for (ClassSymbol classSym : topLevelClasses)
914 annotationComputer.scan(classSym, annotationsPresent);
915 for (PackageSymbol pkgSym : packageInfoFiles)
916 annotationComputer.scan(pkgSym, annotationsPresent);
917
918 updateProcessingState(currentContext, false);
919 }
920 } else
921 break runAround; // No new files
922 }
923 }
924 runLastRound(xout, roundNumber, errorStatus, taskListener);
925
926 compiler.close(false);
927 currentContext = contextForNextRound(currentContext, true);
928 compiler = JavaCompiler.instance(currentContext);
929 filer.newRound(currentContext, true);
930 filer.warnIfUnclosedFiles();
931 warnIfUnmatchedOptions();
932
933 /*
934 * If an annotation processor raises an error in a round,
935 * that round runs to completion and one last round occurs.
936 * The last round may also occur because no more source or
937 * class files have been generated. Therefore, if an error
938 * was raised on either of the last *two* rounds, the compile
939 * should exit with a nonzero exit code. The current value of
940 * errorStatus holds whether or not an error was raised on the
941 * second to last round; errorRaised() gives the error status
942 * of the last round.
943 */
944 errorStatus = errorStatus || messager.errorRaised();
945
946
947 // Free resources
948 this.close();
962 this.context = currentContext;
963 updateProcessingState(currentContext, true);
964 compiler = JavaCompiler.instance(currentContext);
965 if (procOnly && foundTypeProcessors)
966 compiler.shouldStopPolicy = CompileState.FLOW;
967
968 if (true) {
969 compiler.enterTrees(cleanTrees(roots));
970 } else {
971 List<JavaFileObject> fileObjects = List.nil();
972 for (JCCompilationUnit unit : roots)
973 fileObjects = fileObjects.prepend(unit.getSourceFile());
974 roots = null;
975 compiler.enterTrees(compiler.parseFiles(fileObjects.reverse()));
976 }
977 }
978
979 return compiler;
980 }
981
982 // Call the last round of annotation processing
983 private void runLastRound(PrintWriter xout,
984 int roundNumber,
985 boolean errorStatus,
986 TaskListener taskListener) throws IOException {
987 roundNumber++;
988 List<ClassSymbol> noTopLevelClasses = List.nil();
989 Set<TypeElement> noAnnotations = Collections.emptySet();
990 printRoundInfo(xout, roundNumber, noTopLevelClasses, noAnnotations, true);
991
992 Set<Element> emptyRootElements = Collections.emptySet(); // immutable
993 RoundEnvironment renv = new JavacRoundEnvironment(true,
994 errorStatus,
995 emptyRootElements,
996 JavacProcessingEnvironment.this);
997 if (taskListener != null)
998 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
999
1000 try {
1001 discoveredProcs.iterator().runContributingProcs(renv);
1002 } finally {
1003 if (taskListener != null)
1004 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
1005 }
1006 }
1007
1008 private void updateProcessingState(Context currentContext, boolean lastRound) {
1009 filer.newRound(currentContext, lastRound);
1010 messager.newRound(currentContext);
1011
1012 elementUtils.setContext(currentContext);
1013 typeUtils.setContext(currentContext);
1014 }
1015
1016 private void warnIfUnmatchedOptions() {
1017 if (!unmatchedProcessorOptions.isEmpty()) {
1018 log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString());
1019 }
1020 }
1021
1022 private void printRoundInfo(PrintWriter xout,
1023 int roundNumber,
1024 List<ClassSymbol> topLevelClasses,
1025 Set<TypeElement> annotationsPresent,
|
857 * Processors for round n have run to completion. Prepare
858 * for round (n+1) by checked for errors raised by
859 * annotation processors and then checking for syntax
860 * errors on any generated source files.
861 */
862 if (messager.errorRaised()) {
863 errorStatus = true;
864 break runAround;
865 } else {
866 if (moreToDo()) {
867 // annotationsPresentInSource = List.nil();
868 annotationsPresent = new LinkedHashSet<TypeElement>();
869 topLevelClasses = List.nil();
870 packageInfoFiles = List.nil();
871
872 compiler.close(false);
873 currentContext = contextForNextRound(currentContext, true);
874
875 JavaFileManager fileManager = currentContext.get(JavaFileManager.class);
876
877 compiler = JavaCompiler.instance(currentContext);
878 List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler);
879 roots = cleanTrees(roots).appendList(parsedFiles);
880
881 // Check for errors after parsing
882 if (compiler.parseErrors()) {
883 errorStatus = true;
884 break runAround;
885 } else {
886 List<ClassSymbol> newClasses = enterNewClassFiles(currentContext);
887 compiler.enterTrees(roots);
888
889 // annotationsPresentInSource =
890 // collector.findAnnotations(parsedFiles);
891 ListBuffer<ClassSymbol> tlc = new ListBuffer<ClassSymbol>();
892 tlc.appendList(getTopLevelClasses(parsedFiles));
893 tlc.appendList(getTopLevelClassesFromClasses(newClasses));
894 topLevelClasses = tlc.toList();
895
896 ListBuffer<PackageSymbol> pif = new ListBuffer<PackageSymbol>();
897 pif.appendList(getPackageInfoFiles(parsedFiles));
898 pif.appendList(getPackageInfoFilesFromClasses(newClasses));
899 packageInfoFiles = pif.toList();
900
901 annotationsPresent = new LinkedHashSet<TypeElement>();
902 for (ClassSymbol classSym : topLevelClasses)
903 annotationComputer.scan(classSym, annotationsPresent);
904 for (PackageSymbol pkgSym : packageInfoFiles)
905 annotationComputer.scan(pkgSym, annotationsPresent);
906
907 updateProcessingState(currentContext, false);
908 }
909 } else
910 break runAround; // No new files
911 }
912 }
913 roots = runLastRound(xout, roundNumber, errorStatus, compiler, roots, taskListener);
914 // Set error status for any files compiled and generated in
915 // the last round
916 if (compiler.parseErrors())
917 errorStatus = true;
918
919 compiler.close(false);
920 currentContext = contextForNextRound(currentContext, true);
921 compiler = JavaCompiler.instance(currentContext);
922
923 filer.newRound(currentContext, true);
924 filer.warnIfUnclosedFiles();
925 warnIfUnmatchedOptions();
926
927 /*
928 * If an annotation processor raises an error in a round,
929 * that round runs to completion and one last round occurs.
930 * The last round may also occur because no more source or
931 * class files have been generated. Therefore, if an error
932 * was raised on either of the last *two* rounds, the compile
933 * should exit with a nonzero exit code. The current value of
934 * errorStatus holds whether or not an error was raised on the
935 * second to last round; errorRaised() gives the error status
936 * of the last round.
937 */
938 errorStatus = errorStatus || messager.errorRaised();
939
940
941 // Free resources
942 this.close();
956 this.context = currentContext;
957 updateProcessingState(currentContext, true);
958 compiler = JavaCompiler.instance(currentContext);
959 if (procOnly && foundTypeProcessors)
960 compiler.shouldStopPolicy = CompileState.FLOW;
961
962 if (true) {
963 compiler.enterTrees(cleanTrees(roots));
964 } else {
965 List<JavaFileObject> fileObjects = List.nil();
966 for (JCCompilationUnit unit : roots)
967 fileObjects = fileObjects.prepend(unit.getSourceFile());
968 roots = null;
969 compiler.enterTrees(compiler.parseFiles(fileObjects.reverse()));
970 }
971 }
972
973 return compiler;
974 }
975
976 private List<JCCompilationUnit> sourcesToParsedFiles(JavaCompiler compiler)
977 throws IOException {
978 List<JavaFileObject> fileObjects = List.nil();
979 for (JavaFileObject jfo : filer.getGeneratedSourceFileObjects() ) {
980 fileObjects = fileObjects.prepend(jfo);
981 }
982
983 return compiler.parseFiles(fileObjects);
984 }
985
986 // Call the last round of annotation processing
987 private List<JCCompilationUnit> runLastRound(PrintWriter xout,
988 int roundNumber,
989 boolean errorStatus,
990 JavaCompiler compiler,
991 List<JCCompilationUnit> roots,
992 TaskListener taskListener) throws IOException {
993 roundNumber++;
994 List<ClassSymbol> noTopLevelClasses = List.nil();
995 Set<TypeElement> noAnnotations = Collections.emptySet();
996 printRoundInfo(xout, roundNumber, noTopLevelClasses, noAnnotations, true);
997
998 Set<Element> emptyRootElements = Collections.emptySet(); // immutable
999 RoundEnvironment renv = new JavacRoundEnvironment(true,
1000 errorStatus,
1001 emptyRootElements,
1002 JavacProcessingEnvironment.this);
1003 if (taskListener != null)
1004 taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
1005
1006 try {
1007 discoveredProcs.iterator().runContributingProcs(renv);
1008 } finally {
1009 if (taskListener != null)
1010 taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND));
1011 }
1012
1013 // Add any sources generated during the last round to the set
1014 // of files to be compiled.
1015 if (moreToDo()) {
1016 List<JCCompilationUnit> parsedFiles = sourcesToParsedFiles(compiler);
1017 roots = cleanTrees(roots).appendList(parsedFiles);
1018 }
1019
1020 return roots;
1021 }
1022
1023 private void updateProcessingState(Context currentContext, boolean lastRound) {
1024 filer.newRound(currentContext, lastRound);
1025 messager.newRound(currentContext);
1026
1027 elementUtils.setContext(currentContext);
1028 typeUtils.setContext(currentContext);
1029 }
1030
1031 private void warnIfUnmatchedOptions() {
1032 if (!unmatchedProcessorOptions.isEmpty()) {
1033 log.warning("proc.unmatched.processor.options", unmatchedProcessorOptions.toString());
1034 }
1035 }
1036
1037 private void printRoundInfo(PrintWriter xout,
1038 int roundNumber,
1039 List<ClassSymbol> topLevelClasses,
1040 Set<TypeElement> annotationsPresent,
|