57 * If you write code that depends on this, you do so at your own risk. |
57 * If you write code that depends on this, you do so at your own risk. |
58 * This code and its internal interfaces are subject to change or |
58 * This code and its internal interfaces are subject to change or |
59 * deletion without notice.</b> |
59 * deletion without notice.</b> |
60 */ |
60 */ |
61 public class Lower extends TreeTranslator { |
61 public class Lower extends TreeTranslator { |
62 protected static final Context.Key<Lower> lowerKey = |
62 protected static final Context.Key<Lower> lowerKey = new Context.Key<>(); |
63 new Context.Key<Lower>(); |
|
64 |
63 |
65 public static Lower instance(Context context) { |
64 public static Lower instance(Context context) { |
66 Lower instance = context.get(lowerKey); |
65 Lower instance = context.get(lowerKey); |
67 if (instance == null) |
66 if (instance == null) |
68 instance = new Lower(context); |
67 instance = new Lower(context); |
139 */ |
138 */ |
140 Map<ClassSymbol, JCClassDecl> classdefs; |
139 Map<ClassSymbol, JCClassDecl> classdefs; |
141 |
140 |
142 /** A hash table mapping local classes to a list of pruned trees. |
141 /** A hash table mapping local classes to a list of pruned trees. |
143 */ |
142 */ |
144 public Map<ClassSymbol, List<JCTree>> prunedTree = new WeakHashMap<ClassSymbol, List<JCTree>>(); |
143 public Map<ClassSymbol, List<JCTree>> prunedTree = new WeakHashMap<>(); |
145 |
144 |
146 /** A hash table mapping virtual accessed symbols in outer subclasses |
145 /** A hash table mapping virtual accessed symbols in outer subclasses |
147 * to the actually referred symbol in superclasses. |
146 * to the actually referred symbol in superclasses. |
148 */ |
147 */ |
149 Map<Symbol,Symbol> actualSymbols; |
148 Map<Symbol,Symbol> actualSymbols; |
394 return List.nil(); |
393 return List.nil(); |
395 } |
394 } |
396 } |
395 } |
397 } |
396 } |
398 |
397 |
399 Map<TypeSymbol,EnumMapping> enumSwitchMap = new LinkedHashMap<TypeSymbol,EnumMapping>(); |
398 Map<TypeSymbol,EnumMapping> enumSwitchMap = new LinkedHashMap<>(); |
400 |
399 |
401 EnumMapping mapForEnum(DiagnosticPosition pos, TypeSymbol enumClass) { |
400 EnumMapping mapForEnum(DiagnosticPosition pos, TypeSymbol enumClass) { |
402 EnumMapping map = enumSwitchMap.get(enumClass); |
401 EnumMapping map = enumSwitchMap.get(enumClass); |
403 if (map == null) |
402 if (map == null) |
404 enumSwitchMap.put(enumClass, map = new EnumMapping(pos, enumClass)); |
403 enumSwitchMap.put(enumClass, map = new EnumMapping(pos, enumClass)); |
439 * class EnumMapping provides mapping data and support methods for this translation. |
438 * class EnumMapping provides mapping data and support methods for this translation. |
440 */ |
439 */ |
441 class EnumMapping { |
440 class EnumMapping { |
442 EnumMapping(DiagnosticPosition pos, TypeSymbol forEnum) { |
441 EnumMapping(DiagnosticPosition pos, TypeSymbol forEnum) { |
443 this.forEnum = forEnum; |
442 this.forEnum = forEnum; |
444 this.values = new LinkedHashMap<VarSymbol,Integer>(); |
443 this.values = new LinkedHashMap<>(); |
445 this.pos = pos; |
444 this.pos = pos; |
446 Name varName = names |
445 Name varName = names |
447 .fromString(target.syntheticNameChar() + |
446 .fromString(target.syntheticNameChar() + |
448 "SwitchMap" + |
447 "SwitchMap" + |
449 target.syntheticNameChar() + |
448 target.syntheticNameChar() + |
495 JCExpression mapVarInit = make |
494 JCExpression mapVarInit = make |
496 .NewArray(make.Type(syms.intType), List.of(size), null) |
495 .NewArray(make.Type(syms.intType), List.of(size), null) |
497 .setType(new ArrayType(syms.intType, syms.arrayClass)); |
496 .setType(new ArrayType(syms.intType, syms.arrayClass)); |
498 |
497 |
499 // try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {} |
498 // try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {} |
500 ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>(); |
499 ListBuffer<JCStatement> stmts = new ListBuffer<>(); |
501 Symbol ordinalMethod = lookupMethod(pos, |
500 Symbol ordinalMethod = lookupMethod(pos, |
502 names.ordinal, |
501 names.ordinal, |
503 forEnum.type, |
502 forEnum.type, |
504 List.<Type>nil()); |
503 List.<Type>nil()); |
505 List<JCCatch> catcher = List.<JCCatch>nil() |
504 List<JCCatch> catcher = List.<JCCatch>nil() |
1652 boolean finallyCanCompleteNormally, int depth) { |
1651 boolean finallyCanCompleteNormally, int depth) { |
1653 if (resources.isEmpty()) |
1652 if (resources.isEmpty()) |
1654 return block; |
1653 return block; |
1655 |
1654 |
1656 // Add resource declaration or expression to block statements |
1655 // Add resource declaration or expression to block statements |
1657 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); |
1656 ListBuffer<JCStatement> stats = new ListBuffer<>(); |
1658 JCTree resource = resources.head; |
1657 JCTree resource = resources.head; |
1659 JCExpression expr = null; |
1658 JCExpression expr = null; |
1660 if (resource instanceof JCVariableDecl) { |
1659 if (resource instanceof JCVariableDecl) { |
1661 JCVariableDecl var = (JCVariableDecl) resource; |
1660 JCVariableDecl var = (JCVariableDecl) resource; |
1662 expr = make.Ident(var.sym).setType(resource.type); |
1661 expr = make.Ident(var.sym).setType(resource.type); |
2546 JCExpression e_class = classOfType(tree.sym.type, tree.pos()). |
2545 JCExpression e_class = classOfType(tree.sym.type, tree.pos()). |
2547 setType(types.erasure(syms.classType)); |
2546 setType(types.erasure(syms.classType)); |
2548 |
2547 |
2549 // process each enumeration constant, adding implicit constructor parameters |
2548 // process each enumeration constant, adding implicit constructor parameters |
2550 int nextOrdinal = 0; |
2549 int nextOrdinal = 0; |
2551 ListBuffer<JCExpression> values = new ListBuffer<JCExpression>(); |
2550 ListBuffer<JCExpression> values = new ListBuffer<>(); |
2552 ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>(); |
2551 ListBuffer<JCTree> enumDefs = new ListBuffer<>(); |
2553 ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>(); |
2552 ListBuffer<JCTree> otherDefs = new ListBuffer<>(); |
2554 for (List<JCTree> defs = tree.defs; |
2553 for (List<JCTree> defs = tree.defs; |
2555 defs.nonEmpty(); |
2554 defs.nonEmpty(); |
2556 defs=defs.tail) { |
2555 defs=defs.tail) { |
2557 if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) { |
2556 if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) { |
2558 JCVariableDecl var = (JCVariableDecl)defs.head; |
2557 JCVariableDecl var = (JCVariableDecl)defs.head; |
2822 } |
2821 } |
2823 result = tree; |
2822 result = tree; |
2824 } |
2823 } |
2825 //where |
2824 //where |
2826 private Map<Symbol, Symbol> makeTranslationMap(JCMethodDecl tree) { |
2825 private Map<Symbol, Symbol> makeTranslationMap(JCMethodDecl tree) { |
2827 Map<Symbol, Symbol> translationMap = new HashMap<Symbol,Symbol>(); |
2826 Map<Symbol, Symbol> translationMap = new HashMap<>(); |
2828 for (JCVariableDecl vd : tree.params) { |
2827 for (JCVariableDecl vd : tree.params) { |
2829 Symbol p = vd.sym; |
2828 Symbol p = vd.sym; |
2830 if (p != p.baseSymbol()) { |
2829 if (p != p.baseSymbol()) { |
2831 translationMap.put(p.baseSymbol(), p); |
2830 translationMap.put(p.baseSymbol(), p); |
2832 } |
2831 } |
3073 |
3072 |
3074 List<JCExpression> boxArgs(List<Type> parameters, List<JCExpression> _args, Type varargsElement) { |
3073 List<JCExpression> boxArgs(List<Type> parameters, List<JCExpression> _args, Type varargsElement) { |
3075 List<JCExpression> args = _args; |
3074 List<JCExpression> args = _args; |
3076 if (parameters.isEmpty()) return args; |
3075 if (parameters.isEmpty()) return args; |
3077 boolean anyChanges = false; |
3076 boolean anyChanges = false; |
3078 ListBuffer<JCExpression> result = new ListBuffer<JCExpression>(); |
3077 ListBuffer<JCExpression> result = new ListBuffer<>(); |
3079 while (parameters.tail.nonEmpty()) { |
3078 while (parameters.tail.nonEmpty()) { |
3080 JCExpression arg = translate(args.head, parameters.head); |
3079 JCExpression arg = translate(args.head, parameters.head); |
3081 anyChanges |= (arg != args.head); |
3080 anyChanges |= (arg != args.head); |
3082 result.append(arg); |
3081 result.append(arg); |
3083 args = args.tail; |
3082 args = args.tail; |
3084 parameters = parameters.tail; |
3083 parameters = parameters.tail; |
3085 } |
3084 } |
3086 Type parameter = parameters.head; |
3085 Type parameter = parameters.head; |
3087 if (varargsElement != null) { |
3086 if (varargsElement != null) { |
3088 anyChanges = true; |
3087 anyChanges = true; |
3089 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); |
3088 ListBuffer<JCExpression> elems = new ListBuffer<>(); |
3090 while (args.nonEmpty()) { |
3089 while (args.nonEmpty()) { |
3091 JCExpression arg = translate(args.head, varargsElement); |
3090 JCExpression arg = translate(args.head, varargsElement); |
3092 elems.append(arg); |
3091 elems.append(arg); |
3093 args = args.tail; |
3092 args = args.tail; |
3094 } |
3093 } |
3609 tree.selector.type, |
3608 tree.selector.type, |
3610 List.<Type>nil()); |
3609 List.<Type>nil()); |
3611 JCArrayAccess selector = make.Indexed(map.mapVar, |
3610 JCArrayAccess selector = make.Indexed(map.mapVar, |
3612 make.App(make.Select(tree.selector, |
3611 make.App(make.Select(tree.selector, |
3613 ordinalMethod))); |
3612 ordinalMethod))); |
3614 ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); |
3613 ListBuffer<JCCase> cases = new ListBuffer<>(); |
3615 for (JCCase c : tree.cases) { |
3614 for (JCCase c : tree.cases) { |
3616 if (c.pat != null) { |
3615 if (c.pat != null) { |
3617 VarSymbol label = (VarSymbol)TreeInfo.symbol(c.pat); |
3616 VarSymbol label = (VarSymbol)TreeInfo.symbol(c.pat); |
3618 JCLiteral pat = map.forConstant(label); |
3617 JCLiteral pat = map.forConstant(label); |
3619 cases.append(make.Case(pat, c.stats)); |
3618 cases.append(make.Case(pat, c.stats)); |
3672 * strings or a perfect hashing algorithm over the |
3671 * strings or a perfect hashing algorithm over the |
3673 * particular set of case labels, could potentially be |
3672 * particular set of case labels, could potentially be |
3674 * used instead of String.hashCode. |
3673 * used instead of String.hashCode. |
3675 */ |
3674 */ |
3676 |
3675 |
3677 ListBuffer<JCStatement> stmtList = new ListBuffer<JCStatement>(); |
3676 ListBuffer<JCStatement> stmtList = new ListBuffer<>(); |
3678 |
3677 |
3679 // Map from String case labels to their original position in |
3678 // Map from String case labels to their original position in |
3680 // the list of case labels. |
3679 // the list of case labels. |
3681 Map<String, Integer> caseLabelToPosition = |
3680 Map<String, Integer> caseLabelToPosition = new LinkedHashMap<>(alternatives + 1, 1.0f); |
3682 new LinkedHashMap<String, Integer>(alternatives + 1, 1.0f); |
|
3683 |
3681 |
3684 // Map of hash codes to the string case labels having that hashCode. |
3682 // Map of hash codes to the string case labels having that hashCode. |
3685 Map<Integer, Set<String>> hashToString = |
3683 Map<Integer, Set<String>> hashToString = new LinkedHashMap<>(alternatives + 1, 1.0f); |
3686 new LinkedHashMap<Integer, Set<String>>(alternatives + 1, 1.0f); |
|
3687 |
3684 |
3688 int casePosition = 0; |
3685 int casePosition = 0; |
3689 for(JCCase oneCase : caseList) { |
3686 for(JCCase oneCase : caseList) { |
3690 JCExpression expression = oneCase.getExpression(); |
3687 JCExpression expression = oneCase.getExpression(); |
3691 |
3688 |
3695 Assert.checkNull(mapping); |
3692 Assert.checkNull(mapping); |
3696 int hashCode = labelExpr.hashCode(); |
3693 int hashCode = labelExpr.hashCode(); |
3697 |
3694 |
3698 Set<String> stringSet = hashToString.get(hashCode); |
3695 Set<String> stringSet = hashToString.get(hashCode); |
3699 if (stringSet == null) { |
3696 if (stringSet == null) { |
3700 stringSet = new LinkedHashSet<String>(1, 1.0f); |
3697 stringSet = new LinkedHashSet<>(1, 1.0f); |
3701 stringSet.add(labelExpr); |
3698 stringSet.add(labelExpr); |
3702 hashToString.put(hashCode, stringSet); |
3699 hashToString.put(hashCode, stringSet); |
3703 } else { |
3700 } else { |
3704 boolean added = stringSet.add(labelExpr); |
3701 boolean added = stringSet.add(labelExpr); |
3705 Assert.check(added); |
3702 Assert.check(added); |
3905 endPosTable = env.toplevel.endPositions; |
3902 endPosTable = env.toplevel.endPositions; |
3906 currentClass = null; |
3903 currentClass = null; |
3907 currentMethodDef = null; |
3904 currentMethodDef = null; |
3908 outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null; |
3905 outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null; |
3909 outermostMemberDef = null; |
3906 outermostMemberDef = null; |
3910 this.translated = new ListBuffer<JCTree>(); |
3907 this.translated = new ListBuffer<>(); |
3911 classdefs = new HashMap<ClassSymbol,JCClassDecl>(); |
3908 classdefs = new HashMap<>(); |
3912 actualSymbols = new HashMap<Symbol,Symbol>(); |
3909 actualSymbols = new HashMap<>(); |
3913 freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>(); |
3910 freevarCache = new HashMap<>(); |
3914 proxies = new Scope(syms.noSymbol); |
3911 proxies = new Scope(syms.noSymbol); |
3915 twrVars = new Scope(syms.noSymbol); |
3912 twrVars = new Scope(syms.noSymbol); |
3916 outerThisStack = List.nil(); |
3913 outerThisStack = List.nil(); |
3917 accessNums = new HashMap<Symbol,Integer>(); |
3914 accessNums = new HashMap<>(); |
3918 accessSyms = new HashMap<Symbol,MethodSymbol[]>(); |
3915 accessSyms = new HashMap<>(); |
3919 accessConstrs = new HashMap<Symbol,MethodSymbol>(); |
3916 accessConstrs = new HashMap<>(); |
3920 accessConstrTags = List.nil(); |
3917 accessConstrTags = List.nil(); |
3921 accessed = new ListBuffer<Symbol>(); |
3918 accessed = new ListBuffer<>(); |
3922 translate(cdef, (JCExpression)null); |
3919 translate(cdef, (JCExpression)null); |
3923 for (List<Symbol> l = accessed.toList(); l.nonEmpty(); l = l.tail) |
3920 for (List<Symbol> l = accessed.toList(); l.nonEmpty(); l = l.tail) |
3924 makeAccessible(l.head); |
3921 makeAccessible(l.head); |
3925 for (EnumMapping map : enumSwitchMap.values()) |
3922 for (EnumMapping map : enumSwitchMap.values()) |
3926 map.translate(); |
3923 map.translate(); |