diff -r be5cafeb318d -r d8a15fda7e3a src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Jun 23 16:51:30 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Jun 24 10:34:53 2010 -0700 @@ -674,6 +674,40 @@ return rs.resolveInternalField(pos, attrEnv, qual, name); } + /** Anon inner classes are used as access constructor tags. + * accessConstructorTag will use an existing anon class if one is available, + * and synthethise a class (with makeEmptyClass) if one is not available. + * However, there is a small possibility that an existing class will not + * be generated as expected if it is inside a conditional with a constant + * expression. If that is found to be the case, create an empty class here. + */ + private void checkAccessConstructorTags() { + for (List l = accessConstrTags; l.nonEmpty(); l = l.tail) { + ClassSymbol c = l.head; + if (isTranslatedClassAvailable(c)) + continue; + // Create class definition tree. + JCClassDecl cdef = make.ClassDef( + make.Modifiers(STATIC | SYNTHETIC), names.empty, + List.nil(), + null, List.nil(), List.nil()); + cdef.sym = c; + cdef.type = c.type; + // add it to the list of classes to be generated + translated.append(cdef); + } + } + // where + private boolean isTranslatedClassAvailable(ClassSymbol c) { + for (JCTree tree: translated) { + if (tree.getTag() == JCTree.CLASSDEF + && ((JCClassDecl) tree).sym == c) { + return true; + } + } + return false; + } + /************************************************************************** * Access methods *************************************************************************/ @@ -718,6 +752,10 @@ */ private Map accessConstrs; + /** A list of all class symbols used for access constructor tags. + */ + private List accessConstrTags; + /** A queue for all accessed symbols. */ private ListBuffer accessed; @@ -1138,6 +1176,8 @@ ClassSymbol ctag = chk.compiled.get(flatname); if (ctag == null) ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); + // keep a record of all tags, to verify that all are generated as required + accessConstrTags = accessConstrTags.prepend(ctag); return ctag; } @@ -3394,6 +3434,7 @@ accessNums = new HashMap(); accessSyms = new HashMap(); accessConstrs = new HashMap(); + accessConstrTags = List.nil(); accessed = new ListBuffer(); translate(cdef, (JCExpression)null); for (List l = accessed.toList(); l.nonEmpty(); l = l.tail) @@ -3401,6 +3442,7 @@ for (EnumMapping map : enumSwitchMap.values()) map.translate(); checkConflicts(this.translated.toList()); + checkAccessConstructorTags(); translated = this.translated; } finally { // note that recursive invocations of this method fail hard @@ -3420,6 +3462,7 @@ accessNums = null; accessSyms = null; accessConstrs = null; + accessConstrTags = null; accessed = null; enumSwitchMap.clear(); }