568 * its symbol. Return the class definition's symbol. |
568 * its symbol. Return the class definition's symbol. |
569 * and create |
569 * and create |
570 * @param flags The class symbol's flags |
570 * @param flags The class symbol's flags |
571 * @param owner The class symbol's owner |
571 * @param owner The class symbol's owner |
572 */ |
572 */ |
573 ClassSymbol makeEmptyClass(long flags, ClassSymbol owner) { |
573 JCClassDecl makeEmptyClass(long flags, ClassSymbol owner) { |
|
574 return makeEmptyClass(flags, owner, null, true); |
|
575 } |
|
576 |
|
577 JCClassDecl makeEmptyClass(long flags, ClassSymbol owner, Name flatname, |
|
578 boolean addToDefs) { |
574 // Create class symbol. |
579 // Create class symbol. |
575 ClassSymbol c = reader.defineClass(names.empty, owner); |
580 ClassSymbol c = reader.defineClass(names.empty, owner); |
576 c.flatname = chk.localClassName(c); |
581 if (flatname != null) { |
|
582 c.flatname = flatname; |
|
583 } else { |
|
584 c.flatname = chk.localClassName(c); |
|
585 } |
577 c.sourcefile = owner.sourcefile; |
586 c.sourcefile = owner.sourcefile; |
578 c.completer = null; |
587 c.completer = null; |
579 c.members_field = new Scope(c); |
588 c.members_field = new Scope(c); |
580 c.flags_field = flags; |
589 c.flags_field = flags; |
581 ClassType ctype = (ClassType) c.type; |
590 ClassType ctype = (ClassType) c.type; |
595 null, List.<JCExpression>nil(), List.<JCTree>nil()); |
604 null, List.<JCExpression>nil(), List.<JCTree>nil()); |
596 cdef.sym = c; |
605 cdef.sym = c; |
597 cdef.type = c.type; |
606 cdef.type = c.type; |
598 |
607 |
599 // Append class definition tree to owner's definitions. |
608 // Append class definition tree to owner's definitions. |
600 odef.defs = odef.defs.prepend(cdef); |
609 if (addToDefs) odef.defs = odef.defs.prepend(cdef); |
601 |
610 return cdef; |
602 return c; |
|
603 } |
611 } |
604 |
612 |
605 /************************************************************************** |
613 /************************************************************************** |
606 * Symbol manipulation utilities |
614 * Symbol manipulation utilities |
607 *************************************************************************/ |
615 *************************************************************************/ |
704 /** Anon inner classes are used as access constructor tags. |
712 /** Anon inner classes are used as access constructor tags. |
705 * accessConstructorTag will use an existing anon class if one is available, |
713 * accessConstructorTag will use an existing anon class if one is available, |
706 * and synthethise a class (with makeEmptyClass) if one is not available. |
714 * and synthethise a class (with makeEmptyClass) if one is not available. |
707 * However, there is a small possibility that an existing class will not |
715 * However, there is a small possibility that an existing class will not |
708 * be generated as expected if it is inside a conditional with a constant |
716 * be generated as expected if it is inside a conditional with a constant |
709 * expression. If that is found to be the case, create an empty class here. |
717 * expression. If that is found to be the case, create an empty class tree here. |
710 */ |
718 */ |
711 private void checkAccessConstructorTags() { |
719 private void checkAccessConstructorTags() { |
712 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) { |
720 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) { |
713 ClassSymbol c = l.head; |
721 ClassSymbol c = l.head; |
714 if (isTranslatedClassAvailable(c)) |
722 if (isTranslatedClassAvailable(c)) |
715 continue; |
723 continue; |
716 // Create class definition tree. |
724 // Create class definition tree. |
717 JCClassDecl cdef = make.ClassDef( |
725 JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC, |
718 make.Modifiers(STATIC | SYNTHETIC), names.empty, |
726 c.outermostClass(), c.flatname, false); |
719 List.<JCTypeParameter>nil(), |
727 swapAccessConstructorTag(c, cdec.sym); |
720 null, List.<JCExpression>nil(), List.<JCTree>nil()); |
728 translated.append(cdec); |
721 cdef.sym = c; |
|
722 cdef.type = c.type; |
|
723 // add it to the list of classes to be generated |
|
724 translated.append(cdef); |
|
725 } |
729 } |
726 } |
730 } |
727 // where |
731 // where |
728 private boolean isTranslatedClassAvailable(ClassSymbol c) { |
732 private boolean isTranslatedClassAvailable(ClassSymbol c) { |
729 for (JCTree tree: translated) { |
733 for (JCTree tree: translated) { |
731 && ((JCClassDecl) tree).sym == c) { |
735 && ((JCClassDecl) tree).sym == c) { |
732 return true; |
736 return true; |
733 } |
737 } |
734 } |
738 } |
735 return false; |
739 return false; |
|
740 } |
|
741 |
|
742 void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) { |
|
743 for (MethodSymbol methodSymbol : accessConstrs.values()) { |
|
744 Assert.check(methodSymbol.type.hasTag(METHOD)); |
|
745 MethodType oldMethodType = |
|
746 (MethodType)methodSymbol.type; |
|
747 if (oldMethodType.argtypes.head.tsym == oldCTag) |
|
748 methodSymbol.type = |
|
749 types.createMethodTypeWithParameters(oldMethodType, |
|
750 oldMethodType.getParameterTypes().tail |
|
751 .prepend(newCTag.erasure(types))); |
|
752 } |
736 } |
753 } |
737 |
754 |
738 /************************************************************************** |
755 /************************************************************************** |
739 * Access methods |
756 * Access methods |
740 *************************************************************************/ |
757 *************************************************************************/ |
1209 Name flatname = names.fromString("" + topClass.getQualifiedName() + |
1226 Name flatname = names.fromString("" + topClass.getQualifiedName() + |
1210 target.syntheticNameChar() + |
1227 target.syntheticNameChar() + |
1211 "1"); |
1228 "1"); |
1212 ClassSymbol ctag = chk.compiled.get(flatname); |
1229 ClassSymbol ctag = chk.compiled.get(flatname); |
1213 if (ctag == null) |
1230 if (ctag == null) |
1214 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); |
1231 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym; |
1215 // keep a record of all tags, to verify that all are generated as required |
1232 // keep a record of all tags, to verify that all are generated as required |
1216 accessConstrTags = accessConstrTags.prepend(ctag); |
1233 accessConstrTags = accessConstrTags.prepend(ctag); |
1217 return ctag; |
1234 return ctag; |
1218 } |
1235 } |
1219 |
1236 |
1776 Scope s = clazz.members(); |
1793 Scope s = clazz.members(); |
1777 for (Scope.Entry e = s.elems; e != null; e = e.sibling) |
1794 for (Scope.Entry e = s.elems; e != null; e = e.sibling) |
1778 if (e.sym.kind == TYP && |
1795 if (e.sym.kind == TYP && |
1779 e.sym.name == names.empty && |
1796 e.sym.name == names.empty && |
1780 (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym; |
1797 (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym; |
1781 return makeEmptyClass(STATIC | SYNTHETIC, clazz); |
1798 return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym; |
1782 } |
1799 } |
1783 |
1800 |
1784 /** Return symbol for "class$" method. If there is no method definition |
1801 /** Return symbol for "class$" method. If there is no method definition |
1785 * for class$, construct one as follows: |
1802 * for class$, construct one as follows: |
1786 * |
1803 * |