7021183: 269: assertion failure getting enclosing element of an undefined name
authorjjg
Tue, 01 Mar 2011 12:00:06 -0800
changeset 8621 ce0bce60cffc
parent 8620 0b04e5235f25
child 8622 4f032629a0fd
7021183: 269: assertion failure getting enclosing element of an undefined name Reviewed-by: mcimadamore
langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
langtools/test/tools/javac/processing/model/TestSymtabItems.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Feb 28 13:42:24 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Tue Mar 01 12:00:06 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 package com.sun.tools.javac.code;
 
 import java.util.*;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.element.ElementVisitor;
 
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
@@ -345,7 +347,12 @@
         target = Target.instance(context);
 
         // Create the unknown type
-        unknownType = new Type(TypeTags.UNKNOWN, null);
+        unknownType = new Type(TypeTags.UNKNOWN, null) {
+            @Override
+            public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+                return v.visitUnknown(this, p);
+            }
+        };
 
         // create the basic builtin symbols
         rootPackage = new PackageSymbol(names.empty, null);
@@ -355,13 +362,20 @@
                     return messages.getLocalizedString("compiler.misc.unnamed.package");
                 }
             };
-        noSymbol = new TypeSymbol(0, names.empty, Type.noType, rootPackage);
+        noSymbol = new TypeSymbol(0, names.empty, Type.noType, rootPackage) {
+            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+                return v.visitUnknown(this, p);
+            }
+        };
         noSymbol.kind = Kinds.NIL;
 
         // create the error symbols
         errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage);
+        errType = new ErrorType(errSymbol, Type.noType);
+
         unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage);
-        errType = new ErrorType(errSymbol, Type.noType);
+        unknownSymbol.members_field = new Scope.ErrorScope(unknownSymbol);
+        unknownSymbol.type = unknownType;
 
         // initialize builtin types
         initType(byteType, "byte", "Byte");
@@ -382,9 +396,11 @@
 
         // VGJ
         boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol);
+        boundClass.members_field = new Scope.ErrorScope(boundClass);
 
         // the builtin class of all methods
         methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol);
+        methodClass.members_field = new Scope.ErrorScope(boundClass);
 
         // Create class to hold all predefined constants and operations.
         predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/TestSymtabItems.java	Tue Mar 01 12:00:06 2011 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7021183
+ * @summary 269: assertion failure getting enclosing element of an undefined name
+ */
+
+import java.lang.reflect.Field;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.UnknownElementException;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.UnknownTypeException;
+import javax.lang.model.util.ElementScanner7;
+import javax.lang.model.util.SimpleTypeVisitor7;
+import javax.lang.model.util.Types;
+
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.model.JavacTypes;
+import com.sun.tools.javac.util.Context;
+
+/**
+ * Scan javac Symtab looking for TypeMirrors and Elements, and ensure that
+ * no exceptions are thrown when used with javax.lang.model visitors.
+ *
+ */
+public class TestSymtabItems {
+    public static void main(String... args) throws Exception {
+        new TestSymtabItems().run();
+    }
+
+    void run() throws Exception {
+        Context c = new Context();
+        JavacFileManager.preRegister(c);
+        Symtab syms = Symtab.instance(c);
+        JavacTypes types = JavacTypes.instance(c);
+
+//        print("noSymbol", syms.noSymbol);
+//        print("errSymbol", syms.errSymbol);
+//        print("unknownSymbol", syms.unknownSymbol);
+//        print("botType", syms.botType);
+//        print("errType", syms.errType);
+//        print("unknownType", syms.unknownType);
+
+        for (Field f: Symtab.class.getDeclaredFields()) {
+//            System.err.println(f.getType() + " " + f.getName());
+
+            // Temporarily ignore methodHandle and transientMethodHandle
+            // during API evolution
+            if (f.getName().toLowerCase().contains("methodhandle"))
+                continue;
+
+            Class<?> ft = f.getType();
+            if (TypeMirror.class.isAssignableFrom(ft))
+                print(f.getName(), (TypeMirror) f.get(syms), types);
+            else if(Element.class.isAssignableFrom(ft))
+                print(f.getName(), (Element) f.get(syms));
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void print(String label, Element e) {
+        ElemPrinter ep = new ElemPrinter();
+        System.err.println("Test " + label);
+        ep.visit(e);
+        System.err.println();
+    }
+
+    void print(String label, TypeMirror t, Types types) {
+        TypePrinter tp = new TypePrinter();
+        System.err.println("Test " + label);
+        tp.visit(t, types);
+        System.err.println();
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    class ElemPrinter extends ElementScanner7<Void, Void> {
+        @Override
+        public Void visitPackage(PackageElement e, Void p) {
+            show("package", e);
+            indent(+1);
+            super.visitPackage(e, p);
+            indent(-1);
+            return null;
+        }
+
+        @Override
+        public Void visitType(TypeElement e, Void p) {
+            show("type", e);
+            indent(+1);
+            super.visitType(e, p);
+            indent(-1);
+            return null;
+        }
+
+        @Override
+        public Void visitVariable(VariableElement e, Void p) {
+            show("variable", e);
+            indent(+1);
+            super.visitVariable(e, p);
+            indent(-1);
+            return null;
+        }
+
+        @Override
+        public Void visitExecutable(ExecutableElement e, Void p) {
+            show("executable", e);
+            indent(+1);
+            super.visitExecutable(e, p);
+            indent(-1);
+            return null;
+        }
+
+        @Override
+        public Void visitTypeParameter(TypeParameterElement e, Void p) {
+            show("type parameter", e);
+            indent(+1);
+            super.visitTypeParameter(e, p);
+            indent(-1);
+            return null;
+        }
+
+        @Override
+        public Void visitUnknown(Element e, Void p) {
+            show("unknown", e);
+            indent(+1);
+            try {
+                super.visitUnknown(e, p);
+            } catch (UnknownElementException ex) {
+                System.err.println("caught " + ex);
+            }
+            indent(-1);
+            return null;
+        }
+
+        void indent(int i) {
+            indent += i;
+        }
+
+        String sp(int w) {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < w; i++)
+                sb.append("    ");
+            return sb.toString();
+        }
+
+        void show(String label, Element e) {
+            System.err.println(sp(indent) + label
+                    + ": mods:" + e.getModifiers()
+                    + " " + e.getSimpleName()
+                    + ", kind: " + e.getKind()
+                    + ", type: " + e.asType()
+                    + ", encl: " + e.getEnclosingElement());
+
+            // The following checks help establish why NPE might occur when trying to scan children
+            if (e instanceof ClassSymbol) {
+                ClassSymbol csym = (ClassSymbol) e;
+                if (csym.members_field == null)
+                    error("members_field is null");
+                if (csym.type == null)
+                    System.err.println("type is null");
+            }
+        }
+
+        int indent;
+    };
+
+    class TypePrinter extends SimpleTypeVisitor7<Void, Types> {
+        @Override
+        public Void defaultAction(TypeMirror m, Types types) {
+            System.err.println(m.getKind() + " " + m + " " + types.asElement(m));
+            return null;
+        }
+
+        @Override
+        public Void visitUnknown(TypeMirror t, Types types) {
+            try {
+                return super.visitUnknown(t, types);
+            } catch (UnknownTypeException ex) {
+                System.err.println("caught " + ex);
+                return null;
+            }
+        }
+    };
+}