diff -r 058fc03646d9 -r 050370edaade langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Dec 13 10:48:18 2016 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Dec 13 10:49:28 2016 +0100 @@ -34,6 +34,7 @@ import java.net.URL; import java.nio.file.Path; import java.util.*; +import java.util.Map.Entry; import java.util.regex.*; import java.util.stream.Collectors; @@ -827,12 +828,14 @@ private void discoverAndRunProcs(Set annotationsPresent, List topLevelClasses, - List packageInfoFiles) { + List packageInfoFiles, + List moduleInfoFiles) { Map unmatchedAnnotations = new HashMap<>(annotationsPresent.size()); for(TypeElement a : annotationsPresent) { - unmatchedAnnotations.put(a.getQualifiedName().toString(), - a); + ModuleElement mod = elementUtils.getModuleOf(a); + unmatchedAnnotations.put((mod != null ? mod.getSimpleName() + "/" : "") + a.getQualifiedName().toString(), + a); } // Give "*" processors a chance to match @@ -849,6 +852,7 @@ Set rootElements = new LinkedHashSet<>(); rootElements.addAll(topLevelClasses); rootElements.addAll(packageInfoFiles); + rootElements.addAll(moduleInfoFiles); rootElements = Collections.unmodifiableSet(rootElements); RoundEnvironment renv = new JavacRoundEnvironment(false, @@ -986,7 +990,7 @@ /** The trees that need to be cleaned - includes roots and implicitly parsed trees. */ Set treesToClean; /** The classes to be compiler that have were generated. */ - Map genClassFiles; + Map> genClassFiles; /** The set of annotations to be processed this round. */ Set annotationsPresent; @@ -994,6 +998,8 @@ List topLevelClasses; /** The set of package-info files to be processed this round. */ List packageInfoFiles; + /** The set of module-info files to be processed this round. */ + List moduleInfoFiles; /** Create a round (common code). */ private Round(int number, Set treesToClean, @@ -1011,6 +1017,7 @@ // the following will be populated as needed topLevelClasses = List.nil(); packageInfoFiles = List.nil(); + moduleInfoFiles = List.nil(); this.treesToClean = treesToClean; } @@ -1031,12 +1038,14 @@ packageInfoFiles = getPackageInfoFiles(roots); + moduleInfoFiles = getModuleInfoFiles(roots); + findAnnotationsPresent(); } /** Create a new round. */ private Round(Round prev, - Set newSourceFiles, Map newClassFiles) { + Set newSourceFiles, Map> newClassFiles) { this(prev.number+1, prev.treesToClean, null); prev.newRound(); this.genClassFiles = prev.genClassFiles; @@ -1048,9 +1057,13 @@ if (unrecoverableError()) return; + roots = compiler.initModules(roots); + enterClassFiles(genClassFiles); List newClasses = enterClassFiles(newClassFiles); - genClassFiles.putAll(newClassFiles); + for (Entry> moduleAndClassFiles : newClassFiles.entrySet()) { + genClassFiles.computeIfAbsent(moduleAndClassFiles.getKey(), m -> new LinkedHashMap<>()).putAll(moduleAndClassFiles.getValue()); + } enterTrees(roots); if (unrecoverableError()) @@ -1064,11 +1077,13 @@ getPackageInfoFiles(parsedFiles), getPackageInfoFilesFromClasses(newClasses)); + moduleInfoFiles = List.nil(); //module-info cannot be generated + findAnnotationsPresent(); } /** Create the next round to be used. */ - Round next(Set newSourceFiles, Map newClassFiles) { + Round next(Set newSourceFiles, Map> newClassFiles) { return new Round(this, newSourceFiles, newClassFiles); } @@ -1121,45 +1136,47 @@ annotationComputer.scan(classSym, annotationsPresent); for (PackageSymbol pkgSym : packageInfoFiles) annotationComputer.scan(pkgSym, annotationsPresent); + for (ModuleSymbol mdlSym : moduleInfoFiles) + annotationComputer.scan(mdlSym, annotationsPresent); } /** Enter a set of generated class files. */ - private List enterClassFiles(Map classFiles) { + private List enterClassFiles(Map> modulesAndClassFiles) { List list = List.nil(); - for (Map.Entry entry : classFiles.entrySet()) { - Name name = names.fromString(entry.getKey()); - JavaFileObject file = entry.getValue(); - if (file.getKind() != JavaFileObject.Kind.CLASS) - throw new AssertionError(file); - ClassSymbol cs; - // TODO: for now, we assume that generated code is in a default module; - // in time, we need a way to be able to specify the module for generated code - if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { - Name packageName = Convert.packagePart(name); - PackageSymbol p = symtab.enterPackage(defaultModule, packageName); - if (p.package_info == null) - p.package_info = symtab.enterClass(defaultModule, Convert.shortName(name), p); - cs = p.package_info; - cs.reset(); - if (cs.classfile == null) + for (Entry> moduleAndClassFiles : modulesAndClassFiles.entrySet()) { + for (Map.Entry entry : moduleAndClassFiles.getValue().entrySet()) { + Name name = names.fromString(entry.getKey()); + JavaFileObject file = entry.getValue(); + if (file.getKind() != JavaFileObject.Kind.CLASS) + throw new AssertionError(file); + ClassSymbol cs; + if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { + Name packageName = Convert.packagePart(name); + PackageSymbol p = symtab.enterPackage(moduleAndClassFiles.getKey(), packageName); + if (p.package_info == null) + p.package_info = symtab.enterClass(moduleAndClassFiles.getKey(), Convert.shortName(name), p); + cs = p.package_info; + cs.reset(); + if (cs.classfile == null) + cs.classfile = file; + cs.completer = initialCompleter; + } else { + cs = symtab.enterClass(moduleAndClassFiles.getKey(), name); + cs.reset(); cs.classfile = file; - cs.completer = initialCompleter; - } else { - cs = symtab.enterClass(defaultModule, name); - cs.reset(); - cs.classfile = file; - cs.completer = initialCompleter; - cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore + cs.completer = initialCompleter; + cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore + } + list = list.prepend(cs); } - list = list.prepend(cs); } return list.reverse(); } /** Enter a set of syntax trees. */ private void enterTrees(List roots) { - compiler.enterTrees(compiler.initModules(roots)); + compiler.enterTrees(roots); } /** Run a processing round. */ @@ -1179,7 +1196,7 @@ JavacProcessingEnvironment.this); discoveredProcs.iterator().runContributingProcs(renv); } else { - discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles); + discoverAndRunProcs(annotationsPresent, topLevelClasses, packageInfoFiles, moduleInfoFiles); } } catch (Throwable t) { // we're specifically expecting Abort here, but if any Throwable @@ -1418,6 +1435,18 @@ return packages.reverse(); } + private List getModuleInfoFiles(List units) { + List modules = List.nil(); + for (JCCompilationUnit unit : units) { + if (isModuleInfo(unit.sourcefile, JavaFileObject.Kind.SOURCE) && + unit.defs.nonEmpty() && + unit.defs.head.hasTag(Tag.MODULEDEF)) { + modules = modules.prepend(unit.modle); + } + } + return modules.reverse(); + } + // avoid unchecked warning from use of varargs private static List join(List list1, List list2) { return list1.appendList(list2); @@ -1431,6 +1460,10 @@ return isPkgInfo(sym.classfile, JavaFileObject.Kind.CLASS) && (sym.packge().package_info == sym); } + private boolean isModuleInfo(JavaFileObject fo, JavaFileObject.Kind kind) { + return fo.isNameCompatible("module-info", kind); + } + /* * Called retroactively to determine if a class loader was required, * after we have failed to create one. @@ -1625,8 +1658,21 @@ * import-style string, return a regex that won't match anything. */ private static Pattern importStringToPattern(String s, Processor p, Log log) { - if (MatchingUtils.isValidImportString(s)) { - return MatchingUtils.validImportStringToPattern(s); + String module; + String pkg; + int slash = s.indexOf('/'); + if (slash == (-1)) { + if (s.equals("*")) { + return MatchingUtils.validImportStringToPattern(s); + } + module = ".*/"; + pkg = s; + } else { + module = Pattern.quote(s.substring(0, slash + 1)); + pkg = s.substring(slash + 1); + } + if (MatchingUtils.isValidImportString(pkg)) { + return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg)); } else { log.warning("proc.malformed.supported.string", s, p.getClass().getName()); return noMatches; // won't match any valid identifier