return (binding.getAccessFlags() & ACC_ANNOTATION)!=0;
}
+ public boolean isAnnotationWithRuntimeRetention() {
+ if (!isAnnotation()) {
+ return false;
+ } else {
+ throw new RuntimeException("How to implement this? Needs to ask eclipse!");
+ }
+ }
+
public boolean hasAnnotation(TypeX ofType) {
throw new RuntimeException("How to implement this? Needs to ask eclipse!");
}
--- /dev/null
+public aspect BindingLimitation {
+
+ pointcut doSomethingExecution() : execution(* doSomething());
+ pointcut doSomethingCall() : call(* doSomething());
+
+ after(MyAnnotation ann) returning : @target(ann) && doSomethingCall() {
+ // should be compile time error (limitation)
+ }
+
+}
\ No newline at end of file
--- /dev/null
+public aspect NotRuntimeRetention {
+
+ pointcut doSomethingExecution() : execution(* doSomething());
+ pointcut doSomethingCall() : call(* doSomething());
+
+ // CE L7
+ before() : doSomethingExecution() && @this(@MyClassRetentionAnnotation) {
+ // should be compile-time error!
+ System.out.println("How did I get here?");
+ }
+
+ // CE L13
+ after() returning : doSomethingCall() && @target(@MyClassRetentionAnnotation) {
+ // should be compile-time error!
+ System.out.println("How did I get here?");
+ }
+
+}
\ No newline at end of file
System.out.println("@this(@MyAnnotation): " + thisJoinPointStaticPart);\r
}\r
\r
- before() : doSomethingExecution() && @this(@MyClassRetentionAnnotation) {\r
- // should be compile-time error!\r
- }\r
- \r
before() : doSomethingExecution() && @this(@MyInheritableAnnotation) {\r
// should match:\r
// c.doSomething()\r
System.out.println("@this(@MyInheritableAnnotation): " + thisJoinPointStaticPart);\r
}\r
\r
- after() returning : doSomthingCall() && @target(@MyAnnotation) {\r
+ after() returning : doSomethingCall() && @target(@MyAnnotation) {\r
// should match:\r
// b.doSomething(), reallyB.doSomething() [with test],\r
// c.doSomething()\r
System.out.println("@target(@MyAnnotation): " + thisJoinPointStaticPart);\r
}\r
\r
- after() returning : doSomethingCall() && @target(@MyClassRetentionAnnotation) {\r
- // should be compile-time error!\r
- }\r
- \r
after() returning : doSomethingCall() && @target(@MyInheritableAnnotation) {\r
// should match:\r
// c.doSomething()\r
// reallyD.doSomething()\r
System.out.println("@target(@MyInheritableAnnotation): " + thisJoinPointStaticPart);\r
}\r
- \r
- after(MyAnnotation ann) returning : @target(ann) {\r
- // should be compile time error (limitation)\r
- }\r
- \r
+ \r
}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc150;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.tools.ajc.CompilationResult;
+
+/**
+* Tests for @this, @target, @args
+*/
+public class AnnotationRuntimeTests extends TestUtils {
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ baseDir = new File("../tests/java5/annotations/thisOrtarget");
+ }
+
+ public void test001_NoBinding() {
+ CompilationResult cR = binaryWeave("TestingAnnotations.jar","BindingLimitation.aj",1,0);
+ List errors = cR.getErrorMessages();
+ assertTrue("Binding not supported",errors.get(0).toString().startsWith("error Binding not supported"));
+ }
+
+ public void test002_MustHaveRuntimeRetention() {
+ CompilationResult cR = binaryWeave("TestingAnnotations.jar","NotRuntimeRetention.aj",2,0);
+ List errors = new ArrayList();
+ errors.add(new Message(7,"Annotation type MyClassRetentionAnnotation does not have runtime retention"));
+ errors.add(new Message(13,"Annotation type MyClassRetentionAnnotation does not have runtime retention"));
+
+ MessageSpec messageSpec = new MessageSpec(new ArrayList(), errors);
+ assertMessages(cR, messageSpec);
+ }
+
+ public void test003_InheritableOrNot() {
+ CompilationResult cR = binaryWeave("TestingAnnotations.jar","ThisOrTargetTests.aj",0,0);
+ }
+}
return false;
}
+ /**
+ * Note: Only overridden by Name subtype.
+ */
+ public boolean isAnnotationWithRuntimeRetention() {
+ return false;
+ }
public boolean isSynthetic() {
return signature.indexOf("$ajc") != -1;
public boolean isAnnotation() {
return delegate.isAnnotation();
}
+
+ public boolean isAnnotationWithRuntimeRetention() {
+ return delegate.isAnnotationWithRuntimeRetention();
+ }
public final boolean needsNoConversionFrom(TypeX o) {
return isAssignableFrom(o);
public abstract boolean isInterface();
public abstract boolean isEnum();
public abstract boolean isAnnotation();
+ public abstract boolean isAnnotationWithRuntimeRetention();
public abstract boolean hasAnnotation(TypeX ofType);
public abstract ResolvedTypeX[] getAnnotationTypes();
public final boolean isAnnotation(World world) {
return world.resolve(this).isAnnotation();
}
+
+ /**
+ * Determine if this class represents an annotation type that has runtime retention
+ */
+ public final boolean isAnnotationWithRuntimeRetention(World world) {
+ return world.resolve(this).isAnnotationWithRuntimeRetention();
+ }
/**
public static final TypeX SERIALIZABLE = forSignature("Ljava/io/Serializable;");
public static final TypeX THROWABLE = forSignature("Ljava/lang/Throwable;");
public static final TypeX RUNTIME_EXCEPTION = forSignature("Ljava/lang/RuntimeException;");
- public static final TypeX ERROR = forSignature("Ljava/lang/Error;");
+ public static final TypeX ERROR = forSignature("Ljava/lang/Error;");
+ public static final TypeX AT_INHERITED = forSignature("Ljava/lang/annotation/Inherited;");
+ public static final TypeX AT_RETENTION = forSignature("Ljava/lang/annotation/Retention;");
// ---- helpers
public static final String ITDM_ON_ANNOTATION_NOT_ALLOWED = "itdmOnAnnotationNotAllowed";
public static final String ITDF_ON_ANNOTATION_NOT_ALLOWED = "itdfOnAnnotationNotAllowed";
public static final String REFERENCE_TO_NON_ANNOTATION_TYPE = "referenceToNonAnnotationType";
+ public static final String BINDING_NON_RUNTIME_RETENTION_ANNOTATION = "bindingNonRuntimeRetentionAnnotation";
public static String format(String key) {
return bundle.getString(key);
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.ast;
+
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+
+public class HasAnnotation extends Test {
+
+ private Var v;
+ private ResolvedTypeX annType;
+
+ public HasAnnotation(Var v, ResolvedTypeX annType) {
+ super();
+ this.v = v;
+ this.annType = annType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ast.Test#accept(org.aspectj.weaver.ast.ITestVisitor)
+ */
+ public void accept(ITestVisitor v) {
+ v.visit(this);
+ }
+
+ public String toString() {
+ return "(" + v + " has annotation @" + annType + ")";
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof HasAnnotation) {
+ HasAnnotation o = (HasAnnotation) other;
+ return o.v.equals(v) && o.annType.equals(annType);
+ } else {
+ return false;
+ }
+ }
+
+ public Var getVar() {
+ return v;
+ }
+
+ public TypeX getAnnotationType() {
+ return annType;
+ }
+
+}
void visit(Literal literal);
void visit(Call call);
void visit(FieldGetCall fieldGetCall);
+ void visit(HasAnnotation hasAnnotation);
}
return e;
}
+ public static Test makeHasAnnotation(Var v, ResolvedTypeX annTy) {
+ return new HasAnnotation(v,annTy);
+ }
+
public static Test makeCall(Member m, Expr[] args) {
return new Call(m, args);
}
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
+import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.BCException;
return javaClass.isAnnotation();
}
+ public boolean isAnnotationWithRuntimeRetention() {
+ if (!isAnnotation()) {
+ return false;
+ } else {
+ Annotation[] annotationsOnThisType = javaClass.getAnnotations();
+ for (int i = 0; i < annotationsOnThisType.length; i++) {
+ Annotation a = annotationsOnThisType[i];
+ if (a.getTypeName().equals(TypeX.AT_RETENTION.getName())) {
+ List values = a.getValues();
+ boolean isRuntime = false;
+ for (Iterator it = values.iterator(); it.hasNext();) {
+ ElementNameValuePair element = (ElementNameValuePair) it.next();
+ ElementValue v = element.getValue();
+ isRuntime = v.stringifyValue().equals("RUNTIME");
+ }
+ return isRuntime;
+ }
+ }
+ }
+ return false;
+ }
+
public boolean isSynthetic() {
return getResolvedTypeX().isSynthetic();
}
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
+import org.aspectj.apache.bcel.generic.LDC_W;
import org.aspectj.apache.bcel.generic.ReferenceType;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Member;
+import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.ast.And;
import org.aspectj.weaver.ast.Call;
import org.aspectj.weaver.ast.CallExpr;
import org.aspectj.weaver.ast.Expr;
import org.aspectj.weaver.ast.FieldGet;
import org.aspectj.weaver.ast.FieldGetCall;
+import org.aspectj.weaver.ast.HasAnnotation;
import org.aspectj.weaver.ast.IExprVisitor;
import org.aspectj.weaver.ast.ITestVisitor;
import org.aspectj.weaver.ast.Instanceof;
i.getVar().accept(this);
}
+ public void visit(HasAnnotation hasAnnotation) {
+ instructions.insert(createJumpBasedOnBooleanOnStack());
+ // now insert the instructions that leave a boolean on the stack
+ // in Java:
+ // foo.class.isAnnotationPresent(annotationClass);
+ // in bytecode:
+ // load var onto the stack (done for us later)
+ // invokevirtual java/lang/Object.getClass:()Ljava/lang/Class
+ // ldc_w annotationClass
+ // invokevirtual java/lang/Class.isAnnotationPresent:(Ljava/lang/Class;)Z
+ Member getClass = Member.method(TypeX.OBJECT, 0, "getClass", "()Ljava/lang/Class;");
+ instructions.insert(Utility.createInvoke(fact, world, getClass));
+ // aload annotationClass
+ int annClassIndex = fact.getConstantPool().addClass(hasAnnotation.getAnnotationType().getSignature());
+ instructions.insert(new LDC_W(annClassIndex));
+ Member isAnnotationPresent = Member.method(TypeX.forName("Ljava/lang/Class"),0,
+ "isAnnotationPresent","(Ljava/lang/Class;)Z");
+ instructions.insert(Utility.createInvoke(fact,world,isAnnotationPresent));
+ hasAnnotation.getVar().accept(this);
+ }
+
private InstructionList createJumpBasedOnBooleanOnStack() {
InstructionList il = new InstructionList();
if (sk == fk) {
byte key = s.readByte();
switch(key) {
case EXACT: return ExactAnnotationTypePattern.read(s, context);
-// case BINDING: return BindingAnnotationTypePattern.read(s, context);
+ case BINDING: return BindingAnnotationTypePattern.read(s, context);
case NOT: return NotAnnotationTypePattern.read(s, context);
case OR: return OrAnnotationTypePattern.read(s, context);
case AND: return AndAnnotationTypePattern.read(s, context);
world.getMessageHandler().handleMessage(m);
resolved = false;
}
+ if (!annotationType.hasAnnotation(TypeX.AT_RETENTION)) {
+ // default is class visibility
+ IMessage m = MessageUtil.error(
+ WeaverMessages.format(WeaverMessages.BINDING_NON_RUNTIME_RETENTION_ANNOTATION,annotationType.getName()),
+ getSourceLocation());
+ world.getMessageHandler().handleMessage(m);
+ resolved = false;
+ } else {
+ // TO DO... get the retention policy annotation, and check the value is
+ // RetentionPolicy.RUNTIME;
+ }
return this;
}
if (maybeEat(")")) {
throw new ParserException("expecting @AnnotationName or parameter, but found ')'", tokenSource.peek());
}
- AnnotationTypePattern type = parseAnnotationNameOrVarTypePattern();
+ ExactAnnotationTypePattern type = parseAnnotationNameOrVarTypePattern();
eat(")");
return new ThisOrTargetAnnotationPointcut(kind.equals("this"),type);
}
public static final byte ANNOTATION = 16;
public static final byte ATWITHIN = 17;
public static final byte ATWITHINCODE = 18;
+ public static final byte ATTHIS_OR_TARGET = 19;
public static final byte NONE = 20;
case ANNOTATION: ret = AnnotationPointcut.read(s, context); break;
case ATWITHIN: ret = WithinAnnotationPointcut.read(s, context); break;
case ATWITHINCODE: ret = WithinCodeAnnotationPointcut.read(s, context); break;
+ case ATTHIS_OR_TARGET: ret = ThisOrTargetAnnotationPointcut.read(s, context); break;
case NONE: ret = makeMatchesNothing(RESOLVED); break;
default:
throw new BCException("unknown kind: " + kind);
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.JoinPoint.StaticPart;
+import org.aspectj.lang.reflect.Pointcut;
+import org.aspectj.util.FuzzyBoolean;
+
+/**
+ * Implementation of the reflective pointcut interface in org.aspectj.lang.reflect
+ * (not to be confused with the Pointcut class in this package, which itself should
+ * be considered part of the weaver implementation).
+ */
+public class PointcutImpl implements Pointcut {
+
+ private String pointcutExpression;
+ private org.aspectj.weaver.patterns.Pointcut pointcut;
+
+ public PointcutImpl(String pointcutExpression) {
+ this.pointcutExpression = pointcutExpression;
+ try {
+ pointcut = new PatternParser(pointcutExpression).parsePointcut();
+ } catch (ParserException pEx) {
+ throw new IllegalArgumentException(pEx.getMessage());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.lang.reflect.Pointcut#matches(org.aspectj.lang.JoinPoint, org.aspectj.lang.JoinPoint.StaticPart)
+ */
+ public boolean matches(JoinPoint jp, StaticPart enclosingJoinPoint) {
+ return pointcut.match(jp,enclosingJoinPoint) == FuzzyBoolean.YES;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.lang.reflect.Pointcut#getPointcutExpression()
+ */
+ public String getPointcutExpression() {
+ return pointcutExpression;
+ }
+
+}
* ******************************************************************/
package org.aspectj.weaver.patterns;
+import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ShadowMunger;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.ast.Var;
/**
* @author colyer
public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut {
private boolean isThis;
- private AnnotationTypePattern type;
+ private ExactAnnotationTypePattern annotationTypePattern;
+ private ShadowMunger munger;
/**
*
*/
- public ThisOrTargetAnnotationPointcut(boolean isThis, AnnotationTypePattern type) {
+ public ThisOrTargetAnnotationPointcut(boolean isThis, ExactAnnotationTypePattern type) {
super();
this.isThis = isThis;
- this.type = type;
+ this.annotationTypePattern = type;
}
+ public ThisOrTargetAnnotationPointcut(boolean isThis, ExactAnnotationTypePattern type, ShadowMunger munger) {
+ this(isThis,type);
+ this.munger = munger;
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
*/
public FuzzyBoolean fastMatch(FastMatchInfo info) {
- // TODO Auto-generated method stub
- return null;
+ return FuzzyBoolean.MAYBE;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
*/
public FuzzyBoolean match(Shadow shadow) {
- // TODO Auto-generated method stub
- return null;
+ if (!couldMatch(shadow)) return FuzzyBoolean.NO;
+ TypeX annotationType = annotationTypePattern.annotationType;
+ annotationType = annotationType.resolve(shadow.getIWorld());
+ if (annotationType.hasAnnotation(TypeX.AT_INHERITED)) {
+ // we can attempt to match now
+ ResolvedTypeX toMatchAgainst =
+ (isThis ? shadow.getThisType() : shadow.getTargetType() ).resolve(shadow.getIWorld());
+ return FuzzyBoolean.fromBoolean(toMatchAgainst.hasAnnotation(annotationType));
+ }
+ // else we can only do matching via a runtime test
+ return FuzzyBoolean.MAYBE;
}
public boolean isThis() { return isThis; }
* @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings)
*/
protected void resolveBindings(IScope scope, Bindings bindings) {
- // TODO Auto-generated method stub
-
+ annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true);
+ // must be either a Var, or an annotation type pattern
+ // if annotationType does not have runtime retention, this is an error
+ ResolvedTypeX rAnnotationType = (ResolvedTypeX) annotationTypePattern.annotationType;
+ if (!(rAnnotationType.isAnnotationWithRuntimeRetention())) {
+ IMessage m = MessageUtil.error(
+ WeaverMessages.format(WeaverMessages.BINDING_NON_RUNTIME_RETENTION_ANNOTATION,rAnnotationType.getName()),
+ getSourceLocation());
+ scope.getMessageHandler().handleMessage(m);
+ }
+
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
*/
protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
- // TODO Auto-generated method stub
- return null;
+ ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);
+ Pointcut ret = new ThisOrTargetAnnotationPointcut(isThis, newType, bindings.getEnclosingAdvice());
+ ret.copyLocationFrom(this);
+ return ret;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Pointcut#findResidue(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
*/
public Test findResidue(Shadow shadow, ExposedState state) {
- // TODO Auto-generated method stub
- return null;
+ if (!couldMatch(shadow)) return Literal.FALSE;
+ boolean alwaysMatches = match(shadow).alwaysTrue();
+ Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar();
+ Var annVar = null;
+ TypeX annotationType = annotationTypePattern.annotationType;
+ if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
+ BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern;
+ annotationType = btp.annotationType;
+ annVar = isThis ? shadow.getThisAnnotationVar(annotationType) :
+ shadow.getTargetAnnotationVar(annotationType);
+ if (annVar == null) return Literal.TRUE; // should be exception when we implement properly
+ // Check if we have already bound something to this formal
+ if (state.get(btp.getFormalIndex())!=null) {
+ ISourceLocation pcdSloc = getSourceLocation();
+ ISourceLocation shadowSloc = shadow.getSourceLocation();
+ Message errorMessage = new Message(
+ "Cannot use @pointcut to match at this location and bind a formal to type '"+annVar.getType()+
+ "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+
+ ". The secondary source location points to the problematic binding.",
+ shadowSloc,true,new ISourceLocation[]{pcdSloc});
+ shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
+ state.setErroneousVar(btp.getFormalIndex());
+ }
+ state.set(btp.getFormalIndex(),annVar);
+ }
+
+ if (alwaysMatches && (annVar == null)) {
+ return Literal.TRUE;
+ } else {
+ if (annVar != null) {
+ // TODO - need to bind it, next line is a placeholder
+ return Literal.FALSE;
+ } else {
+ ResolvedTypeX rType = annotationType.resolve(shadow.getIWorld());
+ return Test.makeHasAnnotation(var,rType);
+ }
+ }
}
+
+ private boolean couldMatch(Shadow shadow) {
+ return isThis ? shadow.hasThis() : shadow.hasTarget();
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
- // TODO Auto-generated method stub
-
+ s.writeByte(Pointcut.ATTHIS_OR_TARGET);
+ s.writeBoolean(isThis);
+ annotationTypePattern.write(s);
+ writeLocation(s);
}
-
+
+ public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+ boolean isThis = s.readBoolean();
+ AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
+ ThisOrTargetAnnotationPointcut ret = new ThisOrTargetAnnotationPointcut(isThis,(ExactAnnotationTypePattern)type);
+ ret.readLocation(context, s);
+ return ret;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ThisOrTargetAnnotationPointcut)) return false;
+ ThisOrTargetAnnotationPointcut other = (ThisOrTargetAnnotationPointcut) obj;
+ return ( other.annotationTypePattern.equals(this.annotationTypePattern) &&
+ (other.isThis == this.isThis) );
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return 17 + 37*annotationTypePattern.hashCode() + (isThis ? 49 : 13);
+ }
+
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(isThis ? "@this(" : "@target(");
- buf.append(type.toString());
+ buf.append(annotationTypePattern.toString());
buf.append(")");
return buf.toString();
}
itdfOnAnnotationNotAllowed=can''t make inter-type field declarations on annotation types
referenceToNonAnnotationType=Type referred to is not an annotation type: {0}
-
+bindingNonRuntimeRetentionAnnotation=Annotation type {0} does not have runtime retention