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