body.append(InstructionFactory.createThis());
pos++;
}
Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
pos+=paramType.getSize();
}
body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
body.append(
InstructionFactory.createReturn(
BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));
if (weaver.getWorld().isInJava5Mode()) { // Don't need bridge methods if not in 1.5 mode.
createAnyBridgeMethodsForCovariance(weaver, munger, unMangledInterMethod, onType, gen, paramTypes);
}
} else {
//??? this is okay
//if (!(mg.getBody() == null)) throw new RuntimeException("bas");
}
// XXX make sure to check that we set exceptions properly on this guy.
weaver.addLazyMethodGen(newMethod);
weaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(),getSignature().getSourceLocation());
addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
return true;
} else if (onInterface && !Modifier.isAbstract(unMangledInterMethod.getModifiers())) {
// This means the 'gen' should be the top most implementor
// - if it is *not* then something went wrong after we worked
// out that it was the top most implementor (see pr49657)
if (!gen.getType().isTopmostImplementor(onType)) {
ResolvedType rtx = gen.getType().getTopmostImplementor(onType);
if (!rtx.isExposedToWeaver()) {
ISourceLocation sLoc = munger.getSourceLocation();
weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error(
WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR,rtx,getAspectType().getName()),
(sLoc==null?getAspectType().getSourceLocation():sLoc)));
} else {
// XXX what does this state mean?
// We have incorrectly identified what is the top most implementor and its not because
// a type wasn't exposed to the weaver
}
return false;
} else {
ResolvedMember mangledInterMethod =
AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false);
LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
if (mungingInterface) {
// we want the modifiers of the ITD to be used for all *implementors* of the
// interface, but the method itself we add to the interface must be public abstract
mg.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT);
}
Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType());
InstructionList body = mg.getBody();
InstructionFactory fact = gen.getFactory();
int pos = 0;
if (!mangledInterMethod.isStatic()) {
body.append(InstructionFactory.createThis());
pos++;
}
for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
pos+=paramType.getSize();
}
body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
Type t= BcelWorld.makeBcelType(interMethodBody.getReturnType());
if (!t.equals(returnType)) {
body.append(fact.createCast(t,returnType));
}
body.append(InstructionFactory.createReturn(returnType));
mg.definingType = onType;
weaver.addOrReplaceLazyMethodGen(mg);
addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
// Work out if we need a bridge method for the new method added to the topmostimplementor.
if (munger.getDeclaredSignature()!=null) { // Check if the munger being processed is a parameterized form of some original munger.
boolean needsbridging = false;
ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,munger.getSignature().getDeclaringType().resolve(getWorld()),false,munger.getTypeVariableAliases());
if (!toBridgeTo.getReturnType().getErasureSignature().equals(munger.getSignature().getReturnType().getErasureSignature())) needsbridging = true;
UnresolvedType[] originalParams = toBridgeTo.getParameterTypes();
UnresolvedType[] newParams = munger.getSignature().getParameterTypes();
for (int ii = 0;ii<originalParams.length;ii++) {
if (!originalParams[ii].getErasureSignature().equals(newParams[ii].getErasureSignature())) needsbridging=true;
}
if (toBridgeTo!=null && needsbridging) {
ResolvedMember bridgerMethod = AjcMemberMaker.bridgerToInterMethod(unMangledInterMethod,gen.getType());
ResolvedMember bridgingSetter = AjcMemberMaker.interMethod(toBridgeTo, aspectType, false);
// FIXME asc ----------------8<---------------- extract method
LazyMethodGen bridgeMethod = makeMethodGen(gen,bridgingSetter);
paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes());
Type[] bridgingToParms = BcelWorld.makeBcelTypes(unMangledInterMethod.getParameterTypes());
returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType());
body = bridgeMethod.getBody();
fact = gen.getFactory();
pos = 0;
if (!bridgingSetter.isStatic()) {
body.append(InstructionFactory.createThis());
pos++;
}
for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(unMangledInterMethod.getParameterTypes()[i].getErasureSignature()) ) {
// System.err.println("Putting in cast from "+paramType+" to "+bridgingToParms[i]);
body.append(fact.createCast(paramType,bridgingToParms[i]));
}
pos+=paramType.getSize();
}
body.append(Utility.createInvoke(fact, weaver.getWorld(), bridgerMethod));
body.append(InstructionFactory.createReturn(returnType));
gen.addMethodGen(bridgeMethod);