// If it doesn't target an interface and there is a body (i.e. it
// isnt abstract)
if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) {
InstructionList body = newMethod.getBody();
InstructionFactory fact = classGen.getFactory();
int pos = 0;
if (!Modifier.isStatic(unMangledInterMethod.getModifiers())) {
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, classWeaver.getWorld(), interMethodBody));
body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));
if (classWeaver.getWorld().isInJava5Mode()) { // Don't need bridge
// methods if not in
// 1.5 mode.
createAnyBridgeMethodsForCovariance(classWeaver, munger, unMangledInterMethod, onType, classGen, paramTypes);
}
} else {
// ??? this is okay
// if (!(mg.getBody() == null)) throw new
// RuntimeException("bas");
}
if (world.isInJava5Mode()) {
String basicSignature = mangledInterMethod.getSignature();
String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute();
if (!basicSignature.equals(genericSignature)) {
// Add a signature attribute to it
newMethod.addAttribute(createSignatureAttribute(classGen.getConstantPool(), genericSignature));
}
}
// XXX make sure to check that we set exceptions properly on this
// guy.
classWeaver.addLazyMethodGen(newMethod);
classWeaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(), getSignature().getSourceLocation());
addNeededSuperCallMethods(classWeaver, 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 (!classGen.getType().isTopmostImplementor(onType)) {
ResolvedType rtx = classGen.getType().getTopmostImplementor(onType);
if (rtx == null) {
// pr302460
// null means there is something wrong with what we are looking at
ResolvedType rt = classGen.getType();
if (rt.isInterface()) {
ISourceLocation sloc = munger.getSourceLocation();
classWeaver
.getWorld()
.getMessageHandler()
.handleMessage(
MessageUtil.error(
"ITD target "
+ rt.getName()
+ " is an interface but has been incorrectly determined to be the topmost implementor of "
+ onType.getName() + ". ITD is " + this.getSignature(), sloc));
}
if (!onType.isAssignableFrom(rt)) {
ISourceLocation sloc = munger.getSourceLocation();
classWeaver
.getWorld()
.getMessageHandler()
.handleMessage(
MessageUtil.error(
"ITD target " + rt.getName() + " doesn't appear to implement " + onType.getName()
+ " why did we consider it the top most implementor? ITD is "
+ this.getSignature(), sloc));
}
} else if (!rtx.isExposedToWeaver()) {
ISourceLocation sLoc = munger.getSourceLocation();
classWeaver
.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(classGen, mangledInterMethod);
// From 98901#29 - need to copy annotations across
if (classWeaver.getWorld().isInJava5Mode()) {
AnnotationAJ annotationsOnRealMember[] = null;
ResolvedType toLookOn = aspectType;
if (aspectType.isRawType()) {
toLookOn = aspectType.getGenericType();
}
ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, memberHoldingAnyAnnotations, false);
if (realMember == null) {
throw new BCException("Couldn't find ITD holder member '" + memberHoldingAnyAnnotations + "' on aspect "
+ aspectType);
}
annotationsOnRealMember = realMember.getAnnotations();
if (annotationsOnRealMember != null) {
for (AnnotationAJ annotationX : annotationsOnRealMember) {
AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a, classWeaver.getLazyClassGen().getConstantPool(), true);
mg.addAnnotation(new BcelAnnotation(ag, classWeaver.getWorld()));
}
}
copyOverParameterAnnotations(mg, realMember);
}
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 = classGen.getFactory();
int pos = 0;
if (!Modifier.isStatic(mangledInterMethod.getModifiers())) {
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, classWeaver.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;
if (world.isInJava5Mode()) {