@@ -258,6 +258,9 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele | |||
this.sourcefilename = pname.replace('.', '/') + '/' + sourceFileName; | |||
} | |||
} | |||
if (this.sourcefilename!=null && sourceContext instanceof SourceContextImpl) { | |||
((SourceContextImpl)sourceContext).setSourceFileName(this.sourcefilename); | |||
} | |||
} | |||
public ISourceLocation getSourceLocation() { |
@@ -15,8 +15,6 @@ import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
/** | |||
* This type represents the weavers abstraction of an annotation - it is | |||
* not tied to any underlying BCI toolkit. The weaver actualy handles these |
@@ -15,12 +15,12 @@ import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Set; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; | |||
import org.aspectj.apache.bcel.classfile.Utility; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen; | |||
/** | |||
* AnnotationX instances are holders for an annotation from either Bcel or | |||
@@ -31,8 +31,8 @@ public class AnnotationX { | |||
public static final AnnotationX[] NONE = new AnnotationX[0]; | |||
private Annotation theRealBcelAnnotation; | |||
private AnnotationAJ theRealEclipseAnnotation; | |||
private AnnotationGen theRealBcelAnnotation; | |||
private AnnotationAJ theRealEclipseAnnotation; // OPTIMIZE push out into compiler, not ever used if purely binary weaving ? | |||
private int mode = -1; | |||
private final static int MODE_ECLIPSE = 1; | |||
private final static int MODE_BCEL = 2; | |||
@@ -44,7 +44,7 @@ public class AnnotationX { | |||
private AnnotationX atTargetAnnotation = null; | |||
private Set supportedTargets = null; | |||
public AnnotationX(Annotation a,World world) { | |||
public AnnotationX(AnnotationGen a,World world) { | |||
theRealBcelAnnotation = a; | |||
signature = UnresolvedType.forSignature(theRealBcelAnnotation.getTypeSignature()).resolve(world); | |||
mode = MODE_BCEL; | |||
@@ -56,7 +56,7 @@ public class AnnotationX { | |||
mode= MODE_ECLIPSE; | |||
} | |||
public Annotation getBcelAnnotation() { | |||
public AnnotationGen getBcelAnnotation() { | |||
return theRealBcelAnnotation; | |||
} | |||
@@ -168,11 +168,11 @@ public class AnnotationX { | |||
Set supportedTargets = new HashSet(); | |||
if (mode==MODE_BCEL) { | |||
List values = getBcelAnnotation().getValues(); | |||
ElementNameValuePair envp = (ElementNameValuePair)values.get(0); | |||
ArrayElementValue aev = (ArrayElementValue)envp.getValue(); | |||
ElementValue[] evs = aev.getElementValuesArray(); | |||
ElementNameValuePairGen envp = (ElementNameValuePairGen)values.get(0); | |||
ArrayElementValueGen aev = (ArrayElementValueGen)envp.getValue(); | |||
ElementValueGen[] evs = aev.getElementValuesArray(); | |||
for (int i = 0; i < evs.length; i++) { | |||
EnumElementValue ev = (EnumElementValue)evs[i]; | |||
EnumElementValueGen ev = (EnumElementValueGen)evs[i]; | |||
supportedTargets.add(ev.getEnumValueString()); | |||
} | |||
} else { |
@@ -15,8 +15,8 @@ import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
/** | |||
* For implementing declare @type interacting with declare @parents during compilation - we need to be | |||
@@ -27,14 +27,14 @@ import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
* this will allow type resolution to succeed correctly. The FakeAnnotation never makes it to disk, since the weaver | |||
* does the job properly, attaching a real annotation. | |||
*/ | |||
public class FakeAnnotation extends Annotation { | |||
public class FakeAnnotation extends AnnotationGen { | |||
private String name; | |||
private String sig; | |||
private boolean isRuntimeVisible; | |||
public FakeAnnotation(String name,String sig,boolean isRuntimeVisible) { | |||
super(0,null,true); | |||
super(null,null,true,null); | |||
this.name = name; | |||
this.sig = sig; | |||
this.isRuntimeVisible = isRuntimeVisible; | |||
@@ -48,11 +48,11 @@ public class FakeAnnotation extends Annotation { | |||
return sig; | |||
} | |||
public void addElementNameValuePair(ElementNameValuePair evp) { | |||
public void addElementNameValuePair(ElementNameValuePairGen evp) { | |||
// doesnt need to know about name/value pairs | |||
} | |||
protected void dump(DataOutputStream dos) throws IOException { | |||
public void dump(DataOutputStream dos) throws IOException { | |||
// should be serialized | |||
} | |||
@@ -68,7 +68,7 @@ public class FakeAnnotation extends Annotation { | |||
return isRuntimeVisible; | |||
} | |||
protected void isRuntimeVisible(boolean b) { | |||
protected void setIsRuntimeVisible(boolean b) { | |||
} | |||
public String toShortString() { |
@@ -248,7 +248,7 @@ public class JoinPointSignature implements ResolvedMember { | |||
return realMember.toLongString(); | |||
} | |||
public Kind getKind() { | |||
public MemberKind getKind() { | |||
return realMember.getKind(); | |||
} | |||
@@ -386,7 +386,7 @@ public class JoinPointSignature implements ResolvedMember { | |||
realMember.resetName(newName); | |||
} | |||
public void resetKind(Kind newKind) { | |||
public void resetKind(MemberKind newKind) { | |||
realMember.resetKind(newKind); | |||
} | |||
@@ -18,52 +18,31 @@ import java.io.IOException; | |||
import java.util.Collection; | |||
import java.util.Iterator; | |||
import org.aspectj.util.TypeSafeEnum; | |||
public interface Member { | |||
public static class Kind extends TypeSafeEnum { | |||
public Kind(String name, int key) { super(name, key); } | |||
public static Kind read(DataInputStream s) throws IOException { | |||
int key = s.readByte(); | |||
switch(key) { | |||
case 1: return METHOD; | |||
case 2: return FIELD; | |||
case 3: return CONSTRUCTOR; | |||
case 4: return STATIC_INITIALIZATION; | |||
case 5: return POINTCUT; | |||
case 6: return ADVICE; | |||
case 7: return HANDLER; | |||
case 8: return MONITORENTER; | |||
case 9: return MONITOREXIT; | |||
} | |||
throw new BCException("weird kind " + key); | |||
} | |||
} | |||
public static final Member[] NONE = new Member[0]; | |||
public static final Kind METHOD = new Kind("METHOD", 1); | |||
public static final Kind FIELD = new Kind("FIELD", 2); | |||
public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3); | |||
public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4); | |||
public static final Kind POINTCUT = new Kind("POINTCUT", 5); | |||
public static final Kind ADVICE = new Kind("ADVICE", 6); | |||
public static final Kind HANDLER = new Kind("HANDLER", 7); | |||
public static final Kind MONITORENTER = new Kind("MONITORENTER", 8); | |||
public static final Kind MONITOREXIT = new Kind("MONITOREXIT", 9); | |||
public static final MemberKind METHOD = new MemberKind("METHOD", 1); | |||
public static final MemberKind FIELD = new MemberKind("FIELD", 2); | |||
public static final MemberKind CONSTRUCTOR = new MemberKind("CONSTRUCTOR", 3); | |||
public static final MemberKind STATIC_INITIALIZATION = new MemberKind("STATIC_INITIALIZATION", 4); | |||
public static final MemberKind POINTCUT = new MemberKind("POINTCUT", 5); | |||
public static final MemberKind ADVICE = new MemberKind("ADVICE", 6); | |||
public static final MemberKind HANDLER = new MemberKind("HANDLER", 7); | |||
public static final MemberKind MONITORENTER = new MemberKind("MONITORENTER", 8); | |||
public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT", 9); | |||
public static final AnnotationX[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationX[][]{}; | |||
public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][]{}; | |||
public MemberKind getKind(); | |||
public ResolvedMember resolve(World world); | |||
public int compareTo(Object other); | |||
public String toLongString(); | |||
public Kind getKind(); | |||
public UnresolvedType getDeclaringType(); | |||
public UnresolvedType getReturnType(); |
@@ -23,14 +23,16 @@ import java.util.List; | |||
public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
protected Kind kind; | |||
protected MemberKind kind; | |||
protected String name; | |||
protected UnresolvedType declaringType; | |||
protected int modifiers; | |||
protected UnresolvedType returnType; | |||
protected String name; | |||
protected UnresolvedType[] parameterTypes; | |||
private final String signature; | |||
private String paramSignature; | |||
// OPTIMIZE move out of the member! | |||
private boolean reportedCantFindDeclaringType = false; | |||
private boolean reportedUnresolvableMember = false; | |||
@@ -43,7 +45,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
private JoinPointSignatureIterator joinPointSignatures = null; | |||
public MemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
String name, | |||
@@ -68,7 +70,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
} | |||
public MemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
UnresolvedType returnType, | |||
@@ -433,7 +435,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
return buf.toString(); | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.Member#toLongString() | |||
*/ | |||
@@ -455,7 +456,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.Member#getKind() | |||
*/ | |||
public Kind getKind() { return kind; } | |||
public MemberKind getKind() { | |||
return kind; | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.Member#getDeclaringType() | |||
*/ | |||
@@ -712,7 +715,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
public String getSignatureMakerName() { | |||
if (getName().equals("<clinit>")) return "makeInitializerSig"; | |||
Kind kind = getKind(); | |||
MemberKind kind = getKind(); | |||
if (kind == METHOD) { | |||
return "makeMethodSig"; | |||
} else if (kind == CONSTRUCTOR) { | |||
@@ -741,7 +744,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
* @see org.aspectj.weaver.Member#getSignatureType() | |||
*/ | |||
public String getSignatureType() { | |||
Kind kind = getKind(); | |||
MemberKind kind = getKind(); | |||
if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature"; | |||
if (kind == METHOD) { | |||
@@ -771,7 +774,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
public String getSignatureString(World world) { | |||
if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world); | |||
Kind kind = getKind(); | |||
MemberKind kind = getKind(); | |||
if (kind == METHOD) { | |||
return getMethodSignatureString(world); | |||
} else if (kind == CONSTRUCTOR) { | |||
@@ -911,7 +914,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member { | |||
} | |||
protected String makeString(int i) { | |||
return Integer.toString(i, 16); //??? expensive | |||
return Integer.toString(i, 16); | |||
} | |||
@@ -0,0 +1,37 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.weaver; | |||
import java.io.DataInputStream; | |||
import java.io.IOException; | |||
import org.aspectj.util.TypeSafeEnum; | |||
public class MemberKind extends TypeSafeEnum { | |||
public MemberKind(String name, int key) { super(name, key); } | |||
public static MemberKind read(DataInputStream s) throws IOException { | |||
int key = s.readByte(); | |||
switch(key) { | |||
case 1: return Member.METHOD; | |||
case 2: return Member.FIELD; | |||
case 3: return Member.CONSTRUCTOR; | |||
case 4: return Member.STATIC_INITIALIZATION; | |||
case 5: return Member.POINTCUT; | |||
case 6: return Member.ADVICE; | |||
case 7: return Member.HANDLER; | |||
case 8: return Member.MONITORENTER; | |||
case 9: return Member.MONITOREXIT; | |||
} | |||
throw new BCException("weird kind " + key); | |||
} | |||
} |
@@ -155,7 +155,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe | |||
public boolean matches(ResolvedMember aCandidateMatch); | |||
public void resetName(String newName); | |||
public void resetKind(Kind newKind); | |||
public void resetKind(MemberKind newKind); | |||
public void resetModifiers(int newModifiers); | |||
public void resetReturnTypeToObjectArray(); | |||
@@ -60,7 +60,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
//XXX deprecate this in favor of the constructor below | |||
public ResolvedMemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
UnresolvedType returnType, | |||
@@ -73,7 +73,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
public ResolvedMemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
UnresolvedType returnType, | |||
@@ -86,7 +86,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
} | |||
public ResolvedMemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
UnresolvedType returnType, | |||
@@ -101,7 +101,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
} | |||
public ResolvedMemberImpl( | |||
Kind kind, | |||
MemberKind kind, | |||
UnresolvedType declaringType, | |||
int modifiers, | |||
String name, | |||
@@ -413,7 +413,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException { | |||
ResolvedMemberImpl m = new ResolvedMemberImpl(Kind.read(s), UnresolvedType.read(s), s.readInt(), | |||
ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(), | |||
s.readUTF(), s.readUTF()); | |||
m.checkedExceptions = UnresolvedType.readArray(s); | |||
@@ -838,7 +838,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno | |||
* using this method - this is safe. | |||
*/ | |||
public void resetName(String newName) {this.name = newName;} | |||
public void resetKind(Kind newKind) {this.kind=newKind; } | |||
public void resetKind(MemberKind newKind) { this.kind = newKind; } | |||
public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;} | |||
public void resetReturnTypeToObjectArray() { |
@@ -21,20 +21,28 @@ import org.aspectj.bridge.SourceLocation; | |||
public class SourceContextImpl implements ISourceContext { | |||
private AbstractReferenceTypeDelegate delegate; | |||
// private AbstractReferenceTypeDelegate delegate; | |||
private int[] lineBreaks; | |||
String sfname; | |||
public SourceContextImpl(AbstractReferenceTypeDelegate delegate) { | |||
this.delegate = delegate; | |||
// this.delegate = delegate; | |||
sfname = delegate.getSourcefilename(); | |||
} | |||
public void configureFromAttribute(String name,int []linebreaks) { | |||
this.delegate.setSourcefilename(name); | |||
// this.delegate.setSourcefilename(name); | |||
sfname = name; | |||
this.lineBreaks = linebreaks; | |||
} | |||
public void setSourceFileName(String name) { | |||
sfname = name; | |||
} | |||
private File getSourceFile() { | |||
return new File(delegate.getSourcefilename()); | |||
return new File(sfname); | |||
// return new File(delegate.getSourcefilename()); | |||
} | |||
public void tidy() {} |
@@ -28,9 +28,9 @@ import org.aspectj.apache.bcel.classfile.JavaClass; | |||
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.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations; | |||
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
@@ -75,9 +75,7 @@ import org.aspectj.weaver.patterns.SimpleScope; | |||
import org.aspectj.weaver.patterns.TypePattern; | |||
/** | |||
* Annotation defined aspect reader. | |||
* <p/> | |||
* It reads the Java 5 annotations and turns them into AjAttributes | |||
* Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes | |||
* | |||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||
*/ | |||
@@ -94,8 +92,6 @@ public class AtAjAttributes { | |||
/** | |||
* A struct that allows to add extra arguments without always breaking the API | |||
* | |||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||
*/ | |||
private static class AjAttributeStruct { | |||
@@ -149,8 +145,6 @@ public class AtAjAttributes { | |||
/** | |||
* A struct when we read @AJ on field | |||
* | |||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||
*/ | |||
private static class AjAttributeFieldStruct extends AjAttributeStruct { | |||
@@ -184,42 +178,38 @@ public class AtAjAttributes { | |||
* @return list of AjAttributes | |||
*/ | |||
public static List readAj5ClassAttributes(JavaClass javaClass, ReferenceType type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) { | |||
boolean containsPointcut = false; | |||
//FIXME AV - 1.5 feature limitation, kick after implemented | |||
boolean ignoreThisClass = javaClass.getClassName().charAt(0)=='o' && javaClass.getClassName().startsWith("org.aspectj.lang.annotation"); | |||
if (ignoreThisClass) return EMPTY_LIST; | |||
try { | |||
boolean containsAnnotationClassReference = false; | |||
Constant[] cpool = javaClass.getConstantPool().getConstantPool(); | |||
for (int i = 0; i < cpool.length; i++) { | |||
Constant constant = cpool[i]; | |||
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) { | |||
String constantValue = ((ConstantUtf8)constant).getBytes(); | |||
if (constantValue.length()>28 && constantValue.charAt(1)=='o') { | |||
if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) { | |||
containsAnnotationClassReference=true; | |||
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) { | |||
msgHandler.handleMessage( | |||
new Message( | |||
"Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')", | |||
IMessage.WARNING, | |||
null, | |||
type.getSourceLocation() | |||
) | |||
); | |||
} | |||
if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) { | |||
containsPointcut=true; | |||
} | |||
} | |||
} | |||
boolean containsPointcut = false; | |||
boolean containsAnnotationClassReference = false; | |||
Constant[] cpool = javaClass.getConstantPool().getConstantPool(); | |||
for (int i = 0; i < cpool.length; i++) { | |||
Constant constant = cpool[i]; | |||
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) { | |||
String constantValue = ((ConstantUtf8)constant).getBytes(); | |||
if (constantValue.length()>28 && constantValue.charAt(1)=='o') { | |||
if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) { | |||
containsAnnotationClassReference=true; | |||
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) { | |||
msgHandler.handleMessage( | |||
new Message( | |||
"Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')", | |||
IMessage.WARNING, | |||
null, | |||
type.getSourceLocation() | |||
) | |||
); | |||
} | |||
if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) { | |||
containsPointcut=true; | |||
} | |||
} | |||
} | |||
} | |||
if (!containsAnnotationClassReference) return EMPTY_LIST; | |||
} catch (Throwable t) { | |||
; | |||
} | |||
if (!containsAnnotationClassReference) return EMPTY_LIST; | |||
AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler); | |||
Attribute[] attributes = javaClass.getAttributes(); | |||
@@ -230,7 +220,7 @@ public class AtAjAttributes { | |||
Attribute attribute = attributes[i]; | |||
if (acceptAttribute(attribute)) { | |||
RuntimeAnnotations rvs = (RuntimeAnnotations) attribute; | |||
// we don't need to look for several attribute occurence since it cannot happen as per JSR175 | |||
// we don't need to look for several attribute occurrences since it cannot happen as per JSR175 | |||
if (!isCodeStyleAspect && !javaClass.isInterface()) { | |||
hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct); | |||
//TODO AV - if put outside the if isCodeStyleAspect then we would enable mix style | |||
@@ -318,8 +308,9 @@ public class AtAjAttributes { | |||
// code style declare error / warning / implements / parents are field attributes | |||
for (int i = 0; i < javaClass.getFields().length; i++) { | |||
Field field = javaClass.getFields()[i]; | |||
Field[] fs = javaClass.getFields(); | |||
for (int i = 0; i < fs.length; i++) { | |||
Field field = fs[i]; | |||
if (field.getName().startsWith(NameMangler.PREFIX)) continue; // already dealt with by ajc... | |||
//FIXME alex optimize, this method struct will gets recreated for advice extraction | |||
AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, null, type, context, msgHandler); | |||
@@ -499,7 +490,7 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleAspectAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) { | |||
Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.ASPECT_ANNOTATION); | |||
AnnotationGen aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.ASPECT_ANNOTATION); | |||
if (aspect != null) { | |||
// semantic check for inheritance (only one level up) | |||
boolean extendsAspect = false; | |||
@@ -511,7 +502,7 @@ public class AtAjAttributes { | |||
extendsAspect = struct.enclosingType.getSuperclass().isAspect(); | |||
} | |||
ElementNameValuePair aspectPerClause = getAnnotationElement(aspect, VALUE); | |||
ElementNameValuePairGen aspectPerClause = getAnnotationElement(aspect, VALUE); | |||
final PerClause perClause; | |||
if (aspectPerClause == null) { | |||
// empty value means singleton unless inherited | |||
@@ -619,9 +610,9 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handlePrecedenceAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeStruct struct) { | |||
Annotation aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPRECEDENCE_ANNOTATION); | |||
AnnotationGen aspect = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPRECEDENCE_ANNOTATION); | |||
if (aspect != null) { | |||
ElementNameValuePair precedence = getAnnotationElement(aspect, VALUE); | |||
ElementNameValuePairGen precedence = getAnnotationElement(aspect, VALUE); | |||
if (precedence != null) { | |||
String precedencePattern = precedence.getValue().stringifyValue(); | |||
PatternParser parser = new PatternParser(precedencePattern); | |||
@@ -643,7 +634,7 @@ public class AtAjAttributes { | |||
// private static boolean handleDeclareImplementsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) { | |||
// Annotation deci = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREIMPLEMENTS_ANNOTATION); | |||
// if (deci != null) { | |||
// ElementNameValuePair deciPatternNVP = getAnnotationElement(deci, VALUE); | |||
// ElementNameValuePairGen deciPatternNVP = getAnnotationElement(deci, VALUE); | |||
// String deciPattern = deciPatternNVP.getValue().stringifyValue(); | |||
// if (deciPattern != null) { | |||
// TypePattern typePattern = parseTypePattern(deciPattern, struct); | |||
@@ -683,9 +674,9 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleDeclareParentsAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) {//, ResolvedPointcutDefinition preResolvedPointcut) { | |||
Annotation decp = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPARENTS_ANNOTATION); | |||
AnnotationGen decp = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREPARENTS_ANNOTATION); | |||
if (decp != null) { | |||
ElementNameValuePair decpPatternNVP = getAnnotationElement(decp, VALUE); | |||
ElementNameValuePairGen decpPatternNVP = getAnnotationElement(decp, VALUE); | |||
String decpPattern = decpPatternNVP.getValue().stringifyValue(); | |||
if (decpPattern != null) { | |||
TypePattern typePattern = parseTypePattern(decpPattern, struct); | |||
@@ -710,9 +701,9 @@ public class AtAjAttributes { | |||
// do we have a defaultImpl=xxx.class (ie implementation) | |||
String defaultImplClassName = null; | |||
ElementNameValuePair defaultImplNVP = getAnnotationElement(decp, "defaultImpl"); | |||
ElementNameValuePairGen defaultImplNVP = getAnnotationElement(decp, "defaultImpl"); | |||
if (defaultImplNVP != null) { | |||
ClassElementValue defaultImpl = (ClassElementValue) defaultImplNVP.getValue(); | |||
ClassElementValueGen defaultImpl = (ClassElementValueGen) defaultImplNVP.getValue(); | |||
defaultImplClassName = UnresolvedType.forSignature(defaultImpl.getClassString()).getName(); | |||
if (defaultImplClassName.equals("org.aspectj.lang.annotation.DeclareParents")) { | |||
defaultImplClassName = null; | |||
@@ -809,9 +800,9 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleBeforeAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) { | |||
Annotation before = getAnnotation(runtimeAnnotations, AjcMemberMaker.BEFORE_ANNOTATION); | |||
AnnotationGen before = getAnnotation(runtimeAnnotations, AjcMemberMaker.BEFORE_ANNOTATION); | |||
if (before != null) { | |||
ElementNameValuePair beforeAdvice = getAnnotationElement(before, VALUE); | |||
ElementNameValuePairGen beforeAdvice = getAnnotationElement(before, VALUE); | |||
if (beforeAdvice != null) { | |||
// this/target/args binding | |||
String argumentNames = getArgNamesValue(before); | |||
@@ -869,9 +860,9 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleAfterAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) { | |||
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTER_ANNOTATION); | |||
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTER_ANNOTATION); | |||
if (after != null) { | |||
ElementNameValuePair afterAdvice = getAnnotationElement(after, VALUE); | |||
ElementNameValuePairGen afterAdvice = getAnnotationElement(after, VALUE); | |||
if (afterAdvice != null) { | |||
// this/target/args binding | |||
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0]; | |||
@@ -934,11 +925,11 @@ public class AtAjAttributes { | |||
BcelMethod owningMethod) | |||
throws ReturningFormalNotDeclaredInAdviceSignatureException | |||
{ | |||
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION); | |||
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERRETURNING_ANNOTATION); | |||
if (after != null) { | |||
ElementNameValuePair annValue = getAnnotationElement(after, VALUE); | |||
ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT); | |||
ElementNameValuePair annReturned = getAnnotationElement(after, RETURNING); | |||
ElementNameValuePairGen annValue = getAnnotationElement(after, VALUE); | |||
ElementNameValuePairGen annPointcut = getAnnotationElement(after, POINTCUT); | |||
ElementNameValuePairGen annReturned = getAnnotationElement(after, RETURNING); | |||
// extract the pointcut and returned type/binding - do some checks | |||
String pointcut = null; | |||
@@ -1034,11 +1025,11 @@ public class AtAjAttributes { | |||
BcelMethod owningMethod) | |||
throws ThrownFormalNotDeclaredInAdviceSignatureException | |||
{ | |||
Annotation after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION); | |||
AnnotationGen after = getAnnotation(runtimeAnnotations, AjcMemberMaker.AFTERTHROWING_ANNOTATION); | |||
if (after != null) { | |||
ElementNameValuePair annValue = getAnnotationElement(after, VALUE); | |||
ElementNameValuePair annPointcut = getAnnotationElement(after, POINTCUT); | |||
ElementNameValuePair annThrown = getAnnotationElement(after, THROWING); | |||
ElementNameValuePairGen annValue = getAnnotationElement(after, VALUE); | |||
ElementNameValuePairGen annPointcut = getAnnotationElement(after, POINTCUT); | |||
ElementNameValuePairGen annThrown = getAnnotationElement(after, THROWING); | |||
// extract the pointcut and throwned type/binding - do some checks | |||
String pointcut = null; | |||
@@ -1128,9 +1119,9 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleAroundAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct, ResolvedPointcutDefinition preResolvedPointcut) { | |||
Annotation around = getAnnotation(runtimeAnnotations, AjcMemberMaker.AROUND_ANNOTATION); | |||
AnnotationGen around = getAnnotation(runtimeAnnotations, AjcMemberMaker.AROUND_ANNOTATION); | |||
if (around != null) { | |||
ElementNameValuePair aroundAdvice = getAnnotationElement(around, VALUE); | |||
ElementNameValuePairGen aroundAdvice = getAnnotationElement(around, VALUE); | |||
if (aroundAdvice != null) { | |||
// this/target/args binding | |||
String argumentNames = getArgNamesValue(around); | |||
@@ -1187,9 +1178,9 @@ public class AtAjAttributes { | |||
* @return true if a pointcut was handled | |||
*/ | |||
private static boolean handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) { | |||
Annotation pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION); | |||
AnnotationGen pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION); | |||
if (pointcut==null) return false; | |||
ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, VALUE); | |||
ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE); | |||
// semantic check: the method must return void, or be "public static boolean" for if() support | |||
@@ -1281,10 +1272,10 @@ public class AtAjAttributes { | |||
* @return true if found | |||
*/ | |||
private static boolean handleDeclareErrorOrWarningAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeFieldStruct struct) { | |||
Annotation error = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREERROR_ANNOTATION); | |||
AnnotationGen error = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREERROR_ANNOTATION); | |||
boolean hasError = false; | |||
if (error != null) { | |||
ElementNameValuePair declareError = getAnnotationElement(error, VALUE); | |||
ElementNameValuePairGen declareError = getAnnotationElement(error, VALUE); | |||
if (declareError != null) { | |||
if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) { | |||
reportError("@DeclareError used on a non String constant field", struct); | |||
@@ -1301,10 +1292,10 @@ public class AtAjAttributes { | |||
} | |||
} | |||
} | |||
Annotation warning = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREWARNING_ANNOTATION); | |||
AnnotationGen warning = getAnnotation(runtimeAnnotations, AjcMemberMaker.DECLAREWARNING_ANNOTATION); | |||
boolean hasWarning = false; | |||
if (warning != null) { | |||
ElementNameValuePair declareWarning = getAnnotationElement(warning, VALUE); | |||
ElementNameValuePairGen declareWarning = getAnnotationElement(warning, VALUE); | |||
if (declareWarning != null) { | |||
if (!STRING_DESC.equals(struct.field.getSignature()) || struct.field.getConstantValue() == null) { | |||
reportError("@DeclareWarning used on a non String constant field", struct); | |||
@@ -1504,10 +1495,10 @@ public class AtAjAttributes { | |||
* @param annotationType | |||
* @return annotation | |||
*/ | |||
private static Annotation getAnnotation(RuntimeAnnotations rvs, UnresolvedType annotationType) { | |||
private static AnnotationGen getAnnotation(RuntimeAnnotations rvs, UnresolvedType annotationType) { | |||
final String annotationTypeName = annotationType.getName(); | |||
for (Iterator iterator = rvs.getAnnotations().iterator(); iterator.hasNext();) { | |||
Annotation rv = (Annotation) iterator.next(); | |||
AnnotationGen rv = (AnnotationGen) iterator.next(); | |||
if (annotationTypeName.equals(rv.getTypeName())) { | |||
return rv; | |||
} | |||
@@ -1523,9 +1514,9 @@ public class AtAjAttributes { | |||
* @param elementName | |||
* @return annotation NVP | |||
*/ | |||
private static ElementNameValuePair getAnnotationElement(Annotation annotation, String elementName) { | |||
private static ElementNameValuePairGen getAnnotationElement(AnnotationGen annotation, String elementName) { | |||
for (Iterator iterator1 = annotation.getValues().iterator(); iterator1.hasNext();) { | |||
ElementNameValuePair element = (ElementNameValuePair) iterator1.next(); | |||
ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next(); | |||
if (elementName.equals(element.getNameString())) { | |||
return element; | |||
} | |||
@@ -1536,9 +1527,9 @@ public class AtAjAttributes { | |||
/** | |||
* Return the argNames set for an annotation or null if it is not specified. | |||
*/ | |||
private static String getArgNamesValue(Annotation anno) { | |||
private static String getArgNamesValue(AnnotationGen anno) { | |||
for (Iterator iterator1 = anno.getValues().iterator(); iterator1.hasNext();) { | |||
ElementNameValuePair element = (ElementNameValuePair) iterator1.next(); | |||
ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next(); | |||
if (ARGNAMES.equals(element.getNameString())) { | |||
return element.getValue().stringifyValue(); | |||
} |
@@ -12,10 +12,8 @@ | |||
package org.aspectj.weaver.bcel; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.generic.FieldInstruction; | |||
import org.aspectj.apache.bcel.generic.GETFIELD; | |||
import org.aspectj.apache.bcel.generic.GETSTATIC; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
@@ -133,7 +131,7 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
private void openAroundAdvice(LazyMethodGen aroundAdvice) { | |||
InstructionHandle curr = aroundAdvice.getBody().getStart(); | |||
InstructionHandle end = aroundAdvice.getBody().getEnd(); | |||
ConstantPoolGen cpg = aroundAdvice.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPool cpg = aroundAdvice.getEnclosingClass().getConstantPool(); | |||
InstructionFactory factory = aroundAdvice.getEnclosingClass().getFactory(); | |||
boolean realizedCannotInline = false; | |||
@@ -205,7 +203,7 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
&& invoke.getSignature(cpg).equals(resolvedMember.getSignature()) | |||
&& !resolvedMember.isPublic()) { | |||
final ResolvedMember accessor; | |||
if ((inst instanceof GETFIELD) || (inst instanceof GETSTATIC)) { | |||
if ((inst.opcode==Constants.GETFIELD) || (inst.opcode==Constants.GETSTATIC)) { | |||
accessor = createOrGetInlineAccessorForFieldGet(resolvedMember); | |||
} else { | |||
accessor = createOrGetInlineAccessorForFieldSet(resolvedMember); | |||
@@ -259,13 +257,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
// flag it synthetic, AjSynthetic | |||
method.makeSynthetic(); | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen()) | |||
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()) | |||
); | |||
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute( | |||
Utility.bcelAttribute( | |||
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false), | |||
m_aspectGen.getConstantPoolGen() | |||
m_aspectGen.getConstantPool() | |||
) | |||
); | |||
@@ -320,13 +318,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
// flag it synthetic, AjSynthetic | |||
method.makeSynthetic(); | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen()) | |||
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()) | |||
); | |||
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute( | |||
Utility.bcelAttribute( | |||
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false), | |||
m_aspectGen.getConstantPoolGen() | |||
m_aspectGen.getConstantPool() | |||
) | |||
); | |||
@@ -382,13 +380,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
// flag it synthetic, AjSynthetic | |||
method.makeSynthetic(); | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen()) | |||
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()) | |||
); | |||
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute( | |||
Utility.bcelAttribute( | |||
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false), | |||
m_aspectGen.getConstantPoolGen() | |||
m_aspectGen.getConstantPool() | |||
) | |||
); | |||
@@ -440,13 +438,13 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger { | |||
// flag it synthetic, AjSynthetic | |||
method.makeSynthetic(); | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPoolGen()) | |||
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool()) | |||
); | |||
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut | |||
method.addAttribute( | |||
BcelAttributes.bcelAttribute( | |||
Utility.bcelAttribute( | |||
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false), | |||
m_aspectGen.getConstantPoolGen() | |||
m_aspectGen.getConstantPool() | |||
) | |||
); | |||
@@ -18,7 +18,6 @@ import java.util.List; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.Unknown; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ISourceContext; | |||
@@ -28,16 +27,50 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
// this is a class o' static methods for reading attributes. It's pretty much a bridge from | |||
// bcel to AjAttribute. | |||
// OPTIMIZE move the contents of this class to bcel Utility | |||
class BcelAttributes { | |||
/** | |||
* Process an array of Bcel attributes - looking for those with the name prefix org.aspectj.weaver. The returned | |||
* list contains the AspectJ attributes identified and unpacked to 'AjAttribute' objects. | |||
*/ | |||
public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context, | |||
World w,AjAttribute.WeaverVersionInfo version) { | |||
// public static List readAjAttributes(String classname,List as, ISourceContext context, | |||
// World w, AjAttribute.WeaverVersionInfo version) { | |||
// List l = new ArrayList(); | |||
// | |||
// // first pass, look for version | |||
// List forSecondPass = new ArrayList(); | |||
// for (int i = as.size() - 1; i >= 0; i--) { | |||
// Attribute a = (Attribute)as.get(i); | |||
// if (a instanceof Unknown) { | |||
// Unknown u = (Unknown) a; | |||
// String name = u.getName(); | |||
// if (name.charAt(0)=='o') { // 'o'rg.aspectj | |||
// if (name.startsWith(AjAttribute.AttributePrefix)) { | |||
// if (name.endsWith(WeaverVersionInfo.AttributeName)) { | |||
// version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w); | |||
// 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()); | |||
// } | |||
// } | |||
// 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,w); | |||
// if (attr!=null) l.add(attr); | |||
// } | |||
// return l; | |||
// } | |||
public static List readAjAttributes(String classname, Attribute[] as, ISourceContext context, World w, AjAttribute.WeaverVersionInfo version) { | |||
List l = new ArrayList(); | |||
// first pass, look for version | |||
List forSecondPass = new ArrayList(); | |||
for (int i = as.length - 1; i >= 0; i--) { | |||
@@ -45,37 +78,34 @@ class BcelAttributes { | |||
if (a instanceof Unknown) { | |||
Unknown u = (Unknown) a; | |||
String name = u.getName(); | |||
if (name.charAt(0)=='o') { // 'o'rg.aspectj | |||
if (name.charAt(0) == 'o') { // 'o'rg.aspectj | |||
if (name.startsWith(AjAttribute.AttributePrefix)) { | |||
if (name.endsWith(WeaverVersionInfo.AttributeName)) { | |||
version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w); | |||
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()); | |||
version = (AjAttribute.WeaverVersionInfo) AjAttribute.read(version, name, u.getBytes(), context, w); | |||
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()); | |||
} | |||
} | |||
} | |||
forSecondPass.add(a); | |||
} | |||
} | |||
} | |||
} | |||
for (int i = forSecondPass.size()-1; i >= 0; i--) { | |||
Unknown a = (Unknown)forSecondPass.get(i); | |||
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,w); | |||
if (attr!=null) l.add(attr); | |||
AjAttribute attr = AjAttribute.read(version, name, a.getBytes(), context, w); | |||
if (attr != null) l.add(attr); | |||
} | |||
return l; | |||
} | |||
public static Attribute bcelAttribute(AjAttribute a, ConstantPoolGen pool) { | |||
int nameIndex = pool.addUtf8(a.getNameString()); | |||
byte[] bytes = a.getBytes(); | |||
int length = bytes.length; | |||
return new Unknown(nameIndex, length, bytes, pool.getConstantPool()); | |||
} | |||
} |
@@ -13,7 +13,6 @@ | |||
package org.aspectj.weaver.bcel; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
@@ -44,10 +43,10 @@ public class BcelCflowCounterFieldAdder extends BcelTypeMunger { | |||
// Create the field declaration. | |||
// Something like: "public static final CflowCounter ajc$cflowCounter$0;" | |||
Field f = new FieldGen(cflowCounterField.getModifiers(), | |||
FieldGen f = new FieldGen(cflowCounterField.getModifiers(), | |||
BcelWorld.makeBcelType(cflowCounterField.getReturnType()), | |||
cflowCounterField.getName(), | |||
gen.getConstantPoolGen()).getField(); | |||
gen.getConstantPool()); | |||
gen.addField(f,getSourceLocation()); | |||
@@ -14,7 +14,6 @@ | |||
package org.aspectj.weaver.bcel; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
@@ -36,10 +35,10 @@ public class BcelCflowStackFieldAdder extends BcelTypeMunger { | |||
LazyClassGen gen = weaver.getLazyClassGen(); | |||
if (!gen.getType().equals(cflowStackField.getDeclaringType())) return false; | |||
Field f = new FieldGen(cflowStackField.getModifiers(), | |||
FieldGen f = new FieldGen(cflowStackField.getModifiers(), | |||
BcelWorld.makeBcelType(cflowStackField.getReturnType()), | |||
cflowStackField.getName(), | |||
gen.getConstantPoolGen()).getField(); | |||
gen.getConstantPool()); | |||
gen.addField(f,getSourceLocation()); | |||
LazyMethodGen clinit = gen.getAjcPreClinit(); //StaticInitializer(); |
@@ -27,45 +27,29 @@ import java.util.Properties; | |||
import java.util.Set; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.generic.ANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.CPInstruction; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.FieldInstruction; | |||
import org.aspectj.apache.bcel.generic.GOTO; | |||
import org.aspectj.apache.bcel.generic.GOTO_W; | |||
import org.aspectj.apache.bcel.generic.INVOKESPECIAL; | |||
import org.aspectj.apache.bcel.generic.IndexedInstruction; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.generic.InstructionCP; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionSelect; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
import org.aspectj.apache.bcel.generic.LineNumberTag; | |||
import org.aspectj.apache.bcel.generic.LocalVariableInstruction; | |||
import org.aspectj.apache.bcel.generic.LocalVariableTag; | |||
import org.aspectj.apache.bcel.generic.MONITORENTER; | |||
import org.aspectj.apache.bcel.generic.MONITOREXIT; | |||
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.MethodGen; | |||
import org.aspectj.apache.bcel.generic.NEW; | |||
import org.aspectj.apache.bcel.generic.NEWARRAY; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.PUTFIELD; | |||
import org.aspectj.apache.bcel.generic.PUTSTATIC; | |||
import org.aspectj.apache.bcel.generic.RET; | |||
import org.aspectj.apache.bcel.generic.ReturnInstruction; | |||
import org.aspectj.apache.bcel.generic.Select; | |||
import org.aspectj.apache.bcel.generic.StoreInstruction; | |||
import org.aspectj.apache.bcel.generic.Tag; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.Message; | |||
@@ -76,6 +60,7 @@ import org.aspectj.bridge.context.ContextToken; | |||
import org.aspectj.util.PartialOrder; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.AjcMemberMaker; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.AsmRelationshipProvider; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ConcreteTypeMunger; | |||
@@ -102,6 +87,7 @@ import org.aspectj.weaver.patterns.ExactTypePattern; | |||
import org.aspectj.weaver.tools.Trace; | |||
import org.aspectj.weaver.tools.TraceFactory; | |||
class BcelClassWeaver implements IClassWeaver { | |||
private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelClassWeaver.class); | |||
@@ -131,7 +117,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
private final BcelObjectType ty; // alias of clazz.getType() | |||
private final BcelWorld world; // alias of ty.getWorld() | |||
private final ConstantPoolGen cpg; // alias of clazz.getConstantPoolGen() | |||
private final ConstantPool cpg; // alias of clazz.getConstantPoolGen() | |||
private final InstructionFactory fact; // alias of clazz.getFactory(); | |||
@@ -174,7 +160,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
this.typeMungers = typeMungers; | |||
this.lateTypeMungers = lateTypeMungers; | |||
this.ty = clazz.getBcelObjectType(); | |||
this.cpg = clazz.getConstantPoolGen(); | |||
this.cpg = clazz.getConstantPool(); | |||
this.fact = clazz.getFactory(); | |||
fastMatchShadowMungers(shadowMungers); | |||
@@ -799,8 +785,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
if (annotationsToAdd==null) annotationsToAdd = new ArrayList(); | |||
Annotation a = decaM.getAnnotationX().getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); | |||
AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); | |||
annotationsToAdd.add(ag); | |||
mg.addAnnotation(decaM.getAnnotationX()); | |||
@@ -832,9 +818,10 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
if (annotationsToAdd==null) annotationsToAdd = new ArrayList(); | |||
Annotation a = decaM.getAnnotationX().getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); | |||
annotationsToAdd.add(ag); | |||
AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); | |||
//CUSTARD superfluous? | |||
//AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); | |||
annotationsToAdd.add(a); | |||
mg.addAnnotation(decaM.getAnnotationX()); | |||
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod()); | |||
@@ -849,7 +836,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
if (annotationsToAdd!=null) { | |||
Method oldMethod = mg.getMethod(); | |||
MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen(),false);// dont use tags, they won't get repaired like for woven methods. | |||
MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPool(),false);// dont use tags, they won't get repaired like for woven methods. | |||
for (Iterator iter = annotationsToAdd.iterator(); iter.hasNext();) { | |||
AnnotationGen a = (AnnotationGen) iter.next(); | |||
myGen.addAnnotation(a); | |||
@@ -1086,9 +1073,9 @@ class BcelClassWeaver implements IClassWeaver { | |||
return isChanged; | |||
} | |||
private boolean dontAddTwice(DeclareAnnotation decaF, Annotation [] dontAddMeTwice){ | |||
private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX [] dontAddMeTwice){ | |||
for (int i = 0; i < dontAddMeTwice.length; i++){ | |||
Annotation ann = dontAddMeTwice[i]; | |||
AnnotationX ann = dontAddMeTwice[i]; | |||
if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){ | |||
//dontAddMeTwice[i] = null; // incase it really has been added twice! | |||
return true; | |||
@@ -1130,18 +1117,18 @@ class BcelClassWeaver implements IClassWeaver { | |||
List decaFs = getMatchingSubset(allDecafs,clazz.getType()); | |||
if (decaFs.isEmpty()) return false; // nothing more to do | |||
Field[] fields = clazz.getFieldGens(); | |||
List fields = clazz.getFieldGens(); | |||
if (fields!=null) { | |||
Set unusedDecafs = new HashSet(); | |||
unusedDecafs.addAll(decaFs); | |||
for (int fieldCounter = 0;fieldCounter<fields.length;fieldCounter++) { | |||
BcelField aBcelField = new BcelField(clazz.getBcelObjectType(),fields[fieldCounter]); | |||
for (int fieldCounter = 0;fieldCounter<fields.size();fieldCounter++) { | |||
BcelField aBcelField = (BcelField)fields.get(fieldCounter);//new BcelField(clazz.getBcelObjectType(),fields[fieldCounter]); | |||
if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) { | |||
// Single first pass | |||
List worthRetrying = new ArrayList(); | |||
boolean modificationOccured = false; | |||
Annotation [] dontAddMeTwice = fields[fieldCounter].getAnnotations(); | |||
AnnotationX[] dontAddMeTwice = aBcelField.getAnnotations(); | |||
// go through all the declare @field statements | |||
for (Iterator iter = decaFs.iterator(); iter.hasNext();) { | |||
@@ -1159,22 +1146,22 @@ class BcelClassWeaver implements IClassWeaver { | |||
if(decaF.getAnnotationX().isRuntimeVisible()){ // isAnnotationWithRuntimeRetention(clazz.getJavaClass(world))){ | |||
//if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){ | |||
// it should be runtime visible, so put it on the Field | |||
Annotation a = decaF.getAnnotationX().getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); | |||
FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen()); | |||
myGen.addAnnotation(ag); | |||
Field newField = myGen.getField(); | |||
// Annotation a = decaF.getAnnotationX().getBcelAnnotation(); | |||
// AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); | |||
// FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen()); | |||
// myGen.addAnnotation(ag); | |||
// Field newField = myGen.getField(); | |||
aBcelField.addAnnotation(decaF.getAnnotationX()); | |||
clazz.replaceField(fields[fieldCounter],newField); | |||
fields[fieldCounter]=newField; | |||
// clazz.replaceField(fields[fieldCounter],newField); | |||
// fields[fieldCounter]=newField; | |||
} else{ | |||
aBcelField.addAnnotation(decaF.getAnnotationX()); | |||
} | |||
} | |||
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]); | |||
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs()); | |||
reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF); | |||
isChanged = true; | |||
modificationOccured = true; | |||
@@ -1202,7 +1189,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
continue; // skip this one... | |||
} | |||
aBcelField.addAnnotation(decaF.getAnnotationX()); | |||
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]); | |||
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs()); | |||
isChanged = true; | |||
modificationOccured = true; | |||
forRemoval.add(decaF); | |||
@@ -1270,13 +1257,13 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
// TAG: WeavingMessage | |||
private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, Field[] fields, int fieldCounter, DeclareAnnotation decaF) { | |||
private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, List fields, int fieldCounter, DeclareAnnotation decaF) { | |||
if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)){ | |||
Field theField = fields[fieldCounter]; | |||
BcelField theField = (BcelField)fields.get(fieldCounter); | |||
world.getMessageHandler().handleMessage( | |||
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, | |||
new String[]{ | |||
theField.toString() + "' of type '" + clazz.getName(), | |||
theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(), | |||
clazz.getFileName(), | |||
decaF.getAnnotationString(), | |||
"field", | |||
@@ -1389,7 +1376,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
private boolean isThisCall(InstructionHandle ih) { | |||
INVOKESPECIAL inst = (INVOKESPECIAL) ih.getInstruction(); | |||
InvokeInstruction inst = (InvokeInstruction) ih.getInstruction(); | |||
return inst.getClassName(cpg).equals(clazz.getName()); | |||
} | |||
@@ -1520,7 +1507,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
InstructionHandle walker = body.getStart(); | |||
List rets = new ArrayList(); | |||
while (walker!=null) { | |||
if (walker.getInstruction() instanceof ReturnInstruction) { | |||
if (walker.getInstruction().isReturnInstruction()) { | |||
rets.add(walker); | |||
} | |||
walker = walker.getNext(); | |||
@@ -1549,10 +1536,10 @@ class BcelClassWeaver implements IClassWeaver { | |||
// ignore | |||
} else if (targeter instanceof LineNumberTag) { | |||
// ignore | |||
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { | |||
// move it... | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof BranchInstruction) { | |||
// } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) { | |||
// // move it... | |||
// targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof InstructionBranch) { | |||
// move it | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else { | |||
@@ -1612,8 +1599,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
parttwo.append(InstructionFactory.MONITORENTER); | |||
String fieldname = synchronizedMethod.getEnclosingClass().allocateField("class$"); | |||
Field f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE, | |||
Type.getType(Class.class),fieldname,synchronizedMethod.getEnclosingClass().getConstantPoolGen()).getField(); | |||
FieldGen f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE, | |||
Type.getType(Class.class),fieldname,synchronizedMethod.getEnclosingClass().getConstantPool()); | |||
synchronizedMethod.getEnclosingClass().addField(f, null); | |||
// 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; | |||
@@ -1699,7 +1686,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
InstructionHandle walker = body.getStart(); | |||
List rets = new ArrayList(); | |||
while (walker!=null) { //!walker.equals(body.getEnd())) { | |||
if (walker.getInstruction() instanceof ReturnInstruction) { | |||
if (walker.getInstruction().isReturnInstruction()) { | |||
rets.add(walker); | |||
} | |||
walker = walker.getNext(); | |||
@@ -1729,10 +1716,10 @@ class BcelClassWeaver implements IClassWeaver { | |||
// ignore | |||
} else if (targeter instanceof LineNumberTag) { | |||
// ignore | |||
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { | |||
// move it... | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof BranchInstruction) { | |||
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { | |||
// // move it... | |||
// targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof InstructionBranch) { | |||
// move it | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else { | |||
@@ -1807,7 +1794,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
InstructionHandle walker = body.getStart(); | |||
List rets = new ArrayList(); | |||
while (walker!=null) { //!walker.equals(body.getEnd())) { | |||
if (walker.getInstruction() instanceof ReturnInstruction) { | |||
if (walker.getInstruction().isReturnInstruction()) { | |||
rets.add(walker); | |||
} | |||
walker = walker.getNext(); | |||
@@ -1837,10 +1824,10 @@ class BcelClassWeaver implements IClassWeaver { | |||
// ignore | |||
} else if (targeter instanceof LineNumberTag) { | |||
// ignore | |||
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { | |||
// move it... | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof BranchInstruction) { | |||
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { | |||
// // move it... | |||
// targeter.updateTarget(element, monitorExitBlockStart); | |||
} else if (targeter instanceof InstructionBranch) { | |||
// move it | |||
targeter.updateTarget(element, monitorExitBlockStart); | |||
} else { | |||
@@ -1899,8 +1886,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
InstructionList sourceList = donor.getBody(); | |||
Map srcToDest = new HashMap(); | |||
ConstantPoolGen donorCpg = donor.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPoolGen recipientCpg = recipient.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPool donorCpg = donor.getEnclosingClass().getConstantPool(); | |||
ConstantPool recipientCpg = recipient.getEnclosingClass().getConstantPool(); | |||
boolean isAcrossClass = donorCpg != recipientCpg; | |||
@@ -1912,11 +1899,13 @@ class BcelClassWeaver implements IClassWeaver { | |||
{ | |||
Instruction fresh = Utility.copyInstruction(src.getInstruction()); | |||
InstructionHandle dest; | |||
if (fresh instanceof CPInstruction) { | |||
// OPTIMIZE optimize this stuff? | |||
if (fresh.isConstantPoolInstruction()) { | |||
// need to reset index to go to new constant pool. This is totally | |||
// a computation leak... we're testing this LOTS of times. Sigh. | |||
if (isAcrossClass) { | |||
CPInstruction cpi = (CPInstruction) fresh; | |||
InstructionCP cpi = (InstructionCP) fresh; | |||
cpi.setIndex( | |||
recipientCpg.addConstant( | |||
donorCpg.getConstant(cpi.getIndex()), | |||
@@ -1925,19 +1914,20 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
if (src.getInstruction() == Range.RANGEINSTRUCTION) { | |||
dest = ret.append(Range.RANGEINSTRUCTION); | |||
} else if (fresh instanceof ReturnInstruction) { | |||
} else if (fresh.isReturnInstruction()) { | |||
if (keepReturns) { | |||
dest = ret.append(fresh); | |||
} else { | |||
dest = | |||
ret.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); | |||
} | |||
} else if (fresh instanceof BranchInstruction) { | |||
dest = ret.append((BranchInstruction) fresh); | |||
} else if (fresh instanceof InstructionBranch) { | |||
dest = ret.append((InstructionBranch) fresh); | |||
} else if ( | |||
fresh instanceof LocalVariableInstruction || fresh instanceof RET) { | |||
IndexedInstruction indexed = (IndexedInstruction) fresh; | |||
int oldIndex = indexed.getIndex(); | |||
fresh.isLocalVariableInstruction() || fresh instanceof RET) { | |||
// IndexedInstruction indexed = (IndexedInstruction) fresh; | |||
int oldIndex = fresh.getIndex(); | |||
int freshIndex; | |||
if (!frameEnv.hasKey(oldIndex)) { | |||
freshIndex = recipient.allocateLocal(2); | |||
@@ -1945,7 +1935,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
} else { | |||
freshIndex = frameEnv.get(oldIndex); | |||
} | |||
indexed.setIndex(freshIndex); | |||
fresh.setIndex(freshIndex); | |||
dest = ret.append(fresh); | |||
} else { | |||
dest = ret.append(fresh); | |||
@@ -1962,8 +1952,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
Instruction inst = dest.getInstruction(); | |||
// retarget branches | |||
if (inst instanceof BranchInstruction) { | |||
BranchInstruction branch = (BranchInstruction) inst; | |||
if (inst instanceof InstructionBranch) { | |||
InstructionBranch branch = (InstructionBranch) inst; | |||
InstructionHandle oldTarget = branch.getTarget(); | |||
InstructionHandle newTarget = | |||
(InstructionHandle) srcToDest.get(oldTarget); | |||
@@ -1972,8 +1962,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
// this was a return instruction we previously replaced | |||
} else { | |||
branch.setTarget(newTarget); | |||
if (branch instanceof Select) { | |||
Select select = (Select) branch; | |||
if (branch instanceof InstructionSelect) { | |||
InstructionSelect select = (InstructionSelect) branch; | |||
InstructionHandle[] oldTargets = select.getTargets(); | |||
for (int k = oldTargets.length - 1; k >= 0; k--) { | |||
select.setTarget( | |||
@@ -2056,7 +2046,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
InstructionHandle dest; | |||
if (src.getInstruction() == Range.RANGEINSTRUCTION) { | |||
dest = newList.append(Range.RANGEINSTRUCTION); | |||
} else if (fresh instanceof ReturnInstruction) { | |||
} else if (fresh.isReturnInstruction()) { | |||
if (keepReturns) { | |||
newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot)); | |||
newList.append(InstructionConstants.MONITOREXIT); | |||
@@ -2065,12 +2055,12 @@ class BcelClassWeaver implements IClassWeaver { | |||
dest = | |||
newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); | |||
} | |||
} else if (fresh instanceof BranchInstruction) { | |||
dest = newList.append((BranchInstruction) fresh); | |||
} else if (fresh instanceof InstructionBranch) { | |||
dest = newList.append((InstructionBranch) fresh); | |||
} else if ( | |||
fresh instanceof LocalVariableInstruction || fresh instanceof RET) { | |||
IndexedInstruction indexed = (IndexedInstruction) fresh; | |||
int oldIndex = indexed.getIndex(); | |||
fresh.isLocalVariableInstruction() || fresh instanceof RET) { | |||
//IndexedInstruction indexed = (IndexedInstruction) fresh; | |||
int oldIndex = fresh.getIndex(); | |||
int freshIndex; | |||
// if (!frameEnv.hasKey(oldIndex)) { | |||
// freshIndex = recipient.allocateLocal(2); | |||
@@ -2078,7 +2068,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
// } else { | |||
freshIndex = oldIndex;//frameEnv.get(oldIndex); | |||
// } | |||
indexed.setIndex(freshIndex); | |||
fresh.setIndex(freshIndex); | |||
dest = newList.append(fresh); | |||
} else { | |||
dest = newList.append(fresh); | |||
@@ -2095,8 +2085,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
Instruction inst = dest.getInstruction(); | |||
// retarget branches | |||
if (inst instanceof BranchInstruction) { | |||
BranchInstruction branch = (BranchInstruction) inst; | |||
if (inst instanceof InstructionBranch) { | |||
InstructionBranch branch = (InstructionBranch) inst; | |||
InstructionHandle oldTarget = branch.getTarget(); | |||
InstructionHandle newTarget = | |||
(InstructionHandle) srcToDest.get(oldTarget); | |||
@@ -2105,8 +2095,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
// this was a return instruction we previously replaced | |||
} else { | |||
branch.setTarget(newTarget); | |||
if (branch instanceof Select) { | |||
Select select = (Select) branch; | |||
if (branch instanceof InstructionSelect) { | |||
InstructionSelect select = (InstructionSelect) branch; | |||
InstructionHandle[] oldTargets = select.getTargets(); | |||
for (int k = oldTargets.length - 1; k >= 0; k--) { | |||
select.setTarget( | |||
@@ -2278,11 +2268,11 @@ class BcelClassWeaver implements IClassWeaver { | |||
if (start == null) return null; | |||
Instruction inst = start.getInstruction(); | |||
if (inst instanceof INVOKESPECIAL | |||
&& ((INVOKESPECIAL) inst).getName(cpg).equals("<init>")) { | |||
if (inst.opcode==Constants.INVOKESPECIAL | |||
&& ((InvokeInstruction) inst).getName(cpg).equals("<init>")) { | |||
depth--; | |||
if (depth == 0) return start; | |||
} else if (inst instanceof NEW) { | |||
} else if (inst.opcode==Constants.NEW) { | |||
depth++; | |||
} | |||
start = start.getNext(); | |||
@@ -2470,7 +2460,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
if (er.getCatchType() == null) continue; | |||
if (isInitFailureHandler(ih)) return; | |||
if (!(ih.getInstruction() instanceof StoreInstruction) && ih.getInstruction().getOpcode()!=Constants.NOP) { | |||
if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode()!=Constants.NOP) { | |||
// If using cobertura, the catch block stats with INVOKESTATIC rather than ASTORE, in order that the ranges | |||
// for the methodcall and exceptionhandler shadows that occur at this same | |||
// line, we need to modify the instruction list to split them - adding a | |||
@@ -2508,7 +2498,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
) { | |||
FieldInstruction fi = (FieldInstruction) i; | |||
if (fi instanceof PUTFIELD || fi instanceof PUTSTATIC) { | |||
if (fi.opcode==Constants.PUTFIELD || fi.opcode==Constants.PUTSTATIC) { | |||
// check for sets of constant fields. We first check the previous | |||
// instruction. If the previous instruction is a LD_WHATEVER (push | |||
// constant on the stack) then we must resolve the field to determine | |||
@@ -2537,12 +2527,12 @@ class BcelClassWeaver implements IClassWeaver { | |||
} | |||
} else if (i instanceof InvokeInstruction) { | |||
InvokeInstruction ii = (InvokeInstruction) i; | |||
if (ii.getMethodName(clazz.getConstantPoolGen()).equals("<init>")) { | |||
if (ii.getMethodName(clazz.getConstantPool()).equals("<init>")) { | |||
if (canMatch(Shadow.ConstructorCall)) | |||
match( | |||
BcelShadow.makeConstructorCall(world, mg, ih, enclosingShadow), | |||
shadowAccumulator); | |||
} else if (ii instanceof INVOKESPECIAL) { | |||
} else if (ii.opcode==Constants.INVOKESPECIAL) { | |||
String onTypeName = ii.getClassName(cpg); | |||
if (onTypeName.equals(mg.getEnclosingClass().getName())) { | |||
// we are private | |||
@@ -2553,26 +2543,25 @@ class BcelClassWeaver implements IClassWeaver { | |||
} else { | |||
matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); | |||
} | |||
} else if (world.isJoinpointArrayConstructionEnabled() && | |||
(i instanceof NEWARRAY || i instanceof ANEWARRAY || i instanceof MULTIANEWARRAY)) { | |||
} else if (world.isJoinpointArrayConstructionEnabled() && i.isArrayCreationInstruction()) { | |||
if (canMatch(Shadow.ConstructorCall)) { | |||
boolean debug = false; | |||
if (debug) System.err.println("Found new array instruction: "+i); | |||
if (i instanceof ANEWARRAY) { | |||
ANEWARRAY arrayInstruction = (ANEWARRAY)i; | |||
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); | |||
if (i.opcode==Constants.ANEWARRAY) { | |||
// ANEWARRAY arrayInstruction = (ANEWARRAY)i; | |||
ObjectType arrayType = i.getLoadClassType(clazz.getConstantPool()); | |||
if (debug) System.err.println("Array type is "+arrayType); | |||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||
match(ctorCallShadow,shadowAccumulator); | |||
} else if (i instanceof NEWARRAY) { | |||
NEWARRAY arrayInstruction = (NEWARRAY)i; | |||
Type arrayType = arrayInstruction.getType(); | |||
} else if (i.opcode==Constants.NEWARRAY) { | |||
// NEWARRAY arrayInstruction = (NEWARRAY)i; | |||
Type arrayType = i.getType(); | |||
if (debug) System.err.println("Array type is "+arrayType); | |||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||
match(ctorCallShadow,shadowAccumulator); | |||
} else if (i instanceof MULTIANEWARRAY) { | |||
MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i; | |||
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPoolGen()); | |||
ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPool()); | |||
if (debug) System.err.println("Array type is "+arrayType); | |||
BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); | |||
match(ctorCallShadow,shadowAccumulator); | |||
@@ -2587,9 +2576,9 @@ class BcelClassWeaver implements IClassWeaver { | |||
// } else if (i instanceof AASTORE) { | |||
// // ... magic required | |||
} else if ( world.isJoinpointSynchronizationEnabled() && | |||
((i instanceof MONITORENTER) || (i instanceof MONITOREXIT))) { | |||
((i.getOpcode()==Constants.MONITORENTER) || (i.getOpcode()==Constants.MONITOREXIT))) { | |||
// if (canMatch(Shadow.Monitoring)) { | |||
if (i instanceof MONITORENTER) { | |||
if (i.getOpcode()==Constants.MONITORENTER) { | |||
BcelShadow monitorEntryShadow = BcelShadow.makeMonitorEnter(world,mg,ih,enclosingShadow); | |||
match(monitorEntryShadow,shadowAccumulator); | |||
} else { | |||
@@ -2607,8 +2596,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
// 'putstatic ajc$initFailureCause'. If it is then we are | |||
// in the handler we created in AspectClinit.generatePostSyntheticCode() | |||
InstructionHandle twoInstructionsAway = ih.getNext().getNext(); | |||
if (twoInstructionsAway.getInstruction() instanceof PUTSTATIC) { | |||
String name = ((PUTSTATIC)twoInstructionsAway.getInstruction()).getFieldName(cpg); | |||
if (twoInstructionsAway.getInstruction().opcode==Constants.PUTSTATIC) { | |||
String name = ((FieldInstruction)twoInstructionsAway.getInstruction()).getFieldName(cpg); | |||
if (name.equals(NameMangler.INITFAILURECAUSE_FIELD_NAME)) return true; | |||
} | |||
return false; | |||
@@ -2794,13 +2783,12 @@ class BcelClassWeaver implements IClassWeaver { | |||
effectiveSig.getShadowKind(), rm), shadowAccumulator); | |||
} | |||
} else { | |||
if (canMatch(Shadow.MethodCall)) { | |||
if (canMatch(Shadow.MethodCall)) | |||
match( | |||
BcelShadow.makeMethodCall(world, mg, ih, enclosingShadow), | |||
shadowAccumulator); | |||
} | |||
} | |||
} | |||
// static ... so all worlds will share the config for the first one created... | |||
private static boolean checkedXsetForLowLevelContextCapturing = false; |
@@ -10,7 +10,6 @@ | |||
* PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.bcel; | |||
import java.util.Collections; | |||
@@ -20,10 +19,12 @@ import java.util.List; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.GenericSignatureParser; | |||
import org.aspectj.apache.bcel.classfile.Signature; | |||
import org.aspectj.apache.bcel.classfile.Synthetic; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.BCException; | |||
@@ -31,6 +32,7 @@ import org.aspectj.weaver.ResolvedMemberImpl; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; | |||
final class BcelField extends ResolvedMemberImpl { | |||
@@ -45,12 +47,14 @@ final class BcelField extends ResolvedMemberImpl { | |||
private BcelObjectType bcelObjectType; | |||
private UnresolvedType genericFieldType = null; | |||
private boolean unpackedGenericSignature = false; | |||
private boolean annotationsAdded = false; | |||
BcelField(BcelObjectType declaringType, Field field) { | |||
super( | |||
FIELD, | |||
declaringType.getResolvedTypeX(), | |||
field.getAccessFlags(), | |||
field.getModifiers(), | |||
field.getName(), | |||
field.getSignature()); | |||
this.field = field; | |||
@@ -59,20 +63,41 @@ final class BcelField extends ResolvedMemberImpl { | |||
unpackAttributes(world); | |||
checkedExceptions = UnresolvedType.NONE; | |||
} | |||
/** | |||
* Constructs an instance that wrappers a Field object, but where we do not (yet) have | |||
* a BcelObjectType - usually because the containing type (and this field) are being | |||
* constructed at runtime (so there is no .class file to retrieve). | |||
*/ | |||
BcelField(String declaringTypeName, Field field,World world) { | |||
super(FIELD,UnresolvedType.forName(declaringTypeName),field.getModifiers(),field.getName(),field.getSignature()); | |||
this.field = field; | |||
this.world = world; | |||
this.bcelObjectType = null; | |||
unpackAttributes(world); | |||
checkedExceptions = UnresolvedType.NONE; | |||
} | |||
// ---- | |||
private void unpackAttributes(World world) { | |||
Attribute[] attrs = field.getAttributes(); | |||
List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),attrs, getSourceContext(world),world,bcelObjectType.getWeaverVersionAttribute()); | |||
as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler())); | |||
for (Iterator iter = as.iterator(); iter.hasNext();) { | |||
AjAttribute a = (AjAttribute) iter.next(); | |||
if (a instanceof AjAttribute.AjSynthetic) { | |||
isAjSynthetic = true; | |||
} else { | |||
throw new BCException("weird field attribute " + a); | |||
if (attrs!=null && attrs.length>0) { | |||
List as = BcelAttributes.readAjAttributes( | |||
getDeclaringType().getClassName(), | |||
attrs, | |||
getSourceContext(world), | |||
world, | |||
(bcelObjectType!=null?bcelObjectType.getWeaverVersionAttribute():WeaverVersionInfo.CURRENT)); | |||
as.addAll(AtAjAttributes.readAj5FieldAttributes(field, this, world.resolve(getDeclaringType()), getSourceContext(world), world.getMessageHandler())); | |||
for (Iterator iter = as.iterator(); iter.hasNext();) { | |||
AjAttribute a = (AjAttribute) iter.next(); | |||
if (a instanceof AjAttribute.AjSynthetic) { | |||
isAjSynthetic = true; | |||
} else { | |||
throw new BCException("weird field attribute " + a); | |||
} | |||
} | |||
} | |||
isAjSynthetic = false; | |||
@@ -130,7 +155,7 @@ final class BcelField extends ResolvedMemberImpl { | |||
private void ensureAnnotationTypesRetrieved() { | |||
if (annotationTypes == null) { | |||
Annotation annos[] = field.getAnnotations(); | |||
AnnotationGen annos[] = field.getAnnotations(); | |||
if (annos==null || annos.length==0) { | |||
annotationTypes = Collections.EMPTY_SET; | |||
annotations = AnnotationX.NONE; | |||
@@ -138,7 +163,7 @@ final class BcelField extends ResolvedMemberImpl { | |||
annotationTypes = new HashSet(); | |||
annotations = new AnnotationX[annos.length]; | |||
for (int i = 0; i < annos.length; i++) { | |||
Annotation annotation = annos[i]; | |||
AnnotationGen annotation = annos[i]; | |||
annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature()))); | |||
annotations[i] = new AnnotationX(annotation,world); | |||
} | |||
@@ -160,11 +185,13 @@ final class BcelField extends ResolvedMemberImpl { | |||
} | |||
// Add it to the set of annotation types | |||
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world)); | |||
annotationsAdded=true; | |||
// FIXME asc this call here suggests we are managing the annotations at | |||
// too many levels, here in BcelField we keep a set and in the lower 'field' | |||
// object we keep a set - we should think about reducing this to one | |||
// level?? | |||
field.addAnnotation(annotation.getBcelAnnotation()); | |||
//field.addAnnotation(annotation.getBcelAnnotation()); | |||
// FIXME CUSTARD | |||
} | |||
/** | |||
@@ -176,6 +203,29 @@ final class BcelField extends ResolvedMemberImpl { | |||
return genericFieldType; | |||
} | |||
public Field getFieldAsIs() { return field; } | |||
// FIXME asc badly performing code ftw ! | |||
public Field getField(ConstantPool cpg) { | |||
if (!annotationsAdded) return field; | |||
FieldGen fg = new FieldGen(field,cpg); | |||
AnnotationGen[] alreadyHas = fg.getAnnotations(); | |||
if (annotations!=null) { | |||
for (int i = 0; i < annotations.length; i++) { | |||
AnnotationX array_element = annotations[i]; | |||
boolean alreadyHasIt = false; | |||
for (int j = 0; j < alreadyHas.length; j++) { | |||
AnnotationGen gen = alreadyHas[j]; | |||
if (gen.getTypeName().equals(array_element.getTypeName())) alreadyHasIt = true; | |||
} | |||
if (!alreadyHasIt) fg.addAnnotation(new AnnotationGen(array_element.getBcelAnnotation(),cpg,true)); | |||
} | |||
} | |||
field = fg.getField(); | |||
annotationsAdded = false; // we are now correct again | |||
return field; | |||
} | |||
private void unpackGenericSignature() { | |||
if (unpackedGenericSignature) { return; } | |||
if (!world.isInJava5Mode()) { |
@@ -15,6 +15,7 @@ package org.aspectj.weaver.bcel; | |||
import java.lang.reflect.Modifier; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -32,14 +33,15 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTable; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.Signature; | |||
import org.aspectj.apache.bcel.classfile.Signature.TypeVariableSignature; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.SourceLocation; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.MemberKind; | |||
import org.aspectj.weaver.ResolvedMemberImpl; | |||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||
import org.aspectj.weaver.ResolvedType; | |||
@@ -52,12 +54,7 @@ import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSigna | |||
public final class BcelMethod extends ResolvedMemberImpl { | |||
private Method method; | |||
private boolean isAjSynthetic; | |||
private boolean isSynthetic; | |||
private boolean knowIfSynthetic = false; | |||
private ShadowMunger associatedShadowMunger; | |||
private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has pre-resolved the pointcut of some @Advice | |||
@@ -67,10 +64,26 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
private AjAttribute.EffectiveSignatureAttribute effectiveSignature; | |||
private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber; | |||
private World world; | |||
private BcelObjectType bcelObjectType; | |||
private boolean parameterNamesInitialized = false; | |||
private int bitflags; | |||
private static final int KNOW_IF_SYNTHETIC = 0x0001; | |||
private static final int PARAMETER_NAMES_INITIALIZED = 0x0002; | |||
private static final int CAN_BE_PARAMETERIZED = 0x0004; | |||
private static final int UNPACKED_GENERIC_SIGNATURE = 0x0008; | |||
private static final int HAS_EFFECTIVE_SIGNATURE = 0x0010; | |||
private static final int HAS_PRERESOLVED_POINTCUT = 0x0020; | |||
private static final int IS_AJ_SYNTHETIC = 0x0040; | |||
private static final int IS_SYNTHETIC = 0x0080; | |||
private static final int IS_SYNTHETIC_INVERSE = 0x7f7f; // all bits but IS_SYNTHETIC (and topmost bit) | |||
private static final int HAS_ASSOCIATED_SHADOWMUNGER = 0x0100; | |||
private static final int HAS_GENERIC_RETPARAM_TYPES = 0x0200; | |||
private static final int HAS_ANNOTATIONS = 0x0400; | |||
private static final int HAVE_DETERMINED_ANNOTATIONS = 0x0800; | |||
private static final int HAS_MD_LINE_NUMBER_ATTRIBUTE= 0x1000; | |||
private boolean canBeParameterized = false; | |||
// genericized version of return and parameter types | |||
@@ -84,16 +97,15 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
(method.getName().equals("<clinit>") ? STATIC_INITIALIZATION : METHOD), | |||
declaringType.getResolvedTypeX(), | |||
declaringType.isInterface() | |||
? method.getAccessFlags() | Modifier.INTERFACE | |||
: method.getAccessFlags(), | |||
method.getName(), | |||
? method.getModifiers() | Modifier.INTERFACE | |||
: method.getModifiers(), | |||
method.getName(), | |||
method.getSignature()); | |||
this.method = method; | |||
this.sourceContext = declaringType.getResolvedTypeX().getSourceContext(); | |||
this.world = declaringType.getResolvedTypeX().getWorld(); | |||
this.bcelObjectType = declaringType; | |||
unpackJavaAttributes(); | |||
unpackAjAttributes(world); | |||
unpackAjAttributes(bcelObjectType.getWorld()); | |||
} | |||
// ---- | |||
@@ -135,12 +147,12 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
typename.equals("org.aspectj.lang.annotation.Before") || | |||
typename.equals("org.aspectj.lang.annotation.Around") || | |||
typename.startsWith("org.aspectj.lang.annotation.After")) { | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
if (a!=null) { | |||
List values = a.getValues(); | |||
for (Iterator iterator = values.iterator(); iterator | |||
.hasNext();) { | |||
ElementNameValuePair nvPair = (ElementNameValuePair) iterator.next(); | |||
ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next(); | |||
if (nvPair.getNameString().equals("argNames")) { | |||
String argNames = nvPair.getValue().stringifyValue(); | |||
StringTokenizer argNameTokenizer = new StringTokenizer(argNames," ,"); | |||
@@ -195,7 +207,8 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
associatedShadowMunger = ((AjAttribute.AdviceAttribute)a).reify(this, world); | |||
// return; | |||
} else if (a instanceof AjAttribute.AjSynthetic) { | |||
isAjSynthetic = true; | |||
bitflags|=IS_AJ_SYNTHETIC; | |||
// isAjSynthetic = true; | |||
} else if (a instanceof AjAttribute.EffectiveSignatureAttribute) { | |||
//System.out.println("found effective: " + this); | |||
effectiveSignature = (AjAttribute.EffectiveSignatureAttribute)a; | |||
@@ -211,7 +224,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
// for testing - if we have this attribute, return it - will return null if it doesnt know anything | |||
public AjAttribute[] getAttributes(String name) { | |||
List results = new ArrayList(); | |||
List l = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world,bcelObjectType.getWeaverVersionAttribute()); | |||
List l = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(bcelObjectType.getWorld()),bcelObjectType.getWorld(),bcelObjectType.getWeaverVersionAttribute()); | |||
for (Iterator iter = l.iterator(); iter.hasNext();) { | |||
AjAttribute element = (AjAttribute) iter.next(); | |||
if (element.getNameString().equals(name)) results.add(element); | |||
@@ -247,7 +260,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
} | |||
public boolean isAjSynthetic() { | |||
return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX); | |||
return (bitflags&IS_AJ_SYNTHETIC)!=0;//isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX); | |||
} | |||
//FIXME ??? needs an isSynthetic method | |||
@@ -291,7 +304,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
return ret; | |||
} | |||
public Kind getKind() { | |||
public MemberKind getKind() { | |||
if (associatedShadowMunger != null) { | |||
return ADVICE; | |||
} else { | |||
@@ -310,7 +323,11 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
public AnnotationX[] getAnnotations() { | |||
ensureAnnotationsRetrieved(); | |||
return annotations; | |||
if ((bitflags&HAS_ANNOTATIONS)!=0) { | |||
return annotations; | |||
} else { | |||
return AnnotationX.NONE; | |||
} | |||
} | |||
public ResolvedType[] getAnnotationTypes() { | |||
@@ -323,6 +340,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
public AnnotationX getAnnotationOfType(UnresolvedType ofType) { | |||
ensureAnnotationsRetrieved(); | |||
if ((bitflags&HAS_ANNOTATIONS)==0) return null; | |||
for (int i=0; i<annotations.length; i++) { | |||
if (annotations[i].getTypeName().equals(ofType.getName())) return annotations[i]; | |||
} | |||
@@ -331,51 +349,64 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
public void addAnnotation(AnnotationX annotation) { | |||
ensureAnnotationsRetrieved(); | |||
// Add it to the set of annotations | |||
int len = annotations.length; | |||
AnnotationX[] ret = new AnnotationX[len+1]; | |||
System.arraycopy(annotations, 0, ret, 0, len); | |||
ret[len] = annotation; | |||
annotations = ret; | |||
if ((bitflags&HAS_ANNOTATIONS)==0) { | |||
annotations = new AnnotationX[1]; | |||
annotations[0]=annotation; | |||
} else { | |||
// Add it to the set of annotations | |||
int len = annotations.length; | |||
AnnotationX[] ret = new AnnotationX[len+1]; | |||
System.arraycopy(annotations, 0, ret, 0, len); | |||
ret[len] = annotation; | |||
annotations = ret; | |||
} | |||
bitflags|=HAS_ANNOTATIONS; | |||
// Add it to the set of annotation types | |||
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(world)); | |||
if (annotationTypes==Collections.EMPTY_SET) annotationTypes = new HashSet(); | |||
annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(bcelObjectType.getWorld())); | |||
// FIXME asc looks like we are managing two 'bunches' of annotations, one | |||
// here and one in the real 'method' - should we reduce it to one layer? | |||
method.addAnnotation(annotation.getBcelAnnotation()); | |||
// method.addAnnotation(annotation.getBcelAnnotation()); | |||
} | |||
private void ensureAnnotationsRetrieved() { | |||
if (method == null) return; // must be ok, we have evicted it | |||
if (annotationTypes == null || method.getAnnotations().length!=annotations.length) { // sometimes the list changes underneath us! | |||
Annotation annos[] = method.getAnnotations(); | |||
annotationTypes = new HashSet(); | |||
annotations = new AnnotationX[annos.length]; | |||
for (int i = 0; i < annos.length; i++) { | |||
Annotation annotation = annos[i]; | |||
annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature()))); | |||
annotations[i] = new AnnotationX(annotation,world); | |||
} | |||
} | |||
if ((bitflags&HAVE_DETERMINED_ANNOTATIONS)!=0) return; | |||
bitflags|=HAVE_DETERMINED_ANNOTATIONS; | |||
AnnotationGen annos[] = method.getAnnotations(); | |||
if (annos.length!=0) { | |||
annotationTypes = new HashSet(); | |||
annotations = new AnnotationX[annos.length]; | |||
for (int i = 0; i < annos.length; i++) { | |||
AnnotationGen annotation = annos[i]; | |||
annotationTypes.add(bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annotation.getTypeSignature()))); | |||
annotations[i] = new AnnotationX(annotation,bcelObjectType.getWorld()); | |||
} | |||
bitflags|=HAS_ANNOTATIONS; | |||
} else { | |||
annotationTypes=Collections.EMPTY_SET; | |||
} | |||
} | |||
private void ensureParameterAnnotationsRetrieved() { | |||
if (method == null) return; // must be ok, we have evicted it | |||
Annotation[][] pAnns = method.getParameterAnnotations(); | |||
AnnotationGen[][] pAnns = method.getParameterAnnotations(); | |||
if (parameterAnnotationTypes==null || pAnns.length!=parameterAnnotationTypes.length) { | |||
if (pAnns == Method.NO_PARAMETER_ANNOTATIONS) { | |||
parameterAnnotationTypes = BcelMethod.NO_PARAMETER_ANNOTATION_TYPES; | |||
parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS; | |||
} else { | |||
Annotation annos[][] = method.getParameterAnnotations(); | |||
AnnotationGen annos[][] = method.getParameterAnnotations(); | |||
parameterAnnotations = new AnnotationX[annos.length][]; | |||
parameterAnnotationTypes = new ResolvedType[annos.length][]; | |||
for (int i=0;i<annos.length;i++) { | |||
parameterAnnotations[i] = new AnnotationX[annos[i].length]; | |||
parameterAnnotationTypes[i] = new ResolvedType[annos[i].length]; | |||
for (int j=0;j<annos[i].length;j++) { | |||
parameterAnnotations[i][j] = new AnnotationX(annos[i][j],world); | |||
parameterAnnotationTypes[i][j] = world.resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature())); | |||
parameterAnnotations[i][j] = new AnnotationX(annos[i][j],bcelObjectType.getWorld()); | |||
parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature())); | |||
} | |||
} | |||
} | |||
@@ -423,7 +454,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
private void unpackGenericSignature() { | |||
if (unpackedGenericSignature) return; | |||
unpackedGenericSignature = true; | |||
if (!world.isInJava5Mode()) { | |||
if (!bcelObjectType.getWorld().isInJava5Mode()) { | |||
this.genericReturnType = getReturnType(); | |||
this.genericParameterTypes = getParameterTypes(); | |||
return; | |||
@@ -443,7 +474,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable( | |||
methodFtp, | |||
mSig.formalTypeParameters, | |||
world); | |||
bcelObjectType.getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// this is a development bug, so fail fast with good info | |||
throw new IllegalStateException( | |||
@@ -463,7 +494,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
try { | |||
genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
returnTypeSignature, formals, | |||
world); | |||
bcelObjectType.getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
@@ -477,7 +508,7 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
try { | |||
genericParameterTypes[i] = | |||
BcelGenericSignatureToTypeXConverter.typeSignature2TypeX( | |||
paramTypeSigs[i],formals,world); | |||
paramTypeSigs[i],formals,bcelObjectType.getWorld()); | |||
} catch (GenericSignatureFormatException e) { | |||
// development bug, fail fast with good info | |||
throw new IllegalStateException( | |||
@@ -508,27 +539,38 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
} | |||
public boolean isSynthetic() { | |||
if (!knowIfSynthetic) workOutIfSynthetic(); | |||
return isSynthetic; | |||
if ((bitflags&KNOW_IF_SYNTHETIC)==0) { | |||
workOutIfSynthetic(); | |||
} | |||
return (bitflags&IS_SYNTHETIC)!=0;//isSynthetic; | |||
} | |||
// Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a modifier (4096 or 0x1000) | |||
private void workOutIfSynthetic() { | |||
knowIfSynthetic=true; | |||
if ((bitflags&KNOW_IF_SYNTHETIC)!=0) return; | |||
bitflags|=KNOW_IF_SYNTHETIC; | |||
// knowIfSynthetic=true; | |||
JavaClass jc = bcelObjectType.getJavaClass(); | |||
isSynthetic=false; | |||
bitflags&=IS_SYNTHETIC_INVERSE; // unset the bit | |||
// isSynthetic=false; | |||
if (jc==null) return; // what the hell has gone wrong? | |||
if (jc.getMajor()<49/*Java5*/) { | |||
// synthetic is an attribute | |||
String[] synthetics = getAttributeNames(false); | |||
if (synthetics!=null) { | |||
for (int i = 0; i < synthetics.length; i++) { | |||
if (synthetics[i].equals("Synthetic")) {isSynthetic=true;break;} | |||
if (synthetics[i].equals("Synthetic")) { | |||
bitflags|=IS_SYNTHETIC; | |||
// isSynthetic=true; | |||
break;} | |||
} | |||
} | |||
} else { | |||
// synthetic is a modifier (4096) | |||
isSynthetic = (modifiers&4096)!=0; | |||
if ((modifiers&4096)!=0) { | |||
bitflags|=IS_SYNTHETIC; | |||
} | |||
// isSynthetic = (modifiers&4096)!=0; | |||
} | |||
} | |||
@@ -549,4 +591,4 @@ public final class BcelMethod extends ResolvedMemberImpl { | |||
o.getMethod().getCode().getCodeString()); | |||
} | |||
} | |||
} |
@@ -22,15 +22,16 @@ import java.util.Iterator; | |||
import java.util.List; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.AttributeUtils; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.Signature; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen; | |||
import org.aspectj.bridge.IMessageHandler; | |||
import org.aspectj.weaver.AbstractReferenceTypeDelegate; | |||
import org.aspectj.weaver.AjAttribute; | |||
@@ -38,6 +39,7 @@ import org.aspectj.weaver.AjcMemberMaker; | |||
import org.aspectj.weaver.AnnotationTargetKind; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.ReferenceType; | |||
import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||
@@ -133,14 +135,19 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
// @AJ pc refs annotation in class hierarchy | |||
resolvedTypeX.setDelegate(this); | |||
if (resolvedTypeX.getSourceContext()==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) { | |||
setSourceContext(new SourceContextImpl(this)); | |||
ISourceContext sourceContext = resolvedTypeX.getSourceContext(); | |||
if (sourceContext==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) { | |||
sourceContext = new SourceContextImpl(this); | |||
setSourceContext(sourceContext); | |||
} | |||
// this should only ever be java.lang.Object which is | |||
// the only class in Java-1.4 with no superclasses | |||
isObject = (javaClass.getSuperclassNameIndex() == 0); | |||
ensureAspectJAttributesUnpacked(); | |||
// if (sourceContext instanceof SourceContextImpl) { | |||
// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName()); | |||
// } | |||
setSourcefilename(javaClass.getSourceFileName()); | |||
} | |||
@@ -157,7 +164,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
isAnnotation = javaClass.isAnnotation(); | |||
isAnonymous = javaClass.isAnonymous(); | |||
isNested = javaClass.isNested(); | |||
modifiers = javaClass.getAccessFlags(); | |||
modifiers = javaClass.getModifiers(); | |||
superclassName = javaClass.getSuperclassName(); | |||
className = javaClass.getClassName(); | |||
cachedGenericClassTypeSignature = null; | |||
@@ -193,6 +200,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
return res; | |||
} | |||
public World getWorld() { | |||
return getResolvedTypeX().getWorld(); | |||
} | |||
/** | |||
* Retrieves the declared interfaces - this allows for the generic signature on a type. If specified | |||
* then the generic signature is used to work out the types - this gets around the results of | |||
@@ -357,6 +368,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
if (getResolvedTypeX().getSourceContext() instanceof SourceContextImpl) { | |||
AjAttribute.SourceContextAttribute sca = (AjAttribute.SourceContextAttribute)a; | |||
((SourceContextImpl)getResolvedTypeX().getSourceContext()).configureFromAttribute(sca.getSourceFileName(),sca.getLineBreaks()); | |||
setSourcefilename(sca.getSourceFileName()); | |||
} | |||
} else if (a instanceof AjAttribute.WeaverVersionInfo) { | |||
wvInfo = (AjAttribute.WeaverVersionInfo)a; // Set the weaver version used to build this type | |||
@@ -567,8 +580,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) { | |||
List values = ax.getBcelAnnotation().getValues(); | |||
for (Iterator it = values.iterator(); it.hasNext();) { | |||
ElementNameValuePair element = (ElementNameValuePair) it.next(); | |||
EnumElementValue v = (EnumElementValue)element.getValue(); | |||
ElementNameValuePairGen element = (ElementNameValuePairGen) it.next(); | |||
EnumElementValueGen v = (EnumElementValueGen)element.getValue(); | |||
retentionPolicy = v.getEnumValueString(); | |||
return retentionPolicy; | |||
} | |||
@@ -596,15 +609,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used | |||
List targetKinds = new ArrayList(); | |||
if (isAnnotation()) { | |||
AnnotationX[] annotationsOnThisType = getAnnotations(); | |||
AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations(); | |||
for (int i = 0; i < annotationsOnThisType.length; i++) { | |||
Annotation a = annotationsOnThisType[i].getBcelAnnotation(); | |||
AnnotationGen a = annotationsOnThisType[i]; | |||
if (a.getTypeName().equals(UnresolvedType.AT_TARGET.getName())) { | |||
ArrayElementValue arrayValue = (ArrayElementValue)((ElementNameValuePair)a.getValues().get(0)).getValue(); | |||
ElementValue[] evs = arrayValue.getElementValuesArray(); | |||
ArrayElementValueGen arrayValue = (ArrayElementValueGen)((ElementNameValuePairGen)a.getValues().get(0)).getValue(); | |||
ElementValueGen[] evs = arrayValue.getElementValuesArray(); | |||
if (evs!=null) { | |||
for (int j = 0; j < evs.length; j++) { | |||
String targetKind = ((EnumElementValue)evs[j]).getEnumValueString(); | |||
String targetKind = ((EnumElementValueGen)evs[j]).getEnumValueString(); | |||
if (targetKind.equals("ANNOTATION_TYPE")) { targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE); | |||
} else if (targetKind.equals("CONSTRUCTOR")) { targetKinds.add(AnnotationTargetKind.CONSTRUCTOR); | |||
} else if (targetKind.equals("FIELD")) { targetKinds.add(AnnotationTargetKind.FIELD); | |||
@@ -629,7 +642,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
private void ensureAnnotationsUnpacked() { | |||
if (annotationTypes == null) { | |||
Annotation annos[] = javaClass.getAnnotations(); | |||
AnnotationGen annos[] = javaClass.getAnnotations(); | |||
if (annos==null || annos.length==0) { | |||
annotationTypes = ResolvedType.NONE; | |||
annotations = AnnotationX.NONE; | |||
@@ -638,7 +651,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
annotationTypes = new ResolvedType[annos.length]; | |||
annotations = new AnnotationX[annos.length]; | |||
for (int i = 0; i < annos.length; i++) { | |||
Annotation annotation = annos[i]; | |||
AnnotationGen annotation = annos[i]; | |||
annotationTypes[i] = w.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())); | |||
annotations[i] = new AnnotationX(annotation,w); | |||
} | |||
@@ -750,11 +763,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { | |||
private void ensureGenericInfoProcessed() { | |||
if ((bitflag & DISCOVERED_DECLARED_SIGNATURE)!=0) return; | |||
bitflag |= DISCOVERED_DECLARED_SIGNATURE; | |||
Attribute[] as = javaClass.getAttributes(); | |||
for (int i = 0; i < as.length && declaredSignature==null; i++) { | |||
Attribute attribute = as[i]; | |||
if (attribute instanceof Signature) declaredSignature = ((Signature)attribute).getSignature(); | |||
} | |||
Signature sigAttr = AttributeUtils.getSignatureAttribute(javaClass.getAttributes()); | |||
declaredSignature = (sigAttr==null?null:sigAttr.getSignature()); | |||
if (declaredSignature!=null) isGenericType= (declaredSignature.charAt(0)=='<'); | |||
} | |||
@@ -12,16 +12,12 @@ | |||
package org.aspectj.weaver.bcel; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.generic.ATHROW; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.NOP; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.POP; | |||
import org.aspectj.apache.bcel.generic.PUSH; | |||
import org.aspectj.apache.bcel.generic.ReferenceType; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.weaver.AjAttribute; | |||
@@ -170,11 +166,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
//FIXME Alex percflowX is not using this one but AJ code style does generate it so.. | |||
ResolvedMember failureFieldInfo = AjcMemberMaker.initFailureCauseField(aspectType); | |||
classGen.addField(makeFieldGen(classGen, failureFieldInfo).getField(), null); | |||
classGen.addField(makeFieldGen(classGen, failureFieldInfo), null); | |||
if (kind == PerClause.SINGLETON) { | |||
ResolvedMember perSingletonFieldInfo = AjcMemberMaker.perSingletonField(aspectType); | |||
classGen.addField(makeFieldGen(classGen, perSingletonFieldInfo).getField(), null); | |||
classGen.addField(makeFieldGen(classGen, perSingletonFieldInfo), null); | |||
// pr144602 - don't need to do this, PerObjectInterface munger will do it | |||
// } else if (kind == PerClause.PEROBJECT) { | |||
// ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType); | |||
@@ -183,10 +179,10 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
// // it should be done here. | |||
} else if (kind == PerClause.PERCFLOW) { | |||
ResolvedMember perCflowFieldInfo = AjcMemberMaker.perCflowField(aspectType); | |||
classGen.addField(makeFieldGen(classGen, perCflowFieldInfo).getField(), null); | |||
classGen.addField(makeFieldGen(classGen, perCflowFieldInfo), null); | |||
} else if (kind == PerClause.PERTYPEWITHIN) { | |||
ResolvedMember perTypeWithinForField = AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType); | |||
classGen.addField(makeFieldGen(classGen, perTypeWithinForField).getField(), null); | |||
classGen.addField(makeFieldGen(classGen, perTypeWithinForField), null); | |||
// } else { | |||
// throw new Error("Should not happen - no such kind " + kind.toString()); | |||
} | |||
@@ -200,11 +196,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
il.append(Utility.createGet(factory, AjcMemberMaker.perSingletonField(aspectType))); | |||
BranchInstruction ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
InstructionBranch ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
il.append(ifNotNull); | |||
il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); | |||
il.append(InstructionConstants.DUP); | |||
il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName())); | |||
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), aspectType.getName())); | |||
il.append(Utility.createGet(factory, AjcMemberMaker.initFailureCauseField(aspectType))); | |||
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL)); | |||
il.append(InstructionConstants.ATHROW); | |||
@@ -221,11 +217,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
il.append(Utility.createGet(factory, AjcMemberMaker.perSingletonField(aspectType))); | |||
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
InstructionBranch ifNull = (InstructionBranch)InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
il.append(ifNull); | |||
il.append(new PUSH(classGen.getConstantPoolGen(), true)); | |||
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), true)); | |||
il.append(InstructionFactory.createReturn(Type.INT)); | |||
InstructionHandle ifElse = il.append(new PUSH(classGen.getConstantPoolGen(), false)); | |||
InstructionHandle ifElse = il.append(InstructionFactory.PUSH(classGen.getConstantPool(), false)); | |||
il.append(InstructionFactory.createReturn(Type.INT)); | |||
ifNull.setTarget(ifElse); | |||
} | |||
@@ -248,7 +244,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
LazyMethodGen clinit = classGen.getStaticInitializer(); | |||
il = new InstructionList(); | |||
InstructionHandle tryStart = il.append(factory.createInvoke(aspectType.getName(), NameMangler.AJC_POST_CLINIT_NAME, Type.VOID, Type.NO_ARGS, Constants.INVOKESTATIC)); | |||
BranchInstruction tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null); | |||
InstructionBranch tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null); | |||
il.append(tryEnd); | |||
InstructionHandle handler = il.append(InstructionConstants.ASTORE_0); | |||
il.append(InstructionConstants.ALOAD_0); | |||
@@ -258,10 +254,10 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
// replace the original "return" with a "nop" | |||
//TODO AV - a bit odd, looks like Bcel alters bytecode and has a IMPDEP1 in its representation | |||
if (clinit.getBody().getEnd().getInstruction().getOpcode() == Constants.IMPDEP1) { | |||
clinit.getBody().getEnd().getPrev().setInstruction(new NOP()); | |||
if (clinit.getBody().getEnd().getInstruction().opcode == Constants.IMPDEP1) { | |||
clinit.getBody().getEnd().getPrev().setInstruction(InstructionConstants.NOP); | |||
} | |||
clinit.getBody().getEnd().setInstruction(new NOP()); | |||
clinit.getBody().getEnd().setInstruction(InstructionConstants.NOP); | |||
clinit.getBody().append(il); | |||
clinit.addExceptionHandler( | |||
@@ -279,22 +275,22 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createInstanceOf(interfaceType)); | |||
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
il.append(ifEq); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createCheckCast(interfaceType)); | |||
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); | |||
il.append(InstructionConstants.DUP); | |||
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
il.append(ifNull); | |||
il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(aspectType))); | |||
InstructionHandle ifNullElse = il.append(new POP()); | |||
InstructionHandle ifNullElse = il.append(InstructionConstants.POP); | |||
ifNull.setTarget(ifNullElse); | |||
InstructionHandle ifEqElse = il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); | |||
ifEq.setTarget(ifEqElse); | |||
il.append(InstructionConstants.DUP); | |||
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); | |||
il.append(new ATHROW()); | |||
il.append(InstructionConstants.ATHROW); | |||
} | |||
private void generatePerObjectHasAspectMethod(LazyClassGen classGen) { | |||
@@ -307,12 +303,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createInstanceOf(interfaceType)); | |||
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
il.append(ifEq); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createCheckCast(interfaceType)); | |||
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); | |||
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
il.append(ifNull); | |||
il.append(InstructionConstants.ICONST_1); | |||
il.append(InstructionFactory.createReturn(Type.INT)); | |||
@@ -332,12 +328,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createInstanceOf(interfaceType)); | |||
BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
InstructionBranch ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); | |||
il.append(ifEq); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createCheckCast(interfaceType)); | |||
il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); | |||
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
il.append(ifNonNull); | |||
il.append(InstructionConstants.ALOAD_0); | |||
il.append(factory.createCheckCast(interfaceType)); | |||
@@ -449,11 +445,11 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
)); | |||
il.append(InstructionConstants.ASTORE_1); | |||
il.append(InstructionConstants.ALOAD_1); | |||
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
il.append(ifNonNull); | |||
il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); | |||
il.append(InstructionConstants.DUP); | |||
il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName())); | |||
il.append(InstructionFactory.PUSH(classGen.getConstantPool(), aspectType.getName())); | |||
il.append(InstructionConstants.ACONST_NULL); | |||
il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL)); | |||
il.append(InstructionConstants.ATHROW); | |||
@@ -500,7 +496,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
Constants.INVOKESTATIC, | |||
AjcMemberMaker.perTypeWithinGetInstance(aspectType) | |||
)); | |||
BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
InstructionBranch ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
il.append(ifNull); | |||
il.append(InstructionConstants.ICONST_1); | |||
il.append(InstructionConstants.IRETURN); | |||
@@ -525,7 +521,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
InstructionList il = method.getBody(); | |||
InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); | |||
il.append(new PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType))); | |||
il.append(InstructionFactory.PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType))); | |||
il.append(InstructionConstants.ACONST_NULL);//Class[] for "getDeclaredMethod" | |||
il.append(factory.createInvoke( | |||
"java/lang/Class", | |||
@@ -588,9 +584,9 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
methodGen.makeSynthetic(); | |||
} | |||
methodGen.addAttribute( | |||
BcelAttributes.bcelAttribute( | |||
Utility.bcelAttribute( | |||
new AjAttribute.AjSynthetic(), | |||
methodGen.getEnclosingClass().getConstantPoolGen() | |||
methodGen.getEnclosingClass().getConstantPool() | |||
) | |||
); | |||
} |
@@ -24,40 +24,28 @@ import java.util.Map; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.generic.ACONST_NULL; | |||
import org.aspectj.apache.bcel.generic.ALOAD; | |||
import org.aspectj.apache.bcel.generic.ANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.ArrayType; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.generic.DUP; | |||
import org.aspectj.apache.bcel.generic.DUP_X1; | |||
import org.aspectj.apache.bcel.generic.DUP_X2; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.generic.FieldInstruction; | |||
import org.aspectj.apache.bcel.generic.INVOKEINTERFACE; | |||
import org.aspectj.apache.bcel.generic.INVOKESPECIAL; | |||
import org.aspectj.apache.bcel.generic.INVOKESTATIC; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionLV; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
import org.aspectj.apache.bcel.generic.LineNumberTag; | |||
import org.aspectj.apache.bcel.generic.LoadInstruction; | |||
import org.aspectj.apache.bcel.generic.LocalVariableTag; | |||
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.NEW; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.PUSH; | |||
import org.aspectj.apache.bcel.generic.RETURN; | |||
import org.aspectj.apache.bcel.generic.ReturnInstruction; | |||
import org.aspectj.apache.bcel.generic.SWAP; | |||
import org.aspectj.apache.bcel.generic.StoreInstruction; | |||
import org.aspectj.apache.bcel.generic.TargetLostException; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.weaver.Advice; | |||
import org.aspectj.weaver.AdviceKind; | |||
import org.aspectj.weaver.AjcMemberMaker; | |||
@@ -141,7 +129,6 @@ public class BcelShadow extends Shadow { | |||
private ShadowRange range; | |||
private final BcelWorld world; | |||
private final LazyMethodGen enclosingMethod; | |||
// private boolean fallsThrough; //XXX not used anymore | |||
// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed* | |||
public static boolean appliedLazyTjpOptimization; | |||
@@ -150,24 +137,15 @@ public class BcelShadow extends Shadow { | |||
// from the signature (pr109728) (1.4 declaring type issue) | |||
private String actualInstructionTargetType; | |||
// ---- initialization | |||
/** | |||
* This generates an unassociated shadow, rooted in a particular method but not rooted | |||
* This generates an unassociated shadow, rooted in a particular method but not rooted | |||
* to any particular point in the code. It should be given to a rooted ShadowRange | |||
* in the {@link ShadowRange#associateWithShadow(BcelShadow)} method. | |||
*/ | |||
public BcelShadow( | |||
BcelWorld world, | |||
Kind kind, | |||
Member signature, | |||
LazyMethodGen enclosingMethod, | |||
BcelShadow enclosingShadow) | |||
{ | |||
public BcelShadow(BcelWorld world, Kind kind, Member signature, LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) { | |||
super(kind, signature, enclosingShadow); | |||
this.world = world; | |||
this.enclosingMethod = enclosingMethod; | |||
// fallsThrough = kind.argsOnStack(); | |||
} | |||
// ---- copies all state, including Shadow's mungers... | |||
@@ -192,23 +170,21 @@ public class BcelShadow extends Shadow { | |||
return world; | |||
} | |||
private void deleteNewAndDup() { | |||
final ConstantPoolGen cpg = getEnclosingClass().getConstantPoolGen(); | |||
final ConstantPool cpg = getEnclosingClass().getConstantPool(); | |||
int depth = 1; | |||
InstructionHandle ih = range.getStart(); | |||
// Go back from where we are looking for 'NEW' that takes us to a stack depth of 0. INVOKESPECIAL <init> | |||
while (true) { | |||
Instruction inst = ih.getInstruction(); | |||
if (inst instanceof INVOKESPECIAL | |||
&& ((INVOKESPECIAL) inst).getName(cpg).equals("<init>")) { | |||
if (inst.opcode==Constants.INVOKESPECIAL | |||
&& ((InvokeInstruction) inst).getName(cpg).equals("<init>")) { | |||
depth++; | |||
} else if (inst instanceof NEW) { | |||
} else if (inst.opcode==Constants.NEW) { | |||
depth--; | |||
if (depth == 0) break; | |||
} else if (inst instanceof DUP_X2) { | |||
} else if (inst.opcode==Constants.DUP_X2) { | |||
// This code seen in the wild (by Brad): | |||
// 40: new #12; //class java/lang/StringBuffer | |||
// STACK: STRINGBUFFER | |||
@@ -243,7 +219,6 @@ public class BcelShadow extends Shadow { | |||
// bytecode sequence has only been seen once in the wild. | |||
ih.setInstruction(InstructionConstants.DUP); | |||
} | |||
ih = ih.getPrev(); | |||
} | |||
// now IH points to the NEW. We're followed by the DUP, and that is followed | |||
@@ -251,17 +226,15 @@ public class BcelShadow extends Shadow { | |||
InstructionHandle newHandle = ih; | |||
InstructionHandle endHandle = newHandle.getNext(); | |||
InstructionHandle nextHandle; | |||
// | |||
if (endHandle.getInstruction() instanceof DUP) { | |||
if (endHandle.getInstruction().opcode==Constants.DUP) { | |||
nextHandle = endHandle.getNext(); | |||
retargetFrom(newHandle, nextHandle); | |||
retargetFrom(endHandle, nextHandle); | |||
} else if (endHandle.getInstruction() instanceof DUP_X1) { | |||
} else if (endHandle.getInstruction().opcode==Constants.DUP_X1) { | |||
InstructionHandle dupHandle = endHandle; | |||
endHandle = endHandle.getNext(); | |||
nextHandle = endHandle.getNext(); | |||
if (endHandle.getInstruction() instanceof SWAP) {} | |||
if (endHandle.getInstruction().opcode==Constants.SWAP) {} | |||
else { | |||
// XXX see next XXX comment | |||
throw new RuntimeException("Unhandled kind of new " + endHandle); | |||
@@ -532,7 +505,7 @@ public class BcelShadow extends Shadow { | |||
if (clinitStart.getInstruction() instanceof InvokeInstruction) { | |||
InvokeInstruction ii = (InvokeInstruction)clinitStart.getInstruction(); | |||
if (ii | |||
.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()) | |||
.getName(enclosingMethod.getEnclosingClass().getConstantPool()) | |||
.equals(NameMangler.AJC_PRE_CLINIT_NAME)) { | |||
clinitStart = clinitStart.getNext(); | |||
} | |||
@@ -543,7 +516,7 @@ public class BcelShadow extends Shadow { | |||
//XXX should move the end before the postClinit, but the return is then tricky... | |||
// if (clinitEnd.getInstruction() instanceof InvokeInstruction) { | |||
// InvokeInstruction ii = (InvokeInstruction)clinitEnd.getInstruction(); | |||
// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()).equals(NameMangler.AJC_POST_CLINIT_NAME)) { | |||
// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPool()).equals(NameMangler.AJC_POST_CLINIT_NAME)) { | |||
// clinitEnd = clinitEnd.getPrev(); | |||
// } | |||
// } | |||
@@ -602,10 +575,10 @@ public class BcelShadow extends Shadow { | |||
} | |||
private static String findHandlerParamName(InstructionHandle startOfHandler) { | |||
if (startOfHandler.getInstruction() instanceof StoreInstruction && | |||
if (startOfHandler.getInstruction().isStoreInstruction() && | |||
startOfHandler.getNext() != null) | |||
{ | |||
int slot = ((StoreInstruction)startOfHandler.getInstruction()).getIndex(); | |||
int slot = startOfHandler.getInstruction().getIndex(); | |||
//System.out.println("got store: " + startOfHandler.getInstruction() + ", " + index); | |||
InstructionTargeter[] targeters = startOfHandler.getNext().getTargeters(); | |||
if (targeters!=null) { | |||
@@ -1024,7 +997,7 @@ public class BcelShadow extends Shadow { | |||
if (sources != null) { | |||
for (int i = sources.length - 1; i >= 0; i--) { | |||
InstructionTargeter source = sources[i]; | |||
if (source instanceof BranchInstruction) { | |||
if (source instanceof InstructionBranch) { | |||
source.updateTarget(from, to); | |||
} | |||
} | |||
@@ -1259,12 +1232,12 @@ public class BcelShadow extends Shadow { | |||
if (hasThis()) { | |||
((BcelVar)getThisVar()).appendLoad(il, fact); | |||
} else { | |||
il.append(new ACONST_NULL()); | |||
il.append(InstructionConstants.ACONST_NULL); | |||
} | |||
if (hasTarget()) { | |||
((BcelVar)getTargetVar()).appendLoad(il, fact); | |||
} else { | |||
il.append(new ACONST_NULL()); | |||
il.append(InstructionConstants.ACONST_NULL); | |||
} | |||
switch(getArgCount()) { | |||
@@ -1437,34 +1410,32 @@ public class BcelShadow extends Shadow { | |||
// Lets go back through the code from the start of the shadow | |||
InstructionHandle searchPtr = range.getStart().getPrev(); | |||
while (Range.isRangeHandle(searchPtr) || | |||
searchPtr.getInstruction() instanceof StoreInstruction) { // ignore this instruction - it doesnt give us the info we want | |||
searchPtr.getInstruction().isStoreInstruction()) { // ignore this instruction - it doesnt give us the info we want | |||
searchPtr = searchPtr.getPrev(); | |||
} | |||
// A load instruction may tell us the real type of what the clone() call is on | |||
if (searchPtr.getInstruction() instanceof LoadInstruction) { | |||
LoadInstruction li = (LoadInstruction)searchPtr.getInstruction(); | |||
li.getIndex(); | |||
LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,li.getIndex()); | |||
if (searchPtr.getInstruction().isLoadInstruction()) { | |||
LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,searchPtr.getInstruction().getIndex()); | |||
if (lvt!=null) return UnresolvedType.forSignature(lvt.getType()); | |||
} | |||
// A field access instruction may tell us the real type of what the clone() call is on | |||
if (searchPtr.getInstruction() instanceof FieldInstruction) { | |||
FieldInstruction si = (FieldInstruction)searchPtr.getInstruction(); | |||
Type t = si.getFieldType(getEnclosingClass().getConstantPoolGen()); | |||
Type t = si.getFieldType(getEnclosingClass().getConstantPool()); | |||
return BcelWorld.fromBcel(t); | |||
} | |||
// A new array instruction obviously tells us it is an array type ! | |||
if (searchPtr.getInstruction() instanceof ANEWARRAY) { | |||
if (searchPtr.getInstruction().opcode==Constants.ANEWARRAY) { | |||
//ANEWARRAY ana = (ANEWARRAY)searchPoint.getInstruction(); | |||
//Type t = ana.getType(getEnclosingClass().getConstantPoolGen()); | |||
// Type t = ana.getType(getEnclosingClass().getConstantPool()); | |||
// Just use a standard java.lang.object array - that will work fine | |||
return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,1)); | |||
} | |||
// A multi new array instruction obviously tells us it is an array type ! | |||
if (searchPtr.getInstruction() instanceof MULTIANEWARRAY) { | |||
MULTIANEWARRAY ana = (MULTIANEWARRAY)searchPtr.getInstruction(); | |||
// Type t = ana.getType(getEnclosingClass().getConstantPoolGen()); | |||
// Type t = ana.getType(getEnclosingClass().getConstantPool()); | |||
// t = new ArrayType(t,ana.getDimensions()); | |||
// Just use a standard java.lang.object array - that will work fine | |||
return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,ana.getDimensions())); | |||
@@ -1628,7 +1599,7 @@ public class BcelShadow extends Shadow { | |||
// by determining what "kind" of shadow we are, we can find out the | |||
// annotations on the appropriate element (method, field, constructor, type). | |||
// Then create one BcelVar entry in the map for each annotation, keyed by | |||
// annotation type (UnresolvedType). | |||
// annotation type. | |||
// FIXME asc Refactor this code, there is duplication | |||
ResolvedType[] annotations = null; | |||
@@ -1827,7 +1798,7 @@ public class BcelShadow extends Shadow { | |||
private List findReturnInstructions() { | |||
List returns = new ArrayList(); | |||
for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) { | |||
if (ih.getInstruction() instanceof ReturnInstruction) { | |||
if (ih.getInstruction().isReturnInstruction()) { | |||
returns.add(ih); | |||
} | |||
} | |||
@@ -1861,7 +1832,7 @@ public class BcelShadow extends Shadow { | |||
int i=returns.size()-1; | |||
while (newReturnInstruction == null && i>=0) { | |||
InstructionHandle ih = (InstructionHandle)returns.get(i); | |||
if (!(ih.getInstruction() instanceof RETURN)) { | |||
if (ih.getInstruction().opcode!=Constants.RETURN) { | |||
newReturnInstruction = Utility.copyInstruction(ih.getInstruction()); | |||
} | |||
i--; | |||
@@ -1984,7 +1955,7 @@ public class BcelShadow extends Shadow { | |||
InstructionList ih = new InstructionList(InstructionConstants.NOP); | |||
handler.append(exceptionVar.createLoad(fact)); | |||
handler.append(fact.createInstanceOf(eiieBcelType)); | |||
BranchInstruction bi = | |||
InstructionBranch bi = | |||
InstructionFactory.createBranchInstruction(Constants.IFEQ,ih.getStart()); | |||
handler.append(bi); | |||
handler.append(exceptionVar.createLoad(fact)); | |||
@@ -2105,7 +2076,7 @@ public class BcelShadow extends Shadow { | |||
String aspectname = munger.getConcreteAspect().getName(); | |||
String ptwField = NameMangler.perTypeWithinFieldForTarget(munger.getConcreteAspect()); | |||
entrySuccessInstructions.append(new PUSH(fact.getConstantPool(),t.getName())); | |||
entrySuccessInstructions.append(InstructionFactory.PUSH(fact.getConstantPool(),t.getName())); | |||
entrySuccessInstructions.append(fact.createInvoke(aspectname,"ajc$createAspectInstance",new ObjectType(aspectname), | |||
new Type[]{new ObjectType("java.lang.String")},Constants.INVOKESTATIC)); | |||
@@ -2315,7 +2286,7 @@ public class BcelShadow extends Shadow { | |||
boolean canSeeProceedPassedToOther = false; | |||
InstructionHandle curr = adviceMethod.getBody().getStart(); | |||
InstructionHandle end = adviceMethod.getBody().getEnd(); | |||
ConstantPoolGen cpg = adviceMethod.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPool cpg = adviceMethod.getEnclosingClass().getConstantPool(); | |||
while (curr != end) { | |||
InstructionHandle next = curr.getNext(); | |||
Instruction inst = curr.getInstruction(); | |||
@@ -2538,12 +2509,12 @@ public class BcelShadow extends Shadow { | |||
InstructionHandle curr = localAdviceMethod.getBody().getStart(); | |||
InstructionHandle end = localAdviceMethod.getBody().getEnd(); | |||
ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool(); | |||
while (curr != end) { | |||
InstructionHandle next = curr.getNext(); | |||
Instruction inst = curr.getInstruction(); | |||
if ((inst instanceof INVOKESTATIC) | |||
&& proceedName.equals(((INVOKESTATIC) inst).getMethodName(cpg))) { | |||
if ((inst.opcode==Constants.INVOKESTATIC) | |||
&& proceedName.equals(((InvokeInstruction) inst).getMethodName(cpg))) { | |||
localAdviceMethod.getBody().append( | |||
curr, | |||
@@ -2563,7 +2534,7 @@ public class BcelShadow extends Shadow { | |||
// [TODO document @AJ code rule: don't manipulate 2 jps proceed at the same time.. in an advice body] | |||
InstructionHandle curr = localAdviceMethod.getBody().getStart(); | |||
InstructionHandle end = localAdviceMethod.getBody().getEnd(); | |||
ConstantPoolGen cpg = localAdviceMethod.getEnclosingClass().getConstantPoolGen(); | |||
ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool(); | |||
while (curr != end) { | |||
InstructionHandle next = curr.getNext(); | |||
Instruction inst = curr.getInstruction(); | |||
@@ -2753,7 +2724,7 @@ public class BcelShadow extends Shadow { | |||
indexIntoObjectArrayForArguments=1; | |||
} else { | |||
// use local variable 0 (which is 'this' for a non-static method) | |||
ret.append(new ALOAD(0)); | |||
ret.append(InstructionFactory.createALOAD(0)); | |||
indexIntoCallbackMethodForArguments++; | |||
} | |||
} | |||
@@ -2791,7 +2762,7 @@ public class BcelShadow extends Shadow { | |||
Type stateType = callbackMethod.getArgumentTypes()[i]; | |||
BcelWorld.fromBcel(stateType).resolve(world); | |||
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) { | |||
ret.append(new ALOAD(localJp));// from localAdvice signature | |||
ret.append(new InstructionLV(Constants.ALOAD,localJp));// from localAdvice signature | |||
} else { | |||
ret.append(InstructionFactory.createLoad(objectArrayType, localProceedArgArray)); | |||
ret.append(Utility.createConstant(fact, i-indexIntoCallbackMethodForArguments +indexIntoObjectArrayForArguments)); | |||
@@ -2814,7 +2785,7 @@ public class BcelShadow extends Shadow { | |||
/*ResolvedType stateTypeX =*/ | |||
BcelWorld.fromBcel(stateType).resolve(world); | |||
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) { | |||
ret.append(new ALOAD(localJp));// from localAdvice signature | |||
ret.append(InstructionFactory.createALOAD(localJp));// from localAdvice signature | |||
// } else if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(stateType.getSignature())) { | |||
// //FIXME ALEX? | |||
// ret.append(new ALOAD(localJp));// from localAdvice signature | |||
@@ -3089,7 +3060,7 @@ public class BcelShadow extends Shadow { | |||
if (munger.getConcreteAspect()!=null && munger.getConcreteAspect().isAnnotationStyleAspect() | |||
&& munger.getDeclaringAspect()!=null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) { | |||
// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int | |||
closureInstantiation.append(fact.createConstant(new Integer(bitflags))); | |||
closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags))); | |||
closureInstantiation.append(Utility.createInvoke( | |||
getFactory(), | |||
getWorld(), | |||
@@ -3195,7 +3166,7 @@ public class BcelShadow extends Shadow { | |||
stateIndex++; | |||
} | |||
il.append(fact.createNew(new ObjectType(constructor.getDeclaringType().getName()))); | |||
il.append(new DUP()); | |||
il.append(InstructionConstants.DUP); | |||
arrayVar.appendLoad(il, fact); | |||
il.append(Utility.createInvoke(fact, world, constructor)); | |||
if (getKind() == PreInitialization) { | |||
@@ -3246,7 +3217,7 @@ public class BcelShadow extends Shadow { | |||
Modifier.PUBLIC, | |||
new String[] {}, | |||
getWorld()); | |||
InstructionFactory fact = new InstructionFactory(closureClass.getConstantPoolGen()); | |||
InstructionFactory fact = new InstructionFactory(closureClass.getConstantPool()); | |||
// constructor | |||
LazyMethodGen constructor = new LazyMethodGen(Modifier.PUBLIC, | |||
@@ -3393,7 +3364,7 @@ public class BcelShadow extends Shadow { | |||
InvokeInstruction superCallInstruction = | |||
(InvokeInstruction) superCallHandle.getInstruction(); | |||
return superCallInstruction.getArgumentTypes( | |||
getEnclosingClass().getConstantPoolGen()); | |||
getEnclosingClass().getConstantPool()); | |||
} | |||
@@ -21,17 +21,16 @@ import java.util.Map; | |||
import java.util.Set; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.INVOKESPECIAL; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
@@ -67,6 +66,7 @@ import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.patterns.DeclareAnnotation; | |||
import org.aspectj.weaver.patterns.Pointcut; | |||
//XXX addLazyMethodGen is probably bad everywhere | |||
public class BcelTypeMunger extends ConcreteTypeMunger { | |||
@@ -412,9 +412,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
InstructionList insList = aMethod.getBody(); | |||
InstructionHandle handle = insList.getStart(); | |||
while (handle!= null) { | |||
if (handle.getInstruction() instanceof INVOKESPECIAL) { | |||
ConstantPoolGen cpg = newParentTarget.getConstantPoolGen(); | |||
INVOKESPECIAL invokeSpecial = (INVOKESPECIAL)handle.getInstruction(); | |||
if (handle.getInstruction().opcode==Constants.INVOKESPECIAL) { | |||
ConstantPool cpg = newParentTarget.getConstantPool(); | |||
InvokeInstruction invokeSpecial = (InvokeInstruction)handle.getInstruction(); | |||
if (invokeSpecial.getClassName(cpg).equals(currentParent) && invokeSpecial.getMethodName(cpg).equals("<init>")) { | |||
// System.err.println("Transforming super call '<init>"+sp.getSignature(cpg)+"'"); | |||
@@ -458,7 +458,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
/** | |||
* Creates a nice signature for the ctor, something like "(int,Integer,String)" | |||
*/ | |||
private String createReadableCtorSig(ResolvedType newParent, ConstantPoolGen cpg, INVOKESPECIAL invokeSpecial) { | |||
private String createReadableCtorSig(ResolvedType newParent, ConstantPool cpg, InvokeInstruction invokeSpecial) { | |||
StringBuffer sb = new StringBuffer(); | |||
Type[] ctorArgs = invokeSpecial.getArgumentTypes(cpg); | |||
sb.append(newParent.getClassName()); | |||
@@ -523,7 +523,8 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
return true; | |||
//throw new BCException("no match for " + member + " in " + gen); | |||
} else if (member.getKind() == Member.STATIC_INITIALIZATION) { | |||
return gen.forcePublic(); | |||
gen.forcePublic(); | |||
return true; | |||
} else { | |||
throw new RuntimeException("unimplemented"); | |||
} | |||
@@ -639,7 +640,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
member.getModifiers(), | |||
BcelWorld.makeBcelType(member.getReturnType()), | |||
member.getName(), | |||
gen.getConstantPoolGen()); | |||
gen.getConstantPool()); | |||
} | |||
@@ -656,7 +657,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
FieldGen fg = makeFieldGen(gen, | |||
AjcMemberMaker.perObjectField(gen.getType(), aspectType)); | |||
gen.addField(fg.getField(),getSourceLocation()); | |||
gen.addField(fg,getSourceLocation()); | |||
Type fieldType = BcelWorld.makeBcelType(aspectType); | |||
@@ -714,7 +715,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
// Add (to the target type) the field that will hold the aspect instance | |||
// e.g ajc$com_blah_SecurityAspect$ptwAspectInstance | |||
FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType)); | |||
gen.addField(fg.getField(),getSourceLocation()); | |||
gen.addField(fg,getSourceLocation()); | |||
// Add an accessor for this new field, the ajc$<aspectname>$localAspectOf() method | |||
// e.g. "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()" | |||
@@ -808,9 +809,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
newMethod.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld())); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
newMethod.addAnnotation(new AnnotationX(ag,weaver.getWorld())); | |||
} | |||
} | |||
// the below loop fixes the very special (and very stupid) | |||
@@ -903,9 +904,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld())); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); | |||
} | |||
} | |||
} | |||
@@ -1179,9 +1180,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld())); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); | |||
} | |||
} | |||
} | |||
@@ -1192,7 +1193,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
// getfield | |||
body.append(InstructionConstants.ALOAD_0); | |||
body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); | |||
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
body.append(ifNonNull); | |||
// Create and store a new instance | |||
@@ -1247,7 +1248,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
aspectType); | |||
weaver.getLazyClassGen().addField(makeFieldGen( | |||
weaver.getLazyClassGen(), | |||
host).getField(), null); | |||
host), null); | |||
return true; | |||
} | |||
@@ -1387,9 +1388,9 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld())); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); | |||
} | |||
} | |||
// the below loop fixes the very special (and very stupid) | |||
@@ -1578,13 +1579,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
fg.addAnnotation(ag); | |||
} | |||
} | |||
gen.addField(fg.getField(),getSourceLocation()); | |||
gen.addField(fg,getSourceLocation()); | |||
} | |||
return true; | |||
@@ -1602,13 +1603,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
if (annotationsOnRealMember!=null) { | |||
for (int i = 0; i < annotationsOnRealMember.length; i++) { | |||
AnnotationX annotationX = annotationsOnRealMember[i]; | |||
Annotation a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true); | |||
AnnotationGen a = annotationX.getBcelAnnotation(); | |||
AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); | |||
fg.addAnnotation(ag); | |||
} | |||
} | |||
gen.addField(fg.getField(),getSourceLocation()); | |||
gen.addField(fg,getSourceLocation()); | |||
//this uses a shadow munger to add init method to constructors | |||
//weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod)); | |||
@@ -1716,7 +1717,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
public ConcreteTypeMunger parameterizedFor(ResolvedType target) { | |||
return new BcelTypeMunger(munger.parameterizedFor(target),aspectType); | |||
} | |||
public ConcreteTypeMunger parameterizeWith(Map m, World w) { | |||
return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType); | |||
} |
@@ -82,7 +82,6 @@ import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.patterns.AndPointcut; | |||
import org.aspectj.weaver.patterns.BindingAnnotationTypePattern; | |||
import org.aspectj.weaver.patterns.BindingTypePattern; | |||
import org.aspectj.weaver.patterns.CflowPointcut; | |||
import org.aspectj.weaver.patterns.ConcreteCflowPointcut; | |||
import org.aspectj.weaver.patterns.DeclareAnnotation; | |||
import org.aspectj.weaver.patterns.DeclareParents; | |||
@@ -476,6 +475,7 @@ public class BcelWeaver implements IWeaver { | |||
if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this); | |||
needToReweaveWorld = xcutSet.hasChangedSinceLastReset(); | |||
// update mungers | |||
for (Iterator i = addedClasses.iterator(); i.hasNext(); ) { | |||
UnwovenClassFile jc = (UnwovenClassFile)i.next(); |
@@ -24,27 +24,20 @@ import java.util.List; | |||
import java.util.Properties; | |||
import java.util.StringTokenizer; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.ClassParser; | |||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.generic.ANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.FieldInstruction; | |||
import org.aspectj.apache.bcel.generic.GETSTATIC; | |||
import org.aspectj.apache.bcel.generic.INVOKEINTERFACE; | |||
import org.aspectj.apache.bcel.generic.INVOKESPECIAL; | |||
import org.aspectj.apache.bcel.generic.INVOKESTATIC; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
import org.aspectj.apache.bcel.generic.MONITORENTER; | |||
import org.aspectj.apache.bcel.generic.MONITOREXIT; | |||
import org.aspectj.apache.bcel.generic.MULTIANEWARRAY; | |||
import org.aspectj.apache.bcel.generic.NEWARRAY; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.PUTSTATIC; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.util.ClassLoaderReference; | |||
import org.aspectj.apache.bcel.util.ClassLoaderRepository; | |||
@@ -60,6 +53,7 @@ import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ConcreteTypeMunger; | |||
import org.aspectj.weaver.ICrossReferenceHandler; | |||
import org.aspectj.weaver.MemberKind; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.MemberImpl; | |||
import org.aspectj.weaver.NewParentTypeMunger; | |||
@@ -113,9 +107,6 @@ public class BcelWorld extends World implements Repository { | |||
} | |||
private static List getPathEntries(String s) { | |||
List ret = new ArrayList(); | |||
StringTokenizer tok = new StringTokenizer(s, File.pathSeparator); | |||
@@ -145,7 +136,7 @@ public class BcelWorld extends World implements Repository { | |||
// TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); | |||
// if so, how can that be safe in J2EE ?? (static stuff in Bcel) | |||
} | |||
/** | |||
* Build a World from a ClassLoader, for LTW support | |||
* | |||
@@ -439,11 +430,11 @@ public class BcelWorld extends World implements Repository { | |||
} | |||
public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { | |||
ConstantPoolGen cpg = cg.getConstantPoolGen(); | |||
ConstantPool cpg = cg.getConstantPool(); | |||
return | |||
MemberImpl.field( | |||
fi.getClassName(cpg), | |||
(fi instanceof GETSTATIC || fi instanceof PUTSTATIC) | |||
(fi.opcode==Constants.GETSTATIC || fi.opcode==Constants.PUTSTATIC) | |||
? Modifier.STATIC: 0, | |||
fi.getName(cpg), | |||
fi.getSignature(cpg)); | |||
@@ -466,7 +457,7 @@ public class BcelWorld extends World implements Repository { | |||
} | |||
public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberImpl.Kind kind) { | |||
public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) { | |||
Member ret = mg.getMemberView(); | |||
if (ret == null) { | |||
int mods = mg.getAccessFlags(); | |||
@@ -474,6 +465,7 @@ public class BcelWorld extends World implements Repository { | |||
mods |= Modifier.INTERFACE; | |||
} | |||
if (kind == null) { | |||
//OPTIMIZE surely we can pass the kind in and not resort to string compares? | |||
if (mg.getName().equals("<init>")) { | |||
kind = Member.CONSTRUCTOR; | |||
} else if (mg.getName().equals("<clinit>")) { | |||
@@ -496,23 +488,21 @@ public class BcelWorld extends World implements Repository { | |||
} | |||
public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,InstructionHandle h) { | |||
MONITORENTER i = (MONITORENTER)h.getInstruction(); | |||
return MemberImpl.monitorEnter(); | |||
} | |||
public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,InstructionHandle h) { | |||
MONITOREXIT i = (MONITOREXIT)h.getInstruction(); | |||
return MemberImpl.monitorExit(); | |||
} | |||
public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) { | |||
Instruction i = handle.getInstruction(); | |||
ConstantPoolGen cpg = cg.getConstantPoolGen(); | |||
ConstantPool cpg = cg.getConstantPool(); | |||
Member retval = null; | |||
if (i instanceof ANEWARRAY) { | |||
ANEWARRAY arrayInstruction = (ANEWARRAY)i; | |||
Type ot = arrayInstruction.getType(cpg); | |||
if (i.opcode==Constants.ANEWARRAY) { | |||
// ANEWARRAY arrayInstruction = (ANEWARRAY)i; | |||
Type ot = i.getType(cpg); | |||
UnresolvedType ut = fromBcel(ot); | |||
ut = UnresolvedType.makeArray(ut,1); | |||
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT}); | |||
@@ -532,9 +522,9 @@ public class BcelWorld extends World implements Repository { | |||
for (int ii=0;ii<dimensions;ii++) parms[ii] = ResolvedType.INT; | |||
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", parms); | |||
} else if (i instanceof NEWARRAY) { | |||
NEWARRAY arrayInstruction = (NEWARRAY)i; | |||
Type ot = arrayInstruction.getType(); | |||
} else if (i.opcode==Constants.NEWARRAY) { | |||
// NEWARRAY arrayInstruction = (NEWARRAY)i; | |||
Type ot = i.getType(); | |||
UnresolvedType ut = fromBcel(ot); | |||
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT}); | |||
} else { | |||
@@ -544,7 +534,7 @@ public class BcelWorld extends World implements Repository { | |||
} | |||
public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { | |||
ConstantPoolGen cpg = cg.getConstantPoolGen(); | |||
ConstantPool cpg = cg.getConstantPool(); | |||
String name = ii.getName(cpg); | |||
String declaring = ii.getClassName(cpg); | |||
UnresolvedType declaringType = null; | |||
@@ -554,16 +544,16 @@ public class BcelWorld extends World implements Repository { | |||
int modifier = | |||
(ii instanceof INVOKEINTERFACE) | |||
? Modifier.INTERFACE | |||
: (ii instanceof INVOKESTATIC) | |||
: (ii.opcode==Constants.INVOKESTATIC) | |||
? Modifier.STATIC | |||
: (ii instanceof INVOKESPECIAL && ! name.equals("<init>")) | |||
: (ii.opcode==Constants.INVOKESPECIAL && ! name.equals("<init>")) | |||
? Modifier.PRIVATE | |||
: 0; | |||
// in Java 1.4 and after, static method call of super class within subclass method appears | |||
// as declared by the subclass in the bytecode - but they are not | |||
// see #104212 | |||
if (ii instanceof INVOKESTATIC) { | |||
if (ii.opcode==Constants.INVOKESTATIC) { | |||
ResolvedType appearsDeclaredBy = resolve(declaring); | |||
// look for the method there | |||
for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) { | |||
@@ -724,13 +714,13 @@ public class BcelWorld extends World implements Repository { | |||
if (!jc.isClass()) { | |||
return false; | |||
} | |||
Annotation anns[] = jc.getAnnotations(); | |||
AnnotationGen anns[] = jc.getAnnotations(); | |||
if (anns.length == 0) { | |||
return false; | |||
} | |||
boolean couldBeAtAspectJStyle = false; | |||
for (int i = 0; i < anns.length; i++) { | |||
Annotation ann = anns[i]; | |||
AnnotationGen ann = anns[i]; | |||
if ("Lorg/aspectj/lang/annotation/Aspect;".equals(ann.getTypeSignature())) { | |||
couldBeAtAspectJStyle = true; | |||
} |
@@ -32,27 +32,23 @@ import java.util.TreeMap; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.ConstantUtf8; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.Field; | |||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.Signature; | |||
import org.aspectj.apache.bcel.classfile.Synthetic; | |||
import org.aspectj.apache.bcel.classfile.Unknown; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.BasicType; | |||
import org.aspectj.apache.bcel.generic.ClassGen; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.PUSH; | |||
import org.aspectj.apache.bcel.generic.RETURN; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.SourceLocation; | |||
@@ -72,6 +68,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
import org.aspectj.weaver.UnresolvedType.TypeKind; | |||
/** | |||
* Lazy lazy lazy. | |||
* We don't unpack the underlying class unless necessary. Things | |||
@@ -93,10 +90,11 @@ public final class LazyClassGen { | |||
private BcelObjectType myType; // XXX is not set for types we create | |||
private ClassGen myGen; | |||
private ConstantPoolGen constantPoolGen; | |||
private ConstantPool constantPoolGen; | |||
private World world; | |||
private String packageName = null; | |||
private List /*BcelField*/ fields = new ArrayList(); | |||
private List /*LazyMethodGen*/ methodGens = new ArrayList(); | |||
private List /*LazyClassGen*/ classGens = new ArrayList(); | |||
private List /*AnnotationGen*/ annotations = new ArrayList(); | |||
@@ -157,7 +155,7 @@ public final class LazyClassGen { | |||
byte[] bytes = Utility.stringToUTF(data); | |||
int length = bytes.length; | |||
return new Unknown(nameIndex, length, bytes, constantPoolGen.getConstantPool()); | |||
return new Unknown(nameIndex, length, bytes, constantPoolGen); | |||
} | |||
// private LazyClassGen() {} | |||
@@ -292,9 +290,9 @@ public final class LazyClassGen { | |||
// Do we need to calculate an SUID and add it? | |||
if (!hasSerialVersionUIDField && world.isAddSerialVerUID()) { | |||
calculatedSerialVersionUID = myGen.getSUID(); | |||
Field fg = new FieldGen( | |||
FieldGen fg = new FieldGen( | |||
Constants.ACC_PRIVATE|Constants.ACC_FINAL|Constants.ACC_STATIC, | |||
BasicType.LONG,"serialVersionUID",getConstantPoolGen()).getField(); | |||
BasicType.LONG,"serialVersionUID",getConstantPool()); | |||
addField(fg); | |||
hasSerialVersionUIDField=true; | |||
serialVersionUIDRequiresInitialization=true; | |||
@@ -305,11 +303,15 @@ public final class LazyClassGen { | |||
} | |||
} | |||
Method[] methods = myGen.getMethods(); | |||
Method[] methods = myGen.getMethods(); | |||
for (int i = 0; i < methods.length; i++) { | |||
addMethodGen(new LazyMethodGen(methods[i], this)); | |||
} | |||
ResolvedMember[] fields = myType.getDeclaredFields(); | |||
for (int i=0; i<fields.length; i++) { | |||
this.fields.add((BcelField)fields[i]); | |||
} | |||
} | |||
public static boolean hasSerialVersionUIDField (ResolvedType type) { | |||
@@ -333,9 +335,10 @@ public final class LazyClassGen { | |||
// ---- | |||
public String getInternalClassName() { | |||
return getConstantPoolGen().getConstantPool().getConstantString( | |||
myGen.getClassNameIndex(), | |||
Constants.CONSTANT_Class); | |||
return getConstantPool().getConstantString_CONSTANTClass(myGen.getClassNameIndex()); | |||
//getConstantPool().getConstantString( | |||
// myGen.getClassNameIndex(), | |||
// Constants.CONSTANT_Class); | |||
} | |||
@@ -384,7 +387,7 @@ public final class LazyClassGen { | |||
methodGens.add(gen); | |||
if (highestLineNumber < gen.highestLineNumber) highestLineNumber = gen.highestLineNumber; | |||
} | |||
public void addMethodGen(LazyMethodGen gen, ISourceLocation sourceLocation) { | |||
addMethodGen(gen); | |||
if (!gen.getMethod().isPrivate()) { | |||
@@ -393,7 +396,7 @@ public final class LazyClassGen { | |||
} | |||
public void errorOnAddedField (Field field, ISourceLocation sourceLocation) { | |||
public void errorOnAddedField (FieldGen field, ISourceLocation sourceLocation) { | |||
if (isSerializable && !hasSerialVersionUIDField) { | |||
getWorld().getLint().serialVersionUIDBroken.signal( | |||
new String[] { | |||
@@ -438,20 +441,20 @@ public final class LazyClassGen { | |||
return methodGens; //???Collections.unmodifiableList(methodGens); | |||
} | |||
// FIXME asc Should be collection returned here | |||
public Field[] getFieldGens() { | |||
return myGen.getFields(); | |||
public List/*BcelField*/ getFieldGens() { | |||
return fields; | |||
// return myGen.getFields(); | |||
} | |||
public Field getField(String name) { | |||
Field[] allFields = myGen.getFields(); | |||
if (allFields==null) return null; | |||
for (int i = 0; i < allFields.length; i++) { | |||
Field field = allFields[i]; | |||
if (field.getName().equals(name)) return field; | |||
} | |||
return null; | |||
} | |||
// public Field getField(String name) { | |||
// Field[] allFields = myGen.getFields(); | |||
// if (allFields==null) return null; | |||
// for (int i = 0; i < allFields.length; i++) { | |||
// Field field = allFields[i]; | |||
// if (field.getName().equals(name)) return field; | |||
// } | |||
// return null; | |||
// } | |||
// FIXME asc How do the ones on the underlying class surface if this just returns new ones added? | |||
// FIXME asc ...although no one calls this right now ! | |||
@@ -460,7 +463,7 @@ public final class LazyClassGen { | |||
} | |||
private void writeBack(BcelWorld world) { | |||
if (getConstantPoolGen().getSize() > Short.MAX_VALUE) { | |||
if (getConstantPool().getSize() > Short.MAX_VALUE) { | |||
reportClassTooBigProblem(); | |||
return; | |||
} | |||
@@ -470,7 +473,7 @@ public final class LazyClassGen { | |||
AnnotationGen element = (AnnotationGen) iter.next(); | |||
myGen.addAnnotation(element); | |||
} | |||
// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPoolGen(),annotations); | |||
// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPool(),annotations); | |||
// for (int i = 0; i < annAttributes.length; i++) { | |||
// Attribute attribute = annAttributes[i]; | |||
// System.err.println("Adding attribute for "+attribute); | |||
@@ -479,19 +482,14 @@ public final class LazyClassGen { | |||
} | |||
// Add a weaver version attribute to the file being produced (if necessary...) | |||
boolean hasVersionAttribute = false; | |||
Attribute[] attrs = myGen.getAttributes(); | |||
for (int i = 0; i < attrs.length && !hasVersionAttribute; i++) { | |||
Attribute attribute = attrs[i]; | |||
if (attribute.getName().equals("org.aspectj.weaver.WeaverVersion")) hasVersionAttribute=true; | |||
} | |||
if (!hasVersionAttribute) | |||
myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPoolGen())); | |||
if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) { | |||
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool())); | |||
} | |||
if (myType != null && myType.getWeaverState() != null) { | |||
myGen.addAttribute(BcelAttributes.bcelAttribute( | |||
myGen.addAttribute(Utility.bcelAttribute( | |||
new AjAttribute.WeaverState(myType.getWeaverState()), | |||
getConstantPoolGen())); | |||
getConstantPool())); | |||
} | |||
//FIXME ATAJ needed only for slow Aspects.aspectOf() - keep or remove | |||
@@ -502,29 +500,43 @@ public final class LazyClassGen { | |||
// } | |||
addAjcInitializers(); | |||
// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents | |||
// of attribute are confirmed to be correct. | |||
boolean sourceDebugExtensionSupportSwitchedOn = false; | |||
int len = methodGens.size(); | |||
myGen.setMethods(new Method[0]); | |||
if (sourceDebugExtensionSupportSwitchedOn) { | |||
calculateSourceDebugExtensionOffsets(); | |||
} | |||
calculateSourceDebugExtensionOffsets(); | |||
int len = methodGens.size(); | |||
myGen.setMethods(Method.NoMethods); | |||
for (int i = 0; i < len; i++) { | |||
LazyMethodGen gen = (LazyMethodGen) methodGens.get(i); | |||
// we skip empty clinits | |||
if (isEmptyClinit(gen)) continue; | |||
myGen.addMethod(gen.getMethod()); | |||
} | |||
if (inlinedFiles.size() != 0) { | |||
if (hasSourceDebugExtensionAttribute(myGen)) { | |||
world.showMessage( | |||
IMessage.WARNING, | |||
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()), | |||
null, | |||
null); | |||
len = fields.size(); | |||
myGen.setFields(Field.NoFields); | |||
for (int i = 0; i < len; i++) { | |||
BcelField gen = (BcelField) fields.get(i); | |||
myGen.addField(gen.getField(this.constantPoolGen)); | |||
} | |||
if (sourceDebugExtensionSupportSwitchedOn) { | |||
if (inlinedFiles.size() != 0) { | |||
if (hasSourceDebugExtensionAttribute(myGen)) { | |||
world.showMessage( | |||
IMessage.WARNING, | |||
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()), | |||
null, | |||
null); | |||
} | |||
// myGen.addAttribute(getSourceDebugExtensionAttribute()); | |||
} | |||
// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents | |||
// of attribute are confirmed to be correct. | |||
// myGen.addAttribute(getSourceDebugExtensionAttribute()); | |||
} | |||
} | |||
fixupGenericSignatureAttribute(); | |||
} | |||
@@ -551,11 +563,7 @@ public final class LazyClassGen { | |||
// 2. Find the old attribute | |||
Signature sigAttr = null; | |||
if (myType!=null) { // if null, this is a type built from scratch, it won't already have a sig attribute | |||
Attribute[] as = myGen.getAttributes(); | |||
for (int i = 0; i < as.length; i++) { | |||
Attribute attribute = as[i]; | |||
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute; | |||
} | |||
sigAttr = (Signature) myGen.getAttribute("Signature"); | |||
} | |||
// 3. Do we need an attribute? | |||
@@ -610,7 +618,7 @@ public final class LazyClassGen { | |||
private Signature createSignatureAttribute(String signature) { | |||
int nameIndex = constantPoolGen.addUtf8("Signature"); | |||
int sigIndex = constantPoolGen.addUtf8(signature); | |||
return new Signature(nameIndex,2,sigIndex,constantPoolGen.getConstantPool()); | |||
return new Signature(nameIndex,2,sigIndex,constantPoolGen); | |||
} | |||
/** | |||
@@ -623,7 +631,7 @@ public final class LazyClassGen { | |||
// create an empty myGen so that we can give back a return value that doesn't upset the | |||
// rest of the process. | |||
myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), | |||
myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames()); | |||
myGen.getFileName(), myGen.getModifiers(), myGen.getInterfaceNames()); | |||
// raise an error against this compilation unit. | |||
getWorld().showMessage( | |||
IMessage.ERROR, | |||
@@ -634,15 +642,16 @@ public final class LazyClassGen { | |||
} | |||
private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) { | |||
ConstantPoolGen pool = gen.getConstantPool(); | |||
Attribute[] attrs = gen.getAttributes(); | |||
for (int i = 0; i < attrs.length; i++) { | |||
if ("SourceDebugExtension" | |||
.equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
return gen.hasAttribute("SourceDebugExtension"); | |||
// ConstantPool pool = gen.getConstantPool(); | |||
// Attribute[] attrs = gen.getAttributes(); | |||
// for (int i = 0; i < attrs.length; i++) { | |||
// if ("SourceDebugExtension" | |||
// .equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) { | |||
// return true; | |||
// } | |||
// } | |||
// return false; | |||
} | |||
public JavaClass getJavaClass(BcelWorld world) { | |||
@@ -725,10 +734,10 @@ public final class LazyClassGen { | |||
public String toShortString() { | |||
String s = | |||
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getAccessFlags(), true); | |||
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true); | |||
if (s != "") | |||
s += " "; | |||
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getAccessFlags()); | |||
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers()); | |||
s += " "; | |||
s += myGen.getClassName(); | |||
return s; | |||
@@ -798,7 +807,7 @@ public final class LazyClassGen { | |||
//System.err.println("checking clinig: " + gen); | |||
InstructionHandle start = gen.getBody().getStart(); | |||
while (start != null) { | |||
if (Range.isRangeHandle(start) || (start.getInstruction() instanceof RETURN)) { | |||
if (Range.isRangeHandle(start) || (start.getInstruction().opcode==Constants.RETURN)) { | |||
start = start.getNext(); | |||
} else { | |||
return false; | |||
@@ -808,7 +817,7 @@ public final class LazyClassGen { | |||
return true; | |||
} | |||
public ConstantPoolGen getConstantPoolGen() { | |||
public ConstantPool getConstantPool() { | |||
return constantPoolGen; | |||
} | |||
@@ -931,8 +940,9 @@ public final class LazyClassGen { | |||
} else { | |||
jpType = isEnclosingJp?enclosingStaticTjpType:staticTjpType; | |||
} | |||
ret = new FieldGen(modifiers,jpType,"ajc$tjp_" + tjpFields.size(),getConstantPoolGen()).getField(); | |||
addField(ret); | |||
FieldGen fGen = new FieldGen(modifiers,jpType,"ajc$tjp_" + tjpFields.size(),getConstantPool()); | |||
addField(fGen); | |||
ret = fGen.getField(); | |||
tjpFields.put(shadow, ret); | |||
return ret; | |||
} | |||
@@ -945,11 +955,11 @@ public final class LazyClassGen { | |||
// Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC, | |||
// classType, | |||
// "aj$class", | |||
// getConstantPoolGen()).getField(); | |||
// getConstantPool()).getField(); | |||
// addField(ajClassField); | |||
// | |||
// InstructionList il = new InstructionList(); | |||
// il.append(new PUSH(getConstantPoolGen(), getClassName())); | |||
// il.append(new PUSH(getConstantPool(), getClassName())); | |||
// il.append(fact.createInvoke("java.lang.Class", "forName", classType, | |||
// new Type[] {Type.STRING}, Constants.INVOKESTATIC)); | |||
// il.append(fact.createFieldAccess(getClassName(), ajClassField.getName(), | |||
@@ -970,7 +980,7 @@ public final class LazyClassGen { | |||
if (il==null) { | |||
il= new InstructionList(); | |||
} | |||
il.append(new PUSH(getConstantPoolGen(),calculatedSerialVersionUID)); | |||
il.append(InstructionFactory.PUSH(getConstantPool(),calculatedSerialVersionUID)); | |||
il.append(getFactory().createFieldAccess(getClassName(), "serialVersionUID", BasicType.LONG, Constants.PUTSTATIC)); | |||
} | |||
@@ -986,11 +996,11 @@ public final class LazyClassGen { | |||
list.append(fact.createNew(factoryType)); | |||
list.append(InstructionFactory.createDup(1)); | |||
list.append(new PUSH(getConstantPoolGen(), getFileName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(), getFileName())); | |||
// load the current Class object | |||
//XXX check that this works correctly for inners/anonymous | |||
list.append(new PUSH(getConstantPoolGen(), getClassName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(), getClassName())); | |||
//XXX do we need to worry about the fact the theorectically this could throw | |||
//a ClassNotFoundException | |||
list.append(fact.createInvoke("java.lang.Class", "forName", classType, | |||
@@ -1032,13 +1042,13 @@ public final class LazyClassGen { | |||
list.append(InstructionFactory.createLoad(factoryType, 0)); | |||
// load the kind | |||
list.append(new PUSH(getConstantPoolGen(), shadow.getKind().getName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(), shadow.getKind().getName())); | |||
// create the signature | |||
list.append(InstructionFactory.createLoad(factoryType, 0)); | |||
if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2 | |||
list.append(new PUSH(getConstantPoolGen(), sig.getSignatureString(shadow.getWorld()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(), sig.getSignatureString(shadow.getWorld()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1047,13 +1057,13 @@ public final class LazyClassGen { | |||
} else if (sig.getKind().equals(Member.METHOD)) { | |||
BcelWorld w = shadow.getWorld(); | |||
// For methods, push the parts of the signature on. | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),sig.getName())); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getReturnType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType()))); | |||
// And generate a call to the variant of makeMethodSig() that takes 7 strings | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
@@ -1061,14 +1071,14 @@ public final class LazyClassGen { | |||
new Type[] { Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING,Type.STRING }, | |||
Constants.INVOKEVIRTUAL)); | |||
} else if (sig.getKind().equals(Member.MONITORENTER)) { | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
new Type[] { Type.STRING}, | |||
Constants.INVOKEVIRTUAL)); | |||
} else if (sig.getKind().equals(Member.MONITOREXIT)) { | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1076,9 +1086,9 @@ public final class LazyClassGen { | |||
Constants.INVOKEVIRTUAL)); | |||
} else if (sig.getKind().equals(Member.HANDLER)) { | |||
BcelWorld w = shadow.getWorld(); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1088,22 +1098,22 @@ public final class LazyClassGen { | |||
BcelWorld w = shadow.getWorld(); | |||
if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) { | |||
// its the magical new jp | |||
list.append(new PUSH(getConstantPoolGen(),makeString(Modifier.PUBLIC))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes()))); | |||
list.append(new PUSH(getConstantPoolGen(),""));//makeString("")));//sig.getParameterNames(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),""));//makeString("")));//sig.getExceptions(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(Modifier.PUBLIC))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getParameterNames(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getExceptions(w)))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING }, | |||
Constants.INVOKEVIRTUAL)); | |||
} else { | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1112,16 +1122,16 @@ public final class LazyClassGen { | |||
} | |||
} else if(sig.getKind().equals(Member.FIELD)) { | |||
BcelWorld w = shadow.getWorld(); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),sig.getName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); | |||
// see pr227401 | |||
UnresolvedType dType = sig.getDeclaringType(); | |||
if (dType.getTypekind()==TypeKind.PARAMETERIZED || | |||
dType.getTypekind()==TypeKind.GENERIC) { | |||
dType = sig.getDeclaringType().resolve(world).getGenericType(); | |||
} | |||
list.append(new PUSH(getConstantPoolGen(),makeString(dType))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getReturnType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(dType))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1129,13 +1139,13 @@ public final class LazyClassGen { | |||
Constants.INVOKEVIRTUAL)); | |||
} else if(sig.getKind().equals(Member.ADVICE)) { | |||
BcelWorld w = shadow.getWorld(); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),sig.getName())); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterTypes()))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getParameterNames(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getExceptions(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString((sig.getReturnType())))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString((sig.getReturnType())))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1143,15 +1153,15 @@ public final class LazyClassGen { | |||
Constants.INVOKEVIRTUAL)); | |||
} else if(sig.getKind().equals(Member.STATIC_INITIALIZATION)) { | |||
BcelWorld w = shadow.getWorld(); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getModifiers(w)))); | |||
list.append(new PUSH(getConstantPoolGen(),makeString(sig.getDeclaringType()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
new Type[] { Type.STRING, Type.STRING }, | |||
Constants.INVOKEVIRTUAL)); | |||
} else { | |||
list.append(new PUSH(getConstantPoolGen(), sig.getSignatureString(shadow.getWorld()))); | |||
list.append(InstructionFactory.PUSH(getConstantPool(), sig.getSignatureString(shadow.getWorld()))); | |||
list.append(fact.createInvoke(factoryType.getClassName(), | |||
sig.getSignatureMakerName(), | |||
new ObjectType(sig.getSignatureType()), | |||
@@ -1239,12 +1249,20 @@ public final class LazyClassGen { | |||
return myGen.getFileName(); | |||
} | |||
private void addField(Field field) { | |||
myGen.addField(field); | |||
// for *new* fields | |||
private void addField(FieldGen field) { | |||
makeSyntheticAndTransientIfNeeded(field); | |||
BcelField bcelField = null; | |||
if (getBcelObjectType() != null) { | |||
bcelField = new BcelField(getBcelObjectType(),field.getField()); | |||
} else { | |||
bcelField = new BcelField(getName(),field.getField(),world); | |||
} | |||
fields.add(bcelField); | |||
// myGen.addField(field.getField()); | |||
} | |||
private void makeSyntheticAndTransientIfNeeded(Field field) { | |||
private void makeSyntheticAndTransientIfNeeded(FieldGen field) { | |||
if (field.getName().startsWith(NameMangler.PREFIX) && | |||
!field.getName().startsWith("ajc$interField$") && | |||
!field.getName().startsWith("ajc$instance$")) { | |||
@@ -1260,33 +1278,29 @@ public final class LazyClassGen { | |||
} | |||
if (!hasSyntheticAttribute(field.getAttributes())) { | |||
// belt and braces, do the attribute even on Java 5 in addition to the modifier flag | |||
Attribute[] oldAttrs = field.getAttributes(); | |||
Attribute[] newAttrs = new Attribute[oldAttrs.length + 1]; | |||
System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length); | |||
ConstantPoolGen cpg = myGen.getConstantPool(); | |||
// Attribute[] oldAttrs = field.getAttributes(); | |||
// Attribute[] newAttrs = new Attribute[oldAttrs.length + 1]; | |||
// System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length); | |||
ConstantPool cpg = myGen.getConstantPool(); | |||
int index = cpg.addUtf8("Synthetic"); | |||
Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.getConstantPool()); | |||
newAttrs[newAttrs.length - 1] = synthetic; | |||
field.setAttributes(newAttrs); | |||
Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg); | |||
field.addAttribute(synthetic); | |||
// newAttrs[newAttrs.length - 1] = synthetic; | |||
// field.setAttributes(newAttrs); | |||
} | |||
} | |||
} | |||
private boolean hasSyntheticAttribute(Attribute[] attributes) { | |||
for (int i = 0; i < attributes.length; i++) { | |||
if (attributes[i].getName().equals("Synthetic")) { | |||
private boolean hasSyntheticAttribute(List attributes) { | |||
for (int i = 0; i < attributes.size(); i++) { | |||
if (((Attribute)attributes.get(i)).getName().equals("Synthetic")) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
public void replaceField(Field oldF, Field newF){ | |||
myGen.removeField(oldF); | |||
myGen.addField(newF); | |||
} | |||
public void addField(Field field, ISourceLocation sourceLocation) { | |||
public void addField(FieldGen field, ISourceLocation sourceLocation) { | |||
addField(field); | |||
if (!(field.isPrivate() | |||
&& (field.isStatic() || field.isTransient()))) { | |||
@@ -1330,10 +1344,8 @@ public final class LazyClassGen { | |||
} | |||
public boolean forcePublic() { | |||
if (myGen.isPublic()) return false; | |||
myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags())); | |||
return true; | |||
public void forcePublic() { | |||
myGen.setModifiers(Utility.makePublic(myGen.getModifiers())); | |||
} | |||
@@ -1352,9 +1364,9 @@ public final class LazyClassGen { | |||
return false; | |||
} | |||
public void addAnnotation(Annotation a) { | |||
public void addAnnotation(AnnotationGen a) { | |||
if (!hasAnnotation(UnresolvedType.forSignature(a.getTypeSignature()))) { | |||
annotations.add(new AnnotationGen(a,getConstantPoolGen(),true)); | |||
annotations.add(new AnnotationGen(a,getConstantPool(),true)); | |||
} | |||
} | |||
@@ -1388,9 +1400,9 @@ public final class LazyClassGen { | |||
*/ | |||
public String allocateField(String prefix) { | |||
int highestAllocated = -1; | |||
Field[] fs = getFieldGens(); | |||
for (int i = 0; i < fs.length; i++) { | |||
Field field = fs[i]; | |||
List/*BcelField*/ fs = getFieldGens(); | |||
for (int i = 0; i < fs.size(); i++) { | |||
BcelField field = (BcelField)fs.get(i); | |||
if (field.getName().startsWith(prefix)) { | |||
try { | |||
int num = Integer.parseInt(field.getName().substring(prefix.length())); |
@@ -33,28 +33,26 @@ import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.Synthetic; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; | |||
import org.aspectj.apache.bcel.generic.BranchHandle; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.CPInstruction; | |||
import org.aspectj.apache.bcel.generic.ClassGenException; | |||
import org.aspectj.apache.bcel.generic.CodeExceptionGen; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.generic.InstructionComparator; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionSelect; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.LineNumberGen; | |||
import org.aspectj.apache.bcel.generic.LineNumberTag; | |||
import org.aspectj.apache.bcel.generic.LocalVariableGen; | |||
import org.aspectj.apache.bcel.generic.LocalVariableInstruction; | |||
import org.aspectj.apache.bcel.generic.LocalVariableTag; | |||
import org.aspectj.apache.bcel.generic.MethodGen; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.Select; | |||
import org.aspectj.apache.bcel.generic.Tag; | |||
import org.aspectj.apache.bcel.generic.TargetLostException; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.MessageUtil; | |||
@@ -73,6 +71,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
import org.aspectj.weaver.tools.Traceable; | |||
/** | |||
* A LazyMethodGen should be treated as a MethodGen. It's our way of abstracting over the | |||
* low-level Method objects. It converts through {@link MethodGen} to create | |||
@@ -90,14 +89,14 @@ import org.aspectj.weaver.tools.Traceable; | |||
public final class LazyMethodGen implements Traceable { | |||
private static final int ACC_SYNTHETIC = 0x1000; | |||
private int accessFlags; | |||
private Type returnType; | |||
private final String name; | |||
private int accessFlags; | |||
private Type returnType; | |||
private final String name; | |||
private Type[] argumentTypes; | |||
//private final String[] argumentNames; | |||
private String[] declaredExceptions; | |||
private InstructionList body; // leaving null for abstracts | |||
private Attribute[] attributes; | |||
private List attributes; | |||
private List newAnnotations; | |||
private final LazyClassGen enclosingClass; | |||
private BcelMethod memberView; | |||
@@ -106,6 +105,8 @@ public final class LazyMethodGen implements Traceable { | |||
/* | |||
* We use LineNumberTags and not Gens. | |||
* | |||
* This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens | |||
* or if we make it create LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created | |||
* Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and | |||
@@ -118,12 +119,7 @@ public final class LazyMethodGen implements Traceable { | |||
* instructions it targets, it relies on the instructions targetting *it* - this reduces the amount | |||
* of targeter manipulation we have to do. | |||
* | |||
* Because this *could* go wrong - it passes all our tests, but you never know, the option: | |||
* -Xset:optimizeWithTags=false | |||
* will turn it *OFF* | |||
*/ | |||
public static boolean avoidUseOfBcelGenObjects = true; | |||
public static boolean checkedXsetOption = false; | |||
/** This is nonnull if this method is the result of an "inlining". We currently | |||
* copy methods into other classes for around advice. We add this field so | |||
@@ -171,7 +167,7 @@ public final class LazyMethodGen implements Traceable { | |||
} else { | |||
body = null; | |||
} | |||
this.attributes = new Attribute[0]; | |||
this.attributes = new ArrayList(); | |||
this.enclosingClass = enclosingClass; | |||
assertGoodBody(); | |||
@@ -211,7 +207,33 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m); | |||
this.accessFlags = m.getAccessFlags(); | |||
this.accessFlags = m.getModifiers(); | |||
this.name = m.getName(); | |||
// @AJ advice are not inlined by default since requires further analysis | |||
// and weaving ordering control | |||
// TODO AV - improve - note: no room for improvement as long as aspects are reweavable | |||
// since the inlined version with wrappers and an to be done annotation to keep | |||
// inline state will be garbaged due to reweavable impl | |||
if (memberView != null && isAdviceMethod()) { | |||
if (enclosingClass.getType().isAnnotationStyleAspect()) { | |||
//TODO we could check for @Around advice as well | |||
this.canInline = false; | |||
} | |||
} | |||
} | |||
public LazyMethodGen(BcelMethod m,LazyClassGen enclosingClass) { | |||
savedMethod = m.getMethod(); | |||
this.enclosingClass = enclosingClass; | |||
if (!(m.isAbstract() || m.isNative()) && savedMethod.getCode() == null) { | |||
throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass); | |||
} | |||
if ((m.isAbstract() || m.isNative()) && savedMethod.getCode() != null) { | |||
throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass); | |||
} | |||
//this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m); | |||
this.memberView = m; | |||
this.accessFlags = savedMethod.getModifiers(); | |||
this.name = m.getName(); | |||
// @AJ advice are not inlined by default since requires further analysis | |||
@@ -225,6 +247,7 @@ public final class LazyMethodGen implements Traceable { | |||
this.canInline = false; | |||
} | |||
} | |||
} | |||
public boolean hasDeclaredLineNumberInfo() { | |||
@@ -278,21 +301,9 @@ public final class LazyMethodGen implements Traceable { | |||
private void initialize() { | |||
if (returnType != null) return; | |||
// Check whether we need to configure the optimization | |||
if (!checkedXsetOption) { | |||
Properties p = enclosingClass.getWorld().getExtraConfiguration(); | |||
if (p!=null) { | |||
String s = p.getProperty("optimizeWithTags","true"); | |||
avoidUseOfBcelGenObjects = s.equalsIgnoreCase("true"); | |||
if (!avoidUseOfBcelGenObjects) | |||
enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens")); | |||
} | |||
checkedXsetOption=true; | |||
} | |||
//System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod); | |||
MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen(),avoidUseOfBcelGenObjects); | |||
MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),true); | |||
this.returnType = gen.getReturnType(); | |||
this.argumentTypes = gen.getArgumentTypes(); | |||
@@ -318,13 +329,9 @@ public final class LazyMethodGen implements Traceable { | |||
unpackHandlers(gen); | |||
if (avoidUseOfBcelGenObjects) { | |||
ensureAllLineNumberSetup(gen); | |||
highestLineNumber = gen.getHighestlinenumber(); | |||
} else { | |||
unpackLineNumbers(gen); | |||
unpackLocals(gen); | |||
} | |||
ensureAllLineNumberSetup(gen); | |||
highestLineNumber = gen.getHighestlinenumber(); | |||
} | |||
assertGoodBody(); | |||
@@ -388,29 +395,6 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
} | |||
private void unpackLineNumbers(MethodGen gen) { | |||
LineNumberTag lr = null; | |||
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) { | |||
InstructionTargeter[] targeters = ih.getTargeters(); | |||
if (targeters != null) { | |||
for (int i = targeters.length - 1; i >= 0; i--) { | |||
InstructionTargeter targeter = targeters[i]; | |||
if (targeter instanceof LineNumberGen) { | |||
LineNumberGen lng = (LineNumberGen) targeter; | |||
lng.updateTarget(ih, null); | |||
int lineNumber = lng.getSourceLine(); | |||
if (highestLineNumber < lineNumber) highestLineNumber = lineNumber; | |||
lr = new LineNumberTag(lineNumber); | |||
} | |||
} | |||
} | |||
if (lr != null) { | |||
ih.addTargeter(lr); | |||
} | |||
} | |||
gen.removeLineNumbers(); | |||
} | |||
/** | |||
* On entry to this method we have a method whose instruction stream contains a few instructions | |||
* that have line numbers assigned to them (LineNumberTags). The aim is to ensure every instruction | |||
@@ -437,33 +421,6 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
} | |||
} | |||
private void unpackLocals(MethodGen gen) { | |||
Set locals = new HashSet(); | |||
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) { | |||
InstructionTargeter[] targeters = ih.getTargeters(); | |||
List ends = new ArrayList(0); | |||
if (targeters != null) { | |||
for (int i = targeters.length - 1; i >= 0; i--) { | |||
InstructionTargeter targeter = targeters[i]; | |||
if (targeter instanceof LocalVariableGen) { | |||
LocalVariableGen lng = (LocalVariableGen) targeter; | |||
LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition()); | |||
if (lng.getStart() == ih) { | |||
locals.add(lr); | |||
} else { | |||
ends.add(lr); | |||
} | |||
} | |||
} | |||
} | |||
for (Iterator i = locals.iterator(); i.hasNext(); ) { | |||
ih.addTargeter((LocalVariableTag) i.next()); | |||
} | |||
locals.removeAll(ends); | |||
} | |||
gen.removeLocalVariables(); | |||
} | |||
// =============== | |||
@@ -506,7 +463,8 @@ public final class LazyMethodGen implements Traceable { | |||
// ============================= | |||
public String toString() { | |||
WeaverVersionInfo weaverVersion = enclosingClass.getBcelObjectType().getWeaverVersionAttribute(); | |||
BcelObjectType bot = enclosingClass.getBcelObjectType(); | |||
WeaverVersionInfo weaverVersion = (bot==null?WeaverVersionInfo.CURRENT:bot.getWeaverVersionAttribute()); | |||
return toLongString(weaverVersion); | |||
} | |||
@@ -588,7 +546,7 @@ public final class LazyMethodGen implements Traceable { | |||
if (enclosingClass != null && enclosingClass.getType() != null) { | |||
context = enclosingClass.getType().getSourceContext(); | |||
} | |||
List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,weaverVersion); | |||
List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[])attributes.toArray(new Attribute[]{}), context,null,weaverVersion); | |||
if (! as.isEmpty()) { | |||
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger... | |||
} | |||
@@ -606,7 +564,7 @@ public final class LazyMethodGen implements Traceable { | |||
List ranges; | |||
BodyPrinter(PrintStream out) { | |||
this.pool = enclosingClass.getConstantPoolGen().getConstantPool(); | |||
this.pool = enclosingClass.getConstantPool(); | |||
this.body = getBody(); | |||
this.out = out; | |||
} | |||
@@ -634,7 +592,7 @@ public final class LazyMethodGen implements Traceable { | |||
if (r.getStart() == ih) { | |||
insertHandler(r, exnTable); | |||
} | |||
} else if (t instanceof BranchInstruction) { | |||
} else if (t instanceof InstructionBranch) { | |||
if (pendingLabel == null) { | |||
pendingLabel = "L" + lcounter++; | |||
} | |||
@@ -736,14 +694,13 @@ public final class LazyMethodGen implements Traceable { | |||
printLabel((String) labelMap.get(h), depth); | |||
Instruction inst = h.getInstruction(); | |||
if (inst instanceof CPInstruction) { | |||
CPInstruction cpinst = (CPInstruction) inst; | |||
out.print(Constants.OPCODE_NAMES[cpinst.getOpcode()].toUpperCase()); | |||
if (inst.isConstantPoolInstruction()) { | |||
out.print(Constants.OPCODE_NAMES[inst.opcode].toUpperCase()); | |||
out.print(" "); | |||
out.print(pool.constantToString(pool.getConstant(cpinst.getIndex()))); | |||
} else if (inst instanceof Select) { | |||
Select sinst = (Select) inst; | |||
out.println(Constants.OPCODE_NAMES[sinst.getOpcode()].toUpperCase()); | |||
out.print(pool.constantToString(pool.getConstant(inst.getIndex()))); | |||
} else if (inst instanceof InstructionSelect) { | |||
InstructionSelect sinst = (InstructionSelect) inst; | |||
out.println(Constants.OPCODE_NAMES[sinst.opcode].toUpperCase()); | |||
int[] matches = sinst.getMatchs(); | |||
InstructionHandle[] targets = sinst.getTargets(); | |||
InstructionHandle defaultTarget = sinst.getTarget(); | |||
@@ -760,15 +717,15 @@ public final class LazyMethodGen implements Traceable { | |||
out.print(" "); | |||
out.print("default: \t"); | |||
out.print(labelMap.get(defaultTarget)); | |||
} else if (inst instanceof BranchInstruction) { | |||
BranchInstruction brinst = (BranchInstruction) inst; | |||
} else if (inst instanceof InstructionBranch) { | |||
InstructionBranch brinst = (InstructionBranch) inst; | |||
out.print(Constants.OPCODE_NAMES[brinst.getOpcode()].toUpperCase()); | |||
out.print(" "); | |||
out.print(labelMap.get(brinst.getTarget())); | |||
} else if (inst instanceof LocalVariableInstruction) { | |||
LocalVariableInstruction lvinst = (LocalVariableInstruction) inst; | |||
} else if (inst.isLocalVariableInstruction()) { | |||
//LocalVariableInstruction lvinst = (LocalVariableInstruction) inst; | |||
out.print(inst.toString(false).toUpperCase()); | |||
int index = lvinst.getIndex(); | |||
int index = inst.getIndex(); | |||
LocalVariableTag tag = getLocalVariableTag(h, index); | |||
if (tag != null) { | |||
out.print(" // "); | |||
@@ -914,7 +871,7 @@ public final class LazyMethodGen implements Traceable { | |||
return body != null; | |||
} | |||
public Attribute[] getAttributes() { | |||
public List/*Attribute*/ getAttributes() { | |||
return attributes; | |||
} | |||
@@ -947,13 +904,13 @@ public final class LazyMethodGen implements Traceable { | |||
getName(), | |||
getEnclosingClass().getName(), | |||
new InstructionList(), | |||
getEnclosingClass().getConstantPoolGen()); | |||
getEnclosingClass().getConstantPool()); | |||
for (int i = 0, len = declaredExceptions.length; i < len; i++) { | |||
gen.addException(declaredExceptions[i]); | |||
} | |||
for (int i = 0, len = attributes.length; i < len; i++) { | |||
gen.addAttribute(attributes[i]); | |||
for (int i = 0, len = attributes.size(); i < len; i++) { | |||
gen.addAttribute((Attribute)attributes.get(i)); | |||
} | |||
if (newAnnotations!=null) { | |||
@@ -966,7 +923,7 @@ public final class LazyMethodGen implements Traceable { | |||
if (memberView!=null && memberView.getAnnotations()!=null && memberView.getAnnotations().length!=0) { | |||
AnnotationX[] ans = memberView.getAnnotations(); | |||
for (int i = 0, len = ans.length; i < len; i++) { | |||
Annotation a= ans[i].getBcelAnnotation(); | |||
AnnotationGen a= ans[i].getBcelAnnotation(); | |||
gen.addAnnotation(new AnnotationGen(a,gen.getConstantPool(),true)); | |||
} | |||
} | |||
@@ -976,9 +933,9 @@ public final class LazyMethodGen implements Traceable { | |||
gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC); | |||
} | |||
// belt and braces, do the attribute even on Java 5 in addition to the modifier flag | |||
ConstantPoolGen cpg = gen.getConstantPool(); | |||
ConstantPool cpg = gen.getConstantPool(); | |||
int index = cpg.addUtf8("Synthetic"); | |||
gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg.getConstantPool())); | |||
gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg)); | |||
} | |||
if (hasBody()) { | |||
@@ -1045,7 +1002,7 @@ public final class LazyMethodGen implements Traceable { | |||
Instruction oldInstruction = oldInstructionHandle.getInstruction(); | |||
Instruction newInstruction = newInstructionHandle.getInstruction(); | |||
if (oldInstruction instanceof BranchInstruction) { | |||
if (oldInstruction instanceof InstructionBranch) { | |||
handleBranchInstruction(map, oldInstruction, newInstruction); | |||
} | |||
@@ -1148,27 +1105,20 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
private void handleBranchInstruction(Map map, Instruction oldInstruction, Instruction newInstruction) { | |||
BranchInstruction oldBranchInstruction = (BranchInstruction) oldInstruction; | |||
BranchInstruction newBranchInstruction = (BranchInstruction) newInstruction; | |||
InstructionBranch oldBranchInstruction = (InstructionBranch) oldInstruction; | |||
InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction; | |||
InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target | |||
// try { | |||
// New target is in hash map | |||
newBranchInstruction.setTarget(remap(oldTarget, map)); | |||
// } catch (NullPointerException e) { | |||
// print(); | |||
// System.out.println("Was trying to remap " + bi); | |||
// System.out.println("who's target was supposedly " + itarget); | |||
// throw e; | |||
// } | |||
if (oldBranchInstruction instanceof Select) { | |||
// Either LOOKUPSWITCH or TABLESWITCH | |||
InstructionHandle[] oldTargets = ((Select) oldBranchInstruction).getTargets(); | |||
InstructionHandle[] newTargets = ((Select) newBranchInstruction).getTargets(); | |||
if (oldBranchInstruction instanceof InstructionSelect) { | |||
// Either LOOKUPSWITCH or TABLESWITCH | |||
InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets(); | |||
InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets(); | |||
for (int k = oldTargets.length - 1; k >= 0; k--) { | |||
// Update all targets | |||
for (int k = oldTargets.length - 1; k >= 0; k--) { | |||
// Update all targets | |||
newTargets[k] = remap(oldTargets[k], map); | |||
newTargets[k].addTargeter(newBranchInstruction); | |||
} | |||
@@ -1206,8 +1156,8 @@ public final class LazyMethodGen implements Traceable { | |||
Instruction i = ih.getInstruction(); | |||
Instruction c = Utility.copyInstruction(i); | |||
if (c instanceof BranchInstruction) | |||
map.put(ih, intoList.append((BranchInstruction) c)); | |||
if (c instanceof InstructionBranch) | |||
map.put(ih, intoList.append((InstructionBranch) c)); | |||
else | |||
map.put(ih, intoList.append(c)); | |||
} | |||
@@ -1337,80 +1287,71 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
public static void assertGoodBody(InstructionList il, String from) { | |||
if (true) return; // only to be enabled for debugging // should be switchonable via an option | |||
StringBuffer assertionLog = new StringBuffer(); | |||
assertionLog.append("Checking state of an instruction body, from="+from+"\n"); | |||
try { | |||
if (il == null) return; | |||
Set body = new HashSet(); | |||
Stack ranges = new Stack(); | |||
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { | |||
body.add(ih); | |||
if (ih.getInstruction() instanceof BranchInstruction) { | |||
body.add(ih.getInstruction()); | |||
} | |||
} | |||
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { | |||
assertGoodHandle(ih, body, ranges, from, assertionLog); | |||
InstructionTargeter[] ts = ih.getTargeters(); | |||
if (ts != null) { | |||
for (int i = ts.length - 1; i >= 0; i--) { | |||
assertGoodTargeter(ts[i], ih, body, from, assertionLog); | |||
} | |||
} | |||
} | |||
} catch (RuntimeException re) { | |||
System.err.println(assertionLog.toString()); | |||
throw re; | |||
} | |||
if (true) return; // only to be enabled for debugging | |||
if (il == null) return; | |||
Set body = new HashSet(); | |||
Stack ranges = new Stack(); | |||
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { | |||
body.add(ih); | |||
if (ih.getInstruction() instanceof InstructionBranch) { | |||
body.add(ih.getInstruction()); | |||
} | |||
} | |||
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { | |||
assertGoodHandle(ih, body, ranges, from); | |||
InstructionTargeter[] ts = ih.getTargeters(); | |||
if (ts != null) { | |||
for (int i = ts.length - 1; i >= 0; i--) { | |||
assertGoodTargeter(ts[i], ih, body, from); | |||
} | |||
} | |||
} | |||
} | |||
private static void assertGoodHandle(InstructionHandle ih, Set body, Stack ranges, String from, StringBuffer log) { | |||
private static void assertGoodHandle(InstructionHandle ih, Set body, Stack ranges, String from) { | |||
Instruction inst = ih.getInstruction(); | |||
if ((inst instanceof BranchInstruction) ^ (ih instanceof BranchHandle)) { | |||
if ((inst instanceof InstructionBranch) ^ (ih instanceof BranchHandle)) { | |||
throw new BCException("bad instruction/handle pair in " + from); | |||
} | |||
if (Range.isRangeHandle(ih)) { | |||
log.append("Checking range handle '"+ih+"'\n"); | |||
assertGoodRangeHandle(ih, body, ranges, from,log); | |||
} else if (inst instanceof BranchInstruction) { | |||
assertGoodBranchInstruction((BranchHandle) ih, (BranchInstruction) inst, body, ranges, from, log); | |||
assertGoodRangeHandle(ih, body, ranges, from); | |||
} else if (inst instanceof InstructionBranch) { | |||
assertGoodBranchInstruction((BranchHandle) ih, (InstructionBranch) inst, body, ranges, from); | |||
} | |||
} | |||
private static void assertGoodBranchInstruction( | |||
BranchHandle ih, | |||
BranchInstruction inst, | |||
InstructionBranch inst, | |||
Set body, | |||
Stack ranges, | |||
String from, StringBuffer log) | |||
String from) | |||
{ | |||
if (ih.getTarget() != inst.getTarget()) { | |||
throw new BCException("bad branch instruction/handle pair in " + from); | |||
} | |||
InstructionHandle target = ih.getTarget(); | |||
assertInBody(target, body, from, log); | |||
assertInBody(target, body, from); | |||
assertTargetedBy(target, inst, from); | |||
if (inst instanceof Select) { | |||
Select sel = (Select) inst; | |||
if (inst instanceof InstructionSelect) { | |||
InstructionSelect sel = (InstructionSelect) inst; | |||
InstructionHandle[] itargets = sel.getTargets(); | |||
for (int k = itargets.length - 1; k >= 0; k--) { | |||
assertInBody(itargets[k], body, from, log); | |||
assertInBody(itargets[k], body, from); | |||
assertTargetedBy(itargets[k], inst, from); | |||
} | |||
} | |||
} | |||
/** ih is an InstructionHandle or a BranchInstruction */ | |||
private static void assertInBody(Object ih, Set body, String from,StringBuffer log) { | |||
private static void assertInBody(Object ih, Set body, String from) { | |||
if (! body.contains(ih)) throw new BCException("thing not in body in " + from); | |||
} | |||
private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from, StringBuffer log) { | |||
private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from) { | |||
Range r = getRangeAndAssertExactlyOne(ih, from); | |||
assertGoodRange(r, body, from, log); | |||
assertGoodRange(r, body, from); | |||
if (r.getStart() == ih) { | |||
ranges.push(r); | |||
} else if (r.getEnd() == ih) { | |||
@@ -1419,23 +1360,18 @@ public final class LazyMethodGen implements Traceable { | |||
} | |||
} | |||
private static void assertGoodRange(Range r, Set body, String from, StringBuffer log) { | |||
assertInBody(r.getStart(), body, from, log); | |||
private static void assertGoodRange(Range r, Set body, String from) { | |||
assertInBody(r.getStart(), body, from); | |||
assertRangeHandle(r.getStart(), from); | |||
assertTargetedBy(r.getStart(), r, from); | |||
assertInBody(r.getEnd(), body, from, log); | |||
assertInBody(r.getEnd(), body, from); | |||
assertRangeHandle(r.getEnd(), from); | |||
assertTargetedBy(r.getEnd(), r, from); | |||
if (r instanceof ExceptionRange) { | |||
ExceptionRange er = (ExceptionRange) r; | |||
log.append("Checking exception range \n"); | |||
if (!body.contains(er.getHandler())) { | |||
log.append("Exception handler not within body\n"); | |||
throw new BCException("exception handler not in body"); | |||
} | |||
// assertInBody(er.getHandler(), body, from, log); | |||
assertInBody(er.getHandler(), body, from); | |||
assertTargetedBy(er.getHandler(), r, from); | |||
} | |||
} | |||
@@ -1465,11 +1401,11 @@ public final class LazyMethodGen implements Traceable { | |||
if (r instanceof ExceptionRange) { | |||
if (((ExceptionRange)r).getHandler() == target) return; | |||
} | |||
} else if (targeter instanceof BranchInstruction) { | |||
BranchInstruction bi = (BranchInstruction) targeter; | |||
} else if (targeter instanceof InstructionBranch) { | |||
InstructionBranch bi = (InstructionBranch) targeter; | |||
if (bi.getTarget() == target) return; | |||
if (targeter instanceof Select) { | |||
Select sel = (Select) targeter; | |||
if (targeter instanceof InstructionSelect) { | |||
InstructionSelect sel = (InstructionSelect) targeter; | |||
InstructionHandle[] itargets = sel.getTargets(); | |||
for (int k = itargets.length - 1; k >= 0; k--) { | |||
if (itargets[k] == target) return; | |||
@@ -1499,13 +1435,13 @@ public final class LazyMethodGen implements Traceable { | |||
InstructionTargeter t, | |||
InstructionHandle ih, | |||
Set body, | |||
String from, StringBuffer log) | |||
String from) | |||
{ | |||
assertTargets(t, ih, from); | |||
if (t instanceof Range) { | |||
assertGoodRange((Range) t, body, from, log); | |||
} else if (t instanceof BranchInstruction) { | |||
assertInBody(t, body, from, log); | |||
assertGoodRange((Range) t, body, from); | |||
} else if (t instanceof InstructionBranch) { | |||
assertInBody(t, body, from); | |||
} | |||
} | |||
@@ -1513,6 +1449,7 @@ public final class LazyMethodGen implements Traceable { | |||
// ---- | |||
boolean isAdviceMethod() { | |||
if (memberView==null) return false; | |||
return memberView.getAssociatedShadowMunger() != null; | |||
} | |||
@@ -1576,10 +1513,11 @@ public final class LazyMethodGen implements Traceable { | |||
* @param attr | |||
*/ | |||
public void addAttribute(Attribute attr) { | |||
Attribute[] newAttributes = new Attribute[attributes.length + 1]; | |||
System.arraycopy(attributes, 0, newAttributes, 0, attributes.length); | |||
newAttributes[attributes.length] = attr; | |||
attributes = newAttributes; | |||
attributes.add(attr); | |||
// Attribute[] newAttributes = new Attribute[attributes.length + 1]; | |||
// System.arraycopy(attributes, 0, newAttributes, 0, attributes.length); | |||
// newAttributes[attributes.length] = attr; | |||
// attributes = newAttributes; | |||
} | |||
public String toTraceString() { |
@@ -15,8 +15,8 @@ package org.aspectj.weaver.bcel; | |||
import java.util.Map; | |||
import org.aspectj.apache.bcel.generic.IMPDEP1; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
@@ -224,7 +224,7 @@ abstract class Range implements InstructionTargeter { | |||
// note that this is STUPIDLY copied by Instruction.copy(), so don't do that. | |||
public static final Instruction RANGEINSTRUCTION = new IMPDEP1(); | |||
public static final Instruction RANGEINSTRUCTION = InstructionConstants.IMPDEP1; | |||
// ---- | |||
@@ -13,17 +13,15 @@ | |||
package org.aspectj.weaver.bcel; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.IndexedInstruction; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionBranch; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionSelect; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.LocalVariableInstruction; | |||
import org.aspectj.apache.bcel.generic.LocalVariableTag; | |||
import org.aspectj.apache.bcel.generic.RET; | |||
import org.aspectj.apache.bcel.generic.Select; | |||
import org.aspectj.apache.bcel.generic.TargetLostException; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.IntMap; | |||
@@ -76,17 +74,17 @@ final class ShadowRange extends Range { | |||
// Now we add it to the new instruction list. | |||
InstructionHandle freshIh; | |||
if (freshI instanceof BranchInstruction) { | |||
if (freshI instanceof InstructionBranch) { | |||
//If it's a targeting instruction, | |||
// update the target(s) to point to the new copy instead of the old copy. | |||
BranchInstruction oldBranch = (BranchInstruction) oldI; | |||
BranchInstruction freshBranch = (BranchInstruction) freshI; | |||
InstructionBranch oldBranch = (InstructionBranch) oldI; | |||
InstructionBranch freshBranch = (InstructionBranch) freshI; | |||
InstructionHandle oldTarget = oldBranch.getTarget(); | |||
oldTarget.removeTargeter(oldBranch); | |||
oldTarget.addTargeter(freshBranch); | |||
if (freshBranch instanceof Select) { | |||
Select oldSelect = (Select) oldI; | |||
Select freshSelect = (Select) freshI; | |||
if (freshBranch instanceof InstructionSelect) { | |||
InstructionSelect oldSelect = (InstructionSelect) oldI; | |||
InstructionSelect freshSelect = (InstructionSelect) freshI; | |||
InstructionHandle[] oldTargets = freshSelect.getTargets(); | |||
for (int k = oldTargets.length - 1; k >= 0; k--) { | |||
oldTargets[k].removeTargeter(oldSelect); | |||
@@ -161,9 +159,9 @@ final class ShadowRange extends Range { | |||
// do compaction/expansion: allocate a new local variable, and modify the remap | |||
// to handle it. XXX We're doing the safe thing and allocating ALL these local variables | |||
// as double-wides, in case the location is found to hold a double-wide later. | |||
if (freshI instanceof LocalVariableInstruction || freshI instanceof RET) { | |||
IndexedInstruction indexedI = (IndexedInstruction) freshI; | |||
int oldIndex = indexedI.getIndex(); | |||
if (freshI.isLocalVariableInstruction() || freshI instanceof RET) { | |||
// IndexedInstruction indexedI = (IndexedInstruction) freshI; | |||
int oldIndex = freshI.getIndex(); | |||
int freshIndex; | |||
if (! remap.hasKey(oldIndex)) { | |||
freshIndex = freshMethod.allocateLocal(2); | |||
@@ -171,7 +169,7 @@ final class ShadowRange extends Range { | |||
} else { | |||
freshIndex = remap.get(oldIndex); | |||
} | |||
indexedI.setIndex(freshIndex); | |||
freshI.setIndex(freshIndex); | |||
} | |||
// System.err.println("JUST COPIED: " + oldIh.getInstruction().toString(freshMethod.getEnclosingClass().getConstantPoolGen().getConstantPool()) | |||
// + " INTO " + freshIh.getInstruction().toString(freshMethod.getEnclosingClass().getConstantPoolGen().getConstantPool())); |
@@ -24,36 +24,36 @@ import java.util.Hashtable; | |||
import java.util.List; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
import org.aspectj.apache.bcel.classfile.ClassParser; | |||
import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||
import org.aspectj.apache.bcel.classfile.Method; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValue; | |||
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; | |||
import org.aspectj.apache.bcel.classfile.Unknown; | |||
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen; | |||
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValueGen; | |||
import org.aspectj.apache.bcel.generic.ArrayType; | |||
import org.aspectj.apache.bcel.generic.BIPUSH; | |||
import org.aspectj.apache.bcel.generic.BasicType; | |||
import org.aspectj.apache.bcel.generic.BranchInstruction; | |||
import org.aspectj.apache.bcel.generic.ConstantPushInstruction; | |||
import org.aspectj.apache.bcel.generic.INSTANCEOF; | |||
import org.aspectj.apache.bcel.generic.Instruction; | |||
import org.aspectj.apache.bcel.generic.InstructionByte; | |||
import org.aspectj.apache.bcel.generic.InstructionCP; | |||
import org.aspectj.apache.bcel.generic.InstructionConstants; | |||
import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
import org.aspectj.apache.bcel.generic.InstructionSelect; | |||
import org.aspectj.apache.bcel.generic.InstructionShort; | |||
import org.aspectj.apache.bcel.generic.InstructionTargeter; | |||
import org.aspectj.apache.bcel.generic.InvokeInstruction; | |||
import org.aspectj.apache.bcel.generic.LDC; | |||
import org.aspectj.apache.bcel.generic.LineNumberTag; | |||
import org.aspectj.apache.bcel.generic.ObjectType; | |||
import org.aspectj.apache.bcel.generic.ReferenceType; | |||
import org.aspectj.apache.bcel.generic.SIPUSH; | |||
import org.aspectj.apache.bcel.generic.SWITCH; | |||
import org.aspectj.apache.bcel.generic.Select; | |||
import org.aspectj.apache.bcel.generic.SwitchBuilder; | |||
import org.aspectj.apache.bcel.generic.TargetLostException; | |||
import org.aspectj.apache.bcel.generic.Type; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.weaver.AjAttribute; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.Lint; | |||
@@ -207,12 +207,8 @@ public class Utility { | |||
kind = Constants.INVOKEVIRTUAL; | |||
} | |||
return fact.createInvoke( | |||
declaringClass.getClassName(), | |||
newMethod.getName(), | |||
Type.getReturnType(newMethod.getSignature()), | |||
Type.getArgumentTypes(newMethod.getSignature()), | |||
kind); | |||
String sig = newMethod.getSignature(); | |||
return fact.createInvoke(declaringClass.getClassName(),newMethod.getName(),sig,kind); | |||
} | |||
public static byte[] stringToUTF(String s) { | |||
@@ -231,7 +227,7 @@ public class Utility { | |||
(t instanceof ArrayType) | |||
? fact.getConstantPool().addArrayClass((ArrayType)t) | |||
: fact.getConstantPool().addClass((ObjectType)t); | |||
return new INSTANCEOF(cpoolEntry); | |||
return new InstructionCP(Constants.INSTANCEOF,cpoolEntry); | |||
} | |||
public static Instruction createInvoke( | |||
@@ -276,11 +272,17 @@ public class Utility { | |||
kind); | |||
} | |||
private static String[] argNames = new String[] { "arg0", "arg1", "arg2", "arg3", "arg4" }; | |||
// ??? these should perhaps be cached. Remember to profile this to see if it's a problem. | |||
public static String[] makeArgNames(int n) { | |||
String[] ret = new String[n]; | |||
for (int i=0; i<n; i++) { | |||
ret[i] = "arg" + i; | |||
if (i < 5) { | |||
ret[i] = argNames[i]; | |||
} else { | |||
ret[i] = "arg" + i; | |||
} | |||
} | |||
return ret; | |||
} | |||
@@ -384,7 +386,13 @@ public class Utility { | |||
Type from = BcelWorld.makeBcelType(fromType); | |||
Type to = BcelWorld.makeBcelType(toType); | |||
try { | |||
il.append(fact.createCast(from, to)); | |||
Instruction i = fact.createCast(from, to); | |||
if (i!=null) { | |||
il.append(i); | |||
} else { | |||
il.append(fact.createCast(from, Type.INT)); | |||
il.append(fact.createCast(Type.INT, to)); | |||
} | |||
} catch (RuntimeException e) { | |||
il.append(fact.createCast(from, Type.INT)); | |||
il.append(fact.createCast(Type.INT, to)); | |||
@@ -513,11 +521,12 @@ public class Utility { | |||
case 5: inst = InstructionConstants.ICONST_5; break; | |||
} | |||
if (i <= Byte.MAX_VALUE && i >= Byte.MIN_VALUE) { | |||
inst = new BIPUSH((byte)i); | |||
inst = new InstructionByte(Constants.BIPUSH,(byte)i); | |||
} else if (i <= Short.MAX_VALUE && i >= Short.MIN_VALUE) { | |||
inst = new SIPUSH((short)i); | |||
inst = new InstructionShort(Constants.SIPUSH,(short)i); | |||
} else { | |||
inst = new LDC(fact.getClassGen().getConstantPool().addInteger(i)); | |||
int ii = fact.getClassGen().getConstantPool().addInteger(i); | |||
inst = new InstructionCP(i<=Constants.MAX_BYTE?Constants.LDC:Constants.LDC_W,ii); | |||
} | |||
return inst; | |||
} | |||
@@ -555,17 +564,6 @@ public class Utility { | |||
* @param branchInstruction the branch instruction to replace ih with | |||
* @param enclosingMethod where to find ih's instruction list. | |||
*/ | |||
public static void replaceInstruction( | |||
InstructionHandle ih, | |||
BranchInstruction branchInstruction, | |||
LazyMethodGen enclosingMethod) | |||
{ | |||
InstructionList il = enclosingMethod.getBody(); | |||
InstructionHandle fresh = il.append(ih, branchInstruction); | |||
deleteInstruction(ih, fresh, enclosingMethod); | |||
} | |||
public static void replaceInstruction( | |||
InstructionHandle ih, | |||
InstructionList replacementInstructions, | |||
@@ -635,8 +633,8 @@ public class Utility { | |||
* </pre> | |||
*/ | |||
public static Instruction copyInstruction(Instruction i) { | |||
if (i instanceof Select) { | |||
Select freshSelect = (Select)i; | |||
if (i instanceof InstructionSelect) { | |||
InstructionSelect freshSelect = (InstructionSelect)i; | |||
// Create a new targets array that looks just like the existing one | |||
InstructionHandle[] targets = new InstructionHandle[freshSelect.getTargets().length]; | |||
@@ -645,9 +643,8 @@ public class Utility { | |||
} | |||
// Create a new select statement with the new targets array | |||
SWITCH switchStatement = | |||
new SWITCH(freshSelect.getMatchs(), targets, freshSelect.getTarget()); | |||
return (Select)switchStatement.getInstruction(); | |||
return new SwitchBuilder(freshSelect.getMatchs(), targets, freshSelect.getTarget()).getInstruction(); | |||
} else { | |||
return i.copy(); // Use clone for shallow copy... | |||
} | |||
@@ -699,6 +696,7 @@ public class Utility { | |||
// assumes that there is no already extant source line tag. Otherwise we'll have to be better. | |||
public static void setSourceLine(InstructionHandle ih, int lineNumber) { | |||
// OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method... | |||
ih.addTargeter(new LineNumberTag(lineNumber)); | |||
} | |||
@@ -729,7 +727,8 @@ public class Utility { | |||
} | |||
public static boolean isConstantPushInstruction(Instruction i) { | |||
return (i instanceof ConstantPushInstruction) || (i instanceof LDC); | |||
long ii= Constants.instFlags[i.opcode]; | |||
return ((ii&Constants.PUSH_INST)!=0 && (ii&Constants.CONSTANT_INST)!=0); | |||
} | |||
/** | |||
@@ -753,11 +752,11 @@ public class Utility { | |||
suppressed = true; | |||
} else { // (2) | |||
// We know the value is an array value | |||
ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue(); | |||
ElementValue[] values = array.getElementValuesArray(); | |||
ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue(); | |||
ElementValueGen[] values = array.getElementValuesArray(); | |||
for (int j = 0; j < values.length; j++) { | |||
// We know values in the array are strings | |||
SimpleElementValue value = (SimpleElementValue)values[j]; | |||
SimpleElementValueGen value = (SimpleElementValueGen)values[j]; | |||
if (value.getValueString().equals(lintkey)) { | |||
suppressed = true; | |||
} | |||
@@ -785,11 +784,11 @@ public class Utility { | |||
suppressedWarnings.addAll(lint.allKinds()); | |||
} else { // (2) | |||
// We know the value is an array value | |||
ArrayElementValue array = (ArrayElementValue)((ElementNameValuePair)vals.get(0)).getValue(); | |||
ElementValue[] values = array.getElementValuesArray(); | |||
ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue(); | |||
ElementValueGen[] values = array.getElementValuesArray(); | |||
for (int j = 0; j < values.length; j++) { | |||
// We know values in the array are strings | |||
SimpleElementValue value = (SimpleElementValue)values[j]; | |||
SimpleElementValueGen value = (SimpleElementValueGen)values[j]; | |||
Lint.Kind lintKind = lint.getLintKind(value.getValueString()); | |||
if (lintKind != null) suppressedWarnings.add(lintKind); | |||
} | |||
@@ -800,25 +799,33 @@ public class Utility { | |||
} | |||
// not yet used... | |||
public static boolean isSimple(Method method) { | |||
if (method.getCode()==null) return true; | |||
if (method.getCode().getCode().length>10) return false; | |||
InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive! | |||
InstructionHandle InstrHandle = instrucs.getStart(); | |||
while (InstrHandle != null) { | |||
Instruction Instr = InstrHandle.getInstruction(); | |||
int opCode = Instr.getOpcode(); | |||
// if current instruction is a branch instruction, see if it's a backward branch. | |||
// if it is return immediately (can't be trivial) | |||
if (Instr instanceof BranchInstruction) { | |||
BranchInstruction BI = (BranchInstruction) Instr; | |||
if (BI.getIndex() < 0) return false; | |||
} else if (Instr instanceof InvokeInstruction) { | |||
// if current instruction is an invocation, indicate that it can't be trivial | |||
return false; | |||
} | |||
InstrHandle = InstrHandle.getNext(); | |||
} | |||
return true; | |||
} | |||
// public static boolean isSimple(Method method) { | |||
// if (method.getCode()==null) return true; | |||
// if (method.getCode().getCode().length>10) return false; | |||
// InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive! | |||
// InstructionHandle InstrHandle = instrucs.getStart(); | |||
// while (InstrHandle != null) { | |||
// Instruction Instr = InstrHandle.getInstruction(); | |||
// int opCode = Instr.opcode; | |||
// // if current instruction is a branch instruction, see if it's a backward branch. | |||
// // if it is return immediately (can't be trivial) | |||
// if (Instr instanceof InstructionBranch) { | |||
// // InstructionBranch BI = (InstructionBranch) Instr; | |||
// if (Instr.getIndex() < 0) return false; | |||
// } else if (Instr instanceof InvokeInstruction) { | |||
// // if current instruction is an invocation, indicate that it can't be trivial | |||
// return false; | |||
// } | |||
// InstrHandle = InstrHandle.getNext(); | |||
// } | |||
// return true; | |||
// } | |||
public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) { | |||
int nameIndex = pool.addUtf8(a.getNameString()); | |||
byte[] bytes = a.getBytes(); | |||
int length = bytes.length; | |||
return new Unknown(nameIndex, length, bytes, pool); | |||
} | |||
} |
@@ -24,6 +24,7 @@ import java.util.Map; | |||
import java.util.Set; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.MemberKind; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.Shadow; | |||
import org.aspectj.weaver.UnresolvedType; | |||
@@ -1268,7 +1269,7 @@ public class PatternParser { | |||
TypePattern declaringType; | |||
NamePattern name = null; | |||
Member.Kind kind; | |||
MemberKind kind; | |||
// here we can check for 'new' | |||
if (maybeEatNew(returnType)) { | |||
kind = Member.CONSTRUCTOR; |
@@ -36,6 +36,7 @@ import org.aspectj.weaver.ConcreteTypeMunger; | |||
import org.aspectj.weaver.Constants; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.JoinPointSignature; | |||
import org.aspectj.weaver.MemberKind; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.NameMangler; | |||
import org.aspectj.weaver.NewFieldTypeMunger; | |||
@@ -47,7 +48,7 @@ import org.aspectj.weaver.World; | |||
public class SignaturePattern extends PatternNode { | |||
private Member.Kind kind; | |||
private MemberKind kind; | |||
private ModifiersPattern modifiers; | |||
private TypePattern returnType; | |||
private TypePattern declaringType; | |||
@@ -57,7 +58,7 @@ public class SignaturePattern extends PatternNode { | |||
private AnnotationTypePattern annotationPattern; | |||
private transient int hashcode = -1; | |||
public SignaturePattern(Member.Kind kind, ModifiersPattern modifiers, | |||
public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, | |||
TypePattern returnType, TypePattern declaringType, | |||
NamePattern name, TypePatternList parameterTypes, | |||
ThrowsPattern throwsPattern, | |||
@@ -596,7 +597,7 @@ public class SignaturePattern extends PatternNode { | |||
public NamePattern getName() { return name; } | |||
public TypePattern getDeclaringType() { return declaringType; } | |||
public Member.Kind getKind() { | |||
public MemberKind getKind() { | |||
return kind; | |||
} | |||
@@ -682,7 +683,7 @@ public class SignaturePattern extends PatternNode { | |||
} | |||
public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
Member.Kind kind = Member.Kind.read(s); | |||
MemberKind kind = MemberKind.read(s); | |||
ModifiersPattern modifiers = ModifiersPattern.read(s); | |||
TypePattern returnType = TypePattern.read(s, context); | |||
TypePattern declaringType = TypePattern.read(s, context); |
@@ -15,6 +15,7 @@ import java.lang.reflect.Member; | |||
import java.util.Iterator; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.MemberKind; | |||
import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedMemberImpl; | |||
import org.aspectj.weaver.ResolvedType; | |||
@@ -42,7 +43,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { | |||
* @param name | |||
* @param parameterTypes | |||
*/ | |||
public ReflectionBasedResolvedMemberImpl(Kind kind, | |||
public ReflectionBasedResolvedMemberImpl(MemberKind kind, | |||
UnresolvedType declaringType, int modifiers, | |||
UnresolvedType returnType, String name, | |||
UnresolvedType[] parameterTypes, | |||
@@ -60,7 +61,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { | |||
* @param parameterTypes | |||
* @param checkedExceptions | |||
*/ | |||
public ReflectionBasedResolvedMemberImpl(Kind kind, | |||
public ReflectionBasedResolvedMemberImpl(MemberKind kind, | |||
UnresolvedType declaringType, int modifiers, | |||
UnresolvedType returnType, String name, | |||
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, | |||
@@ -80,7 +81,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { | |||
* @param checkedExceptions | |||
* @param backingGenericMember | |||
*/ | |||
public ReflectionBasedResolvedMemberImpl(Kind kind, | |||
public ReflectionBasedResolvedMemberImpl(MemberKind kind, | |||
UnresolvedType declaringType, int modifiers, | |||
UnresolvedType returnType, String name, | |||
UnresolvedType[] parameterTypes, | |||
@@ -99,7 +100,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { | |||
* @param name | |||
* @param signature | |||
*/ | |||
public ReflectionBasedResolvedMemberImpl(Kind kind, | |||
public ReflectionBasedResolvedMemberImpl(MemberKind kind, | |||
UnresolvedType declaringType, int modifiers, String name, | |||
String signature, Member reflectMember) { | |||
super(kind, declaringType, modifiers, name, signature); |
@@ -168,7 +168,7 @@ public class MemberTestCase extends TestCase { | |||
private void declaringTypeTest(Member m, String declaringName) { | |||
assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType()); | |||
} | |||
private void kindTest(Member m, MemberImpl.Kind kind) { | |||
private void kindTest(Member m, MemberKind kind) { | |||
assertEquals(m + " kind", kind, m.getKind()); | |||
} | |||