1 /*
2  * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 6380018 6392177 6993311 8193462
27  * @summary Test the ability to create and process package-info.java files
28  * @author  Joseph D. Darcy
29  * @library /tools/javac/lib
30  * @modules java.compiler
31  *          jdk.compiler
32  * @build   JavacTestingAbstractProcessor
33  * @compile TestPackageInfo.java
34  * @compile -processor TestPackageInfo -proc:only foo/bar/package-info.java TestPackageInfo.java
35  */
36 
37 import java.util.Set;
38 import java.util.Map;
39 import javax.annotation.processing.*;
40 import javax.lang.model.SourceVersion;
41 import static javax.lang.model.SourceVersion.*;
42 import javax.lang.model.element.*;
43 import javax.lang.model.util.*;
44 import static javax.lang.model.util.ElementFilter.*;
45 import static javax.tools.Diagnostic.Kind.*;
46 import static javax.tools.StandardLocation.*;
47 
48 import java.io.*;
49 
50 /**
51  * Test the ability to process annotations on package-info.java files:
52  * 1) Visibility of package-info files from the command line
53  * 2) Visibility of generated package-info.java source files
54  */
55 public class TestPackageInfo extends JavacTestingAbstractProcessor {
56     private int round = 0;
57 
process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)58     public boolean process(Set<? extends TypeElement> annotations,
59                            RoundEnvironment roundEnv) {
60         round++;
61 
62         // Verify annotations are as expected
63         Set<TypeElement> expectedAnnotations =
64             Set.of(eltUtils.getTypeElement("java.lang.Deprecated"));
65 
66         if (!roundEnv.processingOver()) {
67             System.out.println("\nRound " + round);
68             int rootElementSize = roundEnv.getRootElements().size();
69 
70             for(Element elt : roundEnv.getRootElements()) {
71                 System.out.printf("%nElement %s\tkind: %s%n", elt.getSimpleName(), elt.getKind());
72                 eltUtils.printElements(new PrintWriter(System.out), elt);
73             }
74 
75             switch (round) {
76             case 1:
77                 if (rootElementSize != 2)
78                     throw new RuntimeException("Unexpected root element size " + rootElementSize);
79 
80                 // Note that foo.bar.FuBar, an element of package
81                 // foo.bar, contains @Deprecated which should *not* be
82                 // included in the set of annotations to process
83                 if (!expectedAnnotations.equals(annotations)) {
84                     throw new RuntimeException("Unexpected annotations: " + annotations);
85                 }
86 
87                 try {
88                     try {
89                         filer.createClassFile("package-info");
90                         throw new RuntimeException("Created class file for \"package-info\".");
91                     } catch(FilerException fe) {}
92 
93                     try(PrintWriter pw =
94                         new PrintWriter(filer.createSourceFile("foo.package-info").openWriter())) {
95                         pw.println("@Deprecated");
96                         pw.println("package foo;");
97                     }
98 
99                     attemptReopening("foo.package-info");
100                     attemptReopening("TestPackageInfo");      // Initial input
101                     attemptReopening("foo.bar.package-info"); // Initial input
102                 } catch(IOException ioe) {
103                     throw new RuntimeException(ioe);
104                 }
105                 break;
106 
107             case 2:
108                 // Expect foo.package-info
109                 Set<Element> expectedElement = Set.of(eltUtils.getPackageElement("foo"));
110                 if (!expectedElement.equals(roundEnv.getRootElements()))
111                     throw new RuntimeException("Unexpected root element set " + roundEnv.getRootElements());
112 
113                 if (!expectedAnnotations.equals(annotations)) {
114                     throw new RuntimeException("Unexpected annotations: " + annotations);
115                 }
116 
117                 attemptReopening("foo.package-info");
118 
119                 break;
120 
121             default:
122                 throw new RuntimeException("Unexpected round number " + round);
123             }
124         }
125         return false;
126     }
127 
attemptReopening(String name)128     private void attemptReopening(String name) {
129         final String SHOULD_NOT_REACH = "Should not reach: created ";
130         try {
131             try {
132                 filer.createSourceFile(name);
133                 throw new AssertionError(SHOULD_NOT_REACH + name + ".java");
134             } catch (FilerException fe) {
135                 ; // Expected
136             }
137 
138             try {
139                 filer.createClassFile(name);
140                 throw new AssertionError(SHOULD_NOT_REACH + name + ".class");
141             } catch (FilerException fe) {
142                 ; // Expected
143             }
144         } catch (IOException ioe) {
145             throw new RuntimeException(ioe);
146         }
147 
148     }
149 }
150