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