}
}
@Override
public boolean visit(MethodInvocation node) {
IMethodBinding b = node.resolveMethodBinding();
ITypeBinding rtb = b.getMethodDeclaration().getReturnType();
boolean erased = (rtb.isTypeVariable() || rtb.isArray()
&& rtb.getElementType().isTypeVariable())
&& !(node.getParent() instanceof ExpressionStatement);
if (erased) {
javaCast(rtb.getErasure(), b.getReturnType());
} else {
ITypeBinding actualRt = TransformUtil.returnType(b
.getMethodDeclaration().getDeclaringClass(), b
.getMethodDeclaration());
if (!actualRt.isEqualTo(rtb.getErasure())) {
javaCast(actualRt, rtb);
erased = true;
}
}
Expression expr = node.getExpression();
if (expr != null) {
ITypeBinding etb = expr.resolveTypeBinding().getErasure();
boolean isType = expr instanceof Name
&& ((Name) expr).resolveBinding() instanceof ITypeBinding;
int parens = 0;
if (!isType && hidden(etb, b)) {
// Method hidden by method in subclass
assert (!TransformUtil.isStatic(b));
staticCast(etb, b.getDeclaringClass());
parens++;
}
if (TransformUtil.needsJavaCast(etb, b.getDeclaringClass())) {
javaCast(etb, b.getDeclaringClass());
parens++;
}
if (!isType) {
npcAccept(expr);
} else {
expr.accept(this);
}
for (int i = 0; i < parens; ++i) {
print(")");
}
if (isType) {
print("::");
} else {
print("->");
}
hardDep(etb);
} else {
String bname = CName.of(b);
boolean found = localInScope(bname);
if (!b.getDeclaringClass().isEqualTo(type)) {
for (IVariableBinding vb : type.getDeclaredFields()) {
if (bname.equals(CName.of(vb))) {
found = true;
}
}
}
// If the name is already qualified, there won't be a clash
if (found
&& !needsQualification(node.getName(),
b.getDeclaringClass())) {
if (TransformUtil.isStatic(b)) {
print(CName.of(b.getDeclaringClass()) + "::");
} else {
boolean cast = !b.getDeclaringClass().isEqualTo(type);
if (cast) {
staticCast(type, b.getDeclaringClass());
}
print("this");
if (cast) {