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