public static Lower instance(Context context) { Lower instance = context.get(lowerKey); if (instance == null) instance = new Lower(context); return instance; }
/** Lower a tree of the form e++ or e-- where e is an object type */ JCTree lowerBoxedPostop(final JCUnary tree) { // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2 // or // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2 // where OP is += or -= final boolean cast = tree.arg.tag == JCTree.TYPECAST; final JCExpression arg = cast ? ((JCTypeCast)tree.arg).expr : tree.arg; return abstractLval(arg, new TreeBuilder() { public JCTree build(final JCTree tmp1) { return abstractRval(tmp1, tree.arg.type, new TreeBuilder() { public JCTree build(final JCTree tmp2) { int opcode = (tree.tag == JCTree.POSTINC) ? JCTree.PLUS_ASG : JCTree.MINUS_ASG; JCTree lhs = cast ? make.TypeCast(tree.arg.type, (JCExpression)tmp1) : tmp1; JCTree update = makeAssignop(opcode, lhs, make.Literal(1)); return makeComma(update, tmp2); } }); } }); }
public JCTree build(final JCTree indexed) { return abstractRval(i.index, syms.intType, new TreeBuilder() { public JCTree build(final JCTree index) { JCTree newLval = make.Indexed((JCExpression)indexed, (JCExpression)index); newLval.setType(i.type); return builder.build(newLval); } }); } });
public void visitSelect(JCFieldAccess tree) { // need to special case-access of the form C.super.x // these will always need an access method. boolean qualifiedSuperAccess = tree.selected.tag == JCTree.SELECT && TreeInfo.name(tree.selected) == names._super; tree.selected = translate(tree.selected); if (tree.name == names._class) result = classOf(tree.selected); else if (tree.name == names._this || tree.name == names._super) result = makeThis(tree.pos(), tree.selected.type.tsym); else result = access(tree.sym, tree, enclOp, qualifiedSuperAccess); }
/** Add all required access methods for a private symbol to enclosing class. * @param sym The symbol. */ void makeAccessible(Symbol sym) { JCClassDecl cdef = classDef(sym.owner.enclClass()); assert cdef != null : "class def not found: " + sym + " in " + sym.owner; if (sym.name == names.init) { cdef.defs = cdef.defs.prepend( accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym))); } else { MethodSymbol[] accessors = accessSyms.get(sym); for (int i = 0; i < NCODES; i++) { if (accessors[i] != null) cdef.defs = cdef.defs.prepend( accessDef(cdef.pos, sym, accessors[i], i)); } } }
List<Type> argTypes = tree.constructor.type.getParameterTypes(); if (isEnum) argTypes = argTypes.prepend(syms.intType).prepend(syms.stringType); tree.args = boxArgs(argTypes, tree.args, tree.varargsElement); tree.varargsElement = null; tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c))); Symbol constructor = accessConstructor(tree.pos(), tree.constructor); if (constructor != tree.constructor) { tree.args = tree.args.append(makeNull()); tree.constructor = constructor; JCExpression thisArg; if (tree.encl != null) { thisArg = attr.makeNullCheck(translate(tree.encl)); thisArg.type = tree.encl.type; } else if ((c.owner.kind & (MTH | VAR)) != 0) { thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym); } else { thisArg = makeOwnerThis(tree.pos(), c, false); translate(tree.def); tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym)); tree.def = null; } else { tree.clazz = access(c, tree.clazz, enclOp, false);
if (cv != null) { make.at(tree.pos); return makeLit(sym.type, cv); sym = proxies.lookup(proxyName(sym.name)).sym; assert sym != null && (sym.flags_field & FINAL) != 0; tree = make.at(tree.pos).Ident(sym); boolean protAccess = refSuper && !needsPrivateAccess(sym) || needsProtectedAccess(sym, tree); boolean accReq = protAccess || needsPrivateAccess(sym); if (cv != null) return makeLit(sym.type, cv); base = makeOwnerThis(tree.pos(), sym, true); args = args.prepend(base); Symbol access = accessSymbol(sym, tree, enclOp, protAccess, refSuper); accessBase(tree.pos(), sym), sym).setType(tree.type);
: accessClass(sym, protAccess, tree); acode = accessCode(tree, enclOp); if (acode >= FIRSTASGOPcode) { OperatorSymbol operator = binaryAccessOperator(acode); if (operator.opcode == string_add) argtypes = List.of(syms.objectType); accessor = new MethodSymbol( STATIC | SYNTHETIC, accessName(anum.intValue(), acode), new MethodType(argtypes, restype, thrown, syms.methodClass), accOwner); enterSynthetic(tree.pos(), accessor, accOwner.members()); accessors[acode] = accessor;
public void visitAssignop(final JCAssignOp tree) { JCTree lhsAccess = access(TreeInfo.skipParens(tree.lhs)); final boolean boxingReq = !tree.lhs.type.isPrimitive() && tree.operator.type.getReturnType().isPrimitive(); JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { public JCTree build(final JCTree lhs) { JCTree.Tag newTag = tree.getTag().noAssignOp(); result = translate(newTree); return; tree.lhs = translate(tree.lhs, tree); tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head); ? makeString(tree.rhs) : tree.rhs; app.args = List.of(rhs).prependList(app.args);
? ((JCTypeCast)tree.lhs).expr : tree.lhs; JCTree newTree = abstractLval(arg, new TreeBuilder() { public JCTree build(final JCTree lhs) { int newTag = tree.tag - JCTree.ASGOffset; result = translate(newTree); return; tree.lhs = translate(tree.lhs, tree); tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head); ? makeString(tree.rhs) : tree.rhs; app.args = List.of(rhs).prependList(app.args);
private void reassignAllEarlyHolders( Context ctx ) { Object[] earlyAttrHolders = { Resolve.instance( ctx ), DeferredAttr.instance( ctx ), Enter.instance( ctx ), MemberEnter.instance( ctx ), Lower.instance( ctx ), Flow.instance( ctx ), //## todo: some of these need their original Log, e.g., compile this "java.util.Date date = new java.util.Date( asdfg );" and see the fatal error report // TransTypes.instance( ctx ), // Annotate.instance( ctx ), // TypeAnnotations.instance( ctx ), // JavacTrees.instance( ctx ), // JavaCompiler.instance( ctx ), }; for( Object instance: earlyAttrHolders ) { ReflectUtil.LiveFieldRef log = ReflectUtil.WithNull.field( instance, "log" ); if( log != null ) { log.set( this ); } } }
/** The qualifier to be used for accessing a symbol in an outer class. * This is either C.sym or C.this.sym, depending on whether or not * sym is static. * @param sym The accessed symbol. */ JCExpression accessBase(DiagnosticPosition pos, Symbol sym) { return (sym.flags() & STATIC) != 0 ? access(make.at(pos.getStartPosition()).QualIdent(sym.owner)) : makeOwnerThis(pos, sym, true); }
List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner, long additionalFlags) { long flags = FINAL | SYNTHETIC | additionalFlags; if (owner.kind == TYP && target.usePrivateSyntheticFields()) flags |= PRIVATE; List<JCVariableDecl> defs = List.nil(); for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) { VarSymbol v = l.head; VarSymbol proxy = new VarSymbol( flags, proxyName(v.name), v.erasure(types), owner); proxies.enter(proxy); JCVariableDecl vd = make.at(pos).VarDef(proxy, null); vd.vartype = access(vd.vartype); defs = defs.prepend(vd); } return defs; }
public void visitIdent(JCIdent tree) { result = access(tree.sym, tree, enclOp, false); }
/** Definition for this$n field. * @param pos The source code position of the definition. * @param owner The class in which the definition goes. */ JCVariableDecl outerThisDef(int pos, Symbol owner) { long flags = FINAL | SYNTHETIC; if (owner.kind == TYP && target.usePrivateSyntheticFields()) flags |= PRIVATE; Type target = types.erasure(owner.enclClass().type.getEnclosingType()); VarSymbol outerThis = new VarSymbol( flags, outerThisName(target, owner), target, owner); outerThisStack = outerThisStack.prepend(outerThis); JCVariableDecl vd = make.at(pos).VarDef(outerThis, null); vd.vartype = access(vd.vartype); return vd; }
Symbol lid = TreeInfo.symbol(s.selected); if (lid != null && lid.kind == TYP) return builder.build(lval); return abstractRval(s.selected, new TreeBuilder() { public JCTree build(final JCTree selected) { return builder.build(make.Select((JCExpression)selected, s.sym)); return abstractRval(i.indexed, new TreeBuilder() { public JCTree build(final JCTree indexed) { return abstractRval(i.index, syms.intType, new TreeBuilder() { return abstractLval(((JCTypeCast)lval).expr, builder);
/** Return binary operator that corresponds to given access code. */ private OperatorSymbol binaryAccessOperator(int acode) { for (Scope.Entry e = syms.predefClass.members().elems; e != null; e = e.sibling) { if (e.sym instanceof OperatorSymbol) { OperatorSymbol op = (OperatorSymbol)e.sym; if (accessCode(op.opcode) == acode) return op; } } return null; }
/** return access code for identifier, * @param tree The tree representing the identifier use. * @param enclOp The closest enclosing operation node of tree, * null if tree is not a subtree of an operation. */ private static int accessCode(JCTree tree, JCTree enclOp) { if (enclOp == null) return DEREFcode; else if (enclOp.hasTag(ASSIGN) && tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs)) return ASSIGNcode; else if (enclOp.getTag().isIncOrDecUnaryOp() && tree == TreeInfo.skipParens(((JCUnary) enclOp).arg)) return mapTagToUnaryOpCode(enclOp.getTag()); else if (enclOp.getTag().isAssignop() && tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs)) return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode); else return DEREFcode; }
List<Type> argTypes = tree.constructor.type.getParameterTypes(); if (isEnum) argTypes = argTypes.prepend(syms.intType).prepend(syms.stringType); tree.args = boxArgs(argTypes, tree.args, tree.varargsElement); tree.varargsElement = null; tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c))); Symbol constructor = accessConstructor(tree.pos(), tree.constructor); if (constructor != tree.constructor) { tree.args = tree.args.append(makeNull()); tree.constructor = constructor; JCExpression thisArg; if (tree.encl != null) { thisArg = attr.makeNullCheck(translate(tree.encl)); thisArg.type = tree.encl.type; } else if ((c.owner.kind & (MTH | VAR)) != 0) { thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym); } else { thisArg = makeOwnerThis(tree.pos(), c, false); translate(tree.def); tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym)); tree.def = null; } else { tree.clazz = access(c, tree.clazz, enclOp, false);
if (cv != null) { make.at(tree.pos); return makeLit(sym.type, cv); sym = proxies.lookup(proxyName(sym.name)).sym; Assert.check(sym != null && (sym.flags_field & FINAL) != 0); tree = make.at(tree.pos).Ident(sym); boolean protAccess = refSuper && !needsPrivateAccess(sym) || needsProtectedAccess(sym, tree); boolean accReq = protAccess || needsPrivateAccess(sym); Object cv = ((VarSymbol)sym).getConstValue(); if (cv != null) { addPrunedInfo(tree); return makeLit(sym.type, cv); base = makeOwnerThis(tree.pos(), sym, true); args = args.prepend(base); Symbol access = accessSymbol(sym, tree, enclOp, protAccess, refSuper); accessBase(tree.pos(), sym), sym).setType(tree.type);