1 /*
2  * Copyright (c) 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 8202141
27  * @summary Verify that .class synthetic Symbols are not duplicated.
28  * @library /tools/javac/lib
29  * @modules jdk.compiler/com.sun.tools.javac.api
30  *          jdk.compiler/com.sun.tools.javac.code
31  *          jdk.compiler/com.sun.tools.javac.tree
32  *          jdk.compiler/com.sun.tools.javac.util
33  * @build combo.ComboTestHelper
34  * @run main ClassFieldDeduplication
35  */
36 
37 import com.sun.source.util.TaskEvent;
38 import com.sun.source.util.TaskListener;
39 import com.sun.tools.javac.code.Symbol;
40 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
41 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
42 import com.sun.tools.javac.tree.TreeScanner;
43 import combo.ComboInstance;
44 import combo.ComboParameter;
45 import combo.ComboTestHelper;
46 
47 public class ClassFieldDeduplication extends ComboInstance<ClassFieldDeduplication> {
48 
49     enum Type implements ComboParameter {
50         OBJECT("Object"),
51         PRIMITIVE("int"),
52         BOXED_PRIMITIVE("Integer"),
53         VOID("void"),
54         BOXED_VOID("Void"),
55         OBJECT_ARRAY("Object[]"),
56         PRIMITIVE_ARRAY("int[]"),
57         BOXED_PRIMITIVE_ARRAY("Integer[]"),
58         BOXED_VOID_ARRAY("Void[]");
59 
60         String type;
61 
Type(String type)62         Type(String type) {
63             this.type = type;
64         }
65 
66         @Override
expand(String optParameter)67         public String expand(String optParameter) {
68             return type;
69         }
70 
71     }
72 
main(String... args)73     public static void main(String... args) throws Exception {
74         new ComboTestHelper<ClassFieldDeduplication>()
75                 .withDimension("TYPE", Type.values())
76                 .run(ClassFieldDeduplication::new);
77     }
78 
79     private static final String TEMPLATE =
80             "class Test { void t() { Object o1 = #{TYPE}.class; Object o2 = #{TYPE}.class; } }";
81 
82     @Override
doWork()83     protected void doWork() throws Throwable {
84         newCompilationTask()
85                 .withSourceFromTemplate(TEMPLATE)
86                 .withListener(new TaskListener() {
87                     JCCompilationUnit cut;
88                         @Override
89                         public void finished(TaskEvent e) {
90                             if (e.getKind() == TaskEvent.Kind.PARSE) {
91                                 if (cut != null)
92                                     throw new AssertionError();
93                                 cut = (JCCompilationUnit) e.getCompilationUnit();
94                             }
95                             if (e.getKind() == TaskEvent.Kind.ANALYZE) {
96                                 cut.accept(new TreeScanner() {
97                                     Symbol s;
98                                     @Override
99                                     public void visitSelect(JCFieldAccess tree) {
100                                         if (tree.name.contentEquals("class")) {
101                                             if (s == null) {
102                                                 s = tree.sym;
103                                             } else if (s != tree.sym) {
104                                                 throw new AssertionError("Duplicated field symbol.");
105                                             }
106                                         }
107                                         super.visitSelect(tree);
108                                     }
109                                 });
110                             }
111                         }
112 
113                 })
114                 .analyze(els -> {});
115     }
116 
117 }
118