langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java
changeset 44291 e1b620ac6c98
parent 43368 cabe410a7a5c
child 45504 ea7475564d07
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Tue Mar 14 08:19:41 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Tue Mar 14 10:51:19 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,8 @@
 import com.sun.tools.javac.util.DefinedBy.Api;
 
 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.main.Option;
 
 /**
  * The FilerImplementation class must maintain a number of
@@ -384,6 +386,8 @@
 
     private final Set<String> initialClassNames;
 
+    private final String defaultTargetModule;
+
     JavacFiler(Context context) {
         this.context = context;
         fileManager = context.get(JavaFileManager.class);
@@ -408,6 +412,10 @@
         initialClassNames  = new LinkedHashSet<>();
 
         lint = (Lint.instance(context)).isEnabled(PROCESSING);
+
+        Options options = Options.instance(context);
+
+        defaultTargetModule = options.get(Option.DEFAULT_MODULE_FOR_CREATED_FILES);
     }
 
     @Override @DefinedBy(Api.ANNOTATION_PROCESSING)
@@ -427,29 +435,42 @@
     private Pair<ModuleSymbol, String> checkOrInferModule(CharSequence moduleAndPkg) throws FilerException {
         String moduleAndPkgString = moduleAndPkg.toString();
         int slash = moduleAndPkgString.indexOf('/');
-
-        if (slash != (-1)) {
-            //module name specified:
-            String module = moduleAndPkgString.substring(0, slash);
+        String module;
+        String pkg;
 
-            ModuleSymbol explicitModule = syms.getModule(names.fromString(module));
+        if (slash == (-1)) {
+            //module name not specified:
+            int lastDot = moduleAndPkgString.lastIndexOf('.');
+            String pack = lastDot != (-1) ? moduleAndPkgString.substring(0, lastDot) : "";
+            ModuleSymbol msym = inferModule(pack);
 
-            if (explicitModule == null) {
-                throw new FilerException("Module: " + module + " does not exist.");
+            if (msym != null) {
+                return Pair.of(msym, moduleAndPkgString);
+            }
+
+            if (defaultTargetModule == null) {
+                throw new FilerException("Cannot determine target module.");
             }
 
-            if (!modules.isRootModule(explicitModule)) {
-                throw new FilerException("Cannot write to the given module!");
-            }
-
-            return Pair.of(explicitModule, moduleAndPkgString.substring(slash + 1));
+            module = defaultTargetModule;
+            pkg = moduleAndPkgString;
         } else {
-            if (modules.multiModuleMode) {
-                throw new FilerException("No module to write to specified!");
-            }
+            //module name specified:
+            module = moduleAndPkgString.substring(0, slash);
+            pkg = moduleAndPkgString.substring(slash + 1);
+        }
+
+        ModuleSymbol explicitModule = syms.getModule(names.fromString(module));
 
-            return Pair.of(modules.getDefaultModule(), moduleAndPkgString);
+        if (explicitModule == null) {
+            throw new FilerException("Module: " + module + " does not exist.");
         }
+
+        if (!modules.isRootModule(explicitModule)) {
+            throw new FilerException("Cannot write to the given module.");
+        }
+
+        return Pair.of(explicitModule, pkg);
     }
 
     private JavaFileObject createSourceOrClassFile(ModuleSymbol mod, boolean isSourceFile, String name) throws IOException {
@@ -495,17 +516,13 @@
                                      CharSequence moduleAndPkg,
                                      CharSequence relativeName,
                                      Element... originatingElements) throws IOException {
-        Pair<ModuleSymbol, String> moduleAndPackage = checkOrInferModule(moduleAndPkg);
-        ModuleSymbol msym = moduleAndPackage.fst;
-        String pkg = moduleAndPackage.snd;
+        Tuple3<Location, ModuleSymbol, String> locationModuleAndPackage = checkOrInferModule(location, moduleAndPkg, true);
+        location = locationModuleAndPackage.a;
+        ModuleSymbol msym = locationModuleAndPackage.b;
+        String pkg = locationModuleAndPackage.c;
 
         locationCheck(location);
 
-        if (modules.multiModuleMode) {
-            Assert.checkNonNull(msym);
-            location = this.fileManager.getLocationForModule(location, msym.name.toString());
-        }
-
         String strPkg = pkg.toString();
         if (strPkg.length() > 0)
             checkName(strPkg);
@@ -534,14 +551,9 @@
     public FileObject getResource(JavaFileManager.Location location,
                                   CharSequence moduleAndPkg,
                                   CharSequence relativeName) throws IOException {
-        Pair<ModuleSymbol, String> moduleAndPackage = checkOrInferModule(moduleAndPkg);
-        ModuleSymbol msym = moduleAndPackage.fst;
-        String pkg = moduleAndPackage.snd;
-
-        if (modules.multiModuleMode) {
-            Assert.checkNonNull(msym);
-            location = this.fileManager.getLocationForModule(location, msym.name.toString());
-        }
+        Tuple3<Location, ModuleSymbol, String> locationModuleAndPackage = checkOrInferModule(location, moduleAndPkg, false);
+        location = locationModuleAndPackage.a;
+        String pkg = locationModuleAndPackage.c;
 
         if (pkg.length() > 0)
             checkName(pkg);
@@ -578,6 +590,99 @@
         return new FilerInputFileObject(fileObject);
     }
 
+    private Tuple3<JavaFileManager.Location, ModuleSymbol, String> checkOrInferModule(JavaFileManager.Location location,
+                                                           CharSequence moduleAndPkg,
+                                                           boolean write) throws IOException {
+        String moduleAndPkgString = moduleAndPkg.toString();
+        int slash = moduleAndPkgString.indexOf('/');
+        boolean multiModuleLocation = location.isModuleOrientedLocation() ||
+                                      (modules.multiModuleMode && location.isOutputLocation());
+        String module;
+        String pkg;
+
+        if (slash == (-1)) {
+            //module name not specified:
+            if (!multiModuleLocation) {
+                //package oriented location:
+                return new Tuple3<>(location, modules.getDefaultModule(), moduleAndPkgString);
+            }
+
+            if (location.isOutputLocation()) {
+                ModuleSymbol msym = inferModule(moduleAndPkgString);
+
+                if (msym != null) {
+                    Location moduleLoc =
+                            fileManager.getLocationForModule(location, msym.name.toString());
+                    return new Tuple3<>(moduleLoc, msym, moduleAndPkgString);
+                }
+            }
+
+            if (defaultTargetModule == null) {
+                throw new FilerException("No module specified and the location is either " +
+                                         "a module-oriented location, or a multi-module " +
+                                         "output location.");
+            }
+
+            module = defaultTargetModule;
+            pkg = moduleAndPkgString;
+        } else {
+            //module name specified:
+            module = moduleAndPkgString.substring(0, slash);
+            pkg = moduleAndPkgString.substring(slash + 1);
+        }
+
+        if (multiModuleLocation) {
+            ModuleSymbol explicitModule = syms.getModule(names.fromString(module));
+
+            if (explicitModule == null) {
+                throw new FilerException("Module: " + module + " does not exist.");
+            }
+
+            if (write && !modules.isRootModule(explicitModule)) {
+                throw new FilerException("Cannot write to the given module.");
+            }
+
+            Location moduleLoc = fileManager.getLocationForModule(location, module);
+
+            return new Tuple3<>(moduleLoc, explicitModule, pkg);
+        } else {
+            throw new FilerException("Module specified but the location is neither " +
+                                     "a module-oriented location, nor a multi-module " +
+                                     "output location.");
+        }
+    }
+
+    static final class Tuple3<A, B, C> {
+        final A a;
+        final B b;
+        final C c;
+
+        public Tuple3(A a, B b, C c) {
+            this.a = a;
+            this.b = b;
+            this.c = c;
+        }
+    }
+
+    private ModuleSymbol inferModule(String pkg) {
+        if (modules.getDefaultModule() == syms.noModule)
+            return modules.getDefaultModule();
+
+        Set<ModuleSymbol> rootModules = modules.getRootModules();
+
+        if (rootModules.size() == 1) {
+            return rootModules.iterator().next();
+        }
+
+        PackageSymbol pack = elementUtils.getPackageElement(pkg);
+
+        if (pack != null && pack.modle != syms.unnamedModule) {
+            return pack.modle;
+        }
+
+        return null;
+    }
+
     private void checkName(String name) throws FilerException {
         checkName(name, false);
     }