825 } |
826 } |
826 } |
827 } |
827 |
828 |
828 private void discoverAndRunProcs(Set<TypeElement> annotationsPresent, |
829 private void discoverAndRunProcs(Set<TypeElement> annotationsPresent, |
829 List<ClassSymbol> topLevelClasses, |
830 List<ClassSymbol> topLevelClasses, |
830 List<PackageSymbol> packageInfoFiles) { |
831 List<PackageSymbol> packageInfoFiles, |
|
832 List<ModuleSymbol> moduleInfoFiles) { |
831 Map<String, TypeElement> unmatchedAnnotations = new HashMap<>(annotationsPresent.size()); |
833 Map<String, TypeElement> unmatchedAnnotations = new HashMap<>(annotationsPresent.size()); |
832 |
834 |
833 for(TypeElement a : annotationsPresent) { |
835 for(TypeElement a : annotationsPresent) { |
834 unmatchedAnnotations.put(a.getQualifiedName().toString(), |
836 ModuleElement mod = elementUtils.getModuleOf(a); |
835 a); |
837 unmatchedAnnotations.put((mod != null ? mod.getSimpleName() + "/" : "") + a.getQualifiedName().toString(), |
|
838 a); |
836 } |
839 } |
837 |
840 |
838 // Give "*" processors a chance to match |
841 // Give "*" processors a chance to match |
839 if (unmatchedAnnotations.size() == 0) |
842 if (unmatchedAnnotations.size() == 0) |
840 unmatchedAnnotations.put("", null); |
843 unmatchedAnnotations.put("", null); |
984 /** The ASTs to be compiled. */ |
988 /** The ASTs to be compiled. */ |
985 List<JCCompilationUnit> roots; |
989 List<JCCompilationUnit> roots; |
986 /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */ |
990 /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */ |
987 Set<JCCompilationUnit> treesToClean; |
991 Set<JCCompilationUnit> treesToClean; |
988 /** The classes to be compiler that have were generated. */ |
992 /** The classes to be compiler that have were generated. */ |
989 Map<String, JavaFileObject> genClassFiles; |
993 Map<ModuleSymbol, Map<String, JavaFileObject>> genClassFiles; |
990 |
994 |
991 /** The set of annotations to be processed this round. */ |
995 /** The set of annotations to be processed this round. */ |
992 Set<TypeElement> annotationsPresent; |
996 Set<TypeElement> annotationsPresent; |
993 /** The set of top level classes to be processed this round. */ |
997 /** The set of top level classes to be processed this round. */ |
994 List<ClassSymbol> topLevelClasses; |
998 List<ClassSymbol> topLevelClasses; |
995 /** The set of package-info files to be processed this round. */ |
999 /** The set of package-info files to be processed this round. */ |
996 List<PackageSymbol> packageInfoFiles; |
1000 List<PackageSymbol> packageInfoFiles; |
|
1001 /** The set of module-info files to be processed this round. */ |
|
1002 List<ModuleSymbol> moduleInfoFiles; |
997 |
1003 |
998 /** Create a round (common code). */ |
1004 /** Create a round (common code). */ |
999 private Round(int number, Set<JCCompilationUnit> treesToClean, |
1005 private Round(int number, Set<JCCompilationUnit> treesToClean, |
1000 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1006 Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1001 this.number = number; |
1007 this.number = number; |
1029 topLevelClasses = |
1036 topLevelClasses = |
1030 getTopLevelClasses(roots).prependList(classSymbols.reverse()); |
1037 getTopLevelClasses(roots).prependList(classSymbols.reverse()); |
1031 |
1038 |
1032 packageInfoFiles = getPackageInfoFiles(roots); |
1039 packageInfoFiles = getPackageInfoFiles(roots); |
1033 |
1040 |
|
1041 moduleInfoFiles = getModuleInfoFiles(roots); |
|
1042 |
1034 findAnnotationsPresent(); |
1043 findAnnotationsPresent(); |
1035 } |
1044 } |
1036 |
1045 |
1037 /** Create a new round. */ |
1046 /** Create a new round. */ |
1038 private Round(Round prev, |
1047 private Round(Round prev, |
1039 Set<JavaFileObject> newSourceFiles, Map<String,JavaFileObject> newClassFiles) { |
1048 Set<JavaFileObject> newSourceFiles, Map<ModuleSymbol, Map<String,JavaFileObject>> newClassFiles) { |
1040 this(prev.number+1, prev.treesToClean, null); |
1049 this(prev.number+1, prev.treesToClean, null); |
1041 prev.newRound(); |
1050 prev.newRound(); |
1042 this.genClassFiles = prev.genClassFiles; |
1051 this.genClassFiles = prev.genClassFiles; |
1043 |
1052 |
1044 List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles); |
1053 List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles); |
1062 |
1075 |
1063 packageInfoFiles = join( |
1076 packageInfoFiles = join( |
1064 getPackageInfoFiles(parsedFiles), |
1077 getPackageInfoFiles(parsedFiles), |
1065 getPackageInfoFilesFromClasses(newClasses)); |
1078 getPackageInfoFilesFromClasses(newClasses)); |
1066 |
1079 |
|
1080 moduleInfoFiles = List.nil(); //module-info cannot be generated |
|
1081 |
1067 findAnnotationsPresent(); |
1082 findAnnotationsPresent(); |
1068 } |
1083 } |
1069 |
1084 |
1070 /** Create the next round to be used. */ |
1085 /** Create the next round to be used. */ |
1071 Round next(Set<JavaFileObject> newSourceFiles, Map<String, JavaFileObject> newClassFiles) { |
1086 Round next(Set<JavaFileObject> newSourceFiles, Map<ModuleSymbol, Map<String, JavaFileObject>> newClassFiles) { |
1072 return new Round(this, newSourceFiles, newClassFiles); |
1087 return new Round(this, newSourceFiles, newClassFiles); |
1073 } |
1088 } |
1074 |
1089 |
1075 /** Prepare the compiler for the final compilation. */ |
1090 /** Prepare the compiler for the final compilation. */ |
1076 void finalCompiler() { |
1091 void finalCompiler() { |
1119 annotationsPresent = new LinkedHashSet<>(); |
1134 annotationsPresent = new LinkedHashSet<>(); |
1120 for (ClassSymbol classSym : topLevelClasses) |
1135 for (ClassSymbol classSym : topLevelClasses) |
1121 annotationComputer.scan(classSym, annotationsPresent); |
1136 annotationComputer.scan(classSym, annotationsPresent); |
1122 for (PackageSymbol pkgSym : packageInfoFiles) |
1137 for (PackageSymbol pkgSym : packageInfoFiles) |
1123 annotationComputer.scan(pkgSym, annotationsPresent); |
1138 annotationComputer.scan(pkgSym, annotationsPresent); |
|
1139 for (ModuleSymbol mdlSym : moduleInfoFiles) |
|
1140 annotationComputer.scan(mdlSym, annotationsPresent); |
1124 } |
1141 } |
1125 |
1142 |
1126 /** Enter a set of generated class files. */ |
1143 /** Enter a set of generated class files. */ |
1127 private List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) { |
1144 private List<ClassSymbol> enterClassFiles(Map<ModuleSymbol, Map<String, JavaFileObject>> modulesAndClassFiles) { |
1128 List<ClassSymbol> list = List.nil(); |
1145 List<ClassSymbol> list = List.nil(); |
1129 |
1146 |
1130 for (Map.Entry<String,JavaFileObject> entry : classFiles.entrySet()) { |
1147 for (Entry<ModuleSymbol, Map<String, JavaFileObject>> moduleAndClassFiles : modulesAndClassFiles.entrySet()) { |
1131 Name name = names.fromString(entry.getKey()); |
1148 for (Map.Entry<String,JavaFileObject> entry : moduleAndClassFiles.getValue().entrySet()) { |
1132 JavaFileObject file = entry.getValue(); |
1149 Name name = names.fromString(entry.getKey()); |
1133 if (file.getKind() != JavaFileObject.Kind.CLASS) |
1150 JavaFileObject file = entry.getValue(); |
1134 throw new AssertionError(file); |
1151 if (file.getKind() != JavaFileObject.Kind.CLASS) |
1135 ClassSymbol cs; |
1152 throw new AssertionError(file); |
1136 // TODO: for now, we assume that generated code is in a default module; |
1153 ClassSymbol cs; |
1137 // in time, we need a way to be able to specify the module for generated code |
1154 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
1138 if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { |
1155 Name packageName = Convert.packagePart(name); |
1139 Name packageName = Convert.packagePart(name); |
1156 PackageSymbol p = symtab.enterPackage(moduleAndClassFiles.getKey(), packageName); |
1140 PackageSymbol p = symtab.enterPackage(defaultModule, packageName); |
1157 if (p.package_info == null) |
1141 if (p.package_info == null) |
1158 p.package_info = symtab.enterClass(moduleAndClassFiles.getKey(), Convert.shortName(name), p); |
1142 p.package_info = symtab.enterClass(defaultModule, Convert.shortName(name), p); |
1159 cs = p.package_info; |
1143 cs = p.package_info; |
1160 cs.reset(); |
1144 cs.reset(); |
1161 if (cs.classfile == null) |
1145 if (cs.classfile == null) |
1162 cs.classfile = file; |
|
1163 cs.completer = initialCompleter; |
|
1164 } else { |
|
1165 cs = symtab.enterClass(moduleAndClassFiles.getKey(), name); |
|
1166 cs.reset(); |
1146 cs.classfile = file; |
1167 cs.classfile = file; |
1147 cs.completer = initialCompleter; |
1168 cs.completer = initialCompleter; |
1148 } else { |
1169 cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore |
1149 cs = symtab.enterClass(defaultModule, name); |
1170 } |
1150 cs.reset(); |
1171 list = list.prepend(cs); |
1151 cs.classfile = file; |
1172 } |
1152 cs.completer = initialCompleter; |
|
1153 cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore |
|
1154 } |
|
1155 list = list.prepend(cs); |
|
1156 } |
1173 } |
1157 return list.reverse(); |
1174 return list.reverse(); |
1158 } |
1175 } |
1159 |
1176 |
1160 /** Enter a set of syntax trees. */ |
1177 /** Enter a set of syntax trees. */ |
1161 private void enterTrees(List<JCCompilationUnit> roots) { |
1178 private void enterTrees(List<JCCompilationUnit> roots) { |
1162 compiler.enterTrees(compiler.initModules(roots)); |
1179 compiler.enterTrees(roots); |
1163 } |
1180 } |
1164 |
1181 |
1165 /** Run a processing round. */ |
1182 /** Run a processing round. */ |
1166 void run(boolean lastRound, boolean errorStatus) { |
1183 void run(boolean lastRound, boolean errorStatus) { |
1167 printRoundInfo(lastRound); |
1184 printRoundInfo(lastRound); |
1177 errorStatus, |
1194 errorStatus, |
1178 emptyRootElements, |
1195 emptyRootElements, |
1179 JavacProcessingEnvironment.this); |
1196 JavacProcessingEnvironment.this); |
1180 discoveredProcs.iterator().runContributingProcs(renv); |
1197 discoveredProcs.iterator().runContributingProcs(renv); |
1181 } else { |
1198 } else { |
1182 discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles); |
1199 discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles, moduleInfoFiles); |
1183 } |
1200 } |
1184 } catch (Throwable t) { |
1201 } catch (Throwable t) { |
1185 // we're specifically expecting Abort here, but if any Throwable |
1202 // we're specifically expecting Abort here, but if any Throwable |
1186 // comes by, we should flush all deferred diagnostics, rather than |
1203 // comes by, we should flush all deferred diagnostics, rather than |
1187 // drop them on the ground. |
1204 // drop them on the ground. |
1623 * Convert import-style string for supported annotations into a |
1656 * Convert import-style string for supported annotations into a |
1624 * regex matching that string. If the string is not a valid |
1657 * regex matching that string. If the string is not a valid |
1625 * import-style string, return a regex that won't match anything. |
1658 * import-style string, return a regex that won't match anything. |
1626 */ |
1659 */ |
1627 private static Pattern importStringToPattern(String s, Processor p, Log log) { |
1660 private static Pattern importStringToPattern(String s, Processor p, Log log) { |
1628 if (MatchingUtils.isValidImportString(s)) { |
1661 String module; |
1629 return MatchingUtils.validImportStringToPattern(s); |
1662 String pkg; |
|
1663 int slash = s.indexOf('/'); |
|
1664 if (slash == (-1)) { |
|
1665 if (s.equals("*")) { |
|
1666 return MatchingUtils.validImportStringToPattern(s); |
|
1667 } |
|
1668 module = ".*/"; |
|
1669 pkg = s; |
|
1670 } else { |
|
1671 module = Pattern.quote(s.substring(0, slash + 1)); |
|
1672 pkg = s.substring(slash + 1); |
|
1673 } |
|
1674 if (MatchingUtils.isValidImportString(pkg)) { |
|
1675 return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg)); |
1630 } else { |
1676 } else { |
1631 log.warning("proc.malformed.supported.string", s, p.getClass().getName()); |
1677 log.warning("proc.malformed.supported.string", s, p.getClass().getName()); |
1632 return noMatches; // won't match any valid identifier |
1678 return noMatches; // won't match any valid identifier |
1633 } |
1679 } |
1634 } |
1680 } |