--- old/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java 2017-02-08 11:44:10.888660164 -0800 +++ new/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java 2017-02-08 11:44:10.748659112 -0800 @@ -145,7 +145,7 @@ public final boolean multiModuleMode; - private final String moduleOverride; + private final String legacyModuleOverride; private final Name java_se; private final Name java_; @@ -192,7 +192,7 @@ lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); - moduleOverride = options.get(Option.XMODULE); + legacyModuleOverride = options.get(Option.XMODULE); multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH); ClassWriter classWriter = ClassWriter.instance(context); @@ -366,9 +366,26 @@ JavaFileObject prev = log.useSource(tree.sourcefile); try { - Location locn = getModuleLocation(tree); - if (locn != null) { - Name name = names.fromString(fileManager.inferModuleName(locn)); + Location msplocn = getModuleLocation(tree); + Location plocn = fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) ? + fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH, + tree.sourcefile, getPackageName(tree)) : + null; + + if (plocn != null) { + Name name = names.fromString(fileManager.inferModuleName(plocn)); + ModuleSymbol msym = moduleFinder.findModule(name); + tree.modle = msym; + rootModules.add(msym); + + if (msplocn != null) { + Name mspname = names.fromString(fileManager.inferModuleName(msplocn)); + if (name != mspname) { + log.error(tree.pos(), Errors.FilePatchedAndMsp(name, mspname)); + } + } + } else if (msplocn != null) { + Name name = names.fromString(fileManager.inferModuleName(msplocn)); ModuleSymbol msym; JCModuleDecl decl = tree.getModuleDecl(); if (decl != null) { @@ -383,7 +400,7 @@ msym = syms.enterModule(name); } if (msym.sourceLocation == null) { - msym.sourceLocation = locn; + msym.sourceLocation = msplocn; if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { msym.classLocation = fileManager.getLocationForModule( StandardLocation.CLASS_OUTPUT, msym.name.toString()); @@ -414,7 +431,9 @@ } defaultModule = syms.unnamedModule; } else { + ModuleSymbol module = null; if (defaultModule == null) { + String moduleOverride = singleModuleOverride(trees); switch (rootModules.size()) { case 0: defaultModule = moduleFinder.findSingleModule(); @@ -422,38 +441,49 @@ if (moduleOverride != null) { checkNoAllModulePath(); defaultModule = moduleFinder.findModule(names.fromString(moduleOverride)); - defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; + if (legacyModuleOverride != null) { + defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; + } + defaultModule.patchOutputLocation = StandardLocation.CLASS_OUTPUT; } else { // Question: why not do findAllModules and initVisiblePackages here? // i.e. body of unnamedModuleCompleter defaultModule.completer = getUnnamedModuleCompleter(); + defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; defaultModule.classLocation = StandardLocation.CLASS_PATH; } } else { - checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleClasspath); + checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleClassoutput); checkNoAllModulePath(); defaultModule.complete(); // Question: why not do completeModule here? defaultModule.completer = sym -> completeModule((ModuleSymbol) sym); + defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; } rootModules.add(defaultModule); break; case 1: - checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleSourcepath); + checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleSourcepath); checkNoAllModulePath(); defaultModule = rootModules.iterator().next(); + defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; defaultModule.classLocation = StandardLocation.CLASS_OUTPUT; break; default: Assert.error("too many modules"); } - defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; } else if (rootModules.size() == 1 && defaultModule == rootModules.iterator().next()) { defaultModule.complete(); defaultModule.completer = sym -> completeModule((ModuleSymbol) sym); } else { Assert.check(rootModules.isEmpty()); - rootModules.add(defaultModule); + String moduleOverride = singleModuleOverride(trees); + if (moduleOverride != null) { + module = moduleFinder.findModule(names.fromString(moduleOverride)); + } else { + module = defaultModule; + } + rootModules.add(module); } if (defaultModule != syms.unnamedModule) { @@ -461,12 +491,60 @@ syms.unnamedModule.classLocation = StandardLocation.CLASS_PATH; } + if (module == null) { + module = defaultModule; + } + for (JCCompilationUnit tree: trees) { - tree.modle = defaultModule; + tree.modle = module; } } } + private String singleModuleOverride(List trees) { + if (!fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) { + return legacyModuleOverride; + } + + Set override = new LinkedHashSet<>(); + for (JCCompilationUnit tree : trees) { + JavaFileObject fo = tree.sourcefile; + + try { + Location loc = + fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH, + fo, getPackageName(tree)); + + if (loc != null) { + try { + override.add(fileManager.inferModuleName(loc)); + } catch (IOException ex) { + throw new Error(ex); + } + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + switch (override.size()) { + case 0: return legacyModuleOverride; + case 1: return override.iterator().next(); + default: + log.error(Errors.TooManyPatchedModules(override)); + return null; + } + } + + private String getPackageName(JCCompilationUnit tree) { + if (tree.getModuleDecl() != null) { + return null; + } else { + JCPackageDecl pkg = tree.getPackage(); + return (pkg == null) ? "" : TreeInfo.fullName(pkg.pid).toString(); + } + } + /** * Determine the location for the module on the module source path * or source output directory which contains a given CompilationUnit. @@ -478,32 +556,23 @@ * @throws IOException if there is a problem while searching for the module. */ private Location getModuleLocation(JCCompilationUnit tree) throws IOException { - Name pkgName; - if (tree.getModuleDecl() != null) { - pkgName = null; - } else { - JCPackageDecl pkg = tree.getPackage(); - pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid); - } - + String pkgName = getPackageName(tree); JavaFileObject fo = tree.sourcefile; - // For now, just check module source path. - // We may want to check source path as well. Location loc = fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, - fo, (pkgName == null) ? null : pkgName.toString()); + fo, (pkgName == null) ? null : pkgName); if (loc == null) { Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ? StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT; loc = fileManager.getLocationForModule(sourceOutput, - fo, (pkgName == null) ? null : pkgName.toString()); + fo, (pkgName == null) ? null : pkgName); } return loc; } - private void checkSpecifiedModule(List trees, JCDiagnostic.Error error) { + private void checkSpecifiedModule(List trees, String moduleOverride, JCDiagnostic.Error error) { if (moduleOverride != null) { JavaFileObject prev = log.useSource(trees.head.sourcefile); try { @@ -1594,8 +1663,8 @@ } public void newRound() { - rootModules = null; allModules = null; + rootModules = null; warnedMissing.clear(); } }