src/share/classes/com/sun/tools/javac/comp/Lower.java

changeset 595
d8a15fda7e3a
parent 581
f2fdd52e4e87
child 609
13354e1abba7
equal deleted inserted replaced
594:be5cafeb318d 595:d8a15fda7e3a
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;
3418 proxies = null; 3460 proxies = null;
3419 outerThisStack = null; 3461 outerThisStack = null;
3420 accessNums = null; 3462 accessNums = null;
3421 accessSyms = null; 3463 accessSyms = null;
3422 accessConstrs = null; 3464 accessConstrs = null;
3465 accessConstrTags = null;
3423 accessed = null; 3466 accessed = null;
3424 enumSwitchMap.clear(); 3467 enumSwitchMap.clear();
3425 } 3468 }
3426 return translated.toList(); 3469 return translated.toList();
3427 } 3470 }

mercurial