Browse Source

246125: comment 3: reworked AnnotationX - got rid of the thing

tags/V1_6_2
aclement 15 years ago
parent
commit
c3587474e9
32 changed files with 5315 additions and 3571 deletions
  1. 158
    0
      weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java
  2. 3
    3
      weaver/src/org/aspectj/weaver/AnnotatedElement.java
  3. 76
    104
      weaver/src/org/aspectj/weaver/AnnotationAJ.java
  4. 24
    22
      weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java
  5. 0
    224
      weaver/src/org/aspectj/weaver/AnnotationX.java
  6. 106
    76
      weaver/src/org/aspectj/weaver/BoundedReferenceType.java
  7. 23
    14
      weaver/src/org/aspectj/weaver/JoinPointSignature.java
  8. 30
    24
      weaver/src/org/aspectj/weaver/Member.java
  9. 104
    56
      weaver/src/org/aspectj/weaver/MemberImpl.java
  10. 150
    74
      weaver/src/org/aspectj/weaver/ReferenceType.java
  11. 59
    26
      weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java
  12. 27
    15
      weaver/src/org/aspectj/weaver/ResolvedMember.java
  13. 300
    159
      weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
  14. 632
    304
      weaver/src/org/aspectj/weaver/ResolvedType.java
  15. 139
    0
      weaver/src/org/aspectj/weaver/StandardAnnotation.java
  16. 9
    6
      weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java
  17. 107
    0
      weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java
  18. 322
    147
      weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
  19. 11
    11
      weaver/src/org/aspectj/weaver/bcel/BcelField.java
  20. 39
    26
      weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
  21. 67
    35
      weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
  22. 1233
    1218
      weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
  23. 553
    261
      weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
  24. 132
    71
      weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
  25. 108
    55
      weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
  26. 36
    21
      weaver/src/org/aspectj/weaver/bcel/Utility.java
  27. 188
    158
      weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java
  28. 195
    123
      weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
  29. 13
    12
      weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java
  30. 172
    90
      weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
  31. 55
    44
      weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java
  32. 244
    192
      weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java

+ 158
- 0
weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java View File

@@ -0,0 +1,158 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

public abstract class AbstractAnnotationAJ implements AnnotationAJ {

protected final ResolvedType type;

private Set supportedTargets = null; // @target meta annotation

public AbstractAnnotationAJ(ResolvedType type) {
this.type = type;
}

/**
* {@inheritDoc}
*/
public final ResolvedType getType() {
return type;
}

/**
* {@inheritDoc}
*/
public final String getTypeSignature() {
return type.getSignature();
}

/**
* {@inheritDoc}
*/
public final String getTypeName() {
return type.getName();
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnAnnotationType() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("ANNOTATION_TYPE");
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnField() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("FIELD");
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnRegularType() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("TYPE");
}

/**
* {@inheritDoc}
*/
public final void ensureAtTargetInitialized() {
if (supportedTargets == null) {
AnnotationAJ atTargetAnnotation = retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET);
if (atTargetAnnotation == null) {
supportedTargets = Collections.EMPTY_SET;
} else {
supportedTargets = atTargetAnnotation.getTargets();
}
}
}

/**
* {@inheritDoc}
*/
public final String getValidTargets() {
StringBuffer sb = new StringBuffer();
sb.append("{");
for (Iterator iter = supportedTargets.iterator(); iter.hasNext();) {
String evalue = (String) iter.next();
sb.append(evalue);
if (iter.hasNext()) {
sb.append(",");
}
}
sb.append("}");
return sb.toString();
}

/**
* {@inheritDoc}
*/
public final boolean specifiesTarget() {
ensureAtTargetInitialized();
return !supportedTargets.isEmpty();
}

/**
* Helper method to retrieve an annotation on an annotation e.g. retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET)
*/
private final AnnotationAJ retrieveAnnotationOnAnnotation(UnresolvedType requiredAnnotationSignature) {
AnnotationAJ[] annos = type.getAnnotations();
for (int i = 0; i < annos.length; i++) {
AnnotationAJ a = annos[i];
if (a.getTypeSignature().equals(requiredAnnotationSignature.getSignature())) {
return annos[i];
}
}
return null;
}

/**
* {@inheritDoc}
*/
public abstract boolean isRuntimeVisible();

/**
* {@inheritDoc}
*/
public abstract Set getTargets();

/**
* {@inheritDoc}
*/
public abstract boolean hasNameValuePair(String name, String value);

/**
* {@inheritDoc}
*/
public abstract boolean hasNamedValue(String name);

/**
* {@inheritDoc}
*/
public abstract String stringify();

}

+ 3
- 3
weaver/src/org/aspectj/weaver/AnnotatedElement.java View File

@@ -14,8 +14,8 @@ package org.aspectj.weaver;
*/
public interface AnnotatedElement {
boolean hasAnnotation(UnresolvedType ofType);
ResolvedType[] getAnnotationTypes();
AnnotationX getAnnotationOfType(UnresolvedType ofType);
AnnotationAJ getAnnotationOfType(UnresolvedType ofType);
}

+ 76
- 104
weaver/src/org/aspectj/weaver/AnnotationAJ.java View File

@@ -1,121 +1,93 @@
/* *******************************************************************
* Copyright (c) 2006 Contributors
* Copyright (c) 2006-2008 Contributors
* 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:
* Andy Clement IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
* This type represents the weavers abstraction of an annotation - it is
* not tied to any underlying BCI toolkit. The weaver actualy handles these
* through AnnotationX wrapper objects - until we start transforming the
* BCEL annotations into this form (expensive) or offer a clever
* visitor mechanism over the BCEL annotation stuff that builds these
* annotation types directly.
*
* Simple representation of an annotation that the weaver can work with.
*
* @author AndyClement
*/
public class AnnotationAJ {

private String type;
private boolean isRuntimeVisible;
private List /*of AnnotationNVPair*/ nvPairs = null;
public AnnotationAJ(String type,boolean isRuntimeVisible) {
this.type = type;
this.isRuntimeVisible = isRuntimeVisible;
}
public String getTypeSignature() {
return type;
}
public List getNameValuePairs() {
return nvPairs;
}
public boolean hasNameValuePairs() {
return nvPairs!=null && nvPairs.size()!=0;
}
public boolean isRuntimeVisible() {
return isRuntimeVisible;
}
public String stringify() {
StringBuffer sb = new StringBuffer();
sb.append("@").append(UnresolvedType.forSignature(type).getClassName());
if (hasNameValuePairs()) {
sb.append("(");
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.stringify());
}
sb.append(")");
}
return sb.toString();
}

public String getStringValueOf(Object name) {
if (!hasNameValuePairs()) return null;
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair nvpair = (AnnotationNameValuePair) iter.next();
if (nvpair.getName().equals(name)) return nvpair.getValue().stringify();
}
return null;
}

public void addNameValuePair(AnnotationNameValuePair pair) {
if (nvPairs==null) nvPairs=new ArrayList();
nvPairs.add(pair);
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("ANNOTATION ["+getTypeSignature()+"] ["+
(isRuntimeVisible?"runtimeVisible":"runtimeInvisible")+"] [");
if (nvPairs!=null) {
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.toString());
if (iter.hasNext()) sb.append(",");
}
}
sb.append("]");
return sb.toString();
}

public boolean hasNamedValue(String n) {
if (nvPairs==null) return false;
for (int i=0;i<nvPairs.size();i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
if (pair.getName().equals(n)) return true;
}
return false;
}
public interface AnnotationAJ {

public static final AnnotationAJ[] EMPTY_ARRAY = new AnnotationAJ[0];

/**
* @return the signature for the annotation type, eg. Lcom/foo/MyAnno;
*/
public String getTypeSignature();

/**
* @return the type name for the annotation, eg. com.foo.MyAnno
*/
public String getTypeName();

/**
* @return the type of the annotation
*/
public ResolvedType getType();

/**
* return true if this annotation can target an annotation type
*/
public boolean allowedOnAnnotationType();

/**
* @return true if this annotation can be put on a field
*/
public boolean allowedOnField();

/**
* @return true if this annotation can target a 'regular' type. A 'regular' type is enum/class/interface - it is *not*
* annotation.
*/
public boolean allowedOnRegularType();

/**
* Return true if the annotation has a value with the specified name (n) and value (v)
*/
public boolean hasNameValuePair(String n, String v) {
if (nvPairs==null) return false;
for (int i=0;i<nvPairs.size();i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
if (pair.getName().equals(n)) {
if (pair.getValue().stringify().equals(v)) return true;
}
}
return false;
}
* @return for the @target annotation, this will return a set of the element-types it can be applied to. For other annotations ,
* it returns the empty set.
*/
public Set getTargets();

/**
* @param name the name of the value
* @return true if there is a value with that name
*/
public boolean hasNamedValue(String name);

/**
* @param name the name of the annotation field
* @param value the value of the annotation field
* @return true if there is a value with the specified name and value
*/
public boolean hasNameValuePair(String name, String value);

/**
* @return String representation of the valid targets for this annotation, eg. "{TYPE,FIELD}"
*/
public String getValidTargets();

/**
* @return String form of the annotation and any values, eg. @Foo(a=b,c=d)
*/
public String stringify();

/**
* @return true if this annotation is marked with @target
*/
public boolean specifiesTarget();

/**
* @return true if the annotation is marked for runtime visibility
*/
public boolean isRuntimeVisible();

}

+ 24
- 22
weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java View File

@@ -10,7 +10,6 @@
* Andy Clement initial implementation
* ******************************************************************/


package org.aspectj.weaver;

import java.io.DataOutputStream;
@@ -20,10 +19,10 @@ import java.io.IOException;
* Represents adding an annotation to a type
*/
public class AnnotationOnTypeMunger extends ResolvedTypeMunger {
AnnotationX newAnnotation;
public AnnotationOnTypeMunger(AnnotationX anno) {
super(AnnotationOnType,null);
AnnotationAJ newAnnotation;
public AnnotationOnTypeMunger(AnnotationAJ anno) {
super(AnnotationOnType, null);
newAnnotation = anno;
}

@@ -31,25 +30,28 @@ public class AnnotationOnTypeMunger extends ResolvedTypeMunger {
throw new RuntimeException("unimplemented");
}


public AnnotationX getNewAnnotation() {
public AnnotationAJ getNewAnnotation() {
return newAnnotation;
}

public boolean equals(Object other) {
if (!(other instanceof AnnotationOnTypeMunger)) return false;
AnnotationOnTypeMunger o = (AnnotationOnTypeMunger)other;
return newAnnotation.getSignature().equals(o.newAnnotation.getSignature());
}

private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + newAnnotation.getSignature().hashCode();
hashCode = result;
public boolean equals(Object other) {
if (!(other instanceof AnnotationOnTypeMunger))
return false;
AnnotationOnTypeMunger o = (AnnotationOnTypeMunger) other;
// TODO does not check equality of annotation values
return newAnnotation.getTypeSignature().equals(
o.newAnnotation.getTypeSignature());
}

private volatile int hashCode = 0;

public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37 * result + newAnnotation.getTypeSignature().hashCode();
hashCode = result;
}
return hashCode;
}
return hashCode;
}
}

+ 0
- 224
weaver/src/org/aspectj/weaver/AnnotationX.java View File

@@ -1,224 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005 IBM
* 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:
* Andy Clement initial API and implementation
*******************************************************************************/
package org.aspectj.weaver;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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 eclipse. We have this holder so that types about the bcel
* weaver package can work with something not bytecode toolkit specific.
*/
public class AnnotationX {

public static final AnnotationX[] NONE = new AnnotationX[0];

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;

private ResolvedType signature = null;

// @target meta-annotation related stuff, built lazily
private boolean lookedForAtTargetAnnotation = false;
private AnnotationX atTargetAnnotation = null;
private Set supportedTargets = null;

public AnnotationX(AnnotationGen a, World world) {
theRealBcelAnnotation = a;
signature = UnresolvedType.forSignature(theRealBcelAnnotation.getTypeSignature()).resolve(world);
mode = MODE_BCEL;
}

public AnnotationX(AnnotationAJ a, World world) {
theRealEclipseAnnotation = a;
signature = UnresolvedType.forSignature(theRealEclipseAnnotation.getTypeSignature()).resolve(world);
mode = MODE_ECLIPSE;
}

public AnnotationGen getBcelAnnotation() {
return theRealBcelAnnotation;
}

public UnresolvedType getSignature() {
return signature;
}

public String toString() {
if (mode == MODE_BCEL)
return theRealBcelAnnotation.toString();
else
return theRealEclipseAnnotation.toString();
}

public String getTypeName() {
if (mode == MODE_BCEL)
return theRealBcelAnnotation.getTypeName();
else
return Utility.signatureToString(theRealEclipseAnnotation.getTypeSignature());
}

public String getTypeSignature() {
if (mode == MODE_BCEL)
return theRealBcelAnnotation.getTypeSignature();
else
return theRealEclipseAnnotation.getTypeSignature();
}

// @target related helpers
/**
* return true if this annotation can target an annotation type
*/
public boolean allowedOnAnnotationType() {
ensureAtTargetInitialized();
if (atTargetAnnotation == null)
return true; // if no target specified, then return true
return supportedTargets.contains("ANNOTATION_TYPE");
}

/**
* return true if this annotation is marked with @target()
*/
public boolean specifiesTarget() {
ensureAtTargetInitialized();
return atTargetAnnotation != null;
}

/**
* return true if this annotation can target a 'regular' type. A 'regular' type is enum/class/interface - it is *not*
* annotation.
*/
public boolean allowedOnRegularType() {
ensureAtTargetInitialized();
if (atTargetAnnotation == null)
return true; // if no target specified, then return true
return supportedTargets.contains("TYPE");
}

/**
* Use in messages about this annotation
*/
public String stringify() {
return signature.getName();
}

public String getValidTargets() {
StringBuffer sb = new StringBuffer();
sb.append("{");
for (Iterator iter = supportedTargets.iterator(); iter.hasNext();) {
String evalue = (String) iter.next();
sb.append(evalue);
if (iter.hasNext())
sb.append(",");
}
sb.append("}");
return sb.toString();
}

// privates

/**
* Helper method to retrieve an annotation on an annotation e.g. retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET)
*/
private AnnotationX retrieveAnnotationOnAnnotation(UnresolvedType requiredAnnotationSignature) {
AnnotationX[] annos = signature.getAnnotations();
for (int i = 0; i < annos.length; i++) {
AnnotationX annotationX = annos[i];
if (annotationX.getSignature().equals(requiredAnnotationSignature))
return annos[i];
}
return null;
}

/**
* Makes sure we have looked for the @target() annotation on this annotation. Calling this method initializes (and caches) the
* information for later use.
*/
private void ensureAtTargetInitialized() {
if (!lookedForAtTargetAnnotation) {
lookedForAtTargetAnnotation = true;
atTargetAnnotation = retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET);
if (atTargetAnnotation != null) {
supportedTargets = atTargetAnnotation.getTargets();
}
}
}

/**
* For the @Target annotation, this will return a set of the elementtypes it can be applied to. For non @Target annotations, it
* returns null.
*/
public Set /* of String */getTargets() {
if (!signature.equals(UnresolvedType.AT_TARGET))
return null;
Set supportedTargets = new HashSet();
if (mode == MODE_BCEL) {
List values = getBcelAnnotation().getValues();
ElementNameValuePairGen envp = (ElementNameValuePairGen) values.get(0);
ArrayElementValueGen aev = (ArrayElementValueGen) envp.getValue();
ElementValueGen[] evs = aev.getElementValuesArray();
for (int i = 0; i < evs.length; i++) {
EnumElementValueGen ev = (EnumElementValueGen) evs[i];
supportedTargets.add(ev.getEnumValueString());
}
} else {
List values = theRealEclipseAnnotation.getNameValuePairs();
AnnotationNameValuePair nvp = (AnnotationNameValuePair) values.get(0);
ArrayAnnotationValue aav = (ArrayAnnotationValue) nvp.getValue();
AnnotationValue[] avs = aav.getValues();
for (int i = 0; i < avs.length; i++) {
AnnotationValue value = avs[i];
supportedTargets.add(value.stringify());
}
}
return supportedTargets;
}

/**
* @return true if this annotation can be put on a field
*/
public boolean allowedOnField() {
ensureAtTargetInitialized();
if (atTargetAnnotation == null)
return true; // if no target specified, then return true
return supportedTargets.contains("FIELD");
}

public boolean isRuntimeVisible() {
return theRealBcelAnnotation.isRuntimeVisible();
}

public boolean hasNameValuePair(String n, String v) {
if (mode == MODE_BCEL)
return theRealBcelAnnotation.hasNameValuePair(n, v);
else
return theRealEclipseAnnotation.hasNameValuePair(n, v);
}

public boolean hasNamedValue(String n) {
if (mode == MODE_BCEL)
return theRealBcelAnnotation.hasNamedValue(n);
else
return theRealEclipseAnnotation.hasNamedValue(n);
}

}

+ 106
- 76
weaver/src/org/aspectj/weaver/BoundedReferenceType.java View File

@@ -18,8 +18,8 @@ import java.util.Map;
import org.aspectj.weaver.patterns.PerClause;

/**
* A BoundedReferenceType is the result of a generics wildcard expression
* ? extends String, ? super Foo etc..
* A BoundedReferenceType is the result of a generics wildcard expression ?
* extends String, ? super Foo etc..
*
* The "signature" for a bounded reference type follows the generic signature
* specification in section 4.4 of JVM spec: *,+,- plus signature strings.
@@ -28,110 +28,134 @@ import org.aspectj.weaver.patterns.PerClause;
*/
public class BoundedReferenceType extends ReferenceType {

private ResolvedType lowerBound;
private ResolvedType lowerBound;

private ResolvedType upperBound;
private ResolvedType upperBound;

protected ReferenceType[] additionalInterfaceBounds = new ReferenceType[0];
protected ReferenceType[] additionalInterfaceBounds = new ReferenceType[0];

protected boolean isExtends = true;
protected boolean isExtends = true;

protected boolean isSuper = false;
protected boolean isSuper = false;

public UnresolvedType getUpperBound() {
return upperBound;
}
public UnresolvedType getUpperBound() {
return upperBound;
}

public UnresolvedType getLowerBound() {
return lowerBound;
}

public UnresolvedType getLowerBound() {
return lowerBound;
}
public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world) {
super((isExtends ? "+" : "-") + aBound.signature,aBound.signatureErasure,world);
this.isExtends = isExtends;
this.isSuper = !isExtends;
if (isExtends) {
public BoundedReferenceType(ReferenceType aBound, boolean isExtends,
World world) {
super((isExtends ? "+" : "-") + aBound.signature,
aBound.signatureErasure, world);
this.isExtends = isExtends;
this.isSuper = !isExtends;
if (isExtends) {
upperBound = aBound;
} else {
lowerBound = aBound;
upperBound = world.resolve(UnresolvedType.OBJECT);
upperBound = world.resolve(UnresolvedType.OBJECT);
}
setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound()));
setDelegate(new ReferenceTypeReferenceTypeDelegate(
(ReferenceType) getUpperBound()));
}
public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world, ReferenceType[] additionalInterfaces) {
this(aBound,isExtends,world);

public BoundedReferenceType(ReferenceType aBound, boolean isExtends,
World world, ReferenceType[] additionalInterfaces) {
this(aBound, isExtends, world);
this.additionalInterfaceBounds = additionalInterfaces;
}
public ReferenceType[] getAdditionalBounds() {
return additionalInterfaceBounds;
}
public UnresolvedType parameterize(Map typeBindings) {
ReferenceType[] parameterizedAdditionalInterfaces = new ReferenceType[additionalInterfaceBounds==null?0:additionalInterfaceBounds.length];
for (int i=0; i<parameterizedAdditionalInterfaces.length;i++) {
parameterizedAdditionalInterfaces[i] = (ReferenceType)additionalInterfaceBounds[i].parameterize(typeBindings);
ReferenceType[] parameterizedAdditionalInterfaces = new ReferenceType[additionalInterfaceBounds == null ? 0
: additionalInterfaceBounds.length];
for (int i = 0; i < parameterizedAdditionalInterfaces.length; i++) {
parameterizedAdditionalInterfaces[i] = (ReferenceType) additionalInterfaceBounds[i]
.parameterize(typeBindings);
}
if (isExtends) {
return new BoundedReferenceType((ReferenceType)getUpperBound().parameterize(typeBindings),isExtends,world,parameterizedAdditionalInterfaces);
return new BoundedReferenceType((ReferenceType) getUpperBound()
.parameterize(typeBindings), isExtends, world,
parameterizedAdditionalInterfaces);
} else {
return new BoundedReferenceType((ReferenceType)getLowerBound().parameterize(typeBindings),isExtends,world,parameterizedAdditionalInterfaces);
return new BoundedReferenceType((ReferenceType) getLowerBound()
.parameterize(typeBindings), isExtends, world,
parameterizedAdditionalInterfaces);
}
}
/**
* only for use when resolving GenericsWildcardTypeX or a TypeVariableReferenceType
* only for use when resolving GenericsWildcardTypeX or a
* TypeVariableReferenceType
*/
protected BoundedReferenceType(String sig, String sigErasure, World world) {
super(sig, sigErasure, world);
upperBound = world.resolve(UnresolvedType.OBJECT);
setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound()));
setDelegate(new ReferenceTypeReferenceTypeDelegate(
(ReferenceType) getUpperBound()));
}
public ReferenceType[] getInterfaceBounds() {
return additionalInterfaceBounds;
public ReferenceType[] getInterfaceBounds() {
return additionalInterfaceBounds;
}
public boolean hasLowerBound() {
return getLowerBound() != null;
}
public boolean isExtends() { return (isExtends && !getUpperBound().getSignature().equals("Ljava/lang/Object;")); }
public boolean isSuper() { return isSuper; }

public boolean isExtends() {
return (isExtends && !getUpperBound().getSignature().equals(
"Ljava/lang/Object;"));
}

public boolean isSuper() {
return isSuper;
}

public boolean alwaysMatches(ResolvedType aCandidateType) {
if (isExtends()) {
// aCandidateType must be a subtype of upperBound
return ((ReferenceType)getUpperBound()).isAssignableFrom(aCandidateType);
return ((ReferenceType) getUpperBound())
.isAssignableFrom(aCandidateType);
} else if (isSuper()) {
// aCandidateType must be a supertype of lowerBound
return aCandidateType.isAssignableFrom((ReferenceType)getLowerBound());
return aCandidateType
.isAssignableFrom((ReferenceType) getLowerBound());
} else {
return true; // straight '?'
}
}
// this "maybe matches" that
public boolean canBeCoercedTo(ResolvedType aCandidateType) {
if (alwaysMatches(aCandidateType)) return true;
if (alwaysMatches(aCandidateType))
return true;
if (aCandidateType.isGenericWildcard()) {
BoundedReferenceType boundedRT = (BoundedReferenceType) aCandidateType;
BoundedReferenceType boundedRT = (BoundedReferenceType) aCandidateType;
ResolvedType myUpperBound = (ResolvedType) getUpperBound();
ResolvedType myLowerBound = (ResolvedType) getLowerBound();
if (isExtends()) {
if (boundedRT.isExtends()) {
return myUpperBound.isAssignableFrom((ResolvedType) boundedRT.getUpperBound());
} else if (boundedRT.isSuper()) {
return myUpperBound == boundedRT.getLowerBound();
return myUpperBound
.isAssignableFrom((ResolvedType) boundedRT
.getUpperBound());
} else if (boundedRT.isSuper()) {
return myUpperBound == boundedRT.getLowerBound();
} else {
return true; // it's '?'
return true; // it's '?'
}
} else if (isSuper()) {
if (boundedRT.isSuper()) {
return ((ResolvedType) boundedRT.getLowerBound()).isAssignableFrom(myLowerBound);
} else if (boundedRT.isExtends()) {
return myLowerBound == boundedRT.getUpperBound();
return ((ResolvedType) boundedRT.getLowerBound())
.isAssignableFrom(myLowerBound);
} else if (boundedRT.isExtends()) {
return myLowerBound == boundedRT.getUpperBound();
} else {
return true;
}
@@ -142,42 +166,48 @@ public class BoundedReferenceType extends ReferenceType {
return false;
}
}
public String getSimpleName() {
if (!isExtends() && !isSuper()) return "?";
if (!isExtends() && !isSuper())
return "?";
if (isExtends()) {
return ("? extends " + getUpperBound().getSimpleName());
} else {
return ("? super " + getLowerBound().getSimpleName());
}
}
// override to include additional interface bounds...
public ResolvedType[] getDeclaredInterfaces() {
ResolvedType[] interfaces = super.getDeclaredInterfaces();
if (additionalInterfaceBounds.length > 0) {
ResolvedType[] allInterfaces =
new ResolvedType[interfaces.length + additionalInterfaceBounds.length];
System.arraycopy(interfaces, 0, allInterfaces, 0, interfaces.length);
System.arraycopy(additionalInterfaceBounds,0,allInterfaces,interfaces.length,additionalInterfaceBounds.length);
ResolvedType[] allInterfaces = new ResolvedType[interfaces.length
+ additionalInterfaceBounds.length];
System
.arraycopy(interfaces, 0, allInterfaces, 0,
interfaces.length);
System.arraycopy(additionalInterfaceBounds, 0, allInterfaces,
interfaces.length, additionalInterfaceBounds.length);
return allInterfaces;
} else {
return interfaces;
}
}
public boolean isGenericWildcard() {
return true;
}
protected static class ReferenceTypeReferenceTypeDelegate extends AbstractReferenceTypeDelegate {

protected static class ReferenceTypeReferenceTypeDelegate extends
AbstractReferenceTypeDelegate {

public ReferenceTypeReferenceTypeDelegate(ReferenceType backing) {
super(backing,false);
super(backing, false);
}
public void addAnnotation(AnnotationX annotationX) {
throw new UnsupportedOperationException("What on earth do you think you are doing???");

public void addAnnotation(AnnotationAJ annotationX) {
throw new UnsupportedOperationException(
"What on earth do you think you are doing???");
}

public boolean isAspect() {
@@ -203,19 +233,19 @@ public class BoundedReferenceType extends ReferenceType {
public boolean isAnnotationWithRuntimeRetention() {
return resolvedTypeX.isAnnotationWithRuntimeRetention();
}
public boolean isAnonymous() {
return resolvedTypeX.isAnonymous();
}
public boolean isNested() {
return resolvedTypeX.isNested();
}
public ResolvedType getOuterClass() {
return resolvedTypeX.getOuterClass();
}
public String getRetentionPolicy() {
return resolvedTypeX.getRetentionPolicy();
}
@@ -223,11 +253,11 @@ public class BoundedReferenceType extends ReferenceType {
public boolean canAnnotationTargetType() {
return resolvedTypeX.canAnnotationTargetType();
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return resolvedTypeX.getAnnotationTargetKinds();
}
public boolean isGeneric() {
return resolvedTypeX.isGenericType();
}
@@ -235,12 +265,12 @@ public class BoundedReferenceType extends ReferenceType {
public String getDeclaredGenericSignature() {
return resolvedTypeX.getDeclaredGenericSignature();
}
public boolean hasAnnotation(UnresolvedType ofType) {
return resolvedTypeX.hasAnnotation(ofType);
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
return resolvedTypeX.getAnnotations();
}


+ 23
- 14
weaver/src/org/aspectj/weaver/JoinPointSignature.java View File

@@ -22,10 +22,12 @@ import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;

/**
* @author colyer Instances of this class are created by ResolvedMember.getSignatures() when collating all of the signatures for a
* member. We need to create entries in the set for the "gaps" in the hierarchy. For example:
* @author colyer Instances of this class are created by
* ResolvedMember.getSignatures() when collating all of the signatures
* for a member. We need to create entries in the set for the "gaps" in
* the hierarchy. For example:
*
* class A { void foo(); }
* class A { void foo(); }
*
* class B extends A {}
*
@@ -33,7 +35,8 @@ import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
*
* has signatures:
*
* B.foo() AND A.foo() B.foo() will be created as a ResolvedMemberWithSubstituteDeclaringType
* B.foo() AND A.foo() B.foo() will be created as a
* ResolvedMemberWithSubstituteDeclaringType
*
* Oh for a JDK 1.4 dynamic proxy.... we have to run on 1.3 :(
*/
@@ -87,7 +90,7 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.getAnnotationTypes();
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
return realMember.getAnnotationOfType(ofType);
}

@@ -95,7 +98,7 @@ public class JoinPointSignature implements ResolvedMember {
realMember.setAnnotationTypes(annotationtypes);
}

public void addAnnotation(AnnotationX annotation) {
public void addAnnotation(AnnotationAJ annotation) {
realMember.addAnnotation(annotation);
}

@@ -203,14 +206,18 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.getGenericParameterTypes();
}

public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized) {
return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized);
return realMember.parameterizedWith(typeParameters, newDeclaringType,
isParameterized);
}

public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized, List aliases) {
return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized, aliases);
return realMember.parameterizedWith(typeParameters, newDeclaringType,
isParameterized, aliases);
}

public void setTypeVariables(TypeVariable[] types) {
@@ -257,7 +264,7 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.getParameterTypes();
}

public AnnotationX[][] getParameterAnnotations() {
public AnnotationAJ[][] getParameterAnnotations() {
return realMember.getParameterAnnotations();
}

@@ -297,12 +304,13 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.canBeParameterized();
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
return realMember.getAnnotations();
}

public Collection getDeclaringTypes(World world) {
throw new UnsupportedOperationException("Adrian doesn't think you should be calling this...");
throw new UnsupportedOperationException(
"Adrian doesn't think you should be calling this...");
}

public Iterator getJoinPointSignatures(World world) {
@@ -367,7 +375,8 @@ public class JoinPointSignature implements ResolvedMember {
}

public int hashCode() {
return 17 + (37 * realMember.hashCode()) + (37 * substituteDeclaringType.hashCode());
return 17 + (37 * realMember.hashCode())
+ (37 * substituteDeclaringType.hashCode());
}

public boolean hasBackingGenericMember() {

+ 30
- 24
weaver/src/org/aspectj/weaver/Member.java View File

@@ -24,29 +24,33 @@ public interface Member extends Comparable {
public static final Member[] NONE = new Member[0];
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 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 MemberKind MONITORENTER = new MemberKind(
"MONITORENTER", 8);
public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT",
9);

public static final AnnotationAJ[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationAJ[][] {};
public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][] {};

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 int compareTo(Object other);

public UnresolvedType getDeclaringType();

public UnresolvedType getReturnType();
public UnresolvedType getGenericReturnType();
public UnresolvedType[] getGenericParameterTypes();

public UnresolvedType getType();
@@ -56,28 +60,30 @@ public interface Member extends Comparable {
public UnresolvedType[] getParameterTypes();

/**
* Return full signature, including return type, e.g. "()LFastCar;". For a signature without the return type,
* use getParameterSignature() - it is important to choose the right one in the face of covariance.
* Return full signature, including return type, e.g. "()LFastCar;". For a
* signature without the return type, use getParameterSignature() - it is
* important to choose the right one in the face of covariance.
*/
public String getSignature();
public Iterator getJoinPointSignatures(World world);
public Iterator getJoinPointSignatures(World world);

public int getArity();

/**
* Return signature without return type, e.g. "()" for a signature *with* the return type,
* use getSignature() - it is important to choose the right one in the face of covariance.
* Return signature without return type, e.g. "()" for a signature *with*
* the return type, use getSignature() - it is important to choose the right
* one in the face of covariance.
*/
public String getParameterSignature();

public int getModifiers(World world);
public int getModifiers();

public boolean isStatic();
public boolean isStatic();

public boolean isInterface();
public boolean isInterface();

public boolean isPrivate();

@@ -86,11 +92,11 @@ public interface Member extends Comparable {
*/
public boolean canBeParameterized();

public AnnotationX[] getAnnotations();
public Collection/* ResolvedType */getDeclaringTypes(World world);
public AnnotationAJ[] getAnnotations();
public Collection/* ResolvedType */getDeclaringTypes(World world);

public String[] getParameterNames(World world);

public UnresolvedType[] getExceptions(World world);
public UnresolvedType[] getExceptions(World world);
}

+ 104
- 56
weaver/src/org/aspectj/weaver/MemberImpl.java View File

@@ -35,11 +35,13 @@ public class MemberImpl implements Member {
private boolean reportedUnresolvableMember = false;

/**
* All the signatures that a join point with this member as its signature has.
* All the signatures that a join point with this member as its signature
* has.
*/
private JoinPointSignatureIterator joinPointSignatures = null;

public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature) {
public MemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, String name, String signature) {
this.kind = kind;
this.declaringType = declaringType;
this.modifiers = modifiers;
@@ -58,7 +60,8 @@ public class MemberImpl implements Member {
}
}

public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
public MemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes) {
this.kind = kind;
this.declaringType = declaringType;
@@ -80,9 +83,10 @@ public class MemberImpl implements Member {
// ---- utility methods

/**
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, argument types parsed from the JVM
* bytecode signature of a method. Yes, this should actually return a nice statically-typed pair object, but we don't have one
* of those.
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing
* return type, argument types parsed from the JVM bytecode signature of a
* method. Yes, this should actually return a nice statically-typed pair
* object, but we don't have one of those.
*
* <blockquote>
*
@@ -94,11 +98,15 @@ public class MemberImpl implements Member {
*
* </blockquote>
*
* @param signature the JVM bytecode method signature string we want to break apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types.
* @param signature
* the JVM bytecode method signature string we want to break
* apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the
* return types and parameter types.
*/
// OPTIMIZE move static util methods out into a memberutils class
public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) {
public static String typesToSignature(UnresolvedType returnType,
UnresolvedType[] paramTypes, boolean useRawTypes) {
StringBuffer buf = new StringBuffer();
buf.append("(");
for (int i = 0, len = paramTypes.length; i < len; i++) {
@@ -120,8 +128,9 @@ public class MemberImpl implements Member {
}

/**
* Returns "(<signaturesOfParamTypes>,...)" - unlike the other typesToSignature that also includes the return type, this one
* just deals with the parameter types.
* Returns "(<signaturesOfParamTypes>,...)" - unlike the other
* typesToSignature that also includes the return type, this one just deals
* with the parameter types.
*/
public static String typesToSignature(UnresolvedType[] paramTypes) {
StringBuffer buf = new StringBuffer();
@@ -134,9 +143,10 @@ public class MemberImpl implements Member {
}

/**
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, argument types parsed from the JVM
* bytecode signature of a method. Yes, this should actually return a nice statically-typed pair object, but we don't have one
* of those.
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing
* return type, argument types parsed from the JVM bytecode signature of a
* method. Yes, this should actually return a nice statically-typed pair
* object, but we don't have one of those.
*
* <blockquote>
*
@@ -148,10 +158,14 @@ public class MemberImpl implements Member {
*
* </blockquote>
*
* @param signature the JVM bytecode method signature string we want to break apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types.
* @param signature
* the JVM bytecode method signature string we want to break
* apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the
* return types and parameter types.
*/
private static Object[] signatureToTypes(String sig, boolean keepParameterizationInfo) {
private static Object[] signatureToTypes(String sig,
boolean keepParameterizationInfo) {
boolean hasParameters = sig.charAt(1) != ')';
if (hasParameters) {
List l = new ArrayList();
@@ -166,10 +180,13 @@ public class MemberImpl implements Member {
c = sig.charAt(++i);
if (c == 'L' || c == 'P') {
int nextSemicolon = sig.indexOf(';', start);
int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start) : -1);
if (!hasAnyAnglies || firstAngly == -1 || firstAngly > nextSemicolon) {
int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start)
: -1);
if (!hasAnyAnglies || firstAngly == -1
|| firstAngly > nextSemicolon) {
i = nextSemicolon + 1;
l.add(UnresolvedType.forSignature(sig.substring(start, i)));
l.add(UnresolvedType.forSignature(sig.substring(start,
i)));
} else {
// generics generics generics
// Have to skip to the *correct* ';'
@@ -194,9 +211,11 @@ public class MemberImpl implements Member {
}
// posn now points to the correct nextSemicolon :)
i = posn;
l.add(UnresolvedType.forSignature(sig.substring(start, i)));
l.add(UnresolvedType.forSignature(sig.substring(start,
i)));
}
} else if (c == 'T') { // assumed 'reference' to a type variable, so just "Tname;"
} else if (c == 'T') { // assumed 'reference' to a type
// variable, so just "Tname;"
int nextSemicolon = sig.indexOf(';', start);
String nextbit = sig.substring(start, nextSemicolon);
l.add(UnresolvedType.forSignature(nextbit));
@@ -206,74 +225,97 @@ public class MemberImpl implements Member {
l.add(UnresolvedType.forSignature(sig.substring(start, i)));
}
}
UnresolvedType[] paramTypes = (UnresolvedType[]) l.toArray(new UnresolvedType[l.size()]);
UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i + 1, sig.length()));
UnresolvedType[] paramTypes = (UnresolvedType[]) l
.toArray(new UnresolvedType[l.size()]);
UnresolvedType returnType = UnresolvedType.forSignature(sig
.substring(i + 1, sig.length()));
return new Object[] { returnType, paramTypes };
} else {
UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(2));
UnresolvedType returnType = UnresolvedType.forSignature(sig
.substring(2));
return new Object[] { returnType, UnresolvedType.NONE };
}
}

// ---- factory methods
public static MemberImpl field(String declaring, int mods, String name, String signature) {
return field(declaring, mods, UnresolvedType.forSignature(signature), name);
public static MemberImpl field(String declaring, int mods, String name,
String signature) {
return field(declaring, mods, UnresolvedType.forSignature(signature),
name);
}

// public static Member field(UnresolvedType declaring, int mods, String name, UnresolvedType type) {
// return new MemberImpl(FIELD, declaring, mods, type, name, UnresolvedType.NONE);
// public static Member field(UnresolvedType declaring, int mods, String
// name, UnresolvedType type) {
// return new MemberImpl(FIELD, declaring, mods, type, name,
// UnresolvedType.NONE);
// }
// OPTIMIZE do we need to call this? unless necessary the signatureToTypes() call smacks of laziness on the behalf of the caller
// OPTIMIZE do we need to call this? unless necessary the signatureToTypes()
// call smacks of laziness on the behalf of the caller
// of this method
public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) {
public static MemberImpl method(UnresolvedType declaring, int mods,
String name, String signature) {
Object[] pair = signatureToTypes(signature, false);
return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
return method(declaring, mods, (UnresolvedType) pair[0], name,
(UnresolvedType[]) pair[1]);
}

public static MemberImpl monitorEnter() {
return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT, Modifier.STATIC, ResolvedType.VOID, "<lock>",
return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT,
Modifier.STATIC, ResolvedType.VOID, "<lock>",
UnresolvedType.ARRAY_WITH_JUST_OBJECT);
}

public static MemberImpl monitorExit() {
return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT, Modifier.STATIC, ResolvedType.VOID, "<unlock>",
return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT,
Modifier.STATIC, ResolvedType.VOID, "<unlock>",
UnresolvedType.ARRAY_WITH_JUST_OBJECT);
}

public static Member pointcut(UnresolvedType declaring, String name, String signature) {
public static Member pointcut(UnresolvedType declaring, String name,
String signature) {
Object[] pair = signatureToTypes(signature, false);
return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
return pointcut(declaring, 0, (UnresolvedType) pair[0], name,
(UnresolvedType[]) pair[1]);
}

private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) {
return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, ty, name, UnresolvedType.NONE);
private static MemberImpl field(String declaring, int mods,
UnresolvedType ty, String name) {
return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods,
ty, name, UnresolvedType.NONE);
}

public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
public static MemberImpl method(UnresolvedType declTy, int mods,
UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
return new MemberImpl(
// ??? this calls <clinit> a method
name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys);
// ??? this calls <clinit> a method
name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods,
rTy, name, paramTys);
}

private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
private static Member pointcut(UnresolvedType declTy, int mods,
UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
return new MemberImpl(POINTCUT, declTy, mods, rTy, name, paramTys);
}

public static ResolvedMemberImpl makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) {
return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC, "<catch>", "(" + catchType.getSignature() + ")V");
public static ResolvedMemberImpl makeExceptionHandlerSignature(
UnresolvedType inType, UnresolvedType catchType) {
return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC,
"<catch>", "(" + catchType.getSignature() + ")V");
}

public boolean equals(Object other) {
if (!(other instanceof Member))
return false;
Member o = (Member) other;
return (getKind() == o.getKind() && getName().equals(o.getName()) && getSignature().equals(o.getSignature()) && getDeclaringType()
return (getKind() == o.getKind() && getName().equals(o.getName())
&& getSignature().equals(o.getSignature()) && getDeclaringType()
.equals(o.getDeclaringType()));
}

/**
* Equality is checked based on the underlying signature, so the hash code of a member is based on its kind, name, signature,
* and declaring type. The algorithm for this was taken from page 38 of effective java.
* Equality is checked based on the underlying signature, so the hash code
* of a member is based on its kind, name, signature, and declaring type.
* The algorithm for this was taken from page 38 of effective java.
*/
private volatile int hashCode = 0;

@@ -372,7 +414,8 @@ public class MemberImpl implements Member {
return paramSignature;
}

// OPTIMIZE see next line. Why the hell are they in here if we only know it once resolution has occurred...
// OPTIMIZE see next line. Why the hell are they in here if we only know it
// once resolution has occurred...
// ---- things we know only with resolution

public int getModifiers(World world) {
@@ -413,9 +456,10 @@ public class MemberImpl implements Member {
return modifiers;
}

public AnnotationX[] getAnnotations() {
throw new UnsupportedOperationException("You should resolve this member '" + this
+ "' and call getAnnotations() on the result...");
public AnnotationAJ[] getAnnotations() {
throw new UnsupportedOperationException(
"You should resolve this member '" + this
+ "' and call getAnnotations() on the result...");
}

// ---- fields 'n' stuff
@@ -424,7 +468,8 @@ public class MemberImpl implements Member {
ResolvedType myType = getDeclaringType().resolve(world);
Collection ret = new HashSet();
if (kind == CONSTRUCTOR) {
// this is wrong if the member doesn't exist, but that doesn't matter
// this is wrong if the member doesn't exist, but that doesn't
// matter
ret.add(myType);
} else if (isStatic() || kind == FIELD) {
walkUpStatic(ret, myType);
@@ -484,7 +529,8 @@ public class MemberImpl implements Member {
}

/**
* All the signatures that a join point with this member as its signature has.
* All the signatures that a join point with this member as its signature
* has.
*/
public Iterator getJoinPointSignatures(World inAWorld) {
if (joinPointSignatures == null) {
@@ -495,15 +541,17 @@ public class MemberImpl implements Member {
}

/**
* Raises an [Xlint:cantFindType] message if the declaring type cannot be found or an [Xlint:unresolvableMember] message if the
* type can be found (bug 149908)
* Raises an [Xlint:cantFindType] message if the declaring type cannot be
* found or an [Xlint:unresolvableMember] message if the type can be found
* (bug 149908)
*/
private void reportDidntFindMember(World world) {
if (reportedCantFindDeclaringType || reportedUnresolvableMember)
return;
ResolvedType rType = getDeclaringType().resolve(world);
if (rType.isMissing()) {
world.getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, rType.getName()), null);
world.getLint().cantFindType.signal(WeaverMessages.format(
WeaverMessages.CANT_FIND_TYPE, rType.getName()), null);
reportedCantFindDeclaringType = true;
} else {
world.getLint().unresolvableMember.signal(getName(), null);

+ 150
- 74
weaver/src/org/aspectj/weaver/ReferenceType.java View File

@@ -24,21 +24,27 @@ import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.PerClause;

/**
* A reference type represents some 'real' type, not a primitive, not an array - but a real type, for example java.util.List. Each
* ReferenceType has a delegate that is the underlying artifact - either an eclipse artifact or a bcel artifact. If the type
* represents a raw type (i.e. there is a generic form) then the genericType field is set to point to the generic type. If it is for
* a parameterized type then the generic type is also set to point to the generic form.
* A reference type represents some 'real' type, not a primitive, not an array -
* but a real type, for example java.util.List. Each ReferenceType has a
* delegate that is the underlying artifact - either an eclipse artifact or a
* bcel artifact. If the type represents a raw type (i.e. there is a generic
* form) then the genericType field is set to point to the generic type. If it
* is for a parameterized type then the generic type is also set to point to the
* generic form.
*/
public class ReferenceType extends ResolvedType {

/**
* For generic types, this list holds references to all the derived raw and parameterized versions. We need this so that if the
* generic delegate is swapped during incremental compilation, the delegate of the derivatives is swapped also.
* For generic types, this list holds references to all the derived raw and
* parameterized versions. We need this so that if the generic delegate is
* swapped during incremental compilation, the delegate of the derivatives
* is swapped also.
*/
private List/* ReferenceType */derivativeTypes = new ArrayList();

/**
* For parameterized types (or the raw type) - this field points to the actual reference type from which they are derived.
* For parameterized types (or the raw type) - this field points to the
* actual reference type from which they are derived.
*/
ReferenceType genericType = null;

@@ -72,8 +78,10 @@ public class ReferenceType extends ResolvedType {
/**
* Constructor used when creating a parameterized type.
*/
public ReferenceType(ResolvedType theGenericType, ResolvedType[] theParameters, World aWorld) {
super(makeParameterizedSignature(theGenericType, theParameters), theGenericType.signatureErasure, aWorld);
public ReferenceType(ResolvedType theGenericType,
ResolvedType[] theParameters, World aWorld) {
super(makeParameterizedSignature(theGenericType, theParameters),
theGenericType.signatureErasure, aWorld);
ReferenceType genericReferenceType = (ReferenceType) theGenericType;
this.typeParameters = theParameters;
this.genericType = genericReferenceType;
@@ -129,11 +137,11 @@ public class ReferenceType extends ResolvedType {
return (sig == null) ? "" : sig;
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
return delegate.getAnnotations();
}

public void addAnnotation(AnnotationX annotationX) {
public void addAnnotation(AnnotationAJ annotationX) {
delegate.addAnnotation(annotationX);
}

@@ -145,12 +153,13 @@ public class ReferenceType extends ResolvedType {
return delegate.getAnnotationTypes();
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
AnnotationX[] axs = delegate.getAnnotations();
if (axs == null)
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
AnnotationAJ[] axs = delegate.getAnnotations();
if (axs == null) {
return null;
}
for (int i = 0; i < axs.length; i++) {
if (axs[i].getSignature().equals(ofType)) {
if (axs[i].getTypeSignature().equals(ofType.getSignature())) {
return axs[i];
}
}
@@ -221,7 +230,8 @@ public class ReferenceType extends ResolvedType {
}
// ??? needs to be Methods, not just declared methods? JLS 5.5 unclear
ResolvedMember[] a = getDeclaredMethods();
ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast always safe
ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast
// always safe
for (int ai = 0, alen = a.length; ai < alen; ai++) {
for (int bi = 0, blen = b.length; bi < blen; bi++) {
if (!b[bi].isCompatibleWith(a[ai]))
@@ -240,21 +250,26 @@ public class ReferenceType extends ResolvedType {
if (getTypeParameters().length == other.getTypeParameters().length) {
// there's a chance it can be done
ResolvedType[] myTypeParameters = getResolvedTypeParameters();
ResolvedType[] theirTypeParameters = other.getResolvedTypeParameters();
ResolvedType[] theirTypeParameters = other
.getResolvedTypeParameters();
for (int i = 0; i < myTypeParameters.length; i++) {
if (myTypeParameters[i] != theirTypeParameters[i]) {
// thin ice now... but List<String> may still be coerceable from e.g. List<T>
// thin ice now... but List<String> may still be
// coerceable from e.g. List<T>
if (myTypeParameters[i].isGenericWildcard()) {
BoundedReferenceType wildcard = (BoundedReferenceType) myTypeParameters[i];
if (!wildcard.canBeCoercedTo(theirTypeParameters[i]))
if (!wildcard
.canBeCoercedTo(theirTypeParameters[i]))
return false;
} else if (myTypeParameters[i].isTypeVariableReference()) {
} else if (myTypeParameters[i]
.isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) myTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
if (!tv.canBeBoundTo(theirTypeParameters[i]))
return false;
} else if (theirTypeParameters[i].isTypeVariableReference()) {
} else if (theirTypeParameters[i]
.isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) theirTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
@@ -289,7 +304,8 @@ public class ReferenceType extends ResolvedType {
if (other.isPrimitiveType()) {
if (!world.isInJava5Mode())
return false;
if (ResolvedType.validBoxing.contains(this.getSignature() + other.getSignature()))
if (ResolvedType.validBoxing.contains(this.getSignature()
+ other.getSignature()))
return true;
}
if (this == other)
@@ -297,7 +313,8 @@ public class ReferenceType extends ResolvedType {
if (this.getSignature().equals(ResolvedType.OBJECT.getSignature()))
return true;

if ((this.isRawType() || this.isGenericType()) && other.isParameterizedType()) {
if ((this.isRawType() || this.isGenericType())
&& other.isParameterizedType()) {
if (isAssignableFrom((ResolvedType) other.getRawType()))
return true;
}
@@ -328,13 +345,15 @@ public class ReferenceType extends ResolvedType {
if (wildcardsAllTheWay && !other.isParameterizedType())
return true;
// we have to match by parameters one at a time
ResolvedType[] theirParameters = other.getResolvedTypeParameters();
ResolvedType[] theirParameters = other
.getResolvedTypeParameters();
boolean parametersAssignable = true;
if (myParameters.length == theirParameters.length) {
for (int i = 0; i < myParameters.length; i++) {
if (myParameters[i] == theirParameters[i])
continue;
if (myParameters[i].isAssignableFrom(theirParameters[i], allowMissing)) {
if (myParameters[i].isAssignableFrom(
theirParameters[i], allowMissing)) {
continue;
}
if (!myParameters[i].isGenericWildcard()) {
@@ -356,20 +375,38 @@ public class ReferenceType extends ResolvedType {
}
}

if (isTypeVariableReference() && !other.isTypeVariableReference()) { // eg. this=T other=Ljava/lang/Object;
TypeVariable aVar = ((TypeVariableReference) this).getTypeVariable();
if (isTypeVariableReference() && !other.isTypeVariableReference()) { // eg
// .
// this
// =
// T
// other
// =
// Ljava
// /
// lang
// /
// Object
// ;
TypeVariable aVar = ((TypeVariableReference) this)
.getTypeVariable();
return aVar.resolve(world).canBeBoundTo(other);
}

if (other.isTypeVariableReference()) {
TypeVariableReferenceType otherType = (TypeVariableReferenceType) other;
if (this instanceof TypeVariableReference) {
return ((TypeVariableReference) this).getTypeVariable().resolve(world).canBeBoundTo(
otherType.getTypeVariable().getFirstBound().resolve(world));// pr171952
// return ((TypeVariableReference)this).getTypeVariable()==otherType.getTypeVariable();
return ((TypeVariableReference) this).getTypeVariable()
.resolve(world).canBeBoundTo(
otherType.getTypeVariable().getFirstBound()
.resolve(world));// pr171952
// return
// ((TypeVariableReference)this).getTypeVariable()==otherType
// .getTypeVariable();
} else {
// FIXME asc should this say canBeBoundTo??
return this.isAssignableFrom(otherType.getTypeVariable().getFirstBound().resolve(world));
return this.isAssignableFrom(otherType.getTypeVariable()
.getFirstBound().resolve(world));
}
}

@@ -393,7 +430,9 @@ public class ReferenceType extends ResolvedType {
}

public boolean isExposedToWeaver() {
return (delegate == null) || delegate.isExposedToWeaver(); // ??? where does this belong
return (delegate == null) || delegate.isExposedToWeaver(); // ??? where
// does this
// belong
}

public WeaverStateInfo getWeaverState() {
@@ -407,7 +446,8 @@ public class ReferenceType extends ResolvedType {
ResolvedMember[] delegateFields = delegate.getDeclaredFields();
parameterizedFields = new ResolvedMember[delegateFields.length];
for (int i = 0; i < delegateFields.length; i++) {
parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(), this,
parameterizedFields[i] = delegateFields[i].parameterizedWith(
getTypesForMemberParameterization(), this,
isParameterizedType());
}
return parameterizedFields;
@@ -417,40 +457,52 @@ public class ReferenceType extends ResolvedType {
}

/**
* Find out from the generic signature the true signature of any interfaces I implement. If I am parameterized, these may then
* need to be parameterized before returning.
* Find out from the generic signature the true signature of any interfaces
* I implement. If I am parameterized, these may then need to be
* parameterized before returning.
*/
public ResolvedType[] getDeclaredInterfaces() {
if (parameterizedInterfaces != null)
return parameterizedInterfaces;
if (isParameterizedType()) {
ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
// UnresolvedType[] paramTypes = getTypesForMemberParameterization();
ResolvedType[] delegateInterfaces = delegate
.getDeclaredInterfaces();
// UnresolvedType[] paramTypes =
// getTypesForMemberParameterization();
parameterizedInterfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0; i < delegateInterfaces.length; i++) {
// We may have to sub/super set the set of parametertypes if the implemented interface
// We may have to sub/super set the set of parametertypes if the
// implemented interface
// needs more or less than this type does. (pr124803/pr125080)

if (delegateInterfaces[i].isParameterizedType()) {
parameterizedInterfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world);
parameterizedInterfaces[i] = delegateInterfaces[i]
.parameterize(getMemberParameterizationMap())
.resolve(world);
} else {
parameterizedInterfaces[i] = delegateInterfaces[i];
}
}
return parameterizedInterfaces;
} else if (isRawType()) {
ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
ResolvedType[] delegateInterfaces = delegate
.getDeclaredInterfaces();
UnresolvedType[] paramTypes = getTypesForMemberParameterization();
parameterizedInterfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0; i < parameterizedInterfaces.length; i++) {
parameterizedInterfaces[i] = delegateInterfaces[i];
if (parameterizedInterfaces[i].isGenericType()) {
// a generic supertype of a raw type is replaced by its raw equivalent
parameterizedInterfaces[i] = parameterizedInterfaces[i].getRawType().resolve(getWorld());
// a generic supertype of a raw type is replaced by its raw
// equivalent
parameterizedInterfaces[i] = parameterizedInterfaces[i]
.getRawType().resolve(getWorld());
} else if (parameterizedInterfaces[i].isParameterizedType()) {
// a parameterized supertype collapses any type vars to their upper bounds
UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(parameterizedInterfaces[i], paramTypes);
parameterizedInterfaces[i] = parameterizedInterfaces[i].parameterizedWith(toUseForParameterization);
// a parameterized supertype collapses any type vars to
// their upper bounds
UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(
parameterizedInterfaces[i], paramTypes);
parameterizedInterfaces[i] = parameterizedInterfaces[i]
.parameterizedWith(toUseForParameterization);
}
}
return parameterizedInterfaces;
@@ -459,10 +511,12 @@ public class ReferenceType extends ResolvedType {
}

/**
* Locates the named type variable in the list of those on this generic type and returns the type parameter from the second list
* supplied. Returns null if it can't be found
* Locates the named type variable in the list of those on this generic type
* and returns the type parameter from the second list supplied. Returns
* null if it can't be found
*/
// private UnresolvedType findTypeParameterInList(String name, TypeVariable[] tvarsOnThisGenericType, UnresolvedType[]
// private UnresolvedType findTypeParameterInList(String name,
// TypeVariable[] tvarsOnThisGenericType, UnresolvedType[]
// paramTypes) {
// int position = -1;
// for (int i = 0; i < tvarsOnThisGenericType.length; i++) {
@@ -473,31 +527,38 @@ public class ReferenceType extends ResolvedType {
// return paramTypes[position];
// }
/**
* It is possible this type has multiple type variables but the interface we are about to parameterize only uses a subset - this
* method determines the subset to use by looking at the type variable names used. For example: <code>
* It is possible this type has multiple type variables but the interface we
* are about to parameterize only uses a subset - this method determines the
* subset to use by looking at the type variable names used. For example:
* <code>
* class Foo<T extends String,E extends Number> implements SuperInterface<T> {}
* </code> where <code>
* interface SuperInterface<Z> {}
* </code> In that
* example, a use of the 'Foo' raw type should know that it implements the SuperInterface<String>.
* </code> In that example, a use of the 'Foo' raw type should
* know that it implements the SuperInterface<String>.
*/
private UnresolvedType[] determineThoseTypesToUse(ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
private UnresolvedType[] determineThoseTypesToUse(
ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
// What are the type parameters for the supertype?
UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
UnresolvedType[] retVal = new UnresolvedType[tParms.length];

// Go through the supertypes type parameters, if any of them is a type variable, use the
// Go through the supertypes type parameters, if any of them is a type
// variable, use the
// real type variable on the declaring type.

// it is possibly overkill to look up the type variable - ideally the entry in the type parameter list for the
// interface should be the a ref to the type variable in the current type ... but I'm not 100% confident right now.
// it is possibly overkill to look up the type variable - ideally the
// entry in the type parameter list for the
// interface should be the a ref to the type variable in the current
// type ... but I'm not 100% confident right now.
for (int i = 0; i < tParms.length; i++) {
UnresolvedType tParm = tParms[i];
if (tParm.isTypeVariableReference()) {
TypeVariableReference tvrt = (TypeVariableReference) tParm;
TypeVariable tv = tvrt.getTypeVariable();
int rank = getRank(tv.getName());
// -1 probably means it is a reference to a type variable on the outer generic type (see pr129566)
// -1 probably means it is a reference to a type variable on the
// outer generic type (see pr129566)
if (rank != -1) {
retVal[i] = paramTypes[rank];
} else {
@@ -512,8 +573,9 @@ public class ReferenceType extends ResolvedType {
}

/**
* Returns the position within the set of type variables for this type for the specified type variable name. Returns -1 if there
* is no type variable with the specified name.
* Returns the position within the set of type variables for this type for
* the specified type variable name. Returns -1 if there is no type variable
* with the specified name.
*/
private int getRank(String tvname) {
TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables();
@@ -533,7 +595,8 @@ public class ReferenceType extends ResolvedType {
UnresolvedType[] parameters = getTypesForMemberParameterization();
parameterizedMethods = new ResolvedMember[delegateMethods.length];
for (int i = 0; i < delegateMethods.length; i++) {
parameterizedMethods[i] = delegateMethods[i].parameterizedWith(parameters, this, isParameterizedType());
parameterizedMethods[i] = delegateMethods[i].parameterizedWith(
parameters, this, isParameterizedType());
}
return parameterizedMethods;
} else {
@@ -545,11 +608,13 @@ public class ReferenceType extends ResolvedType {
if (parameterizedPointcuts != null)
return parameterizedPointcuts;
if (isParameterizedType()) {
ResolvedMember[] delegatePointcuts = delegate.getDeclaredPointcuts();
ResolvedMember[] delegatePointcuts = delegate
.getDeclaredPointcuts();
parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length];
for (int i = 0; i < delegatePointcuts.length; i++) {
parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(), this,
isParameterizedType());
parameterizedPointcuts[i] = delegatePointcuts[i]
.parameterizedWith(getTypesForMemberParameterization(),
this, isParameterizedType());
}
return parameterizedPointcuts;
} else {
@@ -590,7 +655,8 @@ public class ReferenceType extends ResolvedType {
PerClause pclause = delegate.getPerClause();
if (isParameterizedType()) { // could cache the result here...
Map parameterizationMap = getAjMemberParameterizationMap();
pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, world);
pclause = (PerClause) pclause.parameterizeWith(parameterizationMap,
world);
}
return pclause;
}
@@ -605,7 +671,8 @@ public class ReferenceType extends ResolvedType {
Map parameterizationMap = getAjMemberParameterizationMap();
for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
Declare declareStatement = (Declare) iter.next();
parameterizedDeclares.add(declareStatement.parameterizeWith(parameterizationMap, world));
parameterizedDeclares.add(declareStatement.parameterizeWith(
parameterizationMap, world));
}
declares = parameterizedDeclares;
} else {
@@ -633,7 +700,8 @@ public class ReferenceType extends ResolvedType {
// Map parameterizationMap = getAjMemberParameterizationMap();
// for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
// ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next();
// parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world));
// parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,
// world));
// }
// ret = parameterizedTypeMungers;
// } else {
@@ -659,7 +727,8 @@ public class ReferenceType extends ResolvedType {
world.setTypeVariableLookupScope(null);
}
if (this.isParameterizedType() && ret.isParameterizedType()) {
ret = ret.parameterize(getMemberParameterizationMap()).resolve(getWorld());
ret = ret.parameterize(getMemberParameterizationMap()).resolve(
getWorld());
}
return ret;
}
@@ -669,10 +738,13 @@ public class ReferenceType extends ResolvedType {
}

public void setDelegate(ReferenceTypeDelegate delegate) {
// Don't copy from BcelObjectType to EclipseSourceType - the context may be tidied (result null'd) after previous weaving
if (this.delegate != null && !(this.delegate instanceof BcelObjectType)
// Don't copy from BcelObjectType to EclipseSourceType - the context may
// be tidied (result null'd) after previous weaving
if (this.delegate != null
&& !(this.delegate instanceof BcelObjectType)
&& this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT)
((AbstractReferenceTypeDelegate) delegate).setSourceContext(this.delegate.getSourceContext());
((AbstractReferenceTypeDelegate) delegate)
.setSourceContext(this.delegate.getSourceContext());
this.delegate = delegate;
for (Iterator it = this.derivativeTypes.iterator(); it.hasNext();) {
ReferenceType dependent = (ReferenceType) it.next();
@@ -744,13 +816,15 @@ public class ReferenceType extends ResolvedType {
}

/**
* a parameterized signature starts with a "P" in place of the "L", see the comment on signatures in UnresolvedType.
* a parameterized signature starts with a "P" in place of the "L", see the
* comment on signatures in UnresolvedType.
*
* @param aGenericType
* @param someParameters
* @return
*/
private static String makeParameterizedSignature(ResolvedType aGenericType, ResolvedType[] someParameters) {
private static String makeParameterizedSignature(ResolvedType aGenericType,
ResolvedType[] someParameters) {
String rawSignature = aGenericType.getErasureSignature();
StringBuffer ret = new StringBuffer();
ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
@@ -763,13 +837,15 @@ public class ReferenceType extends ResolvedType {
return ret.toString();
}

private static String makeDeclaredSignature(ResolvedType aGenericType, UnresolvedType[] someParameters) {
private static String makeDeclaredSignature(ResolvedType aGenericType,
UnresolvedType[] someParameters) {
StringBuffer ret = new StringBuffer();
String rawSig = aGenericType.getErasureSignature();
ret.append(rawSig.substring(0, rawSig.length() - 1));
ret.append("<");
for (int i = 0; i < someParameters.length; i++) {
ret.append(((ReferenceType) someParameters[i]).getSignatureForAttribute());
ret.append(((ReferenceType) someParameters[i])
.getSignatureForAttribute());
}
ret.append(">;");
return ret.toString();

+ 59
- 26
weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java View File

@@ -17,55 +17,88 @@ import java.util.Collection;
import org.aspectj.weaver.patterns.PerClause;

/**
* Abstraction over a type - a reference type is Object and a descendant of Object, other types (int/etc) are
* considered primitive types. Abstract implementation provided by AbstractReferenceTypeDelegate.
* Abstraction over a type - a reference type is Object and a descendant of
* Object, other types (int/etc) are considered primitive types. Abstract
* implementation provided by AbstractReferenceTypeDelegate.
*/
public interface ReferenceTypeDelegate {
// TODO asc move to proxy
public void addAnnotation(AnnotationX annotationX);
public void ensureDelegateConsistent(); // Required evil because of mutator methods in delegates :( (see pr85132)
public void addAnnotation(AnnotationAJ annotationX);

public void ensureDelegateConsistent(); // Required evil because of mutator

// methods in delegates :( (see
// pr85132)

public boolean isAspect();
public boolean isAnnotationStyleAspect();
public boolean isInterface();
public boolean isEnum();
public boolean isAnnotation();
public String getRetentionPolicy();
public boolean canAnnotationTargetType();
public AnnotationTargetKind[] getAnnotationTargetKinds();
public boolean isAnnotationWithRuntimeRetention();

public boolean isAnnotationStyleAspect();

public boolean isInterface();

public boolean isEnum();

public boolean isAnnotation();

public String getRetentionPolicy();

public boolean canAnnotationTargetType();

public AnnotationTargetKind[] getAnnotationTargetKinds();

public boolean isAnnotationWithRuntimeRetention();

public boolean isClass();

public boolean isGeneric();

public boolean isAnonymous();

public boolean isNested();

public boolean isExposedToWeaver();
public boolean hasAnnotation(UnresolvedType ofType);
public AnnotationX[] getAnnotations();
public ResolvedType[] getAnnotationTypes();

public AnnotationAJ[] getAnnotations();

public ResolvedType[] getAnnotationTypes();

public ResolvedMember[] getDeclaredFields();
public ResolvedType[] getDeclaredInterfaces();

public ResolvedType[] getDeclaredInterfaces();

public ResolvedMember[] getDeclaredMethods();

public ResolvedMember[] getDeclaredPointcuts();

public TypeVariable[] getTypeVariables();

public PerClause getPerClause();
public Collection getDeclares() ;
public PerClause getPerClause();

public Collection getDeclares();

public Collection getTypeMungers();

public Collection getPrivilegedAccesses();

public int getModifiers();
public ResolvedType getSuperclass();

public ResolvedType getSuperclass();

public WeaverStateInfo getWeaverState();

public ReferenceType getResolvedTypeX();

public boolean doesNotExposeShadowMungers();
public ISourceContext getSourceContext();
public String getSourcefilename();
public String getDeclaredGenericSignature();

public ResolvedType getOuterClass();
}

+ 27
- 15
weaver/src/org/aspectj/weaver/ResolvedMember.java View File

@@ -20,7 +20,8 @@ import java.util.Map;

import org.aspectj.bridge.ISourceLocation;

public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDeclaringElement {
public interface ResolvedMember extends Member, AnnotatedElement,
TypeVariableDeclaringElement {

public static final ResolvedMember[] NONE = new ResolvedMember[0];

@@ -42,13 +43,13 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe

public boolean hasAnnotation(UnresolvedType ofType);

public AnnotationX[] getAnnotations();
public AnnotationAJ[] getAnnotations();

public ResolvedType[] getAnnotationTypes();

public void setAnnotationTypes(UnresolvedType[] annotationtypes);

public void addAnnotation(AnnotationX annotation);
public void addAnnotation(AnnotationAJ annotation);

public boolean isBridgeMethod();

@@ -64,7 +65,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe

public void setParameterNames(String[] names);

public AnnotationX[][] getParameterAnnotations();
public AnnotationAJ[][] getParameterAnnotations();

public ResolvedType[][] getParameterAnnotationTypes();

@@ -118,26 +119,34 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public ResolvedMember getBackingGenericMember();

/**
* Get the UnresolvedType for the return type, taking generic signature into account
* Get the UnresolvedType for the return type, taking generic signature into
* account
*/
public UnresolvedType getGenericReturnType();

/**
* Get the TypeXs of the parameter types, taking generic signature into account
* Get the TypeXs of the parameter types, taking generic signature into
* account
*/
public UnresolvedType[] getGenericParameterTypes();

// return a resolved member in which all type variables in the signature of this
// return a resolved member in which all type variables in the signature of
// this
// member have been replaced with the given bindings.
// the isParameterized flag tells us whether we are creating a raw type version or not
// the isParameterized flag tells us whether we are creating a raw type
// version or not
// if isParameterized List<T> will turn into List<String> (for example),
// but if !isParameterized List<T> will turn into List.
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized);

// this variant allows for aliases for type variables (i.e. allowing them to have another name)
// this is used for processing ITDs that share type variables with their target generic type
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
// this variant allows for aliases for type variables (i.e. allowing them to
// have another name)
// this is used for processing ITDs that share type variables with their
// target generic type
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized, List aliases);

public void setTypeVariables(TypeVariable[] types);
@@ -145,7 +154,8 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public TypeVariable[] getTypeVariables();

// /**
// * If this member is defined by a parameterized super-type, return the erasure
// * If this member is defined by a parameterized super-type, return the
// erasure
// * of that member.
// * For example:
// * interface I<T> { T foo(T aTea); }
@@ -160,8 +170,10 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
// public ResolvedMember getErasure();

/**
* Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing
* parameter types, we allow any type variable to match any other type variable regardless of bounds.
* Returns true if this member matches the other. The matching takes into
* account name and parameter types only. When comparing parameter types, we
* allow any type variable to match any other type variable regardless of
* bounds.
*/
public boolean matches(ResolvedMember aCandidateMatch);


+ 300
- 159
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java View File

@@ -26,27 +26,32 @@ import java.util.Set;
import org.aspectj.bridge.ISourceLocation;

/**
* This is the declared member, i.e. it will always correspond to an actual method/... declaration
* This is the declared member, i.e. it will always correspond to an actual
* method/... declaration
*/
public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, AnnotatedElement, TypeVariableDeclaringElement,
ResolvedMember {
public class ResolvedMemberImpl extends MemberImpl implements IHasPosition,
AnnotatedElement, TypeVariableDeclaringElement, ResolvedMember {

private String[] parameterNames = null;
protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE;
/**
* if this member is a parameterized version of a member in a generic type, then this field holds a reference to the member we
* parameterize.
* if this member is a parameterized version of a member in a generic type,
* then this field holds a reference to the member we parameterize.
*/
protected ResolvedMember backingGenericMember = null;

protected Set annotationTypes = null;
protected ResolvedType[][] parameterAnnotationTypes = null;

// Some members are 'created' to represent other things (for example ITDs). These
// members have their annotations stored elsewhere, and this flag indicates that is
// Some members are 'created' to represent other things (for example ITDs).
// These
// members have their annotations stored elsewhere, and this flag indicates
// that is
// the case. It is up to the caller to work out where that is!
// Once determined the caller may choose to stash the annotations in this member...
private boolean isAnnotatedElsewhere = false; // this field is not serialized.
// Once determined the caller may choose to stash the annotations in this
// member...
private boolean isAnnotatedElsewhere = false; // this field is not
// serialized.
private boolean isAjSynthetic = false;

// generic methods have type variables
@@ -57,33 +62,43 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
protected ISourceContext sourceContext = null;

// XXX deprecate this in favor of the constructor below
public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes) {
super(kind, declaringType, modifiers, returnType, name, parameterTypes);
}

public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions) {
super(kind, declaringType, modifiers, returnType, name, parameterTypes);
this.checkedExceptions = checkedExceptions;
}

public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, ResolvedMember backingGenericMember) {
this(kind, declaringType, modifiers, returnType, name, parameterTypes, checkedExceptions);
public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
UnresolvedType[] checkedExceptions,
ResolvedMember backingGenericMember) {
this(kind, declaringType, modifiers, returnType, name, parameterTypes,
checkedExceptions);
this.backingGenericMember = backingGenericMember;
this.isAjSynthetic = backingGenericMember.isAjSynthetic();
}

public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature) {
public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, String name, String signature) {
super(kind, declaringType, modifiers, name, signature);
}

/**
* Compute the full set of signatures for a member. This walks up the hierarchy giving the ResolvedMember in each defining type
* in the hierarchy. A shadowMember can be created with a target type (declaring type) that does not actually define the member.
* This is ok as long as the member is inherited in the declaring type. Each declaring type in the line to the actual declaring
* type is added as an additional signature. For example:
* Compute the full set of signatures for a member. This walks up the
* hierarchy giving the ResolvedMember in each defining type in the
* hierarchy. A shadowMember can be created with a target type (declaring
* type) that does not actually define the member. This is ok as long as the
* member is inherited in the declaring type. Each declaring type in the
* line to the actual declaring type is added as an additional signature.
* For example:
*
* class A { void foo(); } class B extends A {}
*
@@ -94,19 +109,26 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
* @param joinPointSignature
* @param inAWorld
*/
public static JoinPointSignature[] getJoinPointSignatures(Member joinPointSignature, World inAWorld) {
public static JoinPointSignature[] getJoinPointSignatures(
Member joinPointSignature, World inAWorld) {

// Walk up hierarchy creating one member for each type up to and including the
// Walk up hierarchy creating one member for each type up to and
// including the
// first defining type
ResolvedType originalDeclaringType = joinPointSignature.getDeclaringType().resolve(inAWorld);
ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature.resolve(inAWorld);
ResolvedType originalDeclaringType = joinPointSignature
.getDeclaringType().resolve(inAWorld);
ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature
.resolve(inAWorld);
if (firstDefiningMember == null) {
return new JoinPointSignature[0];
}
// declaringType can be unresolved if we matched a synthetic member generated by Aj...
// should be fixed elsewhere but add this resolve call on the end for now so that we can
// declaringType can be unresolved if we matched a synthetic member
// generated by Aj...
// should be fixed elsewhere but add this resolve call on the end for
// now so that we can
// focus on one problem at a time...
ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType().resolve(inAWorld);
ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType()
.resolve(inAWorld);
if (firstDefiningType != originalDeclaringType) {
if (joinPointSignature.getKind() == Member.CONSTRUCTOR) {
return new JoinPointSignature[0];
@@ -117,23 +139,30 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

List declaringTypes = new ArrayList();
accumulateTypesInBetween(originalDeclaringType, firstDefiningType, declaringTypes);
accumulateTypesInBetween(originalDeclaringType, firstDefiningType,
declaringTypes);
Set memberSignatures = new HashSet();
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
ResolvedType declaringType = (ResolvedType) iter.next();
ResolvedMember member = firstDefiningMember.withSubstituteDeclaringType(declaringType);
ResolvedMember member = firstDefiningMember
.withSubstituteDeclaringType(declaringType);
memberSignatures.add(member);
}

if (shouldWalkUpHierarchyFor(firstDefiningMember)) {
// now walk up the hierarchy from the firstDefiningMember and include the signature for
// every type between the firstDefiningMember and the root defining member.
Iterator superTypeIterator = firstDefiningType.getDirectSupertypes();
// now walk up the hierarchy from the firstDefiningMember and
// include the signature for
// every type between the firstDefiningMember and the root defining
// member.
Iterator superTypeIterator = firstDefiningType
.getDirectSupertypes();
List typesAlreadyVisited = new ArrayList();
accumulateMembersMatching(firstDefiningMember, superTypeIterator, typesAlreadyVisited, memberSignatures);
accumulateMembersMatching(firstDefiningMember, superTypeIterator,
typesAlreadyVisited, memberSignatures);
}

JoinPointSignature[] ret = new JoinPointSignature[memberSignatures.size()];
JoinPointSignature[] ret = new JoinPointSignature[memberSignatures
.size()];
memberSignatures.toArray(ret);
return ret;
}
@@ -149,9 +178,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Build a list containing every type between subtype and supertype, inclusively.
* Build a list containing every type between subtype and supertype,
* inclusively.
*/
private static void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) {
private static void accumulateTypesInBetween(ResolvedType subType,
ResolvedType superType, List types) {
types.add(subType);
if (subType == superType) {
return;
@@ -166,48 +197,67 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* We have a resolved member, possibly with type parameter references as parameters or return type. We need to find all its
* ancestor members. When doing this, a type parameter matches regardless of bounds (bounds can be narrowed down the hierarchy).
* We have a resolved member, possibly with type parameter references as
* parameters or return type. We need to find all its ancestor members. When
* doing this, a type parameter matches regardless of bounds (bounds can be
* narrowed down the hierarchy).
*/
private static void accumulateMembersMatching(ResolvedMemberImpl memberToMatch, Iterator typesToLookIn,
private static void accumulateMembersMatching(
ResolvedMemberImpl memberToMatch, Iterator typesToLookIn,
List typesAlreadyVisited, Set foundMembers) {
while (typesToLookIn.hasNext()) {
ResolvedType toLookIn = (ResolvedType) typesToLookIn.next();
if (!typesAlreadyVisited.contains(toLookIn)) {
typesAlreadyVisited.add(toLookIn);
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch, true);
if (foundMember != null && isVisibleTo(memberToMatch, foundMember)) {
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn
.lookupResolvedMember(memberToMatch, true);
if (foundMember != null
&& isVisibleTo(memberToMatch, foundMember)) {
List declaringTypes = new ArrayList();
// declaring type can be unresolved if the member can from an ITD...
ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(toLookIn.getWorld());
accumulateTypesInBetween(toLookIn, resolvedDeclaringType, declaringTypes);
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
// declaring type can be unresolved if the member can from
// an ITD...
ResolvedType resolvedDeclaringType = foundMember
.getDeclaringType().resolve(toLookIn.getWorld());
accumulateTypesInBetween(toLookIn, resolvedDeclaringType,
declaringTypes);
for (Iterator iter = declaringTypes.iterator(); iter
.hasNext();) {
ResolvedType declaringType = (ResolvedType) iter.next();
// typesAlreadyVisited.add(declaringType);
ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType);
ResolvedMember member = foundMember
.withSubstituteDeclaringType(declaringType);
foundMembers.add(member);
}
if (toLookIn.isParameterizedType() && (foundMember.backingGenericMember != null)) {
foundMembers.add(new JoinPointSignature(foundMember.backingGenericMember, foundMember.declaringType
.resolve(toLookIn.getWorld())));
if (toLookIn.isParameterizedType()
&& (foundMember.backingGenericMember != null)) {
foundMembers.add(new JoinPointSignature(
foundMember.backingGenericMember,
foundMember.declaringType.resolve(toLookIn
.getWorld())));
}
accumulateMembersMatching(foundMember, toLookIn.getDirectSupertypes(), typesAlreadyVisited, foundMembers);
// if this was a parameterized type, look in the generic type that backs it too
accumulateMembersMatching(foundMember, toLookIn
.getDirectSupertypes(), typesAlreadyVisited,
foundMembers);
// if this was a parameterized type, look in the generic
// type that backs it too
}
}
}
}

/**
* Returns true if the parent member is visible to the child member In the same declaring type this is always true, otherwise if
* parent is private it is false.
* Returns true if the parent member is visible to the child member In the
* same declaring type this is always true, otherwise if parent is private
* it is false.
*
* @param childMember
* @param parentMember
* @return
*/
private static boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) {
if (childMember.getDeclaringType().equals(parentMember.getDeclaringType()))
private static boolean isVisibleTo(ResolvedMember childMember,
ResolvedMember parentMember) {
if (childMember.getDeclaringType().equals(
parentMember.getDeclaringType()))
return true;
if (Modifier.isPrivate(parentMember.getModifiers())) {
return false;
@@ -254,12 +304,15 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Check if this member has an annotation of the specified type. If the member has a backing generic member then this member
* represents a parameterization of a member in a generic type and the annotations available on the backing generic member
* should be used.
* Check if this member has an annotation of the specified type. If the
* member has a backing generic member then this member represents a
* parameterization of a member in a generic type and the annotations
* available on the backing generic member should be used.
*
* @param ofType the type of the annotation being searched for
* @return true if the annotation is found on this member or its backing generic member
* @param ofType
* the type of the annotation being searched for
* @return true if the annotation is found on this member or its backing
* generic member
*/
public boolean hasAnnotation(UnresolvedType ofType) {
// The ctors don't allow annotations to be specified ... yet - but
@@ -268,7 +321,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// this type - BcelField/BcelMethod
if (backingGenericMember != null) {
if (annotationTypes != null) {
throw new BCException("Unexpectedly found a backing generic member and a local set of annotations");
throw new BCException(
"Unexpectedly found a backing generic member and a local set of annotations");
}
return backingGenericMember.hasAnnotation(ofType);
}
@@ -285,7 +339,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// this type - BcelField/BcelMethod
if (backingGenericMember != null) {
if (annotationTypes != null) {
throw new BCException("Unexpectedly found a backing generic member and a local set of annotations");
throw new BCException(
"Unexpectedly found a backing generic member and a local set of annotations");
}
return backingGenericMember.getAnnotationTypes();
}
@@ -299,7 +354,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
"You should resolve this member and call getAnnotationDefaultValue() on the result...");
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
if (backingGenericMember != null)
return backingGenericMember.getAnnotations();
return super.getAnnotations();
@@ -320,22 +375,25 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return parameterAnnotationTypes;
}

public AnnotationX[][] getParameterAnnotations() {
public AnnotationAJ[][] getParameterAnnotations() {
if (backingGenericMember != null)
return backingGenericMember.getParameterAnnotations();
throw new BCException("Cannot return parameter annotations for a " + this.getClass().getName() + " member");
throw new BCException("Cannot return parameter annotations for a "
+ this.getClass().getName() + " member");
// return super.getParameterAnnotations();
}

public void addAnnotation(AnnotationX annotation) {
// FIXME asc only allows for annotation types, not instances - should it?
public void addAnnotation(AnnotationAJ annotation) {
// FIXME asc only allows for annotation types, not instances - should
// it?
if (annotationTypes == null)
annotationTypes = new HashSet();
annotationTypes.add(annotation.getSignature());
annotationTypes.add(annotation.getType());
}

public boolean isBridgeMethod() {
return (modifiers & Constants.ACC_BRIDGE) != 0 && getKind().equals(METHOD);
return (modifiers & Constants.ACC_BRIDGE) != 0
&& getKind().equals(METHOD);
}

public boolean isVarargsMethod() {
@@ -347,7 +405,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

public boolean isSynthetic() {
// See Bcelmethod.isSynthetic() which takes account of preJava5 Synthetic modifier
// See Bcelmethod.isSynthetic() which takes account of preJava5
// Synthetic modifier
return (modifiers & 4096) != 0; // do we know better?
}

@@ -387,17 +446,22 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Return the member generic signature that would be suitable for inclusion in a class file Signature attribute. For: <T>
* List<String> getThem(T t) {} we would create: <T:Ljava/lang/Object;>(TT;)Ljava/util/List<Ljava/lang/String;>;;
* Return the member generic signature that would be suitable for inclusion
* in a class file Signature attribute. For: <T> List<String> getThem(T t)
* {} we would create:
* <T:Ljava/lang/Object;>(TT;)Ljava/util/List<Ljava/lang/String;>;;
*
* @return the generic signature for the member that could be inserted into a class file
* @return the generic signature for the member that could be inserted into
* a class file
*/
public String getSignatureForAttribute() {
StringBuffer sb = new StringBuffer();
if (typeVariables != null) {
sb.append("<");
for (int i = 0; i < typeVariables.length; i++) {
sb.append(typeVariables[i].getSignatureForAttribute()); // need a 'getSignatureForAttribute()'
sb.append(typeVariables[i].getSignatureForAttribute()); // need
// a
// 'getSignatureForAttribute()'
}
sb.append(">");
}
@@ -430,18 +494,20 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return sb.toString();
}

public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException {
public static void writeArray(ResolvedMember[] members, DataOutputStream s)
throws IOException {
s.writeInt(members.length);
for (int i = 0, len = members.length; i < len; i++) {
members[i].write(s);
}
}

public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext)
public static ResolvedMemberImpl readResolvedMember(
VersionedDataInputStream s, ISourceContext sourceContext)
throws IOException {

ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(), s.readUTF(), s
.readUTF());
ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s),
UnresolvedType.read(s), s.readInt(), s.readUTF(), s.readUTF());
m.checkedExceptions = UnresolvedType.readArray(s);

m.start = s.readInt();
@@ -470,9 +536,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
int ps = s.readInt();
UnresolvedType[] params = new UnresolvedType[ps];
for (int i = 0; i < params.length; i++) {
params[i] = TypeFactory.createTypeFromSignature(s.readUTF());
params[i] = TypeFactory.createTypeFromSignature(s
.readUTF());
}
UnresolvedType rt = TypeFactory.createTypeFromSignature(s.readUTF());
UnresolvedType rt = TypeFactory.createTypeFromSignature(s
.readUTF());
m.parameterTypes = params;
m.returnType = rt;
}
@@ -481,7 +549,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return m;
}

public static ResolvedMember[] readResolvedMemberArray(VersionedDataInputStream s, ISourceContext context) throws IOException {
public static ResolvedMember[] readResolvedMemberArray(
VersionedDataInputStream s, ISourceContext context)
throws IOException {
int len = s.readInt();
ResolvedMember[] members = new ResolvedMember[len];
for (int i = 0; i < len; i++) {
@@ -490,7 +560,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return members;
}

// OPTIMIZE dont like how resolve(world) on ResolvedMemberImpl does something different to world.resolve(member)
// OPTIMIZE dont like how resolve(world) on ResolvedMemberImpl does
// something different to world.resolve(member)
public ResolvedMember resolve(World world) {
// make sure all the pieces of a resolvedmember really are resolved
try {
@@ -510,7 +581,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
declaringType = declaringType.resolve(world);
if (declaringType.isRawType())
declaringType = ((ReferenceType) declaringType).getGenericType();
declaringType = ((ReferenceType) declaringType)
.getGenericType();

if (parameterTypes != null && parameterTypes.length > 0) {
for (int i = 0; i < parameterTypes.length; i++) {
@@ -602,7 +674,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno

public boolean isVisible(ResolvedType fromType) {
World world = fromType.getWorld();
return ResolvedType.isVisible(getModifiers(), getDeclaringType().resolve(world), fromType);
return ResolvedType.isVisible(getModifiers(), getDeclaringType()
.resolve(world), fromType);
}

public void setCheckedExceptions(UnresolvedType[] checkedExceptions) {
@@ -618,70 +691,89 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Get the UnresolvedType for the return type, taking generic signature into account
* Get the UnresolvedType for the return type, taking generic signature into
* account
*/
public UnresolvedType getGenericReturnType() {
return getReturnType();
}

/**
* Get the TypeXs of the parameter types, taking generic signature into account
* Get the TypeXs of the parameter types, taking generic signature into
* account
*/
public UnresolvedType[] getGenericParameterTypes() {
return getParameterTypes();
}

public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized) {
return parameterizedWith(typeParameters, newDeclaringType, isParameterized, null);
return parameterizedWith(typeParameters, newDeclaringType,
isParameterized, null);
}

/**
* Return a resolvedmember in which all the type variables in the signature have been replaced with the given bindings. The
* 'isParameterized' flag tells us whether we are creating a raw type version or not. if (isParameterized) then List<T> will
* turn into List<String> (for example) - if (!isParameterized) then List<T> will turn into List.
* Return a resolvedmember in which all the type variables in the signature
* have been replaced with the given bindings. The 'isParameterized' flag
* tells us whether we are creating a raw type version or not. if
* (isParameterized) then List<T> will turn into List<String> (for example)
* - if (!isParameterized) then List<T> will turn into List.
*/
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized, List aliases) {
if (// isParameterized && <-- might need this bit...
!getDeclaringType().isGenericType()) {
throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: " + getDeclaringType()
+ " kind(" + getDeclaringType().typeKind + ")");
throw new IllegalStateException(
"Can't ask to parameterize a member of non-generic type: "
+ getDeclaringType() + " kind("
+ getDeclaringType().typeKind + ")");
}
TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
if (isParameterized && (typeVariables.length != typeParameters.length)) {
throw new IllegalStateException("Wrong number of type parameters supplied");
throw new IllegalStateException(
"Wrong number of type parameters supplied");
}
Map typeMap = new HashMap();
boolean typeParametersSupplied = typeParameters != null && typeParameters.length > 0;
boolean typeParametersSupplied = typeParameters != null
&& typeParameters.length > 0;
if (typeVariables != null) {
// If no 'replacements' were supplied in the typeParameters array then collapse
// If no 'replacements' were supplied in the typeParameters array
// then collapse
// type variables to their first bound.
for (int i = 0; i < typeVariables.length; i++) {
UnresolvedType ut = (!typeParametersSupplied ? typeVariables[i].getFirstBound() : typeParameters[i]);
UnresolvedType ut = (!typeParametersSupplied ? typeVariables[i]
.getFirstBound() : typeParameters[i]);
typeMap.put(typeVariables[i].getName(), ut);
}
}
// For ITDs on generic types that use type variables from the target type, the aliases
// record the alternative names used throughout the ITD expression that must map to
// For ITDs on generic types that use type variables from the target
// type, the aliases
// record the alternative names used throughout the ITD expression that
// must map to
// the same value as the type variables real name.
if (aliases != null) {
int posn = 0;
for (Iterator iter = aliases.iterator(); iter.hasNext();) {
String typeVariableAlias = (String) iter.next();
typeMap.put(typeVariableAlias, (!typeParametersSupplied ? typeVariables[posn].getFirstBound()
: typeParameters[posn]));
typeMap.put(typeVariableAlias,
(!typeParametersSupplied ? typeVariables[posn]
.getFirstBound() : typeParameters[posn]));
posn++;
}
}

UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(), typeMap, isParameterized);
UnresolvedType parameterizedReturnType = parameterize(
getGenericReturnType(), typeMap, isParameterized);
UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
for (int i = 0; i < parameterizedParameterTypes.length; i++) {
parameterizedParameterTypes[i] = parameterize(genericParameterTypes[i], typeMap, isParameterized);
parameterizedParameterTypes[i] = parameterize(
genericParameterTypes[i], typeMap, isParameterized);
}
ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), newDeclaringType, getModifiers(), parameterizedReturnType,
ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(),
newDeclaringType, getModifiers(), parameterizedReturnType,
getName(), parameterizedParameterTypes, getExceptions(), this);
ret.setTypeVariables(getTypeVariables());
ret.setSourceContext(getSourceContext());
@@ -691,51 +783,67 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Replace occurrences of type variables in the signature with values contained in the map. The map is of the form
* A=String,B=Integer and so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {}
* Replace occurrences of type variables in the signature with values
* contained in the map. The map is of the form A=String,B=Integer and so a
* signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer
* i) {}
*/
public ResolvedMember parameterizedWith(Map m, World w) {
// if (//isParameterized && <-- might need this bit...
// !getDeclaringType().isGenericType()) {
// throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+
// throw new IllegalStateException(
// "Can't ask to parameterize a member of non-generic type: "
// +getDeclaringType()+" kind("+
// getDeclaringType().typeKind+")");
// }
declaringType = declaringType.resolve(w);
if (declaringType.isRawType())
declaringType = ((ResolvedType) declaringType).getGenericType();
// TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
// if (isParameterized && (typeVariables.length != typeParameters.length)) {
// throw new IllegalStateException("Wrong number of type parameters supplied");
// if (isParameterized && (typeVariables.length !=
// typeParameters.length)) {
// throw new
// IllegalStateException("Wrong number of type parameters supplied");
// }
// Map typeMap = new HashMap();
// boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
// boolean typeParametersSupplied = typeParameters!=null &&
// typeParameters.length>0;
// if (typeVariables!=null) {
// // If no 'replacements' were supplied in the typeParameters array then collapse
// // If no 'replacements' were supplied in the typeParameters array
// then collapse
// // type variables to their first bound.
// for (int i = 0; i < typeVariables.length; i++) {
// UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
// UnresolvedType ut =
// (!typeParametersSupplied?typeVariables[i].getFirstBound
// ():typeParameters[i]);
// typeMap.put(typeVariables[i].getName(),ut);
// }
// }
// // For ITDs on generic types that use type variables from the target type, the aliases
// // record the alternative names used throughout the ITD expression that must map to
// // For ITDs on generic types that use type variables from the target
// type, the aliases
// // record the alternative names used throughout the ITD expression
// that must map to
// // the same value as the type variables real name.
// if (aliases!=null) {
// int posn = 0;
// for (Iterator iter = aliases.iterator(); iter.hasNext();) {
// String typeVariableAlias = (String) iter.next();
// typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
// typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[
// posn].getFirstBound():typeParameters[posn]));
// posn++;
// }
// }

UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(), m, true, w);
UnresolvedType parameterizedReturnType = parameterize(
getGenericReturnType(), m, true, w);
UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
for (int i = 0; i < parameterizedParameterTypes.length; i++) {
parameterizedParameterTypes[i] = parameterize(genericParameterTypes[i], m, true, w);
parameterizedParameterTypes[i] = parameterize(
genericParameterTypes[i], m, true, w);
}
ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), declaringType, getModifiers(), parameterizedReturnType,
ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(),
declaringType, getModifiers(), parameterizedReturnType,
getName(), parameterizedParameterTypes, getExceptions(), this);
ret.setTypeVariables(getTypeVariables());
ret.setSourceContext(getSourceContext());
@@ -752,15 +860,19 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return typeVariables;
}

protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) {
protected UnresolvedType parameterize(UnresolvedType aType,
Map typeVariableMap, boolean inParameterizedType) {
return parameterize(aType, typeVariableMap, inParameterizedType, null);
}

protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType, World w) {
protected UnresolvedType parameterize(UnresolvedType aType,
Map typeVariableMap, boolean inParameterizedType, World w) {
if (aType instanceof TypeVariableReference) {
String variableName = ((TypeVariableReference) aType).getTypeVariable().getName();
String variableName = ((TypeVariableReference) aType)
.getTypeVariable().getName();
if (!typeVariableMap.containsKey(variableName)) {
return aType; // if the type variable comes from the method (and not the type) thats OK
return aType; // if the type variable comes from the method (and
// not the type) thats OK
}
return (UnresolvedType) typeVariableMap.get(variableName);
} else if (aType.isParameterizedType()) {
@@ -772,7 +884,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
if (w != null)
aType = aType.resolve(w);
else {
aType = aType.resolve(((ResolvedType) getDeclaringType()).getWorld());
aType = aType.resolve(((ResolvedType) getDeclaringType())
.getWorld());
}
// }
return aType.parameterize(typeVariableMap);
@@ -785,19 +898,22 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
String sig = aType.getSignature();
while (sig.charAt(dims) == '[')
dims++;
UnresolvedType componentSig = UnresolvedType.forSignature(sig.substring(dims));
UnresolvedType arrayType = ResolvedType.makeArray(parameterize(componentSig, typeVariableMap, inParameterizedType),
dims);
UnresolvedType componentSig = UnresolvedType.forSignature(sig
.substring(dims));
UnresolvedType arrayType = ResolvedType.makeArray(parameterize(
componentSig, typeVariableMap, inParameterizedType), dims);
return arrayType;
}
return aType;
}

/**
* If this member is defined by a parameterized super-type, return the erasure of that member. For example: interface I<T> { T
* foo(T aTea); } class C implements I<String> { String foo(String aString) { return "something"; } } The resolved member for
* C.foo has signature String foo(String). The erasure of that member is Object foo(Object) -- use upper bound of type variable.
* A type is a supertype of itself.
* If this member is defined by a parameterized super-type, return the
* erasure of that member. For example: interface I<T> { T foo(T aTea); }
* class C implements I<String> { String foo(String aString) { return
* "something"; } } The resolved member for C.foo has signature String
* foo(String). The erasure of that member is Object foo(Object) -- use
* upper bound of type variable. A type is a supertype of itself.
*/
// public ResolvedMember getErasure() {
// if (calculatedMyErasure) return myErasure;
@@ -809,14 +925,17 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// } else {
// // we have one or more parameterized super types.
// // this member may be defined by one of them... we need to find out.
// Collection declaringTypes = this.getDeclaringTypes(resolvedDeclaringType.getWorld());
// Collection declaringTypes =
// this.getDeclaringTypes(resolvedDeclaringType.getWorld());
// for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
// ResolvedType aDeclaringType = (ResolvedType) iter.next();
// if (aDeclaringType.isParameterizedType()) {
// // we've found the (a?) parameterized type that defines this member.
// // now get the erasure of it
// ResolvedMemberImpl matchingMember = (ResolvedMemberImpl) aDeclaringType.lookupMemberNoSupers(this);
// if (matchingMember != null && matchingMember.backingGenericMember != null) {
// ResolvedMemberImpl matchingMember = (ResolvedMemberImpl)
// aDeclaringType.lookupMemberNoSupers(this);
// if (matchingMember != null && matchingMember.backingGenericMember !=
// null) {
// myErasure = matchingMember.backingGenericMember;
// return myErasure;
// }
@@ -837,8 +956,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics using this
* method - this is safe.
* For ITDs, we use the default factory methods to build a resolved member,
* then alter a couple of characteristics using this method - this is safe.
*/
public void resetName(String newName) {
this.name = newName;
@@ -857,41 +976,49 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

/**
* Returns a copy of this member but with the declaring type swapped. Copy only needs to be shallow.
* Returns a copy of this member but with the declaring type swapped. Copy
* only needs to be shallow.
*
* @param newDeclaringType
*/
public JoinPointSignature withSubstituteDeclaringType(ResolvedType newDeclaringType) {
public JoinPointSignature withSubstituteDeclaringType(
ResolvedType newDeclaringType) {
JoinPointSignature ret = new JoinPointSignature(this, newDeclaringType);
return ret;
}

/**
* Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing
* parameter types, we allow any type variable to match any other type variable regardless of bounds.
* Returns true if this member matches the other. The matching takes into
* account name and parameter types only. When comparing parameter types, we
* allow any type variable to match any other type variable regardless of
* bounds.
*/
public boolean matches(ResolvedMember aCandidateMatch) {
ResolvedMemberImpl candidateMatchImpl = (ResolvedMemberImpl) aCandidateMatch;
if (!getName().equals(aCandidateMatch.getName()))
return false;
UnresolvedType[] myParameterTypes = getGenericParameterTypes();
UnresolvedType[] candidateParameterTypes = aCandidateMatch.getGenericParameterTypes();
UnresolvedType[] candidateParameterTypes = aCandidateMatch
.getGenericParameterTypes();
if (myParameterTypes.length != candidateParameterTypes.length)
return false;
String myParameterSignature = getParameterSigWithBoundsRemoved();
String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved();
String candidateParameterSignature = candidateMatchImpl
.getParameterSigWithBoundsRemoved();
if (myParameterSignature.equals(candidateParameterSignature)) {
return true;
} else {
// try erasure
myParameterSignature = getParameterSignatureErased();
candidateParameterSignature = candidateMatchImpl.getParameterSignatureErased();
candidateParameterSignature = candidateMatchImpl
.getParameterSignatureErased();
return myParameterSignature.equals(candidateParameterSignature);
}
}

/**
* converts e.g. <T extends Number>.... List<T> to just Ljava/util/List<T;>; whereas the full signature would be
* converts e.g. <T extends Number>.... List<T> to just Ljava/util/List<T;>;
* whereas the full signature would be
* Ljava/util/List<T:Ljava/lang/Number;>;
*/
private String myParameterSignatureWithBoundsRemoved = null;
@@ -900,7 +1027,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
*/
private String myParameterSignatureErasure = null;

// does NOT produce a meaningful java signature, but does give a unique string suitable for
// does NOT produce a meaningful java signature, but does give a unique
// string suitable for
// comparison.
private String getParameterSigWithBoundsRemoved() {
if (myParameterSignatureWithBoundsRemoved != null)
@@ -908,15 +1036,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
StringBuffer sig = new StringBuffer();
UnresolvedType[] myParameterTypes = getGenericParameterTypes();
for (int i = 0; i < myParameterTypes.length; i++) {
appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet());
appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig,
new HashSet());
}
myParameterSignatureWithBoundsRemoved = sig.toString();
return myParameterSignatureWithBoundsRemoved;
}

/**
* Return the erased form of the signature with bounds collapsed for type variables, etc. Does not include the return type, @see
* getParam
* Return the erased form of the signature with bounds collapsed for type
* variables, etc. Does not include the return type, @see getParam
*/
public String getParameterSignatureErased() {
if (myParameterSignatureErasure != null)
@@ -945,9 +1074,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return sb.toString();
}

// does NOT produce a meaningful java signature, but does give a unique string suitable for
// does NOT produce a meaningful java signature, but does give a unique
// string suitable for
// comparison.
public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) {
public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType,
StringBuffer toBuffer, Set alreadyUsedTypeVars) {
if (aType.isTypeVariableReference()) {
TypeVariableReferenceType typeVariableRT = (TypeVariableReferenceType) aType;
// pr204505
@@ -955,14 +1086,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
toBuffer.append("...");
} else {
alreadyUsedTypeVars.add(aType);
appendSigWithTypeVarBoundsRemoved(typeVariableRT.getUpperBound(), toBuffer, alreadyUsedTypeVars);
appendSigWithTypeVarBoundsRemoved(typeVariableRT
.getUpperBound(), toBuffer, alreadyUsedTypeVars);
}
// toBuffer.append("T;");
} else if (aType.isParameterizedType()) {
toBuffer.append(aType.getRawType().getSignature());
toBuffer.append("<");
for (int i = 0; i < aType.getTypeParameters().length; i++) {
appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars);
appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i],
toBuffer, alreadyUsedTypeVars);
}
toBuffer.append(">;");
} else {
@@ -979,11 +1112,14 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// modifiers
int mods = modifiers;
if ((mods & 4096) > 0)
mods = mods - 4096; // remove synthetic (added in the ASM case but not in the BCEL case...)
mods = mods - 4096; // remove synthetic (added in the ASM case but
// not in the BCEL case...)
if ((mods & 512) > 0)
mods = mods - 512; // remove interface (added in the BCEL case but not in the ASM case...)
mods = mods - 512; // remove interface (added in the BCEL case but
// not in the ASM case...)
if ((mods & 131072) > 0)
mods = mods - 131072; // remove deprecated (added in the ASM case but not in the BCEL case...)
mods = mods - 131072; // remove deprecated (added in the ASM case
// but not in the BCEL case...)
String modsStr = Modifier.toString(mods);
if (modsStr.length() != 0)
r.append(modsStr).append("(" + mods + ")").append(" ");
@@ -1013,7 +1149,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
if (kind != FIELD) {
r.append("(");
UnresolvedType[] params = getGenericParameterTypes();
boolean parameterNamesExist = showParameterNames && parameterNames != null && parameterNames.length == params.length;
boolean parameterNamesExist = showParameterNames
&& parameterNames != null
&& parameterNames.length == params.length;
if (params.length != 0) {
for (int i = 0, len = params.length; i < len; i++) {
if (i > 0)
@@ -1028,7 +1166,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return r.toString();
}

// SECRETAPI - controlling whether parameter names come out in the debug string (for testing purposes)
// SECRETAPI - controlling whether parameter names come out in the debug
// string (for testing purposes)
public static boolean showParameterNames = true;

public String toGenericString() {
@@ -1085,14 +1224,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// check the declaring type!
return declaringType.getTypeVariableNamed(name);

// Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause
// Do generic aspects with ITDs that share type variables with the
// aspect and the target type and have their own tvars cause
// this to be messier?
}

public void evictWeavingState() {
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result...");
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
throw new UnsupportedOperationException(
"You should resolve this member and call getAnnotationOfType() on the result...");
}
}

+ 632
- 304
weaver/src/org/aspectj/weaver/ResolvedType.java
File diff suppressed because it is too large
View File


+ 139
- 0
weaver/src/org/aspectj/weaver/StandardAnnotation.java View File

@@ -0,0 +1,139 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
* This type represents the weavers abstraction of an annotation - it is not tied to any underlying BCI toolkit. The weaver actualy
* handles these through AnnotationX wrapper objects - until we start transforming the BCEL annotations into this form (expensive)
* or offer a clever visitor mechanism over the BCEL annotation stuff that builds these annotation types directly.
*
* @author AndyClement
*/
public class StandardAnnotation extends AbstractAnnotationAJ {

private final boolean isRuntimeVisible;

private List /* of AnnotationNVPair */nvPairs = null;

public StandardAnnotation(ResolvedType type, boolean isRuntimeVisible) {
super(type);
this.isRuntimeVisible = isRuntimeVisible;
}

/**
* {@inheritDoc}
*/
public boolean isRuntimeVisible() {
return isRuntimeVisible;
}

/**
* {@inheritDoc}
*/
public String stringify() {
StringBuffer sb = new StringBuffer();
sb.append("@").append(type.getClassName());
if (hasNameValuePairs()) {
sb.append("(");
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.stringify());
}
sb.append(")");
}
return sb.toString();
}

public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("ANNOTATION [" + getTypeSignature() + "] [" + (isRuntimeVisible ? "runtimeVisible" : "runtimeInvisible") + "] [");
if (nvPairs != null) {
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.toString());
if (iter.hasNext())
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}

/**
* {@inheritDoc}
*/
public boolean hasNamedValue(String n) {
if (nvPairs == null)
return false;
for (int i = 0; i < nvPairs.size(); i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair) nvPairs.get(i);
if (pair.getName().equals(n))
return true;
}
return false;
}

/**
* {@inheritDoc}
*/
public boolean hasNameValuePair(String n, String v) {
if (nvPairs == null)
return false;
for (int i = 0; i < nvPairs.size(); i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair) nvPairs.get(i);
if (pair.getName().equals(n)) {
if (pair.getValue().stringify().equals(v))
return true;
}
}
return false;
}

/**
* {@inheritDoc}
*/
public Set /* <String> */getTargets() {
if (!type.equals(UnresolvedType.AT_TARGET)) {
return Collections.EMPTY_SET;
}
AnnotationNameValuePair nvp = (AnnotationNameValuePair) nvPairs.get(0);
ArrayAnnotationValue aav = (ArrayAnnotationValue) nvp.getValue();
AnnotationValue[] avs = aav.getValues();
Set targets = new HashSet();
for (int i = 0; i < avs.length; i++) {
AnnotationValue value = avs[i];
targets.add(value.stringify());
}
return targets;
}

public List getNameValuePairs() {
return nvPairs;
}

public boolean hasNameValuePairs() {
return nvPairs != null && nvPairs.size() != 0;
}

public void addNameValuePair(AnnotationNameValuePair pair) {
if (nvPairs == null) {
nvPairs = new ArrayList();
}
nvPairs.add(pair);
}

}

+ 9
- 6
weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java View File

@@ -20,7 +20,7 @@ import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
@@ -45,16 +45,18 @@ class AnnotationAccessFieldVar extends BcelVar {
}

public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) {
// Only possible to do annotation field value extraction at MethodExecution
// Only possible to do annotation field value extraction at
// MethodExecution
if (annoAccessor.getKind() != Shadow.MethodExecution) {
return;
}
String annotationOfInterestSignature = annoAccessor.getType().getSignature();
// So we have an entity that has an annotation on and within it is the value we want
// So we have an entity that has an annotation on and within it is the
// value we want
Member holder = annoAccessor.getMember();
AnnotationX[] annos = holder.getAnnotations();
AnnotationAJ[] annos = holder.getAnnotations();
for (int i = 0; i < annos.length; i++) {
AnnotationGen annotation = annos[i].getBcelAnnotation();
AnnotationGen annotation = ((BcelAnnotation) annos[i]).getBcelAnnotation();
if (annotation.getTypeSignature().equals(annotationOfInterestSignature)) {
List vals = annotation.getValues();
boolean doneAndDusted = false;
@@ -76,7 +78,8 @@ class AnnotationAccessFieldVar extends BcelVar {
for (int ii = 0; ii < annotationFields.length; ii++) {
if (annotationFields[ii].getType().equals(annoFieldOfInterest)) {
String dvalue = annotationFields[ii].getAnnotationDefaultValue();
// form will be LBLAHBLAHBLAH;X where X is the field within X
// form will be LBLAHBLAHBLAH;X where X is the field
// within X
String typename = dvalue.substring(0, dvalue.lastIndexOf(';') + 1);
String field = dvalue.substring(dvalue.lastIndexOf(';') + 1);
ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(typename));

+ 107
- 0
weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java View File

@@ -0,0 +1,107 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* 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
*
* ******************************************************************/
package org.aspectj.weaver.bcel;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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.weaver.AbstractAnnotationAJ;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;

/**
* Wraps a Bcel Annotation object and uses it to answer AnnotationAJ method calls. This is cheaper than translating all Bcel
* annotations into AnnotationAJ objects.
*
* @author AndyClement
*/
public class BcelAnnotation extends AbstractAnnotationAJ {

private final AnnotationGen bcelAnnotation;

public BcelAnnotation(AnnotationGen theBcelAnnotation, World world) {
super(UnresolvedType.forSignature(theBcelAnnotation.getTypeSignature()).resolve(world));
this.bcelAnnotation = theBcelAnnotation;
}

/**
* {@inheritDoc}
*/
public Set /* of String */getTargets() {
if (!type.equals(UnresolvedType.AT_TARGET)) {
return Collections.EMPTY_SET;
}
List values = bcelAnnotation.getValues();
ElementNameValuePairGen envp = (ElementNameValuePairGen) values.get(0);
ArrayElementValueGen aev = (ArrayElementValueGen) envp.getValue();
ElementValueGen[] evs = aev.getElementValuesArray();
Set targets = new HashSet();
for (int i = 0; i < evs.length; i++) {
EnumElementValueGen ev = (EnumElementValueGen) evs[i];
targets.add(ev.getEnumValueString());
}
return targets;
}

/**
* {@inheritDoc}
*/
public boolean hasNameValuePair(String name, String value) {
return bcelAnnotation.hasNameValuePair(name, value);
}

/**
* {@inheritDoc}
*/
public boolean hasNamedValue(String name) {
return bcelAnnotation.hasNamedValue(name);
}

/**
* {@inheritDoc}
*/
public String stringify() {
StringBuffer sb = new StringBuffer();
sb.append("@").append(type.getClassName());
List values = bcelAnnotation.getValues();
if (values != null && values.size() != 0) {
sb.append("(");
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next();
sb.append(nvPair.getNameString()).append("=").append(nvPair.getValue().stringifyValue());
}
sb.append(")");
}
return sb.toString();
}

/**
* {@inheritDoc}
*/
public boolean isRuntimeVisible() {
return this.bcelAnnotation.isRuntimeVisible();
}

/**
* @return return the real bcel annotation being wrapped
*/
public AnnotationGen getBcelAnnotation() {
return bcelAnnotation;
}

}

+ 322
- 147
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
File diff suppressed because it is too large
View File


+ 11
- 11
weaver/src/org/aspectj/weaver/bcel/BcelField.java View File

@@ -26,7 +26,7 @@ import org.aspectj.apache.bcel.classfile.Synthetic;
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.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
@@ -42,7 +42,7 @@ final class BcelField extends ResolvedMemberImpl {
private Field field;
private boolean isAjSynthetic;
private boolean isSynthetic = false;
private AnnotationX[] annotations;
private AnnotationAJ[] annotations;
private World world;
private BcelObjectType bcelObjectType;
private UnresolvedType genericFieldType = null;
@@ -129,12 +129,12 @@ final class BcelField extends ResolvedMemberImpl {
return ret;
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
ensureAnnotationTypesRetrieved();
return annotations;
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationTypesRetrieved();
for (int i = 0; i < annotations.length; i++) {
if (annotations[i].getTypeName().equals(ofType.getName()))
@@ -148,24 +148,24 @@ final class BcelField extends ResolvedMemberImpl {
AnnotationGen annos[] = field.getAnnotations();
if (annos == null || annos.length == 0) {
annotationTypes = Collections.EMPTY_SET;
annotations = AnnotationX.NONE;
annotations = AnnotationAJ.EMPTY_ARRAY;
} else {
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
annotations = new AnnotationAJ[annos.length];
for (int i = 0; i < annos.length; i++) {
AnnotationGen annotation = annos[i];
annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())));
annotations[i] = new AnnotationX(annotation, world);
annotations[i] = new BcelAnnotation(annotation, world);
}
}
}
}

public void addAnnotation(AnnotationX annotation) {
public void addAnnotation(AnnotationAJ annotation) {
ensureAnnotationTypesRetrieved();
// Add it to the set of annotations
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len + 1];
AnnotationAJ[] ret = new AnnotationAJ[len + 1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
@@ -200,7 +200,7 @@ final class BcelField extends ResolvedMemberImpl {
AnnotationGen[] alreadyHas = fg.getAnnotations();
if (annotations != null) {
for (int i = 0; i < annotations.length; i++) {
AnnotationX array_element = annotations[i];
AnnotationAJ array_element = annotations[i];
boolean alreadyHasIt = false;
for (int j = 0; j < alreadyHas.length; j++) {
AnnotationGen gen = alreadyHas[j];
@@ -208,7 +208,7 @@ final class BcelField extends ResolvedMemberImpl {
alreadyHasIt = true;
}
if (!alreadyHasIt)
fg.addAnnotation(new AnnotationGen(array_element.getBcelAnnotation(), cpg, true));
fg.addAnnotation(new AnnotationGen(((BcelAnnotation) array_element).getBcelAnnotation(), cpg, true));
}
}
field = fg.getField();

+ 39
- 26
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java View File

@@ -37,7 +37,7 @@ 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.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberKind;
@@ -56,12 +56,15 @@ public final class BcelMethod extends ResolvedMemberImpl {

// these fields are not set for many BcelMethods...
private ShadowMunger associatedShadowMunger;
private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has pre-resolved the pointcut of some @Advice
private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has
// pre-resolved the
// pointcut of some
// @Advice
private AjAttribute.EffectiveSignatureAttribute effectiveSignature;

private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
private AnnotationX[] annotations = null;
private AnnotationX[][] parameterAnnotations = null;
private AnnotationAJ[] annotations = null;
private AnnotationAJ[][] parameterAnnotations = null;
private BcelObjectType bcelObjectType;

private int bitflags;
@@ -71,7 +74,9 @@ public final class BcelMethod extends ResolvedMemberImpl {
private static final int UNPACKED_GENERIC_SIGNATURE = 0x0008;
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 IS_SYNTHETIC_INVERSE = 0x7f7f; // all bits but
// IS_SYNTHETIC (and
// topmost bit)
private static final int HAS_ANNOTATIONS = 0x0400;
private static final int HAVE_DETERMINED_ANNOTATIONS = 0x0800;

@@ -123,15 +128,15 @@ public final class BcelMethod extends ResolvedMemberImpl {
if (varTable == null) {
// do we have an annotation with the argNames value specified...
if (hasAnnotations()) {
AnnotationX[] axs = getAnnotations();
AnnotationAJ[] axs = getAnnotations();
for (int i = 0; i < axs.length; i++) {
AnnotationX annotationX = axs[i];
AnnotationAJ annotationX = axs[i];
String typename = annotationX.getTypeName();
if (typename.equals("org.aspectj.lang.annotation.Pointcut")
|| typename.equals("org.aspectj.lang.annotation.Before")
|| typename.equals("org.aspectj.lang.annotation.Around")
|| typename.startsWith("org.aspectj.lang.annotation.After")) {
AnnotationGen a = annotationX.getBcelAnnotation();
AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
if (a != null) {
List values = a.getValues();
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
@@ -198,7 +203,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
// System.out.println("found effective: " + this);
effectiveSignature = (AjAttribute.EffectiveSignatureAttribute) a;
} else if (a instanceof AjAttribute.PointcutDeclarationAttribute) {
// this is an @AspectJ annotated advice method, with pointcut pre-resolved by ajc
// this is an @AspectJ annotated advice method, with pointcut
// pre-resolved by ajc
preResolvedPointcut = ((AjAttribute.PointcutDeclarationAttribute) a).reify();
} else {
throw new BCException("weird method attribute " + a);
@@ -206,7 +212,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
}
}

// for testing - if we have this attribute, return it - will return null if it doesnt know anything
// 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 = Utility.readAjAttributes(getDeclaringType().getClassName(), method.getAttributes(),
@@ -247,7 +254,10 @@ public final class BcelMethod extends ResolvedMemberImpl {
}

public boolean isAjSynthetic() {
return (bitflags & IS_AJ_SYNTHETIC) != 0;// isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
return (bitflags & IS_AJ_SYNTHETIC) != 0;// isAjSynthetic; // ||
// getName(
// ).startsWith(NameMangler
// .PREFIX);
}

// FIXME ??? needs an isSynthetic method
@@ -311,12 +321,12 @@ public final class BcelMethod extends ResolvedMemberImpl {
return false;
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
ensureAnnotationsRetrieved();
if ((bitflags & HAS_ANNOTATIONS) != 0) {
return annotations;
} else {
return AnnotationX.NONE;
return AnnotationAJ.EMPTY_ARRAY;
}
}

@@ -327,7 +337,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
return ret;
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationsRetrieved();
if ((bitflags & HAS_ANNOTATIONS) == 0)
return null;
@@ -338,15 +348,15 @@ public final class BcelMethod extends ResolvedMemberImpl {
return null;
}

public void addAnnotation(AnnotationX annotation) {
public void addAnnotation(AnnotationAJ annotation) {
ensureAnnotationsRetrieved();
if ((bitflags & HAS_ANNOTATIONS) == 0) {
annotations = new AnnotationX[1];
annotations = new AnnotationAJ[1];
annotations[0] = annotation;
} else {
// Add it to the set of annotations
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len + 1];
AnnotationAJ[] ret = new AnnotationAJ[len + 1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
@@ -357,7 +367,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
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
// 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());
}
@@ -372,11 +383,11 @@ public final class BcelMethod extends ResolvedMemberImpl {
AnnotationGen annos[] = method.getAnnotations();
if (annos.length != 0) {
annotationTypes = new HashSet();
annotations = new AnnotationX[annos.length];
annotations = new AnnotationAJ[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());
annotations[i] = new BcelAnnotation(annotation, bcelObjectType.getWorld());
}
bitflags |= HAS_ANNOTATIONS;
} else {
@@ -394,13 +405,13 @@ public final class BcelMethod extends ResolvedMemberImpl {
parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS;
} else {
AnnotationGen annos[][] = method.getParameterAnnotations();
parameterAnnotations = new AnnotationX[annos.length][];
parameterAnnotations = new AnnotationAJ[annos.length][];
parameterAnnotationTypes = new ResolvedType[annos.length][];
for (int i = 0; i < annos.length; i++) {
parameterAnnotations[i] = new AnnotationX[annos[i].length];
parameterAnnotations[i] = new AnnotationAJ[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], bcelObjectType.getWorld());
parameterAnnotations[i][j] = new BcelAnnotation(annos[i][j], bcelObjectType.getWorld());
parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(
UnresolvedType.forSignature(annos[i][j].getTypeSignature()));
}
@@ -409,7 +420,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
}
}

public AnnotationX[][] getParameterAnnotations() {
public AnnotationAJ[][] getParameterAnnotations() {
ensureParameterAnnotationsRetrieved();
return parameterAnnotations;
}
@@ -482,7 +493,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
Signature.FormalTypeParameter[] parentFormals = bcelObjectType.getAllFormals();
Signature.FormalTypeParameter[] formals = new Signature.FormalTypeParameter[parentFormals.length
+ mSig.formalTypeParameters.length];
// put method formal in front of type formals for overriding in lookup
// put method formal in front of type formals for overriding in
// lookup
System.arraycopy(mSig.formalTypeParameters, 0, formals, 0, mSig.formalTypeParameters.length);
System.arraycopy(parentFormals, 0, formals, mSig.formalTypeParameters.length, parentFormals.length);
Signature.TypeSignature returnTypeSignature = mSig.returnType;
@@ -534,7 +546,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
return (bitflags & IS_SYNTHETIC) != 0;// isSynthetic;
}

// Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a modifier (4096 or 0x1000)
// Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a
// modifier (4096 or 0x1000)
private void workOutIfSynthetic() {
if ((bitflags & KNOW_IF_SYNTHETIC) != 0)
return;

+ 67
- 35
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java View File

@@ -37,8 +37,8 @@ import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.AbstractReferenceTypeDelegate;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.AnnotationAJ;
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;
@@ -73,7 +73,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
private ResolvedMember[] fields = null;
private ResolvedMember[] methods = null;
private ResolvedType[] annotationTypes = null;
private AnnotationX[] annotations = null;
private AnnotationAJ[] annotations = null;
private TypeVariable[] typeVars = null;
private String retentionPolicy;
private AnnotationTargetKind[] annotationTargetKinds;
@@ -99,14 +99,16 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
private boolean isNested;
private boolean isObject = false; // set upon construction
private boolean isAnnotationStyleAspect = false;// set upon construction
private boolean isCodeStyleAspect = false; // not redundant with field above!
private boolean isCodeStyleAspect = false; // not redundant with field
// above!

private int bitflag = 0x0000;

// discovery bits
private static final int DISCOVERED_ANNOTATION_RETENTION_POLICY = 0x0001;
private static final int UNPACKED_GENERIC_SIGNATURE = 0x0002;
private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) below
private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1)
// below
private static final int DISCOVERED_ANNOTATION_TARGET_KINDS = 0x0008;
private static final int DISCOVERED_DECLARED_SIGNATURE = 0x0010;
private static final int DISCOVERED_WHETHER_ANNOTATION_STYLE = 0x0020;
@@ -128,7 +130,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
this.javaClass = javaClass;
initializeFromJavaclass();

// ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup
// ATAJ: set the delegate right now for @AJ pointcut, else it is done
// too late to lookup
// @AJ pc refs annotation in class hierarchy
resolvedTypeX.setDelegate(this);

@@ -143,7 +146,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
isObject = (javaClass.getSuperclassNameIndex() == 0);
ensureAspectJAttributesUnpacked();
// if (sourceContext instanceof SourceContextImpl) {
// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName());
// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.
// getSourceFileName());
// }
setSourcefilename(javaClass.getSourceFileName());
}
@@ -274,7 +278,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return TypeVariable.NONE;

if (typeVars == null) {
Signature.ClassSignature classSig = getGenericClassTypeSignature();// cachedGenericClassTypeSignature;//javaClass.
Signature.ClassSignature classSig = getGenericClassTypeSignature();// cachedGenericClassTypeSignature
// ;
// /
// /
// javaClass
// .
// getGenericClassTypeSignature();
typeVars = new TypeVariable[classSig.formalTypeParameters.length];
for (int i = 0; i < typeVars.length; i++) {
@@ -398,7 +407,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
setSourcefilename(sca.getSourceFileName());
}
} else if (a instanceof AjAttribute.WeaverVersionInfo) {
wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver version used to build this type
wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver
// version used to
// build this type
} else {
throw new BCException("bad attribute " + a);
}
@@ -444,7 +455,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
public void resetState() {
if (javaClass == null) {
// we might store the classname and allow reloading?
// At this point we are relying on the world to not evict if it might want to reweave multiple times
// At this point we are relying on the world to not evict if it
// might want to reweave multiple times
throw new BCException("can't weave evicted type");
}

@@ -478,7 +490,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// this.perClause = null;
// this.weaverState = null;
// this.lazyClassGen = null;
// this next line frees up memory, but need to understand incremental implications
// this next line frees up memory, but need to understand incremental
// implications
// before leaving it in.
// getResolvedTypeX().setSourceContext(null);
}
@@ -508,7 +521,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// System.err.println("creating lazy class gen for: " + this);
ret = new LazyClassGen(this);
// ret.print(System.err);
// System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName );
// System.err.println("made LCG from : " +
// this.getJavaClass().getSuperclassName );
if (isAspect()) {
lazyClassGen = ret;
}
@@ -549,7 +563,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
interfaceSignatures = newInterfaceSignatures;
}
}
// System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName);
// System.err.println("javaClass: " +
// Arrays.asList(javaClass.getInterfaceNames()) + " super " +
// superclassName);
// if (lazyClassGen != null) lazyClassGen.print();
}

@@ -560,7 +576,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
return annotationTypes;
}

public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
ensureAnnotationsUnpacked();
return annotations;
}
@@ -576,10 +592,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
}

// evil mutator - adding state not stored in the java class
public void addAnnotation(AnnotationX annotation) {
public void addAnnotation(AnnotationAJ annotation) {
bitflag |= DAMAGED;
int len = annotations.length;
AnnotationX[] ret = new AnnotationX[len + 1];
AnnotationAJ[] ret = new AnnotationAJ[len + 1];
System.arraycopy(annotations, 0, ret, 0, len);
ret[len] = annotation;
annotations = ret;
@@ -602,9 +618,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if (isAnnotation()) {
ensureAnnotationsUnpacked();
for (int i = annotations.length - 1; i >= 0; i--) {
AnnotationX ax = annotations[i];
AnnotationAJ ax = annotations[i];
if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) {
List values = ax.getBcelAnnotation().getValues();
List values = ((BcelAnnotation) ax).getBcelAnnotation().getValues();
for (Iterator it = values.iterator(); it.hasNext();) {
ElementNameValuePairGen element = (ElementNameValuePairGen) it.next();
EnumElementValueGen v = (EnumElementValueGen) element.getValue();
@@ -634,7 +650,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if ((bitflag & DISCOVERED_ANNOTATION_TARGET_KINDS) != 0)
return annotationTargetKinds;
bitflag |= DISCOVERED_ANNOTATION_TARGET_KINDS;
annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used
annotationTargetKinds = null; // null means we have no idea or the
// @Target annotation hasn't been used
List targetKinds = new ArrayList();
if (isAnnotation()) {
AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations();
@@ -683,15 +700,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
AnnotationGen annos[] = javaClass.getAnnotations();
if (annos == null || annos.length == 0) {
annotationTypes = ResolvedType.NONE;
annotations = AnnotationX.NONE;
annotations = AnnotationAJ.EMPTY_ARRAY;
} else {
World w = getResolvedTypeX().getWorld();
annotationTypes = new ResolvedType[annos.length];
annotations = new AnnotationX[annos.length];
annotations = new AnnotationAJ[annos.length];
for (int i = 0; i < annos.length; i++) {
AnnotationGen annotation = annos[i];
annotationTypes[i] = w.resolve(UnresolvedType.forSignature(annotation.getTypeSignature()));
annotations[i] = new AnnotationX(annotation, w);
annotations[i] = new BcelAnnotation(annotation, w);
}
}
}
@@ -714,7 +731,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if (cSig != null) {
formalsForResolution = cSig.formalTypeParameters;
if (isNested()) {
// we have to find any type variables from the outer type before proceeding with resolution.
// we have to find any type variables from the outer type before
// proceeding with resolution.
Signature.FormalTypeParameter[] extraFormals = getFormalTypeParametersFromOuterClass();
if (extraFormals.length > 0) {
List allFormals = new ArrayList();
@@ -732,7 +750,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
try {
// this.superClass =
// BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(
// superSig, formalsForResolution, getResolvedTypeX().getWorld());
// superSig, formalsForResolution,
// getResolvedTypeX().getWorld());

ResolvedType rt = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(superSig, formalsForResolution,
getResolvedTypeX().getWorld());
@@ -745,7 +764,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
+ " with generic signature " + getDeclaredGenericSignature() + " the following error was detected: "
+ e.getMessage());
}
// this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length];
// this.interfaces = new
// ResolvedType[cSig.superInterfaceSignatures.length];
if (cSig.superInterfaceSignatures.length == 0) {
this.interfaceSignatures = NO_INTERFACE_SIGS;
} else {
@@ -753,7 +773,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
for (int i = 0; i < cSig.superInterfaceSignatures.length; i++) {
try {
// this.interfaces[i] =
// BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(
// BcelGenericSignatureToTypeXConverter.
// classTypeSignature2TypeX(
// cSig.superInterfaceSignatures[i],
// formalsForResolution,
// getResolvedTypeX().getWorld());
@@ -772,7 +793,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
if (isGeneric()) {
// update resolved typex to point at generic type not raw type.
ReferenceType genericType = (ReferenceType) this.resolvedTypeX.getGenericType();
// genericType.setSourceContext(this.resolvedTypeX.getSourceContext());
// genericType.setSourceContext(this.resolvedTypeX.getSourceContext()
// );
genericType.setStartPos(this.resolvedTypeX.getStartPos());
this.resolvedTypeX = genericType;
}
@@ -830,9 +852,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
getDeclaredInterfaces();
getDeclaredFields();
getDeclaredMethods();
// The lazyClassGen is preserved for aspects - it exists to enable around advice
// inlining since the method will need 'injecting' into the affected class. If
// XnoInline is on, we can chuck away the lazyClassGen since it won't be required
// The lazyClassGen is preserved for aspects - it exists to enable
// around advice
// inlining since the method will need 'injecting' into the affected
// class. If
// XnoInline is on, we can chuck away the lazyClassGen since it
// won't be required
// later.
if (getResolvedTypeX().getWorld().isXnoInline())
lazyClassGen = null;
@@ -847,8 +872,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
for (int i = fields.length - 1; i >= 0; i--)
fields[i].evictWeavingState();
javaClass = null;
// setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty
// interfaces=null; // force reinit - may get us the right instances!
// setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); //
// bit naughty
// interfaces=null; // force reinit - may get us the right
// instances!
// superClass=null;
}
}
@@ -863,11 +890,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {

// --- methods for testing

// for testing - if we have this attribute, return it - will return null if it doesnt know anything
// 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(javaClass.getClassName(),javaClass.getAttributes(),
// getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),AjAttribute.WeaverVersionInfo.UNKNOWN);
// List l =
// BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass
// .getAttributes(),
// getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),
// AjAttribute.WeaverVersionInfo.UNKNOWN);
// for (Iterator iter = l.iterator(); iter.hasNext();) {
// AjAttribute element = (AjAttribute) iter.next();
// if (element.getNameString().equals(name)) results.add(element);
@@ -878,7 +909,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// return null;
// }
//
// // for testing - use with the method above - this returns *all* including those that are not Aj attributes
// // for testing - use with the method above - this returns *all* including
// those that are not Aj attributes
// public String[] getAttributeNames() {
// Attribute[] as = javaClass.getAttributes();
// String[] strs = new String[as.length];

+ 1233
- 1218
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
File diff suppressed because it is too large
View File


+ 553
- 261
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
File diff suppressed because it is too large
View File


+ 132
- 71
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java View File

@@ -41,8 +41,8 @@ import org.aspectj.apache.bcel.util.Repository;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.AnnotationOnTypeMunger;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ICrossReferenceHandler;
@@ -75,7 +75,8 @@ public class BcelWorld extends World implements Repository {
// private ClassPathManager aspectPath = null;
// private List aspectPathEntries;

private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class);
private static Trace trace = TraceFactory.getTraceFactory().getTrace(
BcelWorld.class);

// ---- constructors

@@ -106,7 +107,8 @@ public class BcelWorld extends World implements Repository {
return ret;
}

public BcelWorld(List classPath, IMessageHandler handler, ICrossReferenceHandler xrefHandler) {
public BcelWorld(List classPath, IMessageHandler handler,
ICrossReferenceHandler xrefHandler) {
// this.aspectPath = new ClassPathManager(aspectPath, handler);
this.classPath = new ClassPathManager(classPath, handler);
setMessageHandler(handler);
@@ -115,7 +117,8 @@ public class BcelWorld extends World implements Repository {
delegate = this;
}

public BcelWorld(ClassPathManager cpm, IMessageHandler handler, ICrossReferenceHandler xrefHandler) {
public BcelWorld(ClassPathManager cpm, IMessageHandler handler,
ICrossReferenceHandler xrefHandler) {
this.classPath = cpm;
setMessageHandler(handler);
setCrossReferenceHandler(xrefHandler);
@@ -130,7 +133,8 @@ public class BcelWorld extends World implements Repository {
* @param handler
* @param xrefHandler
*/
public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) {
public BcelWorld(ClassLoader loader, IMessageHandler handler,
ICrossReferenceHandler xrefHandler) {
this.classPath = null;
this.loaderRef = new WeakClassLoaderReference(loader);
setMessageHandler(handler);
@@ -206,8 +210,10 @@ public class BcelWorld extends World implements Repository {
}
}

public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) {
BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver);
public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX,
JavaClass jc, boolean exposedToWeaver) {
BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc,
exposedToWeaver);
return ret;
}

@@ -217,21 +223,25 @@ public class BcelWorld extends World implements Repository {
ensureRepositorySetup();
JavaClass jc = delegate.loadClass(name);
if (trace.isTraceEnabled())
trace.event("lookupJavaClass", this, new Object[] { name, jc });
trace.event("lookupJavaClass", this, new Object[] { name,
jc });
return jc;
} catch (ClassNotFoundException e) {
if (trace.isTraceEnabled())
trace.error("Unable to find class '" + name + "' in repository", e);
trace.error("Unable to find class '" + name
+ "' in repository", e);
return null;
}
}

try {
ClassPathManager.ClassFile file = classPath.find(UnresolvedType.forName(name));
ClassPathManager.ClassFile file = classPath.find(UnresolvedType
.forName(name));
if (file == null)
return null;

ClassParser parser = new ClassParser(file.getInputStream(), file.getPath());
ClassParser parser = new ClassParser(file.getInputStream(), file
.getPath());

JavaClass jc = parser.parse();
file.close();
@@ -243,15 +253,18 @@ public class BcelWorld extends World implements Repository {

public BcelObjectType addSourceObjectType(JavaClass jc) {
BcelObjectType ret = null;
String signature = UnresolvedType.forName(jc.getClassName()).getSignature();
String signature = UnresolvedType.forName(jc.getClassName())
.getSignature();

Object fromTheMap = typeMap.get(signature);

if (fromTheMap != null && !(fromTheMap instanceof ReferenceType)) {
// what on earth is it then? See pr 112243
StringBuffer exceptionText = new StringBuffer();
exceptionText.append("Found invalid (not a ReferenceType) entry in the type map. ");
exceptionText.append("Signature=[" + signature + "] Found=[" + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]");
exceptionText
.append("Found invalid (not a ReferenceType) entry in the type map. ");
exceptionText.append("Signature=[" + signature + "] Found=["
+ fromTheMap + "] Class=[" + fromTheMap.getClass() + "]");
throw new BCException(exceptionText.toString());
}

@@ -260,10 +273,12 @@ public class BcelWorld extends World implements Repository {
if (nameTypeX == null) {
if (jc.isGeneric() && isInJava5Mode()) {

nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()), this);
nameTypeX = ReferenceType.fromTypeX(UnresolvedType
.forRawTypeName(jc.getClassName()), this);
ret = buildBcelDelegate(nameTypeX, jc, true);
ReferenceType genericRefType = new ReferenceType(UnresolvedType.forGenericTypeSignature(signature, ret
.getDeclaredGenericSignature()), this);
ReferenceType genericRefType = new ReferenceType(UnresolvedType
.forGenericTypeSignature(signature, ret
.getDeclaredGenericSignature()), this);
nameTypeX.setDelegate(ret);
genericRefType.setDelegate(ret);
nameTypeX.setGenericType(genericRefType);
@@ -283,21 +298,26 @@ public class BcelWorld extends World implements Repository {
typeMap.remove(ty.getSignature());
}

public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) {
public static Member makeFieldJoinPointSignature(LazyClassGen cg,
FieldInstruction fi) {
ConstantPool cpg = cg.getConstantPool();
return MemberImpl.field(fi.getClassName(cpg),
(fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC : 0, fi.getName(cpg), fi
.getSignature(cpg));
return MemberImpl
.field(
fi.getClassName(cpg),
(fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC
: 0, fi.getName(cpg), fi.getSignature(cpg));
}

public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) {
public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg,
MemberKind kind) {
Member ret = mg.getMemberView();
if (ret == null) {
int mods = mg.getAccessFlags();
if (mg.getEnclosingClass().isInterface()) {
mods |= Modifier.INTERFACE;
}
return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg.getClassName()), mods, fromBcel(mg.getReturnType()), mg
return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg
.getClassName()), mods, fromBcel(mg.getReturnType()), mg
.getName(), fromBcel(mg.getArgumentTypes()));
} else {
return ret;
@@ -305,15 +325,18 @@ public class BcelWorld extends World implements Repository {

}

public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, InstructionHandle h) {
public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,
InstructionHandle h) {
return MemberImpl.monitorEnter();
}

public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, InstructionHandle h) {
public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,
InstructionHandle h) {
return MemberImpl.monitorExit();
}

public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) {
public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg,
InstructionHandle handle) {
Instruction i = handle.getInstruction();
ConstantPool cpg = cg.getConstantPool();
Member retval = null;
@@ -323,7 +346,8 @@ public class BcelWorld extends World implements Repository {
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 });
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID,
"<init>", new ResolvedType[] { ResolvedType.INT });
} else if (i instanceof MULTIANEWARRAY) {
MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i;
UnresolvedType ut = null;
@@ -339,20 +363,25 @@ public class BcelWorld extends World implements Repository {
ResolvedType[] parms = new ResolvedType[dimensions];
for (int ii = 0; ii < dimensions; ii++)
parms[ii] = ResolvedType.INT;
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", parms);
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID,
"<init>", parms);

} 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 });
retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID,
"<init>", new ResolvedType[] { ResolvedType.INT });
} else {
throw new BCException("Cannot create array construction signature for this non-array instruction:" + i);
throw new BCException(
"Cannot create array construction signature for this non-array instruction:"
+ i);
}
return retval;
}

public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) {
public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg,
InvokeInstruction ii) {
ConstantPool cpg = cg.getConstantPool();
String name = ii.getName(cpg);
String declaring = ii.getClassName(cpg);
@@ -361,19 +390,23 @@ public class BcelWorld extends World implements Repository {
String signature = ii.getSignature(cpg);

int modifier = (ii instanceof INVOKEINTERFACE) ? Modifier.INTERFACE
: (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC : (ii.opcode == Constants.INVOKESPECIAL && !name
.equals("<init>")) ? Modifier.PRIVATE : 0;
: (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC
: (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
// 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.opcode == Constants.INVOKESTATIC) {
ResolvedType appearsDeclaredBy = resolve(declaring);
// look for the method there
for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) {
for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator
.hasNext();) {
ResolvedMember method = (ResolvedMember) iterator.next();
if (method.isStatic()) {
if (name.equals(method.getName()) && signature.equals(method.getSignature())) {
if (name.equals(method.getName())
&& signature.equals(method.getSignature())) {
// we found it
declaringType = method.getDeclaringType();
break;
@@ -400,12 +433,15 @@ public class BcelWorld extends World implements Repository {
return buf.toString();
}

public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) {
// System.err.println("concrete advice: " + signature + " context " + sourceContext);
public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute,
Pointcut pointcut, Member signature) {
// System.err.println("concrete advice: " + signature + " context " +
// sourceContext);
return new BcelAdvice(attribute, pointcut, signature, null);
}

public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger,
ResolvedType aspectType) {
return new BcelTypeMunger(munger, aspectType);
}

@@ -413,27 +449,32 @@ public class BcelWorld extends World implements Repository {
return new BcelCflowStackFieldAdder(cflowField);
}

public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) {
public ConcreteTypeMunger makeCflowCounterFieldAdder(
ResolvedMember cflowField) {
return new BcelCflowCounterFieldAdder(cflowField);
}

/**
* Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed
* Register a munger for perclause @AJ aspect so that we add aspectOf(..) to
* them as needed
*
* @param aspect
* @param kind
* @return munger
*/
public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) {
public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect,
PerClause.Kind kind) {
return new BcelPerClauseAspectAdder(aspect, kind);
}

/**
* Retrieve a bcel delegate for an aspect - this will return NULL if the delegate is an EclipseSourceType and not a
* BcelObjectType - this happens quite often when incrementally compiling.
* Retrieve a bcel delegate for an aspect - this will return NULL if the
* delegate is an EclipseSourceType and not a BcelObjectType - this happens
* quite often when incrementally compiling.
*/
public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) {
ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect).getDelegate();
ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect)
.getDelegate();
if (rtDelegate instanceof BcelObjectType) {
return (BcelObjectType) rtDelegate;
} else {
@@ -442,7 +483,8 @@ public class BcelWorld extends World implements Repository {
}

public void tidyUp() {
// At end of compile, close any open files so deletion of those archives is possible
// At end of compile, close any open files so deletion of those archives
// is possible
classPath.closeArchives();
typeMap.report();
ResolvedType.resetPrimitives();
@@ -477,8 +519,9 @@ public class BcelWorld extends World implements Repository {

// @Override
/**
* The aim of this method is to make sure a particular type is 'ok'. Some operations on the delegate for a type modify it and
* this method is intended to undo that... see pr85132
* The aim of this method is to make sure a particular type is 'ok'. Some
* operations on the delegate for a type modify it and this method is
* intended to undo that... see pr85132
*/
public void validateType(UnresolvedType type) {
ResolvedType result = typeMap.get(type.getSignature());
@@ -489,7 +532,8 @@ public class BcelWorld extends World implements Repository {
ReferenceType rt = (ReferenceType) result;
rt.getDelegate().ensureDelegateConsistent();
// If we want to rebuild it 'from scratch' then:
// ClassParser cp = new ClassParser(new ByteArrayInputStream(newbytes),new String(cs));
// ClassParser cp = new ClassParser(new
// ByteArrayInputStream(newbytes),new String(cs));
// try {
// rt.setDelegate(makeBcelObjectType(rt,cp.parse(),true));
// } catch (ClassFormatException e) {
@@ -512,14 +556,19 @@ public class BcelWorld extends World implements Repository {
for (Iterator j = newParents.iterator(); j.hasNext();) {
ResolvedType newParent = (ResolvedType) j.next();

// We set it here so that the imminent matching for ITDs can succeed - we
// still haven't done the necessary changes to the class file itself
// (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent()
// We set it here so that the imminent matching for ITDs can
// succeed - we
// still haven't done the necessary changes to the class file
// itself
// (like transform super calls) - that is done in
// BcelTypeMunger.mungeNewParent()
classType.addParent(newParent);
ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent);
ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(
newParent);
newParentMunger.setSourceLocation(p.getSourceLocation());
onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, getCrosscuttingMembersSet()
.findAspectDeclaringParents(p)));
onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger,
getCrosscuttingMembersSet().findAspectDeclaringParents(
p)));
}
}
return didSomething;
@@ -528,25 +577,28 @@ public class BcelWorld extends World implements Repository {
/**
* Apply a declare @type - return true if we change the type
*/
private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType, boolean reportProblems) {
private boolean applyDeclareAtType(DeclareAnnotation decA,
ResolvedType onType, boolean reportProblems) {
boolean didSomething = false;
if (decA.matches(onType)) {

if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) {
if (onType.hasAnnotation(decA.getAnnotationX().getType())) {
// already has it
return false;
}

AnnotationX annoX = decA.getAnnotationX();
AnnotationAJ annoX = decA.getAnnotationX();

// check the annotation is suitable for the target
boolean isOK = checkTargetOK(decA, onType, annoX);

if (isOK) {
didSomething = true;
ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX);
ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(
annoX);
newAnnotationTM.setSourceLocation(decA.getSourceLocation());
onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(this)));
onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM,
decA.getAspect().resolve(this)));
decA.copyAnnotationTo(onType);
}
}
@@ -554,23 +606,28 @@ public class BcelWorld extends World implements Repository {
}

/**
* Checks for an @target() on the annotation and if found ensures it allows the annotation to be attached to the target type
* that matched.
* Checks for an @target() on the annotation and if found ensures it allows
* the annotation to be attached to the target type that matched.
*/
private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX) {
private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType,
AnnotationAJ annoX) {
if (annoX.specifiesTarget()) {
if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) {
if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType())
|| (!annoX.allowedOnRegularType())) {
return false;
}
}
return true;
}

// Hmmm - very similar to the code in BcelWeaver.weaveParentTypeMungers - this code
// doesn't need to produce errors/warnings though as it won't really be weaving.
// Hmmm - very similar to the code in BcelWeaver.weaveParentTypeMungers -
// this code
// doesn't need to produce errors/warnings though as it won't really be
// weaving.
protected void weaveInterTypeDeclarations(ResolvedType onType) {

List declareParentsList = getCrosscuttingMembersSet().getDeclareParents();
List declareParentsList = getCrosscuttingMembersSet()
.getDeclareParents();
if (onType.isRawType())
onType = onType.getGenericType();
onType.clearInterTypeMungers();
@@ -585,14 +642,16 @@ public class BcelWorld extends World implements Repository {
boolean typeChanged = applyDeclareParents(decp, onType);
if (typeChanged) {
aParentChangeOccurred = true;
} else { // Perhaps it would have matched if a 'dec @type' had modified the type
} else { // Perhaps it would have matched if a 'dec @type' had
// modified the type
if (!decp.getChild().isStarAnnotation())
decpToRepeat.add(decp);
}
}

// Still first pass - apply all dec @type mungers
for (Iterator i = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); i.hasNext();) {
for (Iterator i = getCrosscuttingMembersSet()
.getDeclareAnnotationOnTypes().iterator(); i.hasNext();) {
DeclareAnnotation decA = (DeclareAnnotation) i.next();
boolean typeChanged = applyDeclareAtType(decA, onType, true);
if (typeChanged) {
@@ -600,7 +659,8 @@ public class BcelWorld extends World implements Repository {
}
}

while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) {
while ((aParentChangeOccurred || anAnnotationChangeOccurred)
&& !decpToRepeat.isEmpty()) {
anAnnotationChangeOccurred = aParentChangeOccurred = false;
List decpToRepeatNextTime = new ArrayList();
for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) {
@@ -613,7 +673,8 @@ public class BcelWorld extends World implements Repository {
}
}

for (Iterator iter = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) {
for (Iterator iter = getCrosscuttingMembersSet()
.getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) {
DeclareAnnotation decA = (DeclareAnnotation) iter.next();
boolean typeChanged = applyDeclareAtType(decA, onType, false);
if (typeChanged) {

+ 108
- 55
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java View File

@@ -51,7 +51,7 @@ import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberImpl;
@@ -134,8 +134,10 @@ public final class LazyMethodGen implements Traceable {

public LazyMethodGen(int accessFlags, Type returnType, String name, Type[] paramTypes, String[] declaredExceptions,
LazyClassGen enclosingClass) {
// System.err.println("raw create of: " + name + ", " + enclosingClass.getName() + ", " + returnType);
this.memberView = null; // ??? should be okay, since constructed ones aren't woven into
// System.err.println("raw create of: " + name + ", " +
// enclosingClass.getName() + ", " + returnType);
this.memberView = null; // ??? should be okay, since constructed ones
// aren't woven into
this.accessFlags = accessFlags;
this.returnType = returnType;
this.name = name;
@@ -154,8 +156,10 @@ public final class LazyMethodGen implements Traceable {

// @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
// 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()) {
@@ -177,7 +181,8 @@ public final class LazyMethodGen implements Traceable {

private Method savedMethod = null;

// build from an existing method, lazy build saves most work for initialization
// build from an existing method, lazy build saves most work for
// initialization
public LazyMethodGen(Method m, LazyClassGen enclosingClass) {
savedMethod = m;

@@ -195,8 +200,10 @@ public final class LazyMethodGen implements Traceable {

// @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
// 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()) {
@@ -215,15 +222,18 @@ public final class LazyMethodGen implements Traceable {
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 = 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
// 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
// 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()) {
@@ -254,7 +264,7 @@ public final class LazyMethodGen implements Traceable {
}
}

public void addAnnotation(AnnotationX ax) {
public void addAnnotation(AnnotationAJ ax) {
initialize();
if (memberView == null) {
// If member view is null, we manage them in newAnnotations
@@ -272,9 +282,10 @@ public final class LazyMethodGen implements Traceable {
// Check local annotations first
if (newAnnotations != null) {
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) {
AnnotationX element = (AnnotationX) iter.next();
if (element.getBcelAnnotation().getTypeName().equals(annotationTypeX.getName()))
AnnotationAJ element = (AnnotationAJ) iter.next();
if (element.getTypeSignature().equals(annotationTypeX.getSignature())) {
return true;
}
}
}
memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod());
@@ -287,7 +298,8 @@ public final class LazyMethodGen implements Traceable {
if (returnType != null)
return;

// System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " +
// System.err.println("initializing: " + getName() + ", " +
// enclosingClass.getName() + ", " + returnType + ", " +
// savedMethod);

MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(), true);
@@ -301,9 +313,12 @@ public final class LazyMethodGen implements Traceable {
this.maxLocals = gen.getMaxLocals();

// this.returnType = BcelWorld.makeBcelType(memberView.getReturnType());
// this.argumentTypes = BcelWorld.makeBcelTypes(memberView.getParameterTypes());
// this.argumentTypes =
// BcelWorld.makeBcelTypes(memberView.getParameterTypes());
//
// this.declaredExceptions = UnresolvedType.getNames(memberView.getExceptions()); //gen.getExceptions();
// this.declaredExceptions =
// UnresolvedType.getNames(memberView.getExceptions());
// //gen.getExceptions();
// this.attributes = new Attribute[0]; //gen.getAttributes();
// this.maxLocals = savedMethod.getCode().getMaxLocals();

@@ -321,13 +336,17 @@ public final class LazyMethodGen implements Traceable {
}
assertGoodBody();

// System.err.println("initialized: " + this.getClassName() + "." + this.getName());
// System.err.println("initialized: " + this.getClassName() + "." +
// this.getName());
}

// XXX we're relying on the javac promise I've just made up that we won't have an early exception
// XXX we're relying on the javac promise I've just made up that we won't
// have an early exception
// in the list mask a later exception: That is, for two exceptions E and F,
// if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So when we add F,
// we add it on the _OUTSIDE_ of any handlers that share starts or ends with it.
// if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So
// when we add F,
// we add it on the _OUTSIDE_ of any handlers that share starts or ends with
// it.

// with that in mind, we merrily go adding ranges for exceptions.

@@ -412,7 +431,8 @@ public final class LazyMethodGen implements Traceable {

public Method getMethod() {
if (savedMethod != null)
return savedMethod; // ??? this relies on gentle treatment of constant pool
return savedMethod; // ??? this relies on gentle treatment of
// constant pool

try {
MethodGen gen = pack();
@@ -423,7 +443,8 @@ public final class LazyMethodGen implements Traceable {
IMessage.ERROR,
WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(), this.getName(), e
.getMessage()), this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null);
// throw e; PR 70201.... let the normal problem reporting infrastructure deal with this rather than crashing.
// throw e; PR 70201.... let the normal problem reporting
// infrastructure deal with this rather than crashing.
body = null;
MethodGen gen = pack();
return gen.getMethod();
@@ -517,7 +538,8 @@ public final class LazyMethodGen implements Traceable {
List as = Utility.readAjAttributes(getClassName(), (Attribute[]) attributes.toArray(new Attribute[] {}), context, null,
weaverVersion);
if (!as.isEmpty()) {
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger...
out.println(" " + as.get(0)); // XXX assuming exactly one
// attribute, munger...
}
}

@@ -555,7 +577,11 @@ public final class LazyMethodGen implements Traceable {
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
Iterator tIter = ih.getTargeters().iterator();
while (tIter.hasNext()) {
InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters[i];
InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters
// [
// i
// ]
// ;
if (t instanceof ExceptionRange) {
// assert isRangeHandle(h);
ExceptionRange r = (ExceptionRange) t;
@@ -594,13 +620,15 @@ public final class LazyMethodGen implements Traceable {
bodyPrint: for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
if (Range.isRangeHandle(ih)) {
Range r = Range.getRange(ih);
// don't print empty ranges, that is, ranges who contain no actual instructions
// don't print empty ranges, that is, ranges who contain no
// actual instructions
for (InstructionHandle xx = r.getStart(); Range.isRangeHandle(xx); xx = xx.getNext()) {
if (xx == r.getEnd())
continue bodyPrint;
}

// doesn't handle nested: if (r.getStart().getNext() == r.getEnd()) continue;
// doesn't handle nested: if (r.getStart().getNext() ==
// r.getEnd()) continue;
if (r.getStart() == ih) {
printRangeString(r, depth++);
} else {
@@ -691,7 +719,8 @@ public final class LazyMethodGen implements Traceable {
out.print(" ");
out.print(labelMap.get(brinst.getTarget()));
} else if (inst.isLocalVariableInstruction()) {
// LocalVariableInstruction lvinst = (LocalVariableInstruction) inst;
// LocalVariableInstruction lvinst = (LocalVariableInstruction)
// inst;
out.print(inst.toString(false).toUpperCase());
int index = inst.getIndex();
LocalVariableTag tag = getLocalVariableTag(h, index);
@@ -864,15 +893,15 @@ public final class LazyMethodGen implements Traceable {

if (newAnnotations != null) {
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) {
AnnotationX element = (AnnotationX) iter.next();
gen.addAnnotation(new AnnotationGen(element.getBcelAnnotation(), gen.getConstantPool(), true));
AnnotationAJ element = (AnnotationAJ) iter.next();
gen.addAnnotation(new AnnotationGen(((BcelAnnotation)element).getBcelAnnotation(), gen.getConstantPool(), true));
}
}

if (memberView != null && memberView.getAnnotations() != null && memberView.getAnnotations().length != 0) {
AnnotationX[] ans = memberView.getAnnotations();
AnnotationAJ[] ans = memberView.getAnnotations();
for (int i = 0, len = ans.length; i < len; i++) {
AnnotationGen a = ans[i].getBcelAnnotation();
AnnotationGen a = ((BcelAnnotation) ans[i]).getBcelAnnotation();
gen.addAnnotation(new AnnotationGen(a, gen.getConstantPool(), true));
}
}
@@ -881,7 +910,8 @@ public final class LazyMethodGen implements Traceable {
if (enclosingClass.getWorld().isInJava5Mode()) {
gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC);
}
// belt and braces, do the attribute even on Java 5 in addition to the modifier flag
// belt and braces, do the attribute even on Java 5 in addition to
// the modifier flag
ConstantPool cpg = gen.getConstantPool();
int index = cpg.addUtf8("Synthetic");
gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg));
@@ -950,7 +980,8 @@ public final class LazyMethodGen implements Traceable {

while (oldInstructionHandle != null) {
if (map.get(oldInstructionHandle) == null) {
// must be a range instruction since they're the only things we didn't copy across
// must be a range instruction since they're the only things we
// didn't copy across
handleRangeInstruction(oldInstructionHandle, exceptionList);
// just increment ih.
oldInstructionHandle = oldInstructionHandle.getNext();
@@ -977,7 +1008,8 @@ public final class LazyMethodGen implements Traceable {
} else if (targeter instanceof LocalVariableTag) {
LocalVariableTag lvt = (LocalVariableTag) targeter;
LVPosition p = (LVPosition) localVariables.get(lvt);
// If we don't know about it, create a new position and store
// If we don't know about it, create a new position and
// store
// If we do know about it - update its end position
if (p == null) {
LVPosition newp = new LVPosition();
@@ -998,10 +1030,13 @@ public final class LazyMethodGen implements Traceable {
addExceptionHandlers(gen, map, exceptionList);
addLocalVariables(gen, localVariables);

// JAVAC adds line number tables (with just one entry) to generated accessor methods - this
// keeps some tools that rely on finding at least some form of linenumbertable happy.
// JAVAC adds line number tables (with just one entry) to generated
// accessor methods - this
// keeps some tools that rely on finding at least some form of
// linenumbertable happy.
// Let's check if we have one - if we don't then let's add one.
// TODO Could be made conditional on whether line debug info is being produced
// TODO Could be made conditional on whether line debug info is being
// produced
if (gen.getLineNumbers().length == 0) {
gen.addLineNumber(gen.getInstructionList().getStart(), 1);
}
@@ -1021,18 +1056,21 @@ public final class LazyMethodGen implements Traceable {
LinkedList exceptionList = new LinkedList();
Set forDeletion = new HashSet();
Set branchInstructions = new HashSet();
// OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList
// OPTIMIZE sort out in here: getRange()/insertHandler() and type of
// exceptionList
while (iHandle != null) {
Instruction inst = iHandle.getInstruction();
// InstructionHandle nextInst = iHandle.getNext();
// OPTIMIZE remove this instructionhandle as it now points to nowhere?
// OPTIMIZE remove this instructionhandle as it now points to
// nowhere?
if (inst == Range.RANGEINSTRUCTION) {
Range r = Range.getRange(iHandle);
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
if (er.getStart() == iHandle) {
if (!er.isEmpty()) {
// order is important, insert handlers in order of start
// order is important, insert handlers in order of
// start
insertHandler(er, exceptionList);
}
}
@@ -1056,7 +1094,8 @@ public final class LazyMethodGen implements Traceable {
} else if (targeter instanceof LocalVariableTag) {
LocalVariableTag lvt = (LocalVariableTag) targeter;
LVPosition p = (LVPosition) localVariables.get(lvt);
// If we don't know about it, create a new position and store
// If we don't know about it, create a new position
// and store
// If we do know about it - update its end position
if (p == null) {
LVPosition newp = new LVPosition();
@@ -1095,10 +1134,13 @@ public final class LazyMethodGen implements Traceable {
gen.setInstructionList(theBody);
addLocalVariables(gen, localVariables);

// JAVAC adds line number tables (with just one entry) to generated accessor methods - this
// keeps some tools that rely on finding at least some form of linenumbertable happy.
// JAVAC adds line number tables (with just one entry) to generated
// accessor methods - this
// keeps some tools that rely on finding at least some form of
// linenumbertable happy.
// Let's check if we have one - if we don't then let's add one.
// TODO Could be made conditional on whether line debug info is being produced
// TODO Could be made conditional on whether line debug info is being
// produced
if (gen.getLineNumbers().length == 0) {
gen.addLineNumber(gen.getInstructionList().getStart(), 1);
}
@@ -1117,7 +1159,8 @@ public final class LazyMethodGen implements Traceable {
Map duplicatedLocalMap = new HashMap();
for (Iterator iter = localVariables.keySet().iterator(); iter.hasNext();) {
LocalVariableTag tag = (LocalVariableTag) iter.next();
// have we already added one with the same slot number and start location?
// have we already added one with the same slot number and start
// location?
// if so, just continue.
LVPosition lvpos = (LVPosition) localVariables.get(tag);
InstructionHandle start = lvpos.start;
@@ -1155,7 +1198,8 @@ public final class LazyMethodGen implements Traceable {
private void handleBranchInstruction(Map map, Instruction oldInstruction, Instruction newInstruction) {
InstructionBranch oldBranchInstruction = (InstructionBranch) oldInstruction;
InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction;
InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old
// target

// New target is in hash map
newBranchInstruction.setTarget(remap(oldTarget, map));
@@ -1301,18 +1345,24 @@ public final class LazyMethodGen implements Traceable {
// block (pr78021,pr79554).

// exception ordering.
// What we should be doing is dealing with priority inversions way earlier than we are
// and counting on the tree structure. In which case, the below code is in fact right.
// What we should be doing is dealing with priority inversions way earlier
// than we are
// and counting on the tree structure. In which case, the below code is in
// fact right.

// XXX THIS COMMENT BELOW IS CURRENTLY WRONG.
// An exception A preceeds an exception B in the exception table iff:

// * A and B were in the original method, and A preceeded B in the original exception table
// * A and B were in the original method, and A preceeded B in the original
// exception table
// * If A has a higher priority than B, than it preceeds B.
// * If A and B have the same priority, then the one whose START happens EARLIEST has LEAST priority.
// * If A and B have the same priority, then the one whose START happens
// EARLIEST has LEAST priority.
// in short, the outermost exception has least priority.
// we implement this with a LinkedList. We could possibly implement this with a java.util.SortedSet,
// but I don't trust the only implementation, TreeSet, to do the right thing.
// we implement this with a LinkedList. We could possibly implement this
// with a java.util.SortedSet,
// but I don't trust the only implementation, TreeSet, to do the right
// thing.

/* private */static void insertHandler(ExceptionRange fresh, LinkedList l) {
// Old implementation, simply: l.add(0,fresh);
@@ -1369,8 +1419,11 @@ public final class LazyMethodGen implements Traceable {

public void assertGoodBody() {
if (true)
return; // only enable for debugging, consider using cheaper toString()
assertGoodBody(getBody(), toString()); // definingType.getNameAsIdentifier() + "." + getName()); //toString());
return; // only enable for debugging, consider using cheaper
// toString()
assertGoodBody(getBody(), toString()); // definingType.getNameAsIdentifier
// () + "." + getName());
// //toString());
}

public static void assertGoodBody(InstructionList il, String from) {

+ 36
- 21
weaver/src/org/aspectj/weaver/bcel/Utility.java View File

@@ -54,7 +54,7 @@ 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.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Lint;
@@ -112,7 +112,8 @@ public class Utility {
if (isl == null || isl.getSourceFile() == null || isl.getSourceFile().getName().indexOf("no debug info available") != -1) {
nice.append("no debug info available");
} else {
// can't use File.getName() as this fails when a Linux box encounters a path created on Windows and vice-versa
// can't use File.getName() as this fails when a Linux box
// encounters a path created on Windows and vice-versa
int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/');
if (takeFrom == -1) {
takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\');
@@ -268,7 +269,8 @@ public class Utility {

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.
// ??? 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++) {
@@ -308,7 +310,8 @@ public class Utility {
if (!toType.isConvertableFrom(fromType) && !fromType.isConvertableFrom(toType)) {
throw new BCException("can't convert from " + fromType + " to " + toType);
}
// XXX I'm sure this test can be simpler but my brain hurts and this works
// XXX I'm sure this test can be simpler but my brain hurts and this
// works
if (!toType.getWorld().isInJava5Mode()) {
if (toType.needsNoConversionFrom(fromType))
return;
@@ -339,7 +342,8 @@ public class Utility {
il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { from },
Constants.INVOKESTATIC));
} else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature() + fromType.getSignature()) != null) {
// XXX could optimize by using any java boxing code that may be just before the call...
// XXX could optimize by using any java boxing code that may be just
// before the call...
Type from = BcelWorld.makeBcelType(fromType);
Type to = BcelWorld.makeBcelType(toType);
String name = (String) validBoxing.get(toType.getSignature() + fromType.getSignature());
@@ -598,7 +602,8 @@ public class Utility {
}

/** returns -1 if no source line attribute */
// this naive version overruns the JVM stack size, if only Java understood tail recursion...
// this naive version overruns the JVM stack size, if only Java understood
// tail recursion...
// public static int getSourceLine(InstructionHandle ih) {
// if (ih == null) return -1;
//
@@ -613,9 +618,11 @@ public class Utility {
// }
// return getSourceLine(ih.getNext());
// }
public static int getSourceLine(InstructionHandle ih) {// ,boolean goforwards) {
public static int getSourceLine(InstructionHandle ih) {// ,boolean
// goforwards) {
int lookahead = 0;
// arbitrary rule that we will never lookahead more than 100 instructions for a line #
// arbitrary rule that we will never lookahead more than 100
// instructions for a line #
while (lookahead++ < 100) {
if (ih == null)
return -1;
@@ -637,9 +644,11 @@ public class Utility {
// return getSourceLine(ih,false);
// }

// assumes that there is no already extant source line tag. Otherwise we'll have to be better.
// 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...
// OPTIMIZE LineNumberTag instances for the same line could be shared
// throughout a method...
ih.addTargeter(new LineNumberTag(lineNumber));
}

@@ -687,18 +696,19 @@ public class Utility {
* (identified by its key) should be ignored.
*
*/
public static boolean isSuppressing(AnnotationX[] anns, String lintkey) {
public static boolean isSuppressing(AnnotationAJ[] anns, String lintkey) {
if (anns == null)
return false;
boolean suppressed = false;
// Go through the annotation types on the advice
for (int i = 0; !suppressed && i < anns.length; i++) {
// Check for the SuppressAjWarnings annotation
if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getTypeSignature())) {
// Two possibilities:
// 1. there are no values specified (i.e. @SuppressAjWarnings)
// 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
List vals = anns[i].getBcelAnnotation().getValues();
// 2. there are values specified (i.e. @SuppressAjWarnings("A")
// or @SuppressAjWarnings({"A","B"})
List vals = ((BcelAnnotation) anns[i]).getBcelAnnotation().getValues();
if (vals == null || vals.isEmpty()) { // (1)
suppressed = true;
} else { // (2)
@@ -718,7 +728,7 @@ public class Utility {
return suppressed;
}

public static List/* Lint.Kind */getSuppressedWarnings(AnnotationX[] anns, Lint lint) {
public static List/* Lint.Kind */getSuppressedWarnings(AnnotationAJ[] anns, Lint lint) {
if (anns == null)
return Collections.EMPTY_LIST;
// Go through the annotation types
@@ -726,12 +736,14 @@ public class Utility {
boolean found = false;
for (int i = 0; !found && i < anns.length; i++) {
// Check for the SuppressAjWarnings annotation
if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(
((BcelAnnotation) anns[i]).getBcelAnnotation().getTypeSignature())) {
found = true;
// Two possibilities:
// 1. there are no values specified (i.e. @SuppressAjWarnings)
// 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
List vals = anns[i].getBcelAnnotation().getValues();
// 2. there are values specified (i.e. @SuppressAjWarnings("A")
// or @SuppressAjWarnings({"A","B"})
List vals = ((BcelAnnotation) anns[i]).getBcelAnnotation().getValues();
if (vals == null || vals.isEmpty()) { // (1)
suppressedWarnings.addAll(lint.allKinds());
} else { // (2)
@@ -755,18 +767,21 @@ public class Utility {
// 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!
// 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 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
// // if current instruction is an invocation, indicate that it can't be
// trivial
// return false;
// }
// InstrHandle = InstrHandle.getNext();

+ 188
- 158
weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java View File

@@ -18,7 +18,7 @@ import java.util.Iterator;
import java.util.Map;

import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
@@ -28,111 +28,124 @@ import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;

public class DeclareAnnotation extends Declare {
public static final Kind AT_TYPE = new Kind(1,"type");
public static final Kind AT_FIELD = new Kind(2,"field");
public static final Kind AT_METHOD = new Kind(3,"method");
public static final Kind AT_CONSTRUCTOR = new Kind(4,"constructor");
public static final Kind AT_TYPE = new Kind(1, "type");
public static final Kind AT_FIELD = new Kind(2, "field");
public static final Kind AT_METHOD = new Kind(3, "method");
public static final Kind AT_CONSTRUCTOR = new Kind(4, "constructor");
private Kind kind;
private TypePattern typePattern; // for declare @type
private SignaturePattern sigPattern; // for declare @field,@method,@constructor
private TypePattern typePattern; // for declare @type
private SignaturePattern sigPattern; // for declare
// @field,@method,@constructor
private String annotationMethod = "unknown";
private String annotationString = "@<annotation>";
private ResolvedType containingAspect;
private AnnotationX annotation;
/**
* Captures type of declare annotation (method/type/field/constructor)
*/
private AnnotationAJ annotation;
/**
* Captures type of declare annotation (method/type/field/constructor)
*/
public static class Kind {
private final int id;
private String s;
private Kind(int n,String name) {
private Kind(int n, String name) {
id = n;
s = name;
}
public int hashCode() {
return (19 + 37*id);
return (19 + 37 * id);
}

public boolean equals(Object obj) {
if (!(obj instanceof Kind)) return false;
Kind other = (Kind) obj;
return other.id == id;
}
public String toString() {
return "at_"+s;
}
}
public boolean equals(Object obj) {
if (!(obj instanceof Kind))
return false;
Kind other = (Kind) obj;
return other.id == id;
}

public String toString() {
return "at_" + s;
}
}

public DeclareAnnotation(Kind kind, TypePattern typePattern) {
this.typePattern = typePattern;
this.kind = kind;
}
/**
* Returns the string, useful before the real annotation has been resolved
*/
public String getAnnotationString() { return annotationString;}

/**
* Returns the string, useful before the real annotation has been resolved
*/
public String getAnnotationString() {
return annotationString;
}

public DeclareAnnotation(Kind kind, SignaturePattern sigPattern) {
this.sigPattern = sigPattern;
this.kind = kind;
}
public boolean isExactPattern() {
return typePattern instanceof ExactTypePattern;
}
public String getAnnotationMethod() { return annotationMethod;}

public String getAnnotationMethod() {
return annotationMethod;
}

public String toString() {
StringBuffer ret = new StringBuffer();
ret.append("declare @");
ret.append(kind);
ret.append(" : ");
ret.append(typePattern != null ? typePattern.toString() : sigPattern.toString());
ret.append(typePattern != null ? typePattern.toString() : sigPattern
.toString());
ret.append(" : ");
ret.append(annotationString);
return ret.toString();
}
public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this,data);
return visitor.visit(this, data);
}
public void resolve(IScope scope) {
if (!scope.getWorld().isInJava5Mode()) {
String msg = null;
if (kind == AT_TYPE) { msg = WeaverMessages.DECLARE_ATTYPE_ONLY_SUPPORTED_AT_JAVA5_LEVEL; }
else if (kind == AT_METHOD) { msg = WeaverMessages.DECLARE_ATMETHOD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;}
else if (kind == AT_FIELD) { msg = WeaverMessages.DECLARE_ATFIELD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;}
else if (kind == AT_CONSTRUCTOR) { msg = WeaverMessages.DECLARE_ATCONS_ONLY_SUPPORTED_AT_JAVA5_LEVEL;}
if (kind == AT_TYPE) {
msg = WeaverMessages.DECLARE_ATTYPE_ONLY_SUPPORTED_AT_JAVA5_LEVEL;
} else if (kind == AT_METHOD) {
msg = WeaverMessages.DECLARE_ATMETHOD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;
} else if (kind == AT_FIELD) {
msg = WeaverMessages.DECLARE_ATFIELD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;
} else if (kind == AT_CONSTRUCTOR) {
msg = WeaverMessages.DECLARE_ATCONS_ONLY_SUPPORTED_AT_JAVA5_LEVEL;
}
scope.message(MessageUtil.error(WeaverMessages.format(msg),
getSourceLocation()));
return;
}
if (typePattern != null) {
typePattern = typePattern.resolveBindings(scope,Bindings.NONE,false,false);
typePattern = typePattern.resolveBindings(scope, Bindings.NONE,
false, false);
}
if (sigPattern != null) {
sigPattern = sigPattern.resolveBindings(scope,Bindings.NONE);
sigPattern = sigPattern.resolveBindings(scope, Bindings.NONE);
}
this.containingAspect = scope.getEnclosingType();
}

public Declare parameterizeWith(Map typeVariableBindingMap,World w) {
public Declare parameterizeWith(Map typeVariableBindingMap, World w) {
DeclareAnnotation ret;
if (this.kind == AT_TYPE) {
ret = new DeclareAnnotation(kind,this.typePattern.parameterizeWith(typeVariableBindingMap,w));
ret = new DeclareAnnotation(kind, this.typePattern
.parameterizeWith(typeVariableBindingMap, w));
} else {
ret = new DeclareAnnotation(kind, this.sigPattern.parameterizeWith(typeVariableBindingMap,w));
ret = new DeclareAnnotation(kind, this.sigPattern.parameterizeWith(
typeVariableBindingMap, w));
}
ret.annotationMethod = this.annotationMethod;
ret.annotationString = this.annotationString;
@@ -141,7 +154,7 @@ public class DeclareAnnotation extends Declare {
ret.copyLocationFrom(this);
return ret;
}
public boolean isAdviceLike() {
return false;
}
@@ -149,49 +162,60 @@ public class DeclareAnnotation extends Declare {
public void setAnnotationString(String as) {
this.annotationString = as;
}
public void setAnnotationMethod(String methName){
public void setAnnotationMethod(String methName) {
this.annotationMethod = methName;
}

public boolean equals(Object obj) {
if (!(obj instanceof DeclareAnnotation)) return false;
if (!(obj instanceof DeclareAnnotation))
return false;
DeclareAnnotation other = (DeclareAnnotation) obj;
if (!this.kind.equals(other.kind)) return false;
if (!this.annotationString.equals(other.annotationString)) return false;
if (!this.annotationMethod.equals(other.annotationMethod)) return false;
if (!this.kind.equals(other.kind))
return false;
if (!this.annotationString.equals(other.annotationString))
return false;
if (!this.annotationMethod.equals(other.annotationMethod))
return false;
if (this.typePattern != null) {
if (!typePattern.equals(other.typePattern)) return false;
if (!typePattern.equals(other.typePattern))
return false;
}
if (this.sigPattern != null) {
if (!sigPattern.equals(other.sigPattern)) return false;
if (!sigPattern.equals(other.sigPattern))
return false;
}
return true;
}
public int hashCode() {
int result = 19;
result = 37*result + kind.hashCode();
result = 37*result + annotationString.hashCode();
result = 37*result + annotationMethod.hashCode();
if (typePattern != null) result = 37*result + typePattern.hashCode();
if (sigPattern != null) result = 37*result + sigPattern.hashCode();
return result;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
int result = 19;
result = 37 * result + kind.hashCode();
result = 37 * result + annotationString.hashCode();
result = 37 * result + annotationMethod.hashCode();
if (typePattern != null)
result = 37 * result + typePattern.hashCode();
if (sigPattern != null)
result = 37 * result + sigPattern.hashCode();
return result;
}

/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
s.writeByte(Declare.ANNOTATION);
s.writeInt(kind.id);
s.writeUTF(annotationString);
s.writeUTF(annotationMethod);
if (typePattern != null) typePattern.write(s);
if (sigPattern != null) sigPattern.write(s);
writeLocation(s);
if (typePattern != null)
typePattern.write(s);
if (sigPattern != null)
sigPattern.write(s);
writeLocation(s);
}

public static Declare read(VersionedDataInputStream s,
@@ -203,61 +227,60 @@ public class DeclareAnnotation extends Declare {
TypePattern tp = null;
SignaturePattern sp = null;
switch (kind) {
case 1:
tp = TypePattern.read(s,context);
ret = new DeclareAnnotation(AT_TYPE,tp);
case 1:
tp = TypePattern.read(s, context);
ret = new DeclareAnnotation(AT_TYPE, tp);
break;
case 2:
sp = SignaturePattern.read(s,context);
ret = new DeclareAnnotation(AT_FIELD,sp);
case 2:
sp = SignaturePattern.read(s, context);
ret = new DeclareAnnotation(AT_FIELD, sp);
break;
case 3:
sp = SignaturePattern.read(s,context);
ret = new DeclareAnnotation(AT_METHOD,sp);
case 3:
sp = SignaturePattern.read(s, context);
ret = new DeclareAnnotation(AT_METHOD, sp);
break;
case 4:
sp = SignaturePattern.read(s,context);
ret = new DeclareAnnotation(AT_CONSTRUCTOR,sp);
case 4:
sp = SignaturePattern.read(s, context);
ret = new DeclareAnnotation(AT_CONSTRUCTOR, sp);
break;
}
// if (kind==AT_TYPE.id) {
// tp = TypePattern.read(s,context);
// ret = new DeclareAnnotation(AT_TYPE,tp);
// } else {
// sp = SignaturePattern.read(s,context);
// ret = new DeclareAnnotation(kind,sp);
// }
// if (kind==AT_TYPE.id) {
// tp = TypePattern.read(s,context);
// ret = new DeclareAnnotation(AT_TYPE,tp);
// } else {
// sp = SignaturePattern.read(s,context);
// ret = new DeclareAnnotation(kind,sp);
// }
ret.setAnnotationString(annotationString);
ret.setAnnotationMethod(annotationMethod);
ret.readLocation(context,s);
ret.readLocation(context, s);
return ret;
}

// public boolean getAnnotationIfMatches(ResolvedType onType) {
// return (match(onType));
// }

// public boolean getAnnotationIfMatches(ResolvedType onType) {
// return (match(onType));
// }

/**
* For @constructor, @method, @field
*/
public boolean matches(ResolvedMember rm,World world) {
return sigPattern.matches(rm,world,false);
/**
* For @constructor, @method, @field
*/
public boolean matches(ResolvedMember rm, World world) {
return sigPattern.matches(rm, world, false);
}
/**
* For @type
*/

/**
* For @type
*/
public boolean matches(ResolvedType typeX) {
if (!typePattern.matchesStatically(typeX)) return false;
if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() &&
!typeX.isExposedToWeaver())
{
typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX.getName(), getSourceLocation());
if (!typePattern.matchesStatically(typeX))
return false;
if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled()
&& !typeX.isExposedToWeaver()) {
typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX
.getName(), getSourceLocation());
}
return true;
return true;
}

public void setAspect(ResolvedType typeX) {
@@ -270,47 +293,49 @@ public class DeclareAnnotation extends Declare {

public void copyAnnotationTo(ResolvedType onType) {
ensureAnnotationDiscovered();
if (!onType.hasAnnotation(annotation.getSignature())) {
onType.addAnnotation(annotation);
if (!onType.hasAnnotation(annotation.getType())) {
onType.addAnnotation(annotation);
}
}
public AnnotationX getAnnotationX() {
public AnnotationAJ getAnnotationX() {
ensureAnnotationDiscovered();
return annotation;
}

/**
* The annotation specified in the declare @type is stored against
* a simple method of the form "ajc$declare_<NN>", this method
* finds that method and retrieves the annotation
* The annotation specified in the declare @type is stored against a simple
* method of the form "ajc$declare_<NN>", this method finds that method and
* retrieves the annotation
*/
private void ensureAnnotationDiscovered() {
if (annotation!=null) return;
if (annotation != null)
return;
for (Iterator iter = containingAspect.getMethods(); iter.hasNext();) {
ResolvedMember member = (ResolvedMember) iter.next();
if (member.getName().equals(annotationMethod)) {
annotation = member.getAnnotations()[0];
}
}
}
}

public TypePattern getTypePattern() {
return typePattern;
}
public SignaturePattern getSignaturePattern() {
return sigPattern;
}
public boolean isStarredAnnotationPattern() {
if (typePattern!=null) return typePattern.isStarAnnotation();
if (sigPattern!=null) return sigPattern.isStarAnnotation();
throw new RuntimeException("Impossible! what kind of deca is this: "+this);
if (typePattern != null)
return typePattern.isStarAnnotation();
if (sigPattern != null)
return sigPattern.isStarAnnotation();
throw new RuntimeException("Impossible! what kind of deca is this: "
+ this);
}


public Kind getKind() {
return kind;
}
@@ -318,61 +343,66 @@ public class DeclareAnnotation extends Declare {
public boolean isDeclareAtConstuctor() {
return kind.equals(AT_CONSTRUCTOR);
}

public boolean isDeclareAtMethod() {
return kind.equals(AT_METHOD);
}

public boolean isDeclareAtType() {
return kind.equals(AT_TYPE);
}

public boolean isDeclareAtField() {
return kind.equals(AT_FIELD);
}

/**
* @return UnresolvedType for the annotation
*/
/**
* @return UnresolvedType for the annotation
*/
public UnresolvedType getAnnotationTypeX() {
ensureAnnotationDiscovered();
return this.annotation.getSignature();
ensureAnnotationDiscovered();
return this.annotation.getType();
}

/**
* @return true if the annotation specified is allowed on a field
*/
public boolean isAnnotationAllowedOnField() {
ensureAnnotationDiscovered();
ensureAnnotationDiscovered();
return annotation.allowedOnField();
}

public String getPatternAsString() {
if (sigPattern!=null) return sigPattern.toString();
if (typePattern!=null) return typePattern.toString();
return "DONT KNOW";
if (sigPattern != null)
return sigPattern.toString();
if (typePattern != null)
return typePattern.toString();
return "DONT KNOW";
}

/**
* Return true if this declare annotation could ever match something
* in the specified type - only really able to make intelligent
* decision if a type was specified in the sig/type pattern
* signature.
* Return true if this declare annotation could ever match something in the
* specified type - only really able to make intelligent decision if a type
* was specified in the sig/type pattern signature.
*/
public boolean couldEverMatch(ResolvedType type) {
// Haven't implemented variant for typePattern (doesn't seem worth it!)
// BUGWARNING This test might not be sufficient for funny cases relating
// Haven't implemented variant for typePattern (doesn't seem worth it!)
// BUGWARNING This test might not be sufficient for funny cases relating
// to interfaces and the use of '+' - but it seems really important to
// do something here so we don't iterate over all fields and all methods
// in all types exposed to the weaver! So look out for bugs here and
// in all types exposed to the weaver! So look out for bugs here and
// we can update the test as appropriate.
if (sigPattern!=null)
return sigPattern.getDeclaringType().matches(type,TypePattern.STATIC).maybeTrue();
if (sigPattern != null)
return sigPattern.getDeclaringType().matches(type,
TypePattern.STATIC).maybeTrue();
return true;
}
/**
* Provide a name suffix so that we can tell the different declare annotations
* forms apart in the AjProblemReporter
* Provide a name suffix so that we can tell the different declare
* annotations forms apart in the AjProblemReporter
*/
public String getNameSuffix() {
return getKind().toString();
return getKind().toString();
}
}

+ 195
- 123
weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java View File

@@ -20,7 +20,7 @@ import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ReferenceType;
@@ -43,14 +43,16 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
protected boolean resolved = false;
protected boolean bindingPattern = false;
private Map annotationValues;
// OPTIMIZE is annotationtype really unresolved???? surely it is resolved by now...
public ExactAnnotationTypePattern(UnresolvedType annotationType, Map annotationValues) {

// OPTIMIZE is annotationtype really unresolved???? surely it is resolved by
// now...
public ExactAnnotationTypePattern(UnresolvedType annotationType,
Map annotationValues) {
this.annotationType = annotationType;
this.annotationValues = annotationValues;
this.resolved = (annotationType instanceof ResolvedType);
}
// Used when deserializing, values will be added
private ExactAnnotationTypePattern(UnresolvedType annotationType) {
this.annotationType = annotationType;
@@ -65,114 +67,144 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
}

public ResolvedType getResolvedAnnotationType() {
if (!resolved) throw new IllegalStateException("I need to be resolved first!");
if (!resolved)
throw new IllegalStateException("I need to be resolved first!");
return (ResolvedType) annotationType;
}
public UnresolvedType getAnnotationType() {
return annotationType;
}
public Map getAnnotationValues() {
return annotationValues;
}
public UnresolvedType getAnnotationType() {
return annotationType;
}
public Map getAnnotationValues() {
return annotationValues;
}

public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
if (annotated.hasAnnotation(annotationType) && annotationValues == null) {
return FuzzyBoolean.YES;
} else {
// could be inherited, but we don't know that until we are
// could be inherited, but we don't know that until we are
// resolved, and we're not yet...
return FuzzyBoolean.MAYBE;
}
}
public FuzzyBoolean matches(AnnotatedElement annotated) {
return matches(annotated,null);
return matches(annotated, null);
}
public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {

public FuzzyBoolean matches(AnnotatedElement annotated,
ResolvedType[] parameterAnnotations) {
if (!isForParameterAnnotationMatch()) {
boolean checkSupers = false;
if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
if (getResolvedAnnotationType().hasAnnotation(
UnresolvedType.AT_INHERITED)) {
if (annotated instanceof ResolvedType) {
checkSupers = true;
}
}
if (annotated.hasAnnotation(annotationType)) {
if (annotationType instanceof ReferenceType) {
ReferenceType rt = (ReferenceType)annotationType;
if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) {
rt.getWorld().getMessageHandler().handleMessage(
MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation()));
ReferenceType rt = (ReferenceType) annotationType;
if (rt.getRetentionPolicy() != null
&& rt.getRetentionPolicy().equals("SOURCE")) {
rt
.getWorld()
.getMessageHandler()
.handleMessage(
MessageUtil
.warn(
WeaverMessages
.format(
WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,
annotationType,
annotated),
getSourceLocation()));
return FuzzyBoolean.NO;
}
}

// Are we also matching annotation values?
if (annotationValues!=null) {
AnnotationX theAnnotation = annotated.getAnnotationOfType(annotationType);
if (annotationValues != null) {
AnnotationAJ theAnnotation = annotated
.getAnnotationOfType(annotationType);

// Check each one
Set keys = annotationValues.keySet();
for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
String k = (String) keyIter.next();
String v = (String)annotationValues.get(k);
String v = (String) annotationValues.get(k);
if (theAnnotation.hasNamedValue(k)) {
// Simple case, value is 'name=value' and the annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k,v)) {
// Simple case, value is 'name=value' and the
// annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k, v)) {
return FuzzyBoolean.NO;
}
}
} else {
// Complex case, look at the default value
ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
ResolvedMember[] ms = ((ResolvedType) annotationType)
.getDeclaredMethods();
boolean foundMatch = false;
for (int i=0; i<ms.length && !foundMatch;i++) {
if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
for (int i = 0; i < ms.length && !foundMatch; i++) {
if (ms[i].isAbstract()
&& ms[i].getParameterTypes().length == 0
&& ms[i].getName().equals(k)) {
// we might be onto something
String s= ms[i].getAnnotationDefaultValue();
if (s!=null && s.equals(v)) foundMatch=true;
String s = ms[i]
.getAnnotationDefaultValue();
if (s != null && s.equals(v))
foundMatch = true;
}
}
if (!foundMatch)
return FuzzyBoolean.NO;
return FuzzyBoolean.NO;
}
}
}
return FuzzyBoolean.YES;
} else if (checkSupers) {
ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
ResolvedType toMatchAgainst = ((ResolvedType) annotated)
.getSuperclass();
while (toMatchAgainst != null) {
if (toMatchAgainst.hasAnnotation(annotationType)) {
// Are we also matching annotation values?
if (annotationValues!=null) {
AnnotationX theAnnotation = toMatchAgainst.getAnnotationOfType(annotationType);
if (annotationValues != null) {
AnnotationAJ theAnnotation = toMatchAgainst
.getAnnotationOfType(annotationType);

// Check each one
Set keys = annotationValues.keySet();
for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
for (Iterator keyIter = keys.iterator(); keyIter
.hasNext();) {
String k = (String) keyIter.next();
String v = (String)annotationValues.get(k);
String v = (String) annotationValues.get(k);
if (theAnnotation.hasNamedValue(k)) {
// Simple case, value is 'name=value' and the annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k,v)) {
// Simple case, value is 'name=value' and
// the annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k, v)) {
return FuzzyBoolean.NO;
}
}
} else {
// Complex case, look at the default value
ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
ResolvedMember[] ms = ((ResolvedType) annotationType)
.getDeclaredMethods();
boolean foundMatch = false;
for (int i=0; i<ms.length && !foundMatch;i++) {
if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
for (int i = 0; i < ms.length
&& !foundMatch; i++) {
if (ms[i].isAbstract()
&& ms[i].getParameterTypes().length == 0
&& ms[i].getName().equals(k)) {
// we might be onto something
String s= ms[i].getAnnotationDefaultValue();
if (s!=null && s.equals(v)) foundMatch=true;
String s = ms[i]
.getAnnotationDefaultValue();
if (s != null && s.equals(v))
foundMatch = true;
}
}
if (!foundMatch)
return FuzzyBoolean.NO;
return FuzzyBoolean.NO;
}
}
}
@@ -180,40 +212,44 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
}
toMatchAgainst = toMatchAgainst.getSuperclass();
}
}
}
} else {
// check parameter annotations
if (parameterAnnotations==null) return FuzzyBoolean.NO;
if (parameterAnnotations == null)
return FuzzyBoolean.NO;
for (int i = 0; i < parameterAnnotations.length; i++) {
if (annotationType.equals(parameterAnnotations[i])) {
// Are we also matching annotation values?
if (annotationValues!=null) {
parameterAnnotations[i].getWorld().getMessageHandler().handleMessage(
MessageUtil.error("Compiler limitation: annotation value matching for parameter annotations not yet supported"));
if (annotationValues != null) {
parameterAnnotations[i]
.getWorld()
.getMessageHandler()
.handleMessage(
MessageUtil
.error("Compiler limitation: annotation value matching for parameter annotations not yet supported"));
return FuzzyBoolean.NO;
}
return FuzzyBoolean.YES;
}
}
}

return FuzzyBoolean.NO;
}
// this version should be called for @this, @target, @args
public FuzzyBoolean matchesRuntimeType(AnnotatedElement annotated) {
if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
if (getResolvedAnnotationType().hasAnnotation(
UnresolvedType.AT_INHERITED)) {
// a static match is good enough
if (matches(annotated).alwaysTrue()) {
return FuzzyBoolean.YES;
}
}
}
// a subtype could match at runtime
return FuzzyBoolean.MAYBE;
}

public void resolve(World world) {
if (!resolved) {
annotationType = annotationType.resolve(world);
@@ -221,59 +257,73 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
resolved = true;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings, boolean)
/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.patterns.AnnotationTypePattern#resolveBindings(org
* .aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings,
* boolean)
*/
public AnnotationTypePattern resolveBindings(IScope scope,
Bindings bindings, boolean allowBinding) {
if (resolved) return this;
if (resolved)
return this;
resolved = true;
String simpleName = maybeGetSimpleName();
if (simpleName != null) {
FormalBinding formalBinding = scope.lookupFormal(simpleName);
if (formalBinding != null) {
if (bindings == null) {
scope.message(IMessage.ERROR, this, "negation doesn't allow binding");
scope.message(IMessage.ERROR, this,
"negation doesn't allow binding");
return this;
}
if (!allowBinding) {
scope.message(IMessage.ERROR, this,
"name binding only allowed in @pcds, args, this, and target");
scope
.message(IMessage.ERROR, this,
"name binding only allowed in @pcds, args, this, and target");
return this;
}
formalName = simpleName;
bindingPattern = true;
verifyIsAnnotationType(formalBinding.getType().resolve(scope.getWorld()),scope);
BindingAnnotationTypePattern binding = new BindingAnnotationTypePattern(formalBinding);
verifyIsAnnotationType(formalBinding.getType().resolve(
scope.getWorld()), scope);
BindingAnnotationTypePattern binding = new BindingAnnotationTypePattern(
formalBinding);
binding.copyLocationFrom(this);
bindings.register(binding, scope);
binding.resolveBinding(scope.getWorld());
if (isForParameterAnnotationMatch()) binding.setForParameterAnnotationMatch();
if (isForParameterAnnotationMatch())
binding.setForParameterAnnotationMatch();

return binding;
}
}
}

// Non binding case
String cleanname = annotationType.getName();
annotationType = scope.getWorld().resolve(annotationType,true);
annotationType = scope.getWorld().resolve(annotationType, true);
// We may not have found it if it is in a package, lets look it up...
if (ResolvedType.isMissing(annotationType)) {
UnresolvedType type = null;
while (ResolvedType.isMissing(type = scope.lookupType(cleanname,this))) {
while (ResolvedType.isMissing(type = scope.lookupType(cleanname,
this))) {
int lastDot = cleanname.lastIndexOf('.');
if (lastDot == -1) break;
cleanname = cleanname.substring(0,lastDot)+"$"+cleanname.substring(lastDot+1);
if (lastDot == -1)
break;
cleanname = cleanname.substring(0, lastDot) + "$"
+ cleanname.substring(lastDot + 1);
}
annotationType = scope.getWorld().resolve(type,true);
annotationType = scope.getWorld().resolve(type, true);
}
verifyIsAnnotationType((ResolvedType)annotationType,scope);
verifyIsAnnotationType((ResolvedType) annotationType, scope);
return this;
}
public AnnotationTypePattern parameterizeWith(Map typeVariableMap,World w) {
public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
UnresolvedType newAnnotationType = annotationType;
if (annotationType.isTypeVariableReference()) {
TypeVariableReference t = (TypeVariableReference) annotationType;
@@ -284,33 +334,40 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
} else if (annotationType.isParameterizedType()) {
newAnnotationType = annotationType.parameterize(typeVariableMap);
}
ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(newAnnotationType,annotationValues);
ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(
newAnnotationType, annotationValues);
ret.formalName = formalName;
ret.bindingPattern = bindingPattern;
ret.copyLocationFrom(this);
if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
if (isForParameterAnnotationMatch())
ret.setForParameterAnnotationMatch();
return ret;
}
protected String maybeGetSimpleName() {
if (formalName != null) return formalName;
if (formalName != null)
return formalName;
String ret = annotationType.getName();
return (ret.indexOf('.') == -1) ? ret : null;
}
protected void verifyIsAnnotationType(ResolvedType type, IScope scope) {
if (!type.isAnnotation()) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE,type.getName()),
getSourceLocation());
IMessage m = MessageUtil.error(WeaverMessages.format(
WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE, type
.getName()), getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
resolved = false;
}
}

private static byte VERSION = 1; // rev if serialisation form changes
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)

/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.EXACT);
@@ -323,7 +380,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
}
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
if (annotationValues==null) {
if (annotationValues == null) {
s.writeInt(0);
} else {
s.writeInt(annotationValues.size());
@@ -331,67 +388,82 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
for (Iterator keys = key.iterator(); keys.hasNext();) {
String k = (String) keys.next();
s.writeUTF(k);
s.writeUTF((String)annotationValues.get(k));
s.writeUTF((String) annotationValues.get(k));
}
}
}

public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException {
public static AnnotationTypePattern read(VersionedDataInputStream s,
ISourceContext context) throws IOException {
ExactAnnotationTypePattern ret;
byte version = s.readByte();
if (version > VERSION) {
throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
throw new BCException(
"ExactAnnotationTypePattern was written by a newer version of AspectJ");
}
boolean isBindingPattern = s.readBoolean();
if (isBindingPattern) {
ret = new ExactAnnotationTypePattern(s.readUTF());
} else {
ret = new ExactAnnotationTypePattern(UnresolvedType.read(s));
ret = new ExactAnnotationTypePattern(UnresolvedType.read(s));
}
ret.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) {
if (s.readBoolean()) ret.setForParameterAnnotationMatch();
ret.readLocation(context, s);
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) {
if (s.readBoolean())
ret.setForParameterAnnotationMatch();
}
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
int annotationValueCount = s.readInt();
if (annotationValueCount>0) {
if (annotationValueCount > 0) {
Map aValues = new HashMap();
for (int i=0;i<annotationValueCount;i++) {
for (int i = 0; i < annotationValueCount; i++) {
String key = s.readUTF();
String val = s.readUTF();
aValues.put(key,val);
aValues.put(key, val);
}
ret.annotationValues = aValues;
}
}
return ret;
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (!(obj instanceof ExactAnnotationTypePattern)) return false;
if (!(obj instanceof ExactAnnotationTypePattern))
return false;
ExactAnnotationTypePattern other = (ExactAnnotationTypePattern) obj;
return (other.annotationType.equals(annotationType)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch() &&
(annotationValues==null?other.annotationValues==null:annotationValues.equals(other.annotationValues));
return (other.annotationType.equals(annotationType))
&& isForParameterAnnotationMatch() == other
.isForParameterAnnotationMatch()
&& (annotationValues == null ? other.annotationValues == null
: annotationValues.equals(other.annotationValues));
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (((annotationType.hashCode())*37+(isForParameterAnnotationMatch()?0:1))*37)+(annotationValues==null?0:annotationValues.hashCode());
return (((annotationType.hashCode()) * 37 + (isForParameterAnnotationMatch() ? 0
: 1)) * 37)
+ (annotationValues == null ? 0 : annotationValues.hashCode());
}
public String toString() {
if (!resolved && formalName != null) return formalName;
if (!resolved && formalName != null)
return formalName;
String ret = "@" + annotationType.toString();
if (formalName != null) ret = ret + " " + formalName;
if (formalName != null)
ret = ret + " " + formalName;
return ret;
}

public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

+ 13
- 12
weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java View File

@@ -14,31 +14,32 @@ package org.aspectj.weaver.reflect;
import java.lang.reflect.Member;
import java.util.Set;

import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;

/**
* @author colyer
* Used in 1.4 code to access annotations safely
* @author colyer Used in 1.4 code to access annotations safely
*/
public interface AnnotationFinder {

void setClassLoader(ClassLoader annotationLoader);
void setWorld(World aWorld);
Object getAnnotation(ResolvedType annotationType, Object onObject);
Object getAnnotationFromMember(ResolvedType annotationType, Member aMember);
public AnnotationX getAnnotationOfType(UnresolvedType ofType,Member onMember);

public AnnotationAJ getAnnotationOfType(UnresolvedType ofType,
Member onMember);

public String getAnnotationDefaultValue(Member onMember);
Object getAnnotationFromClass(ResolvedType annotationType, Class aClass);
Set/*ResolvedType*/ getAnnotations(Member onMember);
Set/* ResolvedType */getAnnotations(Member onMember);
ResolvedType[][] getParameterAnnotationTypes(Member onMember);
}

+ 172
- 90
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java View File

@@ -20,8 +20,8 @@ import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Collections;

import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.AnnotationTargetKind;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ReferenceTypeDelegate;
@@ -36,15 +36,18 @@ import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.PerClause;

/**
* @author colyer
* A delegate for a resolved type that uses runtime type information (java.lang.reflect)
* to answer questions. This class uses only Java 1.4 features to answer questions.
* In a Java 1.5 environment use the Java5ReflectionBasedReferenceTypeDelegate subtype.
* @author colyer A delegate for a resolved type that uses runtime type
* information (java.lang.reflect) to answer questions. This class uses
* only Java 1.4 features to answer questions. In a Java 1.5 environment
* use the Java5ReflectionBasedReferenceTypeDelegate subtype.
*/
public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelegate {
public class ReflectionBasedReferenceTypeDelegate implements
ReferenceTypeDelegate {

private static final ClassLoader BootClassLoader = new URLClassLoader(
new URL[0]);// ReflectionBasedReferenceTypeDelegate.class.
// getClassLoader();

private static final ClassLoader BootClassLoader = new URLClassLoader(new URL[0]);// ReflectionBasedReferenceTypeDelegate.class.getClassLoader();
protected Class myClass = null;
protected WeakClassLoaderReference classLoaderReference = null;
private World world;
@@ -52,64 +55,84 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
private ResolvedMember[] fields = null;
private ResolvedMember[] methods = null;
private ResolvedType[] interfaces = null;
public ReflectionBasedReferenceTypeDelegate(Class forClass, ClassLoader aClassLoader, World inWorld, ReferenceType resolvedType) {
initialize(resolvedType,forClass, aClassLoader, inWorld);

public ReflectionBasedReferenceTypeDelegate(Class forClass,
ClassLoader aClassLoader, World inWorld, ReferenceType resolvedType) {
initialize(resolvedType, forClass, aClassLoader, inWorld);
}
/** for reflective construction only */
public ReflectionBasedReferenceTypeDelegate() {}
public void initialize(ReferenceType aType, Class aClass, ClassLoader aClassLoader, World aWorld) {
public ReflectionBasedReferenceTypeDelegate() {
}

public void initialize(ReferenceType aType, Class aClass,
ClassLoader aClassLoader, World aWorld) {
this.myClass = aClass;
this.resolvedType = aType;
this.world = aWorld;
this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : BootClassLoader);
this.classLoaderReference = new WeakClassLoaderReference(
(aClassLoader != null) ? aClassLoader : BootClassLoader);
}
protected Class getBaseClass() {
protected Class getBaseClass() {
return this.myClass;
}
protected World getWorld() {
return this.world;
}
public ReferenceType buildGenericType() {
throw new UnsupportedOperationException("Shouldn't be asking for generic type at 1.4 source level or lower");
throw new UnsupportedOperationException(
"Shouldn't be asking for generic type at 1.4 source level or lower");
}
/* (non-Javadoc)
* @see org.aspectj.weaver.ReferenceTypeDelegate#addAnnotation(org.aspectj.weaver.AnnotationX)

/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.ReferenceTypeDelegate#addAnnotation(org.aspectj.weaver
* .AnnotationX)
*/
public void addAnnotation(AnnotationX annotationX) {
throw new UnsupportedOperationException("Cannot add an annotation to a reflection based delegate");
public void addAnnotation(AnnotationAJ annotationX) {
throw new UnsupportedOperationException(
"Cannot add an annotation to a reflection based delegate");
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAspect()
*/
public boolean isAspect() {
// we could do better than this in Java 5 by looking at the annotations on the type...
// we could do better than this in Java 5 by looking at the annotations
// on the type...
return false;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationStyleAspect()
*/
public boolean isAnnotationStyleAspect() {
// we could do better than this in Java 5 by looking at the annotations on the type...
// we could do better than this in Java 5 by looking at the annotations
// on the type...
return false;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isInterface()
*/
public boolean isInterface() {
return this.myClass.isInterface();
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isEnum()
*/
public boolean isEnum() {
@@ -117,7 +140,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return false;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotation()
*/
public boolean isAnnotation() {
@@ -125,14 +150,18 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return false;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationWithRuntimeRetention()
/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationWithRuntimeRetention
* ()
*/
public boolean isAnnotationWithRuntimeRetention() {
// cant be an annotation in Java 1.4 or prior
return false;
}
public String getRetentionPolicy() {
// cant be an annotation in Java 1.4 or prior
return null;
@@ -141,44 +170,54 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
public boolean canAnnotationTargetType() {
return false;
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return null;
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isClass()
*/
public boolean isClass() {
return !this.myClass.isInterface() && !this.myClass.isPrimitive() && !this.myClass.isArray();
return !this.myClass.isInterface() && !this.myClass.isPrimitive()
&& !this.myClass.isArray();
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isGeneric()
*/
public boolean isGeneric() {
// cant be generic in 1.4
return false;
}
public boolean isAnonymous() {
return false;
}
public boolean isNested() {
// FIXME this is *wrong* but isMemberClass() doesnt exist in pre-1.5... (same deal as isAnonymous above...)
// FIXME this is *wrong* but isMemberClass() doesnt exist in pre-1.5...
// (same deal as isAnonymous above...)
return true;
// boolean member = this.myClass.isMemberClass();
// return member;
// boolean member = this.myClass.isMemberClass();
// return member;
}
public ResolvedType getOuterClass() {
// FIXME getEnclosingClass() is Java5 ... dammit
// return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(myClass.getEnclosingClass(),world);
// return
// ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(
// myClass.getEnclosingClass(),world);
return null;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isExposedToWeaver()
*/
public boolean isExposedToWeaver() {
@@ -186,23 +225,31 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return false;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ReferenceTypeDelegate#hasAnnotation(org.aspectj.weaver.UnresolvedType)
/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.ReferenceTypeDelegate#hasAnnotation(org.aspectj.weaver
* .UnresolvedType)
*/
public boolean hasAnnotation(UnresolvedType ofType) {
// in Java 1.4 we cant have an annotation
return false;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotations()
*/
public AnnotationX[] getAnnotations() {
public AnnotationAJ[] getAnnotations() {
// no annotations in Java 1.4
return new AnnotationX[0];
return AnnotationAJ.EMPTY_ARRAY;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotationTypes()
*/
public ResolvedType[] getAnnotationTypes() {
@@ -210,7 +257,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return new ResolvedType[0];
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredFields()
*/
public ResolvedMember[] getDeclaredFields() {
@@ -218,15 +267,17 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
Field[] reflectFields = this.myClass.getDeclaredFields();
ResolvedMember[] rFields = new ResolvedMember[reflectFields.length];
for (int i = 0; i < reflectFields.length; i++) {
rFields[i] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world);
rFields[i] = ReflectionBasedReferenceTypeDelegateFactory
.createResolvedMember(reflectFields[i], world);
}
this.fields = rFields;
}
return fields;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredInterfaces()
*/
public ResolvedType[] getDeclaredInterfaces() {
@@ -235,42 +286,49 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
ResolvedType[] rInterfaces = new ResolvedType[reflectInterfaces.length];
for (int i = 0; i < reflectInterfaces.length; i++) {
rInterfaces[i] = ReflectionBasedReferenceTypeDelegateFactory
.resolveTypeInWorld(reflectInterfaces[i],world);
.resolveTypeInWorld(reflectInterfaces[i], world);
}
this.interfaces = rInterfaces;
}
return interfaces;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredMethods()
*/
public ResolvedMember[] getDeclaredMethods() {
if (methods == null) {
Method[] reflectMethods = this.myClass.getDeclaredMethods();
Constructor[] reflectCons = this.myClass.getDeclaredConstructors();
ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length];
ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length
+ reflectCons.length];
for (int i = 0; i < reflectMethods.length; i++) {
rMethods[i] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world);
rMethods[i] = ReflectionBasedReferenceTypeDelegateFactory
.createResolvedMember(reflectMethods[i], world);
}
for (int i = 0; i < reflectCons.length; i++) {
rMethods[i + reflectMethods.length] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectCons[i], world);
rMethods[i + reflectMethods.length] = ReflectionBasedReferenceTypeDelegateFactory
.createResolvedMember(reflectCons[i], world);
}
this.methods = rMethods;
}
return methods;
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredPointcuts()
*/
public ResolvedMember[] getDeclaredPointcuts() {
return new ResolvedMember[0];
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeVariables()
*/
public TypeVariable[] getTypeVariables() {
@@ -278,7 +336,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return new TypeVariable[0];
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getPerClause()
*/
public PerClause getPerClause() {
@@ -286,7 +346,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return null;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclares()
*/
public Collection getDeclares() {
@@ -294,7 +356,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return Collections.EMPTY_SET;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeMungers()
*/
public Collection getTypeMungers() {
@@ -302,7 +366,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return Collections.EMPTY_SET;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getPrivilegedAccesses()
*/
public Collection getPrivilegedAccesses() {
@@ -310,50 +376,64 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
return Collections.EMPTY_SET;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getModifiers()
*/
public int getModifiers() {
return this.myClass.getModifiers();
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getSuperclass()
*/
public ResolvedType getSuperclass() {
if (this.myClass.getSuperclass() == null) {
if (myClass==Object.class) {
if (myClass == Object.class) {
return null;
}
return world.resolve(UnresolvedType.OBJECT);
}
return ReflectionBasedReferenceTypeDelegateFactory
.resolveTypeInWorld(this.myClass.getSuperclass(),world);
return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(
this.myClass.getSuperclass(), world);
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getWeaverState()
*/
public WeaverStateInfo getWeaverState() {
return null;
}

/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getResolvedTypeX()
*/
public ReferenceType getResolvedTypeX() {
return this.resolvedType;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ReferenceTypeDelegate#doesNotExposeShadowMungers()
/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.ReferenceTypeDelegate#doesNotExposeShadowMungers()
*/
public boolean doesNotExposeShadowMungers() {
return false;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredGenericSignature()
/*
* (non-Javadoc)
*
* @see
* org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredGenericSignature()
*/
public String getDeclaredGenericSignature() {
// no generic sig in 1.4
@@ -361,16 +441,18 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
}

public void ensureDelegateConsistent() {
// Nothing to do - a reflection based delegate can't become inconsistent...
// Nothing to do - a reflection based delegate can't become
// inconsistent...
}
public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) {

public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(
Member aMember) {
return null;
}
public String getSourcefilename() {
// crappy guess..
return resolvedType.getName() + ".class";
// crappy guess..
return resolvedType.getName() + ".class";
}

public ISourceContext getSourceContext() {

+ 55
- 44
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java View File

@@ -14,27 +14,25 @@ package org.aspectj.weaver.reflect;
import java.lang.reflect.Member;
import java.util.Iterator;

import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;


/**
* Subtype of ResolvedMemberImpl used in reflection world.
* Knows how to get annotations from a java.lang.reflect.Member
*
* Subtype of ResolvedMemberImpl used in reflection world. Knows how to get
* annotations from a java.lang.reflect.Member
*
*/
public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {

private AnnotationFinder annotationFinder = null;
private GenericSignatureInformationProvider gsigInfoProvider =
new Java14GenericSignatureInformationProvider();
private GenericSignatureInformationProvider gsigInfoProvider = new Java14GenericSignatureInformationProvider();

private Member reflectMember;
/**
* @param kind
* @param declaringType
@@ -46,8 +44,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
Member reflectMember) {
UnresolvedType[] parameterTypes, Member reflectMember) {
super(kind, declaringType, modifiers, returnType, name, parameterTypes);
this.reflectMember = reflectMember;
}
@@ -64,8 +61,8 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions,
Member reflectMember) {
UnresolvedType[] parameterTypes,
UnresolvedType[] checkedExceptions, Member reflectMember) {
super(kind, declaringType, modifiers, returnType, name, parameterTypes,
checkedExceptions);
this.reflectMember = reflectMember;
@@ -86,8 +83,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
UnresolvedType[] checkedExceptions,
ResolvedMember backingGenericMember,
Member reflectMember) {
ResolvedMember backingGenericMember, Member reflectMember) {
super(kind, declaringType, modifiers, returnType, name, parameterTypes,
checkedExceptions, backingGenericMember);
this.reflectMember = reflectMember;
@@ -110,93 +106,108 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
public Member getMember() {
return this.reflectMember;
}
// generic signature support
public void setGenericSignatureInformationProvider(GenericSignatureInformationProvider gsigProvider) {

public void setGenericSignatureInformationProvider(
GenericSignatureInformationProvider gsigProvider) {
this.gsigInfoProvider = gsigProvider;
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ResolvedMemberImpl#getGenericParameterTypes()
*/
public UnresolvedType[] getGenericParameterTypes() {
return this.gsigInfoProvider.getGenericParameterTypes(this);
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ResolvedMemberImpl#getGenericReturnType()
*/
public UnresolvedType getGenericReturnType() {
return this.gsigInfoProvider.getGenericReturnType(this);
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ResolvedMemberImpl#isSynthetic()
*/
public boolean isSynthetic() {
return this.gsigInfoProvider.isSynthetic(this);
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ResolvedMemberImpl#isVarargsMethod()
*/
public boolean isVarargsMethod() {
return this.gsigInfoProvider.isVarArgs(this);
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ResolvedMemberImpl#isBridgeMethod()
*/
public boolean isBridgeMethod() {
return this.gsigInfoProvider.isBridge(this);
}
// annotation support
public void setAnnotationFinder(AnnotationFinder finder) {
this.annotationFinder = finder;
}
public boolean hasAnnotation(UnresolvedType ofType) {
unpackAnnotations();
return super.hasAnnotation(ofType);
}
public boolean hasAnnotations() {
unpackAnnotations();
return super.hasAnnotations();
}
public ResolvedType[] getAnnotationTypes() {
unpackAnnotations();
return super.getAnnotationTypes();
}
public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
unpackAnnotations();
if (annotationFinder==null) return null;
if (annotationFinder == null)
return null;
for (Iterator iterator = annotationTypes.iterator(); iterator.hasNext();) {
ResolvedType type = (ResolvedType) iterator.next();
if (type.getSignature().equals(ofType.getSignature())) {
return annotationFinder.getAnnotationOfType(ofType, reflectMember);
return annotationFinder.getAnnotationOfType(ofType,
reflectMember);
}
}
return null;
}

public String getAnnotationDefaultValue() {
if (annotationFinder==null) return null;
if (annotationFinder == null)
return null;
return annotationFinder.getAnnotationDefaultValue(reflectMember);
}

public ResolvedType[][] getParameterAnnotationTypes() {
if (parameterAnnotationTypes==null && annotationFinder!=null) {
parameterAnnotationTypes = annotationFinder.getParameterAnnotationTypes(reflectMember);
}
return parameterAnnotationTypes;
}
if (parameterAnnotationTypes == null && annotationFinder != null) {
parameterAnnotationTypes = annotationFinder
.getParameterAnnotationTypes(reflectMember);
}
return parameterAnnotationTypes;
}

private void unpackAnnotations() {
if (annotationTypes == null && annotationFinder != null) {
annotationTypes = annotationFinder.getAnnotations(reflectMember);

+ 244
- 192
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java View File

@@ -14,344 +14,396 @@ import junit.framework.TestCase;
import org.aspectj.bridge.AbortException;
import org.aspectj.util.LangUtil;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.BcweaverTests;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.bcel.BcelWorld;

public class AnnotationPatternTestCase extends TestCase {

public void testParseSimpleAnnotationPattern() {
PatternParser p = new PatternParser("@Foo");
AnnotationTypePattern foo = p.maybeParseAnnotationPattern();
foo = foo.resolveBindings(makeSimpleScope(),new Bindings(3),true);
assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
assertEquals("Foo", UnresolvedType.forSignature("LFoo;"), ((ExactAnnotationTypePattern) foo).annotationType);
foo = foo.resolveBindings(makeSimpleScope(), new Bindings(3), true);
assertTrue("ExactAnnotationTypePattern",
foo instanceof ExactAnnotationTypePattern);
assertEquals("Foo", UnresolvedType.forSignature("LFoo;"),
((ExactAnnotationTypePattern) foo).annotationType);
}
public void testParseAndAnnotationPattern() {
PatternParser p = new PatternParser("@Foo @Goo");
AnnotationTypePattern fooAndGoo = p.maybeParseAnnotationPattern();
assertTrue("AndAnnotationTypePattern",fooAndGoo instanceof AndAnnotationTypePattern);
assertEquals("@(Foo) @(Goo)",fooAndGoo.toString());
fooAndGoo = fooAndGoo.resolveBindings(makeSimpleScope(),new Bindings(3),true);
assertEquals("@Foo @Goo",fooAndGoo.toString());
AnnotationTypePattern left = ((AndAnnotationTypePattern)fooAndGoo).getLeft();
AnnotationTypePattern right = ((AndAnnotationTypePattern)fooAndGoo).getRight();
assertEquals("Foo", UnresolvedType.forSignature("LFoo;"), ((ExactAnnotationTypePattern) left).annotationType);
assertEquals("Goo", UnresolvedType.forSignature("LGoo;"), ((ExactAnnotationTypePattern) right).annotationType);
assertTrue("AndAnnotationTypePattern",
fooAndGoo instanceof AndAnnotationTypePattern);
assertEquals("@(Foo) @(Goo)", fooAndGoo.toString());
fooAndGoo = fooAndGoo.resolveBindings(makeSimpleScope(),
new Bindings(3), true);
assertEquals("@Foo @Goo", fooAndGoo.toString());
AnnotationTypePattern left = ((AndAnnotationTypePattern) fooAndGoo)
.getLeft();
AnnotationTypePattern right = ((AndAnnotationTypePattern) fooAndGoo)
.getRight();
assertEquals("Foo", UnresolvedType.forSignature("LFoo;"),
((ExactAnnotationTypePattern) left).annotationType);
assertEquals("Goo", UnresolvedType.forSignature("LGoo;"),
((ExactAnnotationTypePattern) right).annotationType);
}
//
// public void testParseOrAnnotationPattern() {
// PatternParser p = new PatternParser("@Foo || @Goo");
// AnnotationTypePattern fooOrGoo = p.parseAnnotationTypePattern();
// assertTrue("OrAnnotationTypePattern",fooOrGoo instanceof OrAnnotationTypePattern);
// assertEquals("(@Foo || @Goo)",fooOrGoo.toString());
// AnnotationTypePattern left = ((OrAnnotationTypePattern)fooOrGoo).getLeft();
// AnnotationTypePattern right = ((OrAnnotationTypePattern)fooOrGoo).getRight();
// assertEquals("Foo",UnresolvedType.forName("Foo"),((ExactAnnotationTypePattern)left).annotationType);
// assertEquals("Goo",UnresolvedType.forName("Goo"),((ExactAnnotationTypePattern)right).annotationType);
// }
//

//
// public void testParseOrAnnotationPattern() {
// PatternParser p = new PatternParser("@Foo || @Goo");
// AnnotationTypePattern fooOrGoo = p.parseAnnotationTypePattern();
// assertTrue("OrAnnotationTypePattern",fooOrGoo instanceof
// OrAnnotationTypePattern);
// assertEquals("(@Foo || @Goo)",fooOrGoo.toString());
// AnnotationTypePattern left =
// ((OrAnnotationTypePattern)fooOrGoo).getLeft();
// AnnotationTypePattern right =
// ((OrAnnotationTypePattern)fooOrGoo).getRight();
// assertEquals("Foo",UnresolvedType.forName("Foo"),((
// ExactAnnotationTypePattern)left).annotationType);
// assertEquals("Goo",UnresolvedType.forName("Goo"),((
// ExactAnnotationTypePattern)right).annotationType);
// }
//
public void testParseNotAnnotationPattern() {
PatternParser p = new PatternParser("!@Foo");
AnnotationTypePattern notFoo = p.maybeParseAnnotationPattern();
assertTrue("NotAnnotationTypePattern",notFoo instanceof NotAnnotationTypePattern);
notFoo = notFoo.resolveBindings(makeSimpleScope(),new Bindings(3),true);
assertEquals("!@Foo",notFoo.toString());
AnnotationTypePattern body = ((NotAnnotationTypePattern)notFoo).getNegatedPattern();
assertEquals("Foo",UnresolvedType.forName("Foo"),((ExactAnnotationTypePattern)body).annotationType);
assertTrue("NotAnnotationTypePattern",
notFoo instanceof NotAnnotationTypePattern);
notFoo = notFoo.resolveBindings(makeSimpleScope(), new Bindings(3),
true);
assertEquals("!@Foo", notFoo.toString());
AnnotationTypePattern body = ((NotAnnotationTypePattern) notFoo)
.getNegatedPattern();
assertEquals("Foo", UnresolvedType.forName("Foo"),
((ExactAnnotationTypePattern) body).annotationType);
}

public void testParseBracketedAnnotationPattern() {
PatternParser p = new PatternParser("(@Foo)");
AnnotationTypePattern foo = p.maybeParseAnnotationPattern();
// cannot start with ( so, we get ANY
assertEquals("ANY",AnnotationTypePattern.ANY,foo);
assertEquals("ANY", AnnotationTypePattern.ANY, foo);
}
public void testParseFQAnnPattern() {
PatternParser p = new PatternParser("@org.aspectj.Foo");
AnnotationTypePattern foo = p.maybeParseAnnotationPattern();
assertEquals("@(org.aspectj.Foo)",foo.toString());
assertEquals("@(org.aspectj.Foo)", foo.toString());
}
public void testParseComboPattern() {
// PatternParser p = new PatternParser("!((@Foo || @Goo) && !@Boo)");
// PatternParser p = new PatternParser("!((@Foo || @Goo) && !@Boo)");
PatternParser p = new PatternParser("@(Foo || Goo)!@Boo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
AndAnnotationTypePattern atp = (AndAnnotationTypePattern) ap;
NotAnnotationTypePattern notBoo = (NotAnnotationTypePattern) atp.getRight();
// ExactAnnotationTypePattern boo = (ExactAnnotationTypePattern)
notBoo.getNegatedPattern();
// AnnotationTypePattern fooOrGoo = (AnnotationTypePattern)
atp.getLeft();
assertEquals("@((Foo || Goo)) !@Boo",ap.toString());
NotAnnotationTypePattern notBoo = (NotAnnotationTypePattern) atp
.getRight();
// ExactAnnotationTypePattern boo = (ExactAnnotationTypePattern)
notBoo.getNegatedPattern();
// AnnotationTypePattern fooOrGoo = (AnnotationTypePattern)
atp.getLeft();
assertEquals("@((Foo || Goo)) !@Boo", ap.toString());
}
// public void testParseAndOrPattern() {
// PatternParser p = new PatternParser("@Foo && @Boo || @Goo");
// AnnotationTypePattern andOr = p.parseAnnotationTypePattern();
// assertTrue("Should be or pattern",andOr instanceof OrAnnotationTypePattern);
// }
//

// public void testParseAndOrPattern() {
// PatternParser p = new PatternParser("@Foo && @Boo || @Goo");
// AnnotationTypePattern andOr = p.parseAnnotationTypePattern();
// assertTrue("Should be or pattern",andOr instanceof
// OrAnnotationTypePattern);
// }
//
public void testParseBadPattern() {
PatternParser p = new PatternParser("@@Foo");
try {
p.maybeParseAnnotationPattern();
fail("ParserException expected");
} catch(ParserException pEx) {
assertEquals("name pattern",pEx.getMessage());
} catch (ParserException pEx) {
assertEquals("name pattern", pEx.getMessage());
}
}
public void testParseBadPattern2() {
PatternParser p = new PatternParser("Foo");
AnnotationTypePattern bad = p.maybeParseAnnotationPattern();
assertEquals("ANY",AnnotationTypePattern.ANY,bad);
assertEquals("ANY", AnnotationTypePattern.ANY, bad);
}

public void testParseNameOrVarAnnotationPattern() {
PatternParser p = new PatternParser("Foo");
AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
assertTrue("ExactAnnotationTypePattern expected",foo!=null);
assertEquals("Foo",UnresolvedType.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
assertTrue("ExactAnnotationTypePattern expected", foo != null);
assertEquals("Foo", UnresolvedType.forName("Foo"),
((ExactAnnotationTypePattern) foo).annotationType);
}
public void testParseNameOrVarAnnotationPatternWithNot() {
PatternParser p = new PatternParser("!@Foo");
try {
// AnnotationTypePattern bad =
p.parseAnnotationNameOrVarTypePattern();
// AnnotationTypePattern bad =
p.parseAnnotationNameOrVarTypePattern();
fail("ParserException expected");
} catch(ParserException pEx) {
assertEquals("identifier",pEx.getMessage());
}
} catch (ParserException pEx) {
assertEquals("identifier", pEx.getMessage());
}
}

public void testParseNameOrVarAnnotationPatternWithOr() {
PatternParser p = new PatternParser("Foo || Boo");
AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
// rest of pattern not consumed...
assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
assertEquals("Foo",UnresolvedType.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
assertTrue("ExactAnnotationTypePattern",
foo instanceof ExactAnnotationTypePattern);
assertEquals("Foo", UnresolvedType.forName("Foo"),
((ExactAnnotationTypePattern) foo).annotationType);
}
public void testParseNameOrVarAnnotationWithBinding() {
PatternParser p = new PatternParser("foo");
AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
assertEquals("@foo",((ExactAnnotationTypePattern)foo).toString());
assertTrue("ExactAnnotationTypePattern",
foo instanceof ExactAnnotationTypePattern);
assertEquals("@foo", ((ExactAnnotationTypePattern) foo).toString());
}

public void testParseNameOrVarAnnotationPatternWithAnd() {
PatternParser p = new PatternParser("Foo Boo");
AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
// rest of pattern not consumed...
assertEquals("@Foo",foo.toString());
assertEquals("@Foo", foo.toString());
}

public void testMaybeParseAnnotationPattern() {
PatternParser p = new PatternParser("@Foo");
AnnotationTypePattern a = p.maybeParseAnnotationPattern();
assertNotNull("Should find annotation pattern",a);
assertNotNull("Should find annotation pattern", a);
p = new PatternParser("Foo && Boo");
a = p.maybeParseAnnotationPattern();
assertEquals("Should be ANY pattern for a non-match",AnnotationTypePattern.ANY,a);
assertEquals("Should be ANY pattern for a non-match",
AnnotationTypePattern.ANY, a);
}
public void testParseTypePatternsWithAnnotations() {
PatternParser p = new PatternParser("@Foo *");
TypePattern t = p.parseTypePattern();
assertTrue("WildTypePattern",t instanceof WildTypePattern);
assertTrue("WildTypePattern", t instanceof WildTypePattern);
AnnotationTypePattern atp = t.annotationPattern;
assertEquals("@(Foo)",atp.toString());
assertEquals("(@(Foo) *)",t.toString());
assertEquals("@(Foo)", atp.toString());
assertEquals("(@(Foo) *)", t.toString());
}
public void testParseTypePatternsWithAnnotationsComplex() {
PatternParser p = new PatternParser("(@(Foo || Boo) (Foo || Boo))");
TypePattern t = p.parseTypePattern();
assertTrue("OrTypePattern",t instanceof OrTypePattern);
assertEquals("((@((Foo || Boo)) Foo) || (@((Foo || Boo)) Boo))",t.toString());
assertTrue("OrTypePattern", t instanceof OrTypePattern);
assertEquals("((@((Foo || Boo)) Foo) || (@((Foo || Boo)) Boo))", t
.toString());
}
public void testNotSyntax() {
PatternParser p = new PatternParser("!@Foo (Foo || Boo))");
TypePattern t = p.parseTypePattern();
assertTrue("OrTypePattern",t instanceof OrTypePattern);
assertEquals("((!@(Foo) Foo) || (!@(Foo) Boo))",t.toString());
assertTrue("OrTypePattern", t instanceof OrTypePattern);
assertEquals("((!@(Foo) Foo) || (!@(Foo) Boo))", t.toString());
}

public void testParseMethodOrConstructorSigNoAP() {
PatternParser p = new PatternParser("* *.*(..)");
SignaturePattern s = p.parseMethodOrConstructorSignaturePattern();
assertEquals("Any annotation",AnnotationTypePattern.ANY,s.getAnnotationPattern());
assertEquals("Any return","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("* *.*(..)",s.toString());
assertEquals("Any annotation", AnnotationTypePattern.ANY, s
.getAnnotationPattern());
assertEquals("Any return", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("* *.*(..)", s.toString());
}
public void testParseMethodOrConstructorSigSimpleAP() {
PatternParser p = new PatternParser("@Foo * *.*(..)");
SignaturePattern s = p.parseMethodOrConstructorSignaturePattern();
assertEquals("@(Foo) annotation","@(Foo)",s.getAnnotationPattern().toString());
assertEquals("Any return","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("@(Foo) * *.*(..)",s.toString());
assertEquals("@(Foo) annotation", "@(Foo)", s.getAnnotationPattern()
.toString());
assertEquals("Any return", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("@(Foo) * *.*(..)", s.toString());
}
public void testParseMethodOrConstructorSigComplexAP() {
PatternParser p = new PatternParser("!@(Foo || Goo) * *.*(..)");
SignaturePattern s = p.parseMethodOrConstructorSignaturePattern();
assertEquals("complex annotation","!@((Foo || Goo))",s.getAnnotationPattern().toString());
assertEquals("Any return","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("!@((Foo || Goo)) * *.*(..)",s.toString());
assertEquals("complex annotation", "!@((Foo || Goo))", s
.getAnnotationPattern().toString());
assertEquals("Any return", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("!@((Foo || Goo)) * *.*(..)", s.toString());
}
public void testParseMethodFieldSigNoAP() {
PatternParser p = new PatternParser("* *.*");
SignaturePattern s = p.parseFieldSignaturePattern();
assertEquals("Any annotation",AnnotationTypePattern.ANY,s.getAnnotationPattern());
assertEquals("Any field type","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("* *.*",s.toString());
assertEquals("Any annotation", AnnotationTypePattern.ANY, s
.getAnnotationPattern());
assertEquals("Any field type", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("* *.*", s.toString());
}
public void testParseFieldSigSimpleAP() {
PatternParser p = new PatternParser("@Foo * *.*");
SignaturePattern s = p.parseFieldSignaturePattern();
assertEquals("@Foo annotation","@(Foo)",s.getAnnotationPattern().toString());
assertEquals("Any field type","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("@(Foo) * *.*",s.toString());
assertEquals("@Foo annotation", "@(Foo)", s.getAnnotationPattern()
.toString());
assertEquals("Any field type", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("@(Foo) * *.*", s.toString());
}
public void testParseFieldSigComplexAP() {
PatternParser p = new PatternParser("!@(Foo || Goo) * *.*");
SignaturePattern s = p.parseFieldSignaturePattern();
assertEquals("complex annotation","!@((Foo || Goo))",s.getAnnotationPattern().toString());
assertEquals("Any field type","*",s.getReturnType().toString());
assertEquals("Any dec type","*",s.getDeclaringType().toString());
assertEquals("Any name","*",s.getName().toString());
assertEquals("!@((Foo || Goo)) * *.*",s.toString());
assertEquals("complex annotation", "!@((Foo || Goo))", s
.getAnnotationPattern().toString());
assertEquals("Any field type", "*", s.getReturnType().toString());
assertEquals("Any dec type", "*", s.getDeclaringType().toString());
assertEquals("Any name", "*", s.getName().toString());
assertEquals("!@((Foo || Goo)) * *.*", s.toString());
}
public void testExactAnnotationPatternMatching() {
if (LangUtil.is15VMOrGreater()) {
PatternParser p = new PatternParser("@Foo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[]{"Foo"});
assertTrue("matches element with Foo",ap.matches(ae).alwaysTrue());
AnnotatedElementImpl ae2 = new AnnotatedElementImpl(new String[]{"Boo"});
assertTrue("does not match element with Boo",ap.matches(ae2).alwaysFalse());
PatternParser p = new PatternParser("@Foo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(
new String[] { "Foo" });
assertTrue("matches element with Foo", ap.matches(ae).alwaysTrue());
AnnotatedElementImpl ae2 = new AnnotatedElementImpl(
new String[] { "Boo" });
assertTrue("does not match element with Boo", ap.matches(ae2)
.alwaysFalse());
}
}
public void testBindingAnnotationPatternMatching() {
if (LangUtil.is15VMOrGreater()) {
PatternParser p = new PatternParser("foo");
AnnotationTypePattern ap = p.parseAnnotationNameOrVarTypePattern();
try {
ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
} catch(AbortException abEx) {
assertEquals("Binding not supported in @pcds (1.5.0 M1 limitation): null",abEx.getMessage());
}
// uncomment these next lines once binding is supported
// AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[]{"Foo"});
// assertTrue("matches element with Foo",ap.matches(ae).alwaysTrue());
// AnnotatedElementImpl ae2 = new AnnotatedElementImpl(new String[]{"Boo"});
// assertTrue("does not match element with Boo",ap.matches(ae2).alwaysFalse());
PatternParser p = new PatternParser("foo");
AnnotationTypePattern ap = p.parseAnnotationNameOrVarTypePattern();
try {
ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3),
true);
} catch (AbortException abEx) {
assertEquals(
"Binding not supported in @pcds (1.5.0 M1 limitation): null",
abEx.getMessage());
}
// uncomment these next lines once binding is supported
// AnnotatedElementImpl ae = new AnnotatedElementImpl(new
// String[]{"Foo"});
//assertTrue("matches element with Foo",ap.matches(ae).alwaysTrue())
// ;
// AnnotatedElementImpl ae2 = new AnnotatedElementImpl(new
// String[]{"Boo"});
// assertTrue("does not match element with Boo",ap.matches(ae2).
// alwaysFalse());
}
}
public void testAndAnnotationPatternMatching() {
if (LangUtil.is15VMOrGreater()) {
PatternParser p = new PatternParser("@Foo @Boo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {"Foo","Boo"});
assertTrue("matches foo and boo",ap.matches(ae).alwaysTrue());
ae = new AnnotatedElementImpl(new String[] {"Foo"});
assertTrue("does not match foo",ap.matches(ae).alwaysFalse());
ae = new AnnotatedElementImpl(new String[] {"Boo"});
assertTrue("does not match boo",ap.matches(ae).alwaysFalse());
ae = new AnnotatedElementImpl(new String[] {"Goo"});
assertTrue("does not match goo",ap.matches(ae).alwaysFalse());
PatternParser p = new PatternParser("@Foo @Boo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {
"Foo", "Boo" });
assertTrue("matches foo and boo", ap.matches(ae).alwaysTrue());
ae = new AnnotatedElementImpl(new String[] { "Foo" });
assertTrue("does not match foo", ap.matches(ae).alwaysFalse());
ae = new AnnotatedElementImpl(new String[] { "Boo" });
assertTrue("does not match boo", ap.matches(ae).alwaysFalse());
ae = new AnnotatedElementImpl(new String[] { "Goo" });
assertTrue("does not match goo", ap.matches(ae).alwaysFalse());
}
}
//
// public void testOrAnnotationPatternMatching() {
// PatternParser p = new PatternParser("@Foo || @Boo");
// AnnotationTypePattern ap = p.parseAnnotationTypePattern();
// ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
// AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {"Foo","Boo"});
// assertTrue("matches foo and boo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Foo"});
// assertTrue("matches foo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Boo"});
// assertTrue("matches boo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Goo"});
// assertTrue("does not match goo",ap.matches(ae).alwaysFalse());
// }
//

//
// public void testOrAnnotationPatternMatching() {
// PatternParser p = new PatternParser("@Foo || @Boo");
// AnnotationTypePattern ap = p.parseAnnotationTypePattern();
// ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
// AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[]
// {"Foo","Boo"});
// assertTrue("matches foo and boo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Foo"});
// assertTrue("matches foo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Boo"});
// assertTrue("matches boo",ap.matches(ae).alwaysTrue());
// ae = new AnnotatedElementImpl(new String[] {"Goo"});
// assertTrue("does not match goo",ap.matches(ae).alwaysFalse());
// }
//
public void testNotAnnotationPatternMatching() {
if (LangUtil.is15VMOrGreater()) {
PatternParser p = new PatternParser("!@Foo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {"Foo","Boo"});
assertTrue("does not match foo and boo",ap.matches(ae).alwaysFalse());
ae = new AnnotatedElementImpl(new String[] {"Boo"});
assertTrue("matches boo",ap.matches(ae).alwaysTrue());
PatternParser p = new PatternParser("!@Foo");
AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {
"Foo", "Boo" });
assertTrue("does not match foo and boo", ap.matches(ae)
.alwaysFalse());
ae = new AnnotatedElementImpl(new String[] { "Boo" });
assertTrue("matches boo", ap.matches(ae).alwaysTrue());
}
}
public void testAnyAnnotationPatternMatching() {
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {"Foo","Boo"});
assertTrue("always matches",AnnotationTypePattern.ANY.matches(ae).alwaysTrue());
AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] {
"Foo", "Boo" });
assertTrue("always matches", AnnotationTypePattern.ANY.matches(ae)
.alwaysTrue());
ae = new AnnotatedElementImpl(new String[] {});
assertTrue("always matches",AnnotationTypePattern.ANY.matches(ae).alwaysTrue());
assertTrue("always matches", AnnotationTypePattern.ANY.matches(ae)
.alwaysTrue());
}

public TestScope makeSimpleScope() {
BcelWorld bWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH + "/testcode.jar"); // testcode contains Foo/Boo/Goo/etc
BcelWorld bWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH
+ "/testcode.jar"); // testcode contains Foo/Boo/Goo/etc
bWorld.setBehaveInJava5Way(true);
return new TestScope(new String[] {"int", "java.lang.String","Foo","Boo","Goo"},
new String[] {"a", "b","foo","boo","goo"},
bWorld);
return new TestScope(new String[] { "int", "java.lang.String", "Foo",
"Boo", "Goo" }, new String[] { "a", "b", "foo", "boo", "goo" },
bWorld);
}
// put test cases for AnnotationPatternList matching in separate test class...

// put test cases for AnnotationPatternList matching in separate test
// class...

static class AnnotatedElementImpl implements AnnotatedElement {

private String[] annotationTypes;
public AnnotatedElementImpl(String[] annotationTypes) {
public AnnotatedElementImpl(String[] annotationTypes) {
this.annotationTypes = annotationTypes;
}
public boolean hasAnnotation(UnresolvedType ofType) {
for (int i = 0; i < annotationTypes.length; i++) {
if (annotationTypes[i].equals(ofType.getName())) return true;
if (annotationTypes[i].equals(ofType.getName()))
return true;
}
return false;
}
/* (non-Javadoc)

/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
*/
public ResolvedType[] getAnnotationTypes() {
@@ -359,10 +411,10 @@ public class AnnotationPatternTestCase extends TestCase {
return null;
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
// TODO Auto-generated method stub
return null;
}
}
}

Loading…
Cancel
Save