@@ -271,6 +271,8 @@ public class AspectDeclaration extends TypeDeclaration { | |||
if (!isAbstract()) generatePerSupportMembers(classFile); | |||
generateInlineAccessMembers(classFile); | |||
classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.WeaverVersionInfo())); | |||
classFile.extraAttributes.add( | |||
new EclipseAttributeAdapter(new AjAttribute.Aspect(perClause))); |
@@ -14,6 +14,7 @@ | |||
package org.aspectj.ajdt.internal.compiler.ast; | |||
import java.lang.reflect.Modifier; | |||
import java.util.Iterator; | |||
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory; | |||
import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext; | |||
@@ -204,12 +205,30 @@ public class PointcutDeclaration extends AjMethodDeclaration { | |||
this.world = EclipseFactory.fromScopeLookupEnvironment(classScope); | |||
if (ignoreFurtherInvestigation) return ; | |||
classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute())); | |||
addVersionAttributeIfNecessary(classFile); | |||
if (generateSyntheticPointcutMethod) { | |||
super.generateCode(classScope,classFile); | |||
} | |||
return; | |||
} | |||
/** | |||
* Normally, pointcuts occur in aspects - aspects are always tagged with a weaver version attribute, | |||
* see AspectDeclaration. However, pointcuts can also occur in regular classes and in this case there | |||
* is no AspectDeclaration to ensure the attribute is added. So, this method adds the attribute | |||
* if someone else hasn't already. | |||
*/ | |||
private void addVersionAttributeIfNecessary(ClassFile classFile) { | |||
for (Iterator iter = classFile.extraAttributes.iterator(); iter.hasNext();) { | |||
EclipseAttributeAdapter element = (EclipseAttributeAdapter) iter.next(); | |||
if (CharOperation.equals(element.getNameChars(),weaverVersionChars)) return; | |||
} | |||
classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.WeaverVersionInfo())); | |||
} | |||
private static char[] weaverVersionChars = "org.aspectj.weaver.WeaverVersion".toCharArray(); | |||
protected int generateInfoAttributes(ClassFile classFile) { | |||
return super.generateInfoAttributes(classFile,true); | |||
} |
@@ -23,6 +23,7 @@ import org.aspectj.bridge.IMessageHandler; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
@@ -30,30 +31,35 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
// bcel to AjAttribute. | |||
class BcelAttributes { | |||
public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context,IMessageHandler msgHandler) { | |||
public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context,IMessageHandler msgHandler,AjAttribute.WeaverVersionInfo version) { | |||
List l = new ArrayList(); | |||
AjAttribute.WeaverVersionInfo version = new WeaverVersionInfo(); | |||
// first pass, look for version | |||
List forSecondPass = new ArrayList(); | |||
for (int i = as.length - 1; i >= 0; i--) { | |||
Attribute a = as[i]; | |||
if (a instanceof Unknown) { | |||
Unknown u = (Unknown) a; | |||
String name = u.getName(); | |||
if (name.startsWith(AjAttribute.AttributePrefix)) { | |||
AjAttribute attr = AjAttribute.read(version,name,u.getBytes(),context,msgHandler); | |||
if (attr!=null && attr instanceof AjAttribute.WeaverVersionInfo) { | |||
version = (AjAttribute.WeaverVersionInfo)attr; | |||
// Do a version check, this weaver can't process versions | |||
// from a future AspectJ (where the major number has changed) | |||
if (name.endsWith(WeaverVersionInfo.AttributeName)) { | |||
version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,msgHandler); | |||
if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) { | |||
throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+ | |||
WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString()); | |||
} | |||
} | |||
if (attr!=null) l.add(attr); | |||
} | |||
forSecondPass.add(a); | |||
} | |||
} | |||
} | |||
for (int i = forSecondPass.size()-1; i >= 0; i--) { | |||
Unknown a = (Unknown)forSecondPass.get(i); | |||
String name = a.getName(); | |||
AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,msgHandler); | |||
if (attr!=null) l.add(attr); | |||
} | |||
return l; | |||
} | |||
@@ -36,6 +36,7 @@ final class BcelField extends ResolvedMember { | |||
private ResolvedType[] annotationTypes; | |||
private AnnotationX[] annotations; | |||
private World world; | |||
private BcelObjectType bcelObjectType; | |||
BcelField(BcelObjectType declaringType, Field field) { | |||
super( | |||
@@ -46,6 +47,7 @@ final class BcelField extends ResolvedMember { | |||
field.getSignature()); | |||
this.field = field; | |||
this.world = declaringType.getResolvedTypeX().getWorld(); | |||
this.bcelObjectType = declaringType; | |||
unpackAttributes(world); | |||
checkedExceptions = UnresolvedType.NONE; | |||
} | |||
@@ -54,7 +56,7 @@ final class BcelField extends ResolvedMember { | |||
private void unpackAttributes(World world) { | |||
Attribute[] attrs = field.getAttributes(); | |||
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world.getMessageHandler()); | |||
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world.getMessageHandler(),bcelObjectType.getWeaverVersionAttribute()); | |||
as.addAll(AtAjAttributes.readAj5FieldAttributes(field, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler())); | |||
for (Iterator iter = as.iterator(); iter.hasNext();) { |
@@ -104,7 +104,7 @@ final class BcelMethod extends ResolvedMember { | |||
private void unpackAjAttributes(World world) { | |||
associatedShadowMunger = null; | |||
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler()); | |||
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler(),bcelObjectType.getWeaverVersionAttribute()); | |||
processAttributes(world, as); | |||
as = AtAjAttributes.readAj5MethodAttributes(method, this, world.resolve(getDeclaringType()), preResolvedPointcut,getSourceContext(world), world.getMessageHandler()); | |||
processAttributes(world,as); |
@@ -72,7 +72,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
private ResolvedPointcutDefinition[] pointcuts = null; | |||
private PerClause perClause = null; | |||
private WeaverStateInfo weaverState = null; | |||
private AjAttribute.WeaverVersionInfo wvInfo = null; | |||
private AjAttribute.WeaverVersionInfo wvInfo = AjAttribute.WeaverVersionInfo.UNKNOWN; | |||
private List typeMungers = Collections.EMPTY_LIST; | |||
private List declares = Collections.EMPTY_LIST; | |||
private ResolvedMember[] privilegedAccess = null; | |||
@@ -247,23 +247,13 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
typeMungers = new ArrayList(); | |||
declares = new ArrayList(); | |||
// Pass in empty list that can store things for readAj5 to process | |||
List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler()); | |||
List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler(),AjAttribute.WeaverVersionInfo.UNKNOWN); | |||
processAttributes(l,pointcuts,false); | |||
l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), getResolvedTypeX().getWorld().getMessageHandler(),isCodeStyleAspect); | |||
processAttributes(l,pointcuts,true); | |||
this.pointcuts = (ResolvedPointcutDefinition[]) | |||
pointcuts.toArray(new ResolvedPointcutDefinition[pointcuts.size()]); | |||
// Test isn't quite right, leaving this out for now... | |||
// if (isAspect() && wvInfo.getMajorVersion() == WeaverVersionInfo.UNKNOWN.getMajorVersion()) { | |||
// throw new BCException("Unable to continue, this version of AspectJ cannot use aspects as input that were built "+ | |||
// "with an AspectJ earlier than version 1.2.1. Please rebuild class: "+javaClass.getClassName()); | |||
// } | |||
// this.typeMungers = (BcelTypeMunger[]) | |||
// typeMungers.toArray(new BcelTypeMunger[typeMungers.size()]); | |||
// this.declares = (Declare[]) | |||
// declares.toArray(new Declare[declares.size()]); | |||
} | |||
@@ -500,7 +500,7 @@ public final class LazyMethodGen { | |||
if (enclosingClass != null && enclosingClass.getType() != null) { | |||
context = enclosingClass.getType().getSourceContext(); | |||
} | |||
List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null); | |||
List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,AjAttribute.WeaverVersionInfo.UNKNOWN); | |||
if (! as.isEmpty()) { | |||
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger... | |||
} |