8193462: Fix Filer handling of package-info initial elements
authordarcy
Wed, 18 Jul 2018 00:23:06 -0700
changeset 51177 ae39ec0b0502
parent 51176 0d02393d9115
child 51178 416a76fe8067
8193462: Fix Filer handling of package-info initial elements Reviewed-by: vromero
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java
test/langtools/tools/javac/processing/filer/TestPackageInfo.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jul 18 00:16:37 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jul 18 00:23:06 2018 -0700
@@ -379,6 +379,7 @@
             c.completer = Completer.NULL_COMPLETER;
                 c.members_field = WriteableScope.create(c);
                 tree.packge.package_info = c;
+                tree.packge.sourcefile = tree.sourcefile;
             }
             classEnter(tree.defs, topEnv);
             if (addEnv) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Wed Jul 18 00:16:37 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Wed Jul 18 00:23:06 2018 -0700
@@ -53,6 +53,7 @@
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.Modules;
 import com.sun.tools.javac.model.JavacElements;
@@ -717,7 +718,7 @@
         boolean alreadySeen = aggregateGeneratedSourceNames.contains(Pair.of(mod, typename)) ||
                               aggregateGeneratedClassNames.contains(Pair.of(mod, typename)) ||
                               initialClassNames.contains(typename) ||
-                              (existing != null && initialInputs.contains(existing.sourcefile));
+                              containedInInitialInputs(typename);
         if (alreadySeen) {
             if (lint)
                 log.warning(Warnings.ProcTypeRecreate(typename));
@@ -731,6 +732,22 @@
         }
     }
 
+    private boolean containedInInitialInputs(String typename) {
+        // Name could be a type name or the name of a package-info file
+        JavaFileObject sourceFile = null;
+
+        ClassSymbol existingClass = elementUtils.getTypeElement(typename);
+        if (existingClass != null) {
+            sourceFile = existingClass.sourcefile;
+        } else if (typename.endsWith(".package-info")) {
+            String targetName = typename.substring(0, typename.length() - ".package-info".length());
+            PackageSymbol existingPackage = elementUtils.getPackageElement(targetName);
+            if (existingPackage != null)
+                sourceFile = existingPackage.sourcefile;
+        }
+        return (sourceFile == null) ? false : initialInputs.contains(sourceFile);
+    }
+
     /**
      * Check to see if the file has already been opened; if so, throw
      * an exception, otherwise add it to the set of files.
--- a/test/langtools/tools/javac/processing/filer/TestPackageInfo.java	Wed Jul 18 00:16:37 2018 -0700
+++ b/test/langtools/tools/javac/processing/filer/TestPackageInfo.java	Wed Jul 18 00:23:06 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6380018 6392177 6993311
+ * @bug 6380018 6392177 6993311 8193462
  * @summary Test the ability to create and process package-info.java files
  * @author  Joseph D. Darcy
  * @library /tools/javac/lib
@@ -35,7 +35,6 @@
  */
 
 import java.util.Set;
-import java.util.HashSet;
 import java.util.Map;
 import javax.annotation.processing.*;
 import javax.lang.model.SourceVersion;
@@ -61,8 +60,8 @@
         round++;
 
         // Verify annotations are as expected
-        Set<TypeElement> expectedAnnotations = new HashSet<TypeElement>();
-        expectedAnnotations.add(eltUtils.getTypeElement("java.lang.Deprecated"));
+        Set<TypeElement> expectedAnnotations =
+            Set.of(eltUtils.getTypeElement("java.lang.Deprecated"));
 
         if (!roundEnv.processingOver()) {
             System.out.println("\nRound " + round);
@@ -91,11 +90,15 @@
                         throw new RuntimeException("Created class file for \"package-info\".");
                     } catch(FilerException fe) {}
 
-                    PrintWriter pw = new PrintWriter(filer.createSourceFile("foo.package-info").openWriter());
-                    pw.println("@Deprecated");
-                    pw.println("package foo;");
-                    pw.close();
+                    try(PrintWriter pw =
+                        new PrintWriter(filer.createSourceFile("foo.package-info").openWriter())) {
+                        pw.println("@Deprecated");
+                        pw.println("package foo;");
+                    }
 
+                    attemptReopening("foo.package-info");
+                    attemptReopening("TestPackageInfo");      // Initial input
+                    attemptReopening("foo.bar.package-info"); // Initial input
                 } catch(IOException ioe) {
                     throw new RuntimeException(ioe);
                 }
@@ -103,9 +106,7 @@
 
             case 2:
                 // Expect foo.package-info
-
-                Set<Element> expectedElement = new HashSet<Element>();
-                expectedElement.add(eltUtils.getPackageElement("foo"));
+                Set<Element> expectedElement = Set.of(eltUtils.getPackageElement("foo"));
                 if (!expectedElement.equals(roundEnv.getRootElements()))
                     throw new RuntimeException("Unexpected root element set " + roundEnv.getRootElements());
 
@@ -113,6 +114,8 @@
                     throw new RuntimeException("Unexpected annotations: " + annotations);
                 }
 
+                attemptReopening("foo.package-info");
+
                 break;
 
             default:
@@ -121,4 +124,26 @@
         }
         return false;
     }
+
+    private void attemptReopening(String name) {
+        final String SHOULD_NOT_REACH = "Should not reach: created ";
+        try {
+            try {
+                filer.createSourceFile(name);
+                throw new AssertionError(SHOULD_NOT_REACH + name + ".java");
+            } catch (FilerException fe) {
+                ; // Expected
+            }
+
+            try {
+                filer.createClassFile(name);
+                throw new AssertionError(SHOULD_NOT_REACH + name + ".class");
+            } catch (FilerException fe) {
+                ; // Expected
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+
+    }
 }