1 /*
   2  * Copyright (c) 2011, 2016, 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 7021183 7025809
  27  * @summary 269: assertion failure getting enclosing element of an undefined name
  28  * @modules jdk.compiler/com.sun.tools.javac.code:+open
  29  *          jdk.compiler/com.sun.tools.javac.file
  30  *          jdk.compiler/com.sun.tools.javac.main
  31  *          jdk.compiler/com.sun.tools.javac.model
  32  *          jdk.compiler/com.sun.tools.javac.util
  33  */
  34 
  35 import java.lang.reflect.Field;
  36 
  37 import javax.lang.model.element.Element;
  38 import javax.lang.model.element.ExecutableElement;
  39 import javax.lang.model.element.ModuleElement;
  40 import javax.lang.model.element.PackageElement;
  41 import javax.lang.model.element.TypeElement;
  42 import javax.lang.model.element.TypeParameterElement;
  43 import javax.lang.model.element.UnknownElementException;
  44 import javax.lang.model.element.VariableElement;
  45 import javax.lang.model.type.TypeMirror;
  46 import javax.lang.model.type.UnknownTypeException;
  47 import javax.lang.model.util.*;
  48 
  49 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  50 import com.sun.tools.javac.code.Symtab;
  51 import com.sun.tools.javac.file.JavacFileManager;
  52 import com.sun.tools.javac.main.JavaCompiler;
  53 import com.sun.tools.javac.model.JavacTypes;
  54 import com.sun.tools.javac.util.Context;
  55 
  56 /**
  57  * Scan javac Symtab looking for TypeMirrors and Elements, and ensure that
  58  * no exceptions are thrown when used with javax.lang.model visitors.
  59  *
  60  */
  61 public class TestSymtabItems {
  62     public static void main(String... args) throws Exception {
  63         new TestSymtabItems().run();
  64     }
  65 
  66     void run() throws Exception {
  67         Context c = new Context();
  68         JavacFileManager.preRegister(c);
  69         Symtab syms = Symtab.instance(c);
  70         JavacTypes types = JavacTypes.instance(c);
  71         JavaCompiler.instance(c);  // will init ClassReader.sourceCompleter
  72 
  73 //        print("noSymbol", syms.noSymbol);
  74 //        print("errSymbol", syms.errSymbol);
  75 //        print("unknownSymbol", syms.unknownSymbol);
  76 //        print("botType", syms.botType);
  77 //        print("errType", syms.errType);
  78 //        print("unknownType", syms.unknownType);
  79 
  80         for (Field f: Symtab.class.getDeclaredFields()) {
  81 //            System.err.println(f.getType() + " " + f.getName());
  82 
  83             // Temporarily ignore methodHandle and transientMethodHandle
  84             // during API evolution
  85             if (f.getName().toLowerCase().contains("methodhandle"))
  86                 continue;
  87 
  88             //both noModule and unnamedModule claim the unnamed package, ignore noModule for now:
  89             if (f.getName().equals("noModule"))
  90                 continue;
  91 
  92             f.setAccessible(true);
  93             Class<?> ft = f.getType();
  94             if (TypeMirror.class.isAssignableFrom(ft))
  95                 print(f.getName(), (TypeMirror) f.get(syms), types);
  96             else if(Element.class.isAssignableFrom(ft))
  97                 print(f.getName(), (Element) f.get(syms));
  98         }
  99 
 100         if (errors > 0)
 101             throw new Exception(errors + " errors occurred");
 102     }
 103 
 104     void print(String label, Element e) {
 105         ElemPrinter ep = new ElemPrinter();
 106         System.err.println("Test " + label);
 107         ep.visit(e);
 108         System.err.println();
 109     }
 110 
 111     void print(String label, TypeMirror t, Types types) {
 112         TypePrinter tp = new TypePrinter();
 113         System.err.println("Test " + label);
 114         tp.visit(t, types);
 115         System.err.println();
 116     }
 117 
 118     void error(String msg) {
 119         System.err.println("Error: " + msg);
 120         errors++;
 121     }
 122 
 123     int errors;
 124 
 125     class ElemPrinter extends ElementScanner9<Void, Void> {
 126         @Override
 127         public Void visitModule(ModuleElement e, Void p) {
 128             show("module", e);
 129             indent(+1);
 130             super.visitModule(e, p);
 131             indent(-1);
 132             return null;
 133         }
 134 
 135         @Override
 136         public Void visitPackage(PackageElement e, Void p) {
 137             show("package", e);
 138             indent(+1);
 139             super.visitPackage(e, p);
 140             indent(-1);
 141             return null;
 142         }
 143 
 144         @Override
 145         public Void visitType(TypeElement e, Void p) {
 146             show("type", e);
 147             indent(+1);
 148             super.visitType(e, p);
 149             indent(-1);
 150             return null;
 151         }
 152 
 153         @Override
 154         public Void visitVariable(VariableElement e, Void p) {
 155             show("variable", e);
 156             indent(+1);
 157             super.visitVariable(e, p);
 158             indent(-1);
 159             return null;
 160         }
 161 
 162         @Override
 163         public Void visitExecutable(ExecutableElement e, Void p) {
 164             show("executable", e);
 165             indent(+1);
 166             super.visitExecutable(e, p);
 167             indent(-1);
 168             return null;
 169         }
 170 
 171         @Override
 172         public Void visitTypeParameter(TypeParameterElement e, Void p) {
 173             show("type parameter", e);
 174             indent(+1);
 175             super.visitTypeParameter(e, p);
 176             indent(-1);
 177             return null;
 178         }
 179 
 180         @Override
 181         public Void visitUnknown(Element e, Void p) {
 182             show("unknown", e);
 183             indent(+1);
 184             try {
 185                 super.visitUnknown(e, p);
 186             } catch (UnknownElementException ex) {
 187                 System.err.println("caught " + ex);
 188             }
 189             indent(-1);
 190             return null;
 191         }
 192 
 193         void indent(int i) {
 194             indent += i;
 195         }
 196 
 197         String sp(int w) {
 198             StringBuilder sb = new StringBuilder();
 199             for (int i = 0; i < w; i++)
 200                 sb.append("    ");
 201             return sb.toString();
 202         }
 203 
 204         void show(String label, Element e) {
 205             System.err.println(sp(indent) + label
 206                     + ": mods:" + e.getModifiers()
 207                     + " " + e.getSimpleName()
 208                     + ", kind: " + e.getKind()
 209                     + ", type: " + e.asType()
 210                     + ", encl: " + e.getEnclosingElement());
 211 
 212             // The following checks help establish why NPE might occur when trying to scan children
 213             if (e instanceof ClassSymbol) {
 214                 ClassSymbol csym = (ClassSymbol) e;
 215                 if (csym.members_field == null)
 216                     error("members_field is null");
 217                 if (csym.type == null)
 218                     System.err.println("type is null");
 219             }
 220         }
 221 
 222         int indent;
 223     };
 224 
 225     class TypePrinter extends SimpleTypeVisitor9<Void, Types> {
 226         @Override
 227         public Void defaultAction(TypeMirror m, Types types) {
 228             System.err.println(m.getKind() + " " + m + " " + types.asElement(m));
 229             return null;
 230         }
 231 
 232         @Override
 233         public Void visitUnknown(TypeMirror t, Types types) {
 234             try {
 235                 return super.visitUnknown(t, types);
 236             } catch (UnknownTypeException ex) {
 237                 System.err.println("caught " + ex);
 238                 return null;
 239             }
 240         }
 241     };
 242 }