*******************************************************************************/
package org.aspectj.weaver.bcel;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import org.aspectj.apache.bcel.classfile.LocalVariable;
import org.aspectj.apache.bcel.classfile.LocalVariableTable;
import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.BindingScope;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MethodDelegateTypeMunger;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.Bindings;
boolean hasAtAspectAnnotation = false;
boolean hasAtPrecedenceAnnotation = false;
+ boolean versionProcessed = false;
for (int i = 0; i < attributes.length; i++) {
Attribute attribute = attributes[i];
if (acceptAttribute(attribute)) {
break;
}
}
+ for (int i = attributes.length - 1; i >= 0; i--) {
+ Attribute attribute = attributes[i];
+ if (attribute.getName().equals(WeaverVersionInfo.AttributeName)) {
+ try {
+ VersionedDataInputStream s = new VersionedDataInputStream(new ByteArrayInputStream(
+ ((Unknown) attribute).getBytes()), null);
+ WeaverVersionInfo wvi = WeaverVersionInfo.read(s);
+ struct.ajAttributes.add(0, wvi);
+ versionProcessed = true;
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ }
+ if (!versionProcessed) {
+ // If we are in here due to a resetState() call (presumably because of reweavable state processing), the
+ // original type delegate will have been set with a version but that version will be missing from
+ // the new set of attributes (looks like a bug where the version attribute was not included in the
+ // data compressed into the attribute). So rather than 'defaulting' to current, we should use one
+ // if it set on the delegate for the type.
+ ReferenceTypeDelegate delegate = type.getDelegate();
+ if (delegate instanceof BcelObjectType) {
+ WeaverVersionInfo wvi = ((BcelObjectType) delegate).getWeaverVersionAttribute();
+ if (wvi != null && wvi.getMajorVersion() != WeaverVersionInfo.WEAVER_VERSION_MAJOR_UNKNOWN) {
+ // use this one
+ struct.ajAttributes.add(0, wvi);
+ versionProcessed = true;
+ }
+ }
+ if (!versionProcessed) {
+ struct.ajAttributes.add(0, new AjAttribute.WeaverVersionInfo());
+ }
+ }
// basic semantic check
if (hasAtPrecedenceAnnotation && !hasAtAspectAnnotation) {
perClause.setLocation(struct.context, -1, -1);// struct.context.getOffset(),
// struct.context.getOffset()+1);//FIXME
// AVASM
- // FIXME asc see related comment way about about the version...
- struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
+ // Not setting version here
+ //struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
AjAttribute.Aspect aspectAttribute = new AjAttribute.Aspect(perClause);
struct.ajAttributes.add(aspectAttribute);
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
return formalName;
}
}
-}
+}
\ No newline at end of file
package org.aspectj.weaver.bcel;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+ List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
+ methodAttributes.add(new AjAttribute.AjSynthetic());
+ methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember,
- Shadow.MethodCall, false), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
: Constants.INVOKEVIRTUAL, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+ m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
+ methodAttributes));
}
return inlineAccessor;
}
LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+ List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
+ methodAttributes.add(new AjAttribute.AjSynthetic());
+ methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember,
- Shadow.MethodCall, false), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
il.append(Utility.createInvoke(factory, Constants.INVOKESPECIAL, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+ m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
+ methodAttributes));
}
return inlineAccessor;
}
LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+ List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
+ methodAttributes.add(new AjAttribute.AjSynthetic());
+ methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet,
- false), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
il.append(Utility.createGet(factory, resolvedMember));
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(inlineAccessor.getReturnType())));
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+ m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
+ methodAttributes));
}
return inlineAccessor;
}
LazyMethodGen method = makeMethodGen(m_aspectGen, inlineAccessor);
// flag it synthetic, AjSynthetic
method.makeSynthetic();
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()));
+ List<AjAttribute> methodAttributes = new ArrayList<AjAttribute>();
+ methodAttributes.add(new AjAttribute.AjSynthetic());
+ methodAttributes.add(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(0), m_aspectGen.getConstantPool()));
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
- method.addAttribute(Utility.bcelAttribute(new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet,
- false), m_aspectGen.getConstantPool()));
+ method.addAttribute(Utility.bcelAttribute(methodAttributes.get(1), m_aspectGen.getConstantPool()));
inlineAccessorMethodGens.add(method);
}
il.append(Utility.createSet(factory, resolvedMember));
il.append(InstructionConstants.RETURN);
-
- m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod()));
+ m_inlineAccessorBcelMethods.put(accessor, new BcelMethod(m_aspectGen.getBcelObjectType(), method.getMethod(),
+ methodAttributes));
}
return inlineAccessor;
}
unpackAjAttributes(bcelObjectType.getWorld());
}
+ /**
+ * This constructor expects to be passed the attributes, rather than deserializing them.
+ */
+ BcelMethod(BcelObjectType declaringType, Method method, List<AjAttribute> attributes) {
+ super(method.getName().equals("<init>") ? CONSTRUCTOR : (method.getName().equals("<clinit>") ? STATIC_INITIALIZATION
+ : METHOD), declaringType.getResolvedTypeX(), declaringType.isInterface() ? method.getModifiers()
+ | Modifier.INTERFACE : method.getModifiers(), method.getName(), method.getSignature());
+ this.method = method;
+ sourceContext = declaringType.getResolvedTypeX().getSourceContext();
+ bcelObjectType = declaringType;
+ unpackJavaAttributes();
+ processAttributes(bcelObjectType.getWorld(), attributes);
+ }
+
// ----
private void unpackJavaAttributes() {
ExceptionTable exnTable = method.getExceptionTable();
checkedExceptions = (exnTable == null) ? UnresolvedType.NONE : UnresolvedType.forNames(exnTable.getExceptionNames());
-
}
@Override
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
import org.aspectj.apache.bcel.classfile.annotation.NameValuePair;
+import org.aspectj.asm.AsmManager;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.GenericSignature;
typeMungers = new ArrayList<ConcreteTypeMunger>();
declares = new ArrayList<Declare>();
processAttributes(l, pointcuts, false);
- l = AtAjAttributes.readAj5ClassAttributes(((BcelWorld) getResolvedTypeX().getWorld()).getModelAsAsmManager(), javaClass,
- getResolvedTypeX(), getResolvedTypeX().getSourceContext(), msgHandler, isCodeStyleAspect);
+ ReferenceType type = getResolvedTypeX();
+ AsmManager asmManager = ((BcelWorld) type.getWorld()).getModelAsAsmManager();
+ l = AtAjAttributes.readAj5ClassAttributes(asmManager, javaClass, type, type.getSourceContext(), msgHandler,
+ isCodeStyleAspect);
AjAttribute.Aspect deferredAspectAttribute = processAttributes(l, pointcuts, true);
if (pointcuts.size() == 0) {
setSourcefilename(sca.getSourceFileName());
}
} else if (a instanceof AjAttribute.WeaverVersionInfo) {
- wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver
- // version used to
- // build this type
+ // Set the weaver version used to build this type
+ wvInfo = (AjAttribute.WeaverVersionInfo) a;
} else {
throw new BCException("bad attribute " + a);
}
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.AnnotationOnTypeMunger;
import org.aspectj.weaver.BCException;
// new: reweavable default with clever diff
if (!world.isOverWeaving()) {
byte[] bytes = wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes());
- classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), bytes), true);
+ WeaverVersionInfo wvi = classType.getWeaverVersionAttribute();
+ JavaClass newJavaClass = Utility.makeJavaClass(classType.getJavaClass().getFileName(), bytes);
+ classType.setJavaClass(newJavaClass, true);
classType.getResolvedTypeX().ensureConsistent();
}
// } else {