672 */ |
672 */ |
673 private VarSymbol lookupField(DiagnosticPosition pos, Type qual, Name name) { |
673 private VarSymbol lookupField(DiagnosticPosition pos, Type qual, Name name) { |
674 return rs.resolveInternalField(pos, attrEnv, qual, name); |
674 return rs.resolveInternalField(pos, attrEnv, qual, name); |
675 } |
675 } |
676 |
676 |
|
677 /** Anon inner classes are used as access constructor tags. |
|
678 * accessConstructorTag will use an existing anon class if one is available, |
|
679 * and synthethise a class (with makeEmptyClass) if one is not available. |
|
680 * However, there is a small possibility that an existing class will not |
|
681 * be generated as expected if it is inside a conditional with a constant |
|
682 * expression. If that is found to be the case, create an empty class here. |
|
683 */ |
|
684 private void checkAccessConstructorTags() { |
|
685 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) { |
|
686 ClassSymbol c = l.head; |
|
687 if (isTranslatedClassAvailable(c)) |
|
688 continue; |
|
689 // Create class definition tree. |
|
690 JCClassDecl cdef = make.ClassDef( |
|
691 make.Modifiers(STATIC | SYNTHETIC), names.empty, |
|
692 List.<JCTypeParameter>nil(), |
|
693 null, List.<JCExpression>nil(), List.<JCTree>nil()); |
|
694 cdef.sym = c; |
|
695 cdef.type = c.type; |
|
696 // add it to the list of classes to be generated |
|
697 translated.append(cdef); |
|
698 } |
|
699 } |
|
700 // where |
|
701 private boolean isTranslatedClassAvailable(ClassSymbol c) { |
|
702 for (JCTree tree: translated) { |
|
703 if (tree.getTag() == JCTree.CLASSDEF |
|
704 && ((JCClassDecl) tree).sym == c) { |
|
705 return true; |
|
706 } |
|
707 } |
|
708 return false; |
|
709 } |
|
710 |
677 /************************************************************************** |
711 /************************************************************************** |
678 * Access methods |
712 * Access methods |
679 *************************************************************************/ |
713 *************************************************************************/ |
680 |
714 |
681 /** Access codes for dereferencing, assignment, |
715 /** Access codes for dereferencing, assignment, |
715 private Map<Symbol,MethodSymbol[]> accessSyms; |
749 private Map<Symbol,MethodSymbol[]> accessSyms; |
716 |
750 |
717 /** A mapping from (constructor) symbols to access constructor symbols. |
751 /** A mapping from (constructor) symbols to access constructor symbols. |
718 */ |
752 */ |
719 private Map<Symbol,MethodSymbol> accessConstrs; |
753 private Map<Symbol,MethodSymbol> accessConstrs; |
|
754 |
|
755 /** A list of all class symbols used for access constructor tags. |
|
756 */ |
|
757 private List<ClassSymbol> accessConstrTags; |
720 |
758 |
721 /** A queue for all accessed symbols. |
759 /** A queue for all accessed symbols. |
722 */ |
760 */ |
723 private ListBuffer<Symbol> accessed; |
761 private ListBuffer<Symbol> accessed; |
724 |
762 |
1136 target.syntheticNameChar() + |
1174 target.syntheticNameChar() + |
1137 "1"); |
1175 "1"); |
1138 ClassSymbol ctag = chk.compiled.get(flatname); |
1176 ClassSymbol ctag = chk.compiled.get(flatname); |
1139 if (ctag == null) |
1177 if (ctag == null) |
1140 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); |
1178 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); |
|
1179 // keep a record of all tags, to verify that all are generated as required |
|
1180 accessConstrTags = accessConstrTags.prepend(ctag); |
1141 return ctag; |
1181 return ctag; |
1142 } |
1182 } |
1143 |
1183 |
1144 /** Add all required access methods for a private symbol to enclosing class. |
1184 /** Add all required access methods for a private symbol to enclosing class. |
1145 * @param sym The symbol. |
1185 * @param sym The symbol. |
3392 proxies = new Scope(syms.noSymbol); |
3432 proxies = new Scope(syms.noSymbol); |
3393 outerThisStack = List.nil(); |
3433 outerThisStack = List.nil(); |
3394 accessNums = new HashMap<Symbol,Integer>(); |
3434 accessNums = new HashMap<Symbol,Integer>(); |
3395 accessSyms = new HashMap<Symbol,MethodSymbol[]>(); |
3435 accessSyms = new HashMap<Symbol,MethodSymbol[]>(); |
3396 accessConstrs = new HashMap<Symbol,MethodSymbol>(); |
3436 accessConstrs = new HashMap<Symbol,MethodSymbol>(); |
|
3437 accessConstrTags = List.nil(); |
3397 accessed = new ListBuffer<Symbol>(); |
3438 accessed = new ListBuffer<Symbol>(); |
3398 translate(cdef, (JCExpression)null); |
3439 translate(cdef, (JCExpression)null); |
3399 for (List<Symbol> l = accessed.toList(); l.nonEmpty(); l = l.tail) |
3440 for (List<Symbol> l = accessed.toList(); l.nonEmpty(); l = l.tail) |
3400 makeAccessible(l.head); |
3441 makeAccessible(l.head); |
3401 for (EnumMapping map : enumSwitchMap.values()) |
3442 for (EnumMapping map : enumSwitchMap.values()) |
3402 map.translate(); |
3443 map.translate(); |
3403 checkConflicts(this.translated.toList()); |
3444 checkConflicts(this.translated.toList()); |
|
3445 checkAccessConstructorTags(); |
3404 translated = this.translated; |
3446 translated = this.translated; |
3405 } finally { |
3447 } finally { |
3406 // note that recursive invocations of this method fail hard |
3448 // note that recursive invocations of this method fail hard |
3407 attrEnv = null; |
3449 attrEnv = null; |
3408 this.make = null; |
3450 this.make = null; |