/** Construct an attributed tree to coerce an expression to some erased * target type, unless the expression is already assignable to that type. * If target type is a constant type, use its base type instead. * @param tree The expression tree. * @param target The target type. */ public JCExpression coerce(Env<AttrContext> env, JCExpression tree, Type target) { Env<AttrContext> prevEnv = this.env; try { this.env = env; return coerce(tree, target); } finally { this.env = prevEnv; } } JCExpression coerce(JCExpression tree, Type target) {
/** Construct an attributed tree to coerce an expression to some erased * target type, unless the expression is already assignable to that type. * If target type is a constant type, use its base type instead. * @param tree The expression tree. * @param target The target type. */ public JCExpression coerce(Env<AttrContext> env, JCExpression tree, Type target) { Env<AttrContext> prevEnv = this.env; try { this.env = env; return coerce(tree, target); } finally { this.env = prevEnv; } } JCExpression coerce(JCExpression tree, Type target) {
target = erasure(tree.type); tree.type = erasedType; if (target != null) return coerce(tree, target);
target = erasure(tree.type); tree.type = erasedType; if (target != null) return coerce(tree, target);
return coerce(tree, target);
return coerce(tree, target);
public void visitTypeCast(JCTypeCast tree) { tree.clazz = translate(tree.clazz, null); Type originalTarget = tree.type; tree.type = erasure(tree.type); tree.expr = translate(tree.expr, tree.type); if (originalTarget.isIntersection()) { Type.IntersectionClassType ict = (Type.IntersectionClassType)originalTarget; for (Type c : ict.getExplicitComponents()) { Type ec = erasure(c); if (!types.isSameType(ec, tree.type)) { tree.expr = coerce(tree.expr, ec); } } } result = tree; }
public void visitTypeCast(JCTypeCast tree) { tree.clazz = translate(tree.clazz, null); Type originalTarget = tree.type; tree.type = erasure(tree.type); tree.expr = translate(tree.expr, tree.type); if (originalTarget.isCompound()) { Type.IntersectionClassType ict = (Type.IntersectionClassType)originalTarget; for (Type c : ict.getExplicitComponents()) { Type ec = erasure(c); if (!types.isSameType(ec, tree.type)) { tree.expr = coerce(tree.expr, ec); } } } result = tree; }
/** * determine the receiver of the method call - the receiver can * be a type qualifier, the synthetic receiver parameter or 'super'. */ private JCExpression expressionInvoke(VarSymbol rcvr) { JCExpression qualifier = (rcvr != null) ? makeReceiver(rcvr) : tree.getQualifierExpression(); //create the qualifier expression JCFieldAccess select = make.Select(qualifier, tree.sym.name); select.sym = tree.sym; select.type = tree.sym.erasure(types); //create the method call expression JCExpression apply = make.Apply(List.<JCExpression>nil(), select, convertArgs(tree.sym, args.toList(), tree.varargsElement)). setType(tree.sym.erasure(types).getReturnType()); apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType()); setVarargsIfNeeded(apply, tree.varargsElement); return apply; }
/** * determine the receiver of the bridged method call - the receiver can * be either the synthetic receiver parameter or a type qualifier; the * original qualifier expression is never used here, as it might refer * to symbols not available in the static context of the bridge */ private JCExpression bridgeExpressionInvoke(JCExpression rcvr) { JCExpression qualifier = tree.sym.isStatic() ? make.Type(tree.sym.owner.type) : (rcvr != null) ? rcvr : tree.getQualifierExpression(); //create the qualifier expression JCFieldAccess select = make.Select(qualifier, tree.sym.name); select.sym = tree.sym; select.type = tree.sym.erasure(types); //create the method call expression JCExpression apply = make.Apply(List.<JCExpression>nil(), select, convertArgs(tree.sym, args.toList(), tree.varargsElement)). setType(tree.sym.erasure(types).getReturnType()); apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType()); setVarargsIfNeeded(apply, tree.varargsElement); return apply; }
public void visitSelect(JCFieldAccess tree) { Type t = tree.selected.type; while (t.hasTag(TYPEVAR)) t = t.getUpperBound(); if (t.isCompound()) { if ((tree.sym.flags() & IPROXY) != 0) { tree.sym = ((MethodSymbol)tree.sym). implemented((TypeSymbol)tree.sym.owner, types); } tree.selected = coerce( translate(tree.selected, erasure(tree.selected.type)), erasure(tree.sym.owner.type)); } else tree.selected = translate(tree.selected, erasure(t)); // Map constants expressions to themselves. if (tree.type.constValue() != null) { result = tree; } // Insert casts of variable uses as needed. else if (tree.sym.kind == VAR) { result = retype(tree, tree.sym.erasure(types), pt); } else { tree.type = erasure(tree.type); result = tree; } }
public void visitSelect(JCFieldAccess tree) { Type t = tree.selected.type; while (t.hasTag(TYPEVAR)) t = t.getUpperBound(); if (t.isCompound()) { if ((tree.sym.flags() & IPROXY) != 0) { tree.sym = ((MethodSymbol)tree.sym). implemented((TypeSymbol)tree.sym.owner, types); } tree.selected = coerce( translate(tree.selected, erasure(tree.selected.type)), erasure(tree.sym.owner.type)); } else tree.selected = translate(tree.selected, erasure(t)); // Map constants expressions to themselves. if (tree.type.constValue() != null) { result = tree; } // Insert casts of variable uses as needed. else if (tree.sym.kind == VAR) { result = retype(tree, tree.sym.erasure(types), pt); } else { tree.type = erasure(tree.type); result = tree; } }
private JCBlock makeLambdaExpressionBody(JCExpression expr, JCMethodDecl lambdaMethodDecl) { Type restype = lambdaMethodDecl.type.getReturnType(); boolean isLambda_void = expr.type.hasTag(VOID); boolean isTarget_void = restype.hasTag(VOID); boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type); int prevPos = make.pos; try { if (isTarget_void) { //target is void: // BODY; JCStatement stat = make.at(expr).Exec(expr); return make.Block(0, List.<JCStatement>of(stat)); } else if (isLambda_void && isTarget_Void) { //void to Void conversion: // BODY; return null; ListBuffer<JCStatement> stats = new ListBuffer<>(); stats.append(make.at(expr).Exec(expr)); stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType))); return make.Block(0, stats.toList()); } else { //non-void to non-void conversion: // return (TYPE)BODY; JCExpression retExpr = transTypes.coerce(attrEnv, expr, restype); return make.at(retExpr).Block(0, List.<JCStatement>of(make.Return(retExpr))); } } finally { make.at(prevPos); } }
private JCBlock makeLambdaExpressionBody(JCExpression expr, JCMethodDecl lambdaMethodDecl) { Type restype = lambdaMethodDecl.type.getReturnType(); boolean isLambda_void = expr.type.hasTag(VOID); boolean isTarget_void = restype.hasTag(VOID); boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type); int prevPos = make.pos; try { if (isTarget_void) { //target is void: // BODY; JCStatement stat = make.at(expr).Exec(expr); return make.Block(0, List.<JCStatement>of(stat)); } else if (isLambda_void && isTarget_Void) { //void to Void conversion: // BODY; return null; ListBuffer<JCStatement> stats = new ListBuffer<>(); stats.append(make.at(expr).Exec(expr)); stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType))); return make.Block(0, stats.toList()); } else { //non-void to non-void conversion: // return (TYPE)BODY; JCExpression retExpr = transTypes.coerce(attrEnv, expr, restype); return make.at(retExpr).Block(0, List.<JCStatement>of(make.Return(retExpr))); } } finally { make.at(prevPos); } }
private void addOverrideBridges(DiagnosticPosition pos, MethodSymbol impl, MethodSymbol member, ClassSymbol c, ListBuffer<JCTree> bridges) { Type implErasure = impl.erasure(types); long flags = (impl.flags() & AccessFlags) | SYNTHETIC | BRIDGE | OVERRIDE_BRIDGE; member = new MethodSymbol(flags, member.name, member.type, c); JCMethodDecl md = make.MethodDef(member, null); JCExpression receiver = make.Super(types.supertype(c.type).tsym.erasure(types), c); Type calltype = erasure(impl.type.getReturnType()); JCExpression call = make.Apply(null, make.Select(receiver, impl).setType(calltype), translateArgs(make.Idents(md.params), implErasure.getParameterTypes(), null)) .setType(calltype); JCStatement stat = (member.getReturnType().hasTag(VOID)) ? make.Exec(call) : make.Return(coerce(call, member.erasure(types).getReturnType())); md.body = make.Block(0, List.of(stat)); c.members().enter(member); bridges.append(md); }
JCStatement stat = (origErasure.getReturnType().tag == VOID) ? make.Exec(call) : make.Return(coerce(call, bridgeType.getReturnType())); md.body = make.Block(0, List.of(stat));
JCStatement stat = (origErasure.getReturnType().tag == VOID) ? make.Exec(call) : make.Return(coerce(call, bridgeType.getReturnType())); md.body = make.Block(0, List.of(stat));
private void addOverrideBridges(DiagnosticPosition pos, MethodSymbol impl, MethodSymbol member, ClassSymbol c, ListBuffer<JCTree> bridges) { Type implErasure = impl.erasure(types); long flags = (impl.flags() & AccessFlags) | SYNTHETIC | BRIDGE | OVERRIDE_BRIDGE; member = new MethodSymbol(flags, member.name, member.type, c); JCMethodDecl md = make.MethodDef(member, null); JCExpression receiver = make.Super(types.supertype(c.type).tsym.erasure(types), c); Type calltype = erasure(impl.type.getReturnType()); JCExpression call = make.Apply(null, make.Select(receiver, impl).setType(calltype), translateArgs(make.Idents(md.params), implErasure.getParameterTypes(), null)) .setType(calltype); JCStatement stat = (member.getReturnType().hasTag(VOID)) ? make.Exec(call) : make.Return(coerce(call, member.erasure(types).getReturnType())); md.body = make.Block(0, List.of(stat)); c.members().enter(member); bridges.append(md); }
JCStatement stat = (origErasure.getReturnType().hasTag(VOID)) ? make.Exec(call) : make.Return(coerce(call, bridgeType.getReturnType())); md.body = make.Block(0, List.of(stat));
JCStatement stat = (origErasure.getReturnType().hasTag(VOID)) ? make.Exec(call) : make.Return(coerce(call, bridgeType.getReturnType())); md.body = make.Block(0, List.of(stat));