diff options
36 files changed, 1265 insertions, 30 deletions
diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java new file mode 100644 index 000000000..5835f3767 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java @@ -0,0 +1,25 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.annotation; + +import java.lang.annotation.*; + +/** + * internal representation of declare annotation statement, used by reflect api + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcDeclareAnnotation { + String pattern(); + String annotation(); + String kind(); +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareParents.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareParents.java new file mode 100644 index 000000000..14860e006 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareParents.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +/** + * @author colyer + * Marker annotation for code style declare parent declarations + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcDeclareParents { + String targetTypePattern(); + String parentTypes(); + boolean isExtends(); +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java new file mode 100644 index 000000000..ef6197557 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java @@ -0,0 +1,32 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +/** + * @author colyer + * Marker annotation for code style declare precedence declarations + * ajc prefix used to indicate that this annotation is *internal* + * Can't use DeclarePrecedence as that has target = type and we + * need method to cope with the (rare) case of multiple declare + * precendence statements in the same aspect. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcDeclarePrecedence { + String value(); +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java index 3a9005146..f97de09e2 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java @@ -25,6 +25,6 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ajcDeclareSoft { - Class exceptionType(); + String exceptionType(); String pointcut(); } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java index 7bfba4ca1..0cdf0bc96 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java @@ -12,6 +12,7 @@ package org.aspectj.internal.lang.reflect; import java.lang.reflect.Method; +import java.lang.reflect.Type; import org.aspectj.lang.annotation.AdviceName; import org.aspectj.lang.reflect.Advice; @@ -25,10 +26,16 @@ import org.aspectj.lang.reflect.PointcutExpression; * */ public class AdviceImpl implements Advice { + + private static final String AJC_INTERNAL = "org.aspectj.runtime.internal"; private final AdviceKind kind; private final Method adviceMethod; private PointcutExpression pointcutExpression; + private boolean hasExtraParam = false; + private Type[] genericParameterTypes; + private AjType[] parameterTypes; + private AjType[] exceptionTypes; protected AdviceImpl(Method method, String pointcut, AdviceKind type) { this.kind = type; @@ -36,10 +43,62 @@ public class AdviceImpl implements Advice { this.pointcutExpression = new PointcutExpressionImpl(pointcut); } + protected AdviceImpl(Method method, String pointcut, AdviceKind type, String extraParamName) { + this(method,pointcut,type); + this.hasExtraParam = true; + } + public AjType getDeclaringType() { return AjTypeSystem.getAjType(adviceMethod.getDeclaringClass()); } + public Type[] getGenericParameterTypes() { + if (this.genericParameterTypes == null) { + Type[] genTypes = adviceMethod.getGenericParameterTypes(); + int syntheticCount = 0; + for (Type t : genTypes) { + if (t instanceof Class) { + if (((Class)t).getPackage().getName().equals(AJC_INTERNAL)) syntheticCount++; + } + } + this.genericParameterTypes = new Type[genTypes.length - syntheticCount]; + for (int i = 0; i < genericParameterTypes.length; i++) { + if (genTypes[i] instanceof Class) { + this.genericParameterTypes[i] = AjTypeSystem.getAjType((Class)genTypes[i]); + } else { + this.genericParameterTypes[i] = genTypes[i]; + } + } + } + return this.genericParameterTypes; + } + + public AjType<?>[] getParameterTypes() { + if (this.parameterTypes == null) { + Class<?>[] ptypes = adviceMethod.getParameterTypes(); + int syntheticCount = 0; + for(Class<?> c : ptypes) { + if (c.getPackage().getName().equals(AJC_INTERNAL)) syntheticCount++; + } + this.parameterTypes = new AjType<?>[ptypes.length - syntheticCount]; + for (int i = 0; i < parameterTypes.length; i++) { + this.parameterTypes[i] = AjTypeSystem.getAjType(ptypes[i]); + } + } + return this.parameterTypes; + } + + public AjType<?>[] getExceptionTypes() { + if (this.exceptionTypes == null) { + Class<?>[] exTypes = adviceMethod.getExceptionTypes(); + this.exceptionTypes = new AjType<?>[exTypes.length]; + for (int i = 0; i < exTypes.length; i++) { + this.exceptionTypes[i] = AjTypeSystem.getAjType(exTypes[i]); + } + } + return this.exceptionTypes; + } + public AdviceKind getKind() { return kind; } @@ -58,4 +117,71 @@ public class AdviceImpl implements Advice { return pointcutExpression; } + public String toString() { + StringBuffer sb = new StringBuffer(); + if (getName().length() > 0) { + sb.append("@AdviceName(\""); + sb.append(getName()); + sb.append("\") "); + } + if (getKind() == AdviceKind.AROUND) { + sb.append(adviceMethod.getGenericReturnType().toString()); + sb.append(" "); + } + switch(getKind()) { + case AFTER: + sb.append("after("); + break; + case AFTER_RETURNING: + sb.append("after("); + break; + case AFTER_THROWING: + sb.append("after("); + break; + case AROUND: + sb.append("around("); + break; + case BEFORE: + sb.append("before("); + break; + } + AjType<?>[] ptypes = getParameterTypes(); + int len = ptypes.length; + if (hasExtraParam) len--; + for (int i = 0; i < len; i++) { + sb.append(ptypes[i].getName()); + if (i+1 < len) sb.append(","); + } + sb.append(") "); + switch(getKind()) { + case AFTER_RETURNING: + sb.append("returning"); + if (hasExtraParam) { + sb.append("("); + sb.append(ptypes[len-1].getName()); + sb.append(") "); + } + case AFTER_THROWING: + sb.append("throwing"); + if (hasExtraParam) { + sb.append("("); + sb.append(ptypes[len-1].getName()); + sb.append(") "); + } + default: // no-op + } + AjType<?>[] exTypes = getExceptionTypes(); + if (exTypes.length > 0) { + sb.append("throws "); + for (int i = 0; i < exTypes.length; i++) { + sb.append(exTypes[i].getName()); + if (i+1 < exTypes.length) sb.append(","); + } + sb.append(" "); + } + sb.append(": "); + sb.append(getPointcutExpression().asString()); + return sb.toString(); + } + } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java index bb5faf655..7ecebd13b 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java @@ -24,7 +24,11 @@ import java.util.EnumSet; import java.util.List; import java.util.Set; +import org.aspectj.internal.lang.annotation.ajcDeclareAnnotation; import org.aspectj.internal.lang.annotation.ajcDeclareEoW; +import org.aspectj.internal.lang.annotation.ajcDeclareParents; +import org.aspectj.internal.lang.annotation.ajcDeclarePrecedence; +import org.aspectj.internal.lang.annotation.ajcDeclareSoft; import org.aspectj.internal.lang.annotation.ajcPrivileged; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; @@ -526,13 +530,13 @@ public class AjTypeImpl<T> implements AjType<T> { if (afterReturningAnn != null) { String pcExpr = afterReturningAnn.pointcut(); if (pcExpr.equals("")) pcExpr = afterReturningAnn.value(); - return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_RETURNING); + return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_RETURNING,afterReturningAnn.returning()); } AfterThrowing afterThrowingAnn = method.getAnnotation(AfterThrowing.class); if (afterThrowingAnn != null) { String pcExpr = afterThrowingAnn.pointcut(); if (pcExpr == null) pcExpr = afterThrowingAnn.value(); - return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_THROWING); + return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_THROWING,afterThrowingAnn.throwing()); } Around aroundAnn = method.getAnnotation(Around.class); if (aroundAnn != null) return new AdviceImpl(method,aroundAnn.value(),AdviceKind.AROUND); @@ -684,31 +688,121 @@ public class AjTypeImpl<T> implements AjType<T> { * @see org.aspectj.lang.reflect.AjType#getDeclareParents() */ public DeclareParents[] getDeclareParents() { - // TODO Auto-generated method stub - return null; + List<DeclareParents> decps = new ArrayList<DeclareParents>(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(ajcDeclareParents.class)) { + ajcDeclareParents decPAnn = method.getAnnotation(ajcDeclareParents.class); + DeclareParentsImpl decp = new DeclareParentsImpl( + decPAnn.targetTypePattern(), + decPAnn.parentTypes(), + decPAnn.isExtends(), + this + ); + decps.add(decp); + } + } + if (getSupertype().isAspect()) { + decps.addAll(Arrays.asList(getSupertype().getDeclareParents())); + } + DeclareParents[] ret = new DeclareParents[decps.size()]; + decps.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclareSofts() */ public DeclareSoft[] getDeclareSofts() { - return null; + List<DeclareSoft> decs = new ArrayList<DeclareSoft>(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(ajcDeclareSoft.class)) { + ajcDeclareSoft decSAnn = method.getAnnotation(ajcDeclareSoft.class); + DeclareSoftImpl ds = new DeclareSoftImpl( + this, + decSAnn.pointcut(), + decSAnn.exceptionType() + ); + decs.add(ds); + } + } + if (getSupertype().isAspect()) { + decs.addAll(Arrays.asList(getSupertype().getDeclareSofts())); + } + DeclareSoft[] ret = new DeclareSoft[decs.size()]; + decs.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclareAnnotations() */ public DeclareAnnotation[] getDeclareAnnotations() { - // TODO Auto-generated method stub - return null; + List<DeclareAnnotation> decAs = new ArrayList<DeclareAnnotation>(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(ajcDeclareAnnotation.class)) { + ajcDeclareAnnotation decAnn = method.getAnnotation(ajcDeclareAnnotation.class); + // the target annotation is on this method... + Annotation targetAnnotation = null; + Annotation[] anns = method.getAnnotations(); + for (Annotation ann: anns) { + if (ann.annotationType() != ajcDeclareAnnotation.class) { + // this must be the one... + targetAnnotation = ann; + break; + } + } + DeclareAnnotationImpl da = new DeclareAnnotationImpl( + this, + decAnn.kind(), + decAnn.pattern(), + targetAnnotation, + decAnn.annotation() + ); + decAs.add(da); + } + } + if (getSupertype().isAspect()) { + decAs.addAll(Arrays.asList(getSupertype().getDeclareAnnotations())); + } + DeclareAnnotation[] ret = new DeclareAnnotation[decAs.size()]; + decAs.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclarePrecedence() */ public DeclarePrecedence[] getDeclarePrecedence() { - // TODO Auto-generated method stub - return null; + List<DeclarePrecedence> decps = new ArrayList<DeclarePrecedence>(); + + // @AspectJ Style + if (clazz.isAnnotationPresent(org.aspectj.lang.annotation.DeclarePrecedence.class)) { + org.aspectj.lang.annotation.DeclarePrecedence ann = + clazz.getAnnotation(org.aspectj.lang.annotation.DeclarePrecedence.class); + DeclarePrecedenceImpl decp = new DeclarePrecedenceImpl( + ann.value(), + this + ); + decps.add(decp); + } + + // annotated code-style + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(ajcDeclarePrecedence.class)) { + ajcDeclarePrecedence decPAnn = method.getAnnotation(ajcDeclarePrecedence.class); + DeclarePrecedenceImpl decp = new DeclarePrecedenceImpl( + decPAnn.value(), + this + ); + decps.add(decp); + } + } + if (getSupertype().isAspect()) { + decps.addAll(Arrays.asList(getSupertype().getDeclarePrecedence())); + } + DeclarePrecedence[] ret = new DeclarePrecedence[decps.size()]; + decps.toArray(ret); + return ret; } /* (non-Javadoc) @@ -819,5 +913,7 @@ public class AjTypeImpl<T> implements AjType<T> { } return classes; } + + public String toString() { return getName(); } } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java new file mode 100644 index 000000000..bcc91b987 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java @@ -0,0 +1,115 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import java.lang.annotation.Annotation; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.DeclareAnnotation; +import org.aspectj.lang.reflect.SignaturePattern; +import org.aspectj.lang.reflect.TypePattern; + +/** + * @author colyer + * + */ +public class DeclareAnnotationImpl implements DeclareAnnotation { + + private Annotation theAnnotation; + private String annText; + private AjType<?> declaringType; + private DeclareAnnotation.Kind kind; + private TypePattern typePattern; + private SignaturePattern signaturePattern; + + public DeclareAnnotationImpl(AjType<?> declaring, String kindString, String pattern, Annotation ann, String annText) { + this.declaringType = declaring; + if (kindString.equals("at_type")) this.kind = DeclareAnnotation.Kind.Type; + else if (kindString.equals("at_field")) this.kind = DeclareAnnotation.Kind.Field; + else if (kindString.equals("at_method")) this.kind = DeclareAnnotation.Kind.Method; + else if (kindString.equals("at_constructor")) this.kind = DeclareAnnotation.Kind.Constructor; + else throw new IllegalStateException("Unknown declare annotation kind: " + kindString); + if (kind == DeclareAnnotation.Kind.Type) { + this.typePattern = new TypePatternImpl(pattern); + } else { + this.signaturePattern = new SignaturePatternImpl(pattern); + } + this.theAnnotation = ann; + this.annText = annText; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareAnnotation#getDeclaringType() + */ + public AjType<?> getDeclaringType() { + return this.declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareAnnotation#getKind() + */ + public Kind getKind() { + return this.kind; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareAnnotation#getSignaturePattern() + */ + public SignaturePattern getSignaturePattern() { + return this.signaturePattern; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareAnnotation#getTypePattern() + */ + public TypePattern getTypePattern() { + return this.typePattern; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareAnnotation#getAnnotation() + */ + public Annotation getAnnotation() { + return this.theAnnotation; + } + + public String getAnnotationAsText() { + return this.annText; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("declare @"); + switch(getKind()) { + case Type: + sb.append("type : "); + sb.append(getTypePattern().asString()); + break; + case Method: + sb.append("method : "); + sb.append(getSignaturePattern().asString()); + break; + case Field: + sb.append("field : "); + sb.append(getSignaturePattern().asString()); + break; + case Constructor: + sb.append("constructor : "); + sb.append(getSignaturePattern().asString()); + break; + } + sb.append(" : "); + sb.append(getAnnotationAsText()); + return sb.toString(); + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java index f474698ea..5420f8274 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java @@ -55,5 +55,17 @@ public class DeclareErrorOrWarningImpl implements DeclareErrorOrWarning { public boolean isError() { return isError; } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("declare "); + sb.append(isError() ? "error : " : "warning : "); + sb.append(getPointcutExpression().asString()); + sb.append(" : "); + sb.append("\""); + sb.append(getMessage()); + sb.append("\""); + return sb.toString(); + } } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java new file mode 100644 index 000000000..1a04fc507 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java @@ -0,0 +1,151 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.StringTokenizer; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.DeclareParents; +import org.aspectj.lang.reflect.TypePattern; + +/** + * @author colyer + * + */ +public class DeclareParentsImpl implements DeclareParents { + + private AjType<?> declaringType; + private TypePattern targetTypesPattern; + private Type[] parents; + private String parentsString; + private String firstMissingTypeName; + private boolean isExtends; + private boolean parentsError = false; + + /** + * Parents arg is a comma-separate list of type names that needs to be turned into + * AjTypes + */ + public DeclareParentsImpl(String targets, String parentsAsString, boolean isExtends, AjType<?> declaring) + { + this.targetTypesPattern = new TypePatternImpl(targets); + this.isExtends = isExtends; + this.declaringType = declaring; + this.parentsString = parentsAsString; + this.parents = commaSeparatedListToTypeArray(parentsAsString); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareParents#getDeclaringType() + */ + public AjType getDeclaringType() { + return this.declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareParents#getTargetTypesPattern() + */ + public TypePattern getTargetTypesPattern() { + return this.targetTypesPattern; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareParents#isExtends() + */ + public boolean isExtends() { + return this.isExtends; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareParents#isImplements() + */ + public boolean isImplements() { + return !this.isExtends; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareParents#getParentTypes() + */ + public Type[] getParentTypes() throws ClassNotFoundException { + if (parentsError) { + throw new ClassNotFoundException(this.firstMissingTypeName); + } + return this.parents; + } + + private Type[] commaSeparatedListToTypeArray(String typeNames) { + StringTokenizer strTok = new StringTokenizer(typeNames,","); + Type[] ret = new Type[strTok.countTokens()]; + int index = 0; + outer: while (strTok.hasMoreTokens()) { + String parentTypeName = strTok.nextToken().trim(); + try { + if (parentTypeName.indexOf("<") == -1) { + ret[index] = AjTypeSystem.getAjType(Class.forName(parentTypeName)); + } else { + ret[index] = makeParameterizedType(parentTypeName); + } + } catch (ClassNotFoundException e) { + // could be a type variable + TypeVariable[] tVars = this.declaringType.getJavaClass().getTypeParameters(); + for (int i = 0; i < tVars.length; i++) { + if (tVars[i].getName().equals(parentTypeName)) { + ret[index] = tVars[i]; + continue outer; + } + } + ret[index] = null; + if (this.firstMissingTypeName == null) this.firstMissingTypeName = parentTypeName; + this.parentsError = true; + } + index++; + } + return ret; + } + + private Type makeParameterizedType(String typeName) + throws ClassNotFoundException { + int paramStart = typeName.indexOf('<'); + String baseName = typeName.substring(0, paramStart); + final Class baseClass = Class.forName(baseName); + int paramEnd = typeName.lastIndexOf('>'); + String params = typeName.substring(paramStart+1,paramEnd); + final Type[] typeParams = commaSeparatedListToTypeArray(params); + return new ParameterizedType() { + + public Type[] getActualTypeArguments() { + return typeParams; + } + + public Type getRawType() { + return baseClass; + } + + public Type getOwnerType() { + return baseClass.getEnclosingClass(); + } + }; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("declare parents : "); + sb.append(getTargetTypesPattern().asString()); + sb.append(isExtends() ? " extends " : " implements "); + sb.append(this.parentsString); + return sb.toString(); + } +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java new file mode 100644 index 000000000..7188606c6 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java @@ -0,0 +1,62 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import java.util.StringTokenizer; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.DeclarePrecedence; +import org.aspectj.lang.reflect.TypePattern; + +/** + * @author colyer + * + */ +public class DeclarePrecedenceImpl implements DeclarePrecedence { + + private AjType<?> declaringType; + private TypePattern[] precedenceList; + private String precedenceString; + + public DeclarePrecedenceImpl(String precedenceList, AjType declaring) { + this.declaringType = declaring; + this.precedenceString = precedenceList; + String toTokenize = precedenceList; + if (toTokenize.startsWith("(")) { + toTokenize = toTokenize.substring(1,toTokenize.length() - 1); + } + StringTokenizer strTok = new StringTokenizer(toTokenize,","); + this.precedenceList = new TypePattern[strTok.countTokens()]; + for (int i = 0; i < this.precedenceList.length; i++) { + this.precedenceList[i] = new TypePatternImpl(strTok.nextToken().trim()); + } + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclarePrecedence#getDeclaringType() + */ + public AjType getDeclaringType() { + return this.declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclarePrecedence#getPrecedenceOrder() + */ + public TypePattern[] getPrecedenceOrder() { + return this.precedenceList; + } + + public String toString() { + return "declare precedence : " + this.precedenceString; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java new file mode 100644 index 000000000..c980cdf8f --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java @@ -0,0 +1,75 @@ +/* ******************************************************************* + * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.internal.lang.reflect; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.DeclareSoft; +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +public class DeclareSoftImpl implements DeclareSoft { + + private AjType<?> declaringType; + private PointcutExpression pointcut; + private AjType<?> exceptionType; + private String missingTypeName; + + + public DeclareSoftImpl(AjType declaringType, String pcut, String exceptionTypeName) { + this.declaringType = declaringType; + this.pointcut = new PointcutExpressionImpl(pcut); + try { + this.exceptionType = AjTypeSystem.getAjType(Class.forName(exceptionTypeName)); + } catch (ClassNotFoundException ex) { + this.missingTypeName = exceptionTypeName; + } + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareSoft#getDeclaringType() + */ + public AjType getDeclaringType() { + return this.declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareSoft#getSoftenedExceptionType() + */ + public AjType getSoftenedExceptionType() throws ClassNotFoundException { + if (this.missingTypeName != null) throw new ClassNotFoundException(this.missingTypeName); + return this.exceptionType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareSoft#getPointcutExpression() + */ + public PointcutExpression getPointcutExpression() { + return this.pointcut; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("declare soft : "); + if (this.missingTypeName != null) { + sb.append(this.exceptionType.getName()); + } else { + sb.append(this.missingTypeName); + } + sb.append(" : "); + sb.append(getPointcutExpression().asString()); + return sb.toString(); + } +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java index 779e3a46e..663a44c20 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java @@ -33,4 +33,7 @@ public class PerClauseImpl implements PerClause { return kind; } + public String toString() { + return "issingleton()"; + } } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java index 3e3eb2f8e..5049d3a42 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java @@ -34,4 +34,16 @@ public class PointcutBasedPerClauseImpl extends PerClauseImpl implements return pointcutExpression; } + public String toString() { + StringBuffer sb = new StringBuffer(); + switch(getKind()) { + case PERCFLOW: sb.append("percflow("); break; + case PERCFLOWBELOW: sb.append("percflowbelow("); break; + case PERTARGET: sb.append("pertarget("); break; + case PERTHIS: sb.append("perthis("); break; + } + sb.append(this.pointcutExpression.asString()); + sb.append(")"); + return sb.toString(); + } } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java index 63c8764a3..b94f1c864 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java @@ -79,4 +79,22 @@ public class PointcutImpl implements Pointcut { } return ret; } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getName()); + sb.append("("); + AjType<?>[] ptypes = getParameterTypes(); + for (int i = 0; i < ptypes.length; i++) { + sb.append(ptypes[i].getName()); + if (this.parameterNames != null && this.parameterNames[i] != null) { + sb.append(" "); + sb.append(this.parameterNames[i]); + } + if (i+1 < ptypes.length) sb.append(","); + } + sb.append(") : "); + sb.append(getPointcutExpression().asString()); + return sb.toString(); + } } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java index df80a0e08..e9bb08573 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java @@ -35,5 +35,9 @@ public class TypePatternBasedPerClauseImpl extends PerClauseImpl implements public TypePattern getTypePattern() { return this.typePattern; } + + public String toString() { + return "pertypewithin(" + typePattern.asString() + ")"; + } } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java index 581c5a5fb..03be6c7f1 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java @@ -11,6 +11,8 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import java.lang.reflect.Type; + /** * Runtime representation of an advice declaration inside an aspect */ @@ -36,6 +38,21 @@ public interface Advice { String getName(); /** + * The advice parameters + */ + AjType<?>[] getParameterTypes(); + + /** + * The generic parameter types, @see java.lang.reflect.Method.getGenericParameterTypes + */ + Type[] getGenericParameterTypes(); + + /** + * The declared thrown exceptions by the advice + */ + AjType<?>[] getExceptionTypes(); + + /** * The pointcut expression associated with the advice declaration. */ PointcutExpression getPointcutExpression(); diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareAnnotation.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareAnnotation.java index 4e0f78aa7..faee5d495 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareAnnotation.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareAnnotation.java @@ -11,10 +11,46 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import java.lang.annotation.Annotation; + /** * The AspectJ runtime representation of a declare annotation member in an aspect. * */ public interface DeclareAnnotation { - + + public enum Kind { Field, Method, Constructor, Type }; + + /** + * The aspect that declared this member. + */ + AjType<?> getDeclaringType(); + + /** + * The target element kind + */ + Kind getKind(); + + /** + * The target signature pattern. Returns null if getKind() == Type + */ + SignaturePattern getSignaturePattern(); + + /** + * The target type pattern. Returns null if getKind() != Type + */ + TypePattern getTypePattern(); + + /** + * The declared annotation. If the declared annotation does not have runtime retention, + * this method returns null. + */ + Annotation getAnnotation(); + + /** + * Returns the text of the annotation as declared in this member. Available for + * both runtime and class-file retention annotations + */ + String getAnnotationAsText(); + } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareParents.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareParents.java index f8ee5c99d..8d3c98b78 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareParents.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareParents.java @@ -11,6 +11,8 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import java.lang.reflect.Type; + /** * A declare parents member defined inside an aspect */ @@ -40,6 +42,6 @@ public interface DeclareParents { * The set of types that the types matching getTargetTypesPattern are * declared to implement or extend */ - AjType[] getParentTypes(); + Type[] getParentTypes() throws ClassNotFoundException; } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareSoft.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareSoft.java index b397c94f3..cc607d680 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareSoft.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/DeclareSoft.java @@ -24,7 +24,7 @@ public interface DeclareSoft { /** * The softened exception type */ - AjType getSoftenedExceptionType(); + AjType getSoftenedExceptionType() throws ClassNotFoundException; /** * The pointcut determining the join points at which the exception is to be softened. diff --git a/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java index a01287d0a..7b15d3e64 100644 --- a/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java +++ b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java @@ -59,22 +59,27 @@ public class AjTypeTestsWithAspects extends TestCase { PerClause pc = perThisA.getPerClause(); assertEquals(PerClauseKind.PERTHIS,pc.getKind()); assertEquals("pc()",((PointcutBasedPerClause)pc).getPointcutExpression().asString()); + assertEquals("perthis(pc())",pc.toString()); pc= perTargetA.getPerClause(); assertEquals(PerClauseKind.PERTARGET,pc.getKind()); assertEquals("pc()",((PointcutBasedPerClause)pc).getPointcutExpression().asString()); + assertEquals("pertarget(pc())",pc.toString()); pc= perCflowA.getPerClause(); assertEquals(PerClauseKind.PERCFLOW,pc.getKind()); assertEquals("pc()",((PointcutBasedPerClause)pc).getPointcutExpression().asString()); + assertEquals("percflow(pc())",pc.toString()); pc= perCflowbelowA.getPerClause(); assertEquals(PerClauseKind.PERCFLOWBELOW,pc.getKind()); assertEquals("pc()",((PointcutBasedPerClause)pc).getPointcutExpression().asString()); + assertEquals("percflowbelow(pc())",pc.toString()); pc= perTypeWithinA.getPerClause(); assertEquals(PerClauseKind.PERTYPEWITHIN,pc.getKind()); assertEquals("org.aspectj..*",((TypePatternBasedPerClause)pc).getTypePattern().asString()); + assertEquals("pertypewithin(org.aspectj..*)",pc.toString()); } @@ -151,6 +156,7 @@ public class AjTypeTestsWithAspects extends TestCase { Pointcut p1 = sa.getDeclaredPointcut("simpleAspectMethodExecution"); assertEquals("simpleAspectMethodExecution",p1.getName()); assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression().asString()); + assertEquals("simpleAspectMethodExecution() : execution(* SimpleAspect.*(..))",p1.toString()); assertEquals(sa,p1.getDeclaringType()); assertEquals(0,p1.getParameterTypes().length); assertTrue(Modifier.isPublic(p1.getModifiers())); @@ -231,10 +237,12 @@ public class AjTypeTestsWithAspects extends TestCase { atwo = advice[0]; } assertEquals("execution(* SimpleAspect.*(..))",aone.getPointcutExpression().toString()); + assertEquals("@AdviceName(\"logEntry\") before() : execution(* SimpleAspect.*(..))",aone.toString()); assertEquals("logEntry",aone.getName()); assertEquals(AdviceKind.BEFORE,aone.getKind()); assertEquals("execution(* SimpleAspect.*(..))",atwo.getPointcutExpression().toString()); assertEquals("",atwo.getName()); + assertEquals("before() : execution(* SimpleAspect.*(..))",atwo.toString()); } public void testGetAdvice() { @@ -320,7 +328,10 @@ public class AjTypeTestsWithAspects extends TestCase { boolean foundAnnError = false; for (DeclareErrorOrWarning deow : deows) { if (deow.isError()) { - if (deow.getMessage().equals("dont call this method code")) foundCodeError = true; + if (deow.getMessage().equals("dont call this method code")) { + foundCodeError = true; + assertEquals("declare error : call(* DontDoIt.*(..)) : \"dont call this method code\"",deow.toString()); + } if (deow.getMessage().equals("dont call this method ann")) foundAnnError = true; assertEquals("call(* DontDoIt.*(..))",deow.getPointcutExpression().toString()); } else { diff --git a/lib/aspectj/lib/aspectjrt.jar b/lib/aspectj/lib/aspectjrt.jar Binary files differindex 2d53746c7..9c65f72d7 100644 --- a/lib/aspectj/lib/aspectjrt.jar +++ b/lib/aspectj/lib/aspectjrt.jar diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar Binary files differindex 2d53746c7..9c65f72d7 100644 --- a/lib/test/aspectjrt.jar +++ b/lib/test/aspectjrt.jar diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java index 225ac7e0d..35ea7c5d3 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java @@ -297,7 +297,7 @@ public class AdviceDeclaration extends AjMethodDeclaration { } else if (kind == AdviceKind.Around) { adviceAnnotation = AtAspectJAnnotationFactory.createAroundAnnotation(pointcutExpression,declarationSourceStart); } - AtAspectJAnnotationFactory.addAnnotation(this, adviceAnnotation); + AtAspectJAnnotationFactory.addAnnotation(this, adviceAnnotation,this.scope); } // override, Called by ClassScope.postParse diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java index b8a8c8c37..79fdb87be 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java @@ -20,6 +20,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TrueLiteral; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FalseLiteral; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits; /** @@ -44,6 +45,10 @@ public class AtAspectJAnnotationFactory { static final char[] around = "Around".toCharArray(); static final char[] pointcut = "Pointcut".toCharArray(); static final char[] declareErrorOrWarning = "ajcDeclareEoW".toCharArray(); + static final char[] declareParents = "ajcDeclareParents".toCharArray(); + static final char[] declareSoft = "ajcDeclareSoft".toCharArray(); + static final char[] declarePrecedence = "ajcDeclarePrecedence".toCharArray(); + static final char[] declareAnnotation = "ajcDeclareAnnotation".toCharArray(); /** * Create an @Aspect annotation for a code style aspect declaration starting at @@ -151,6 +156,66 @@ public class AtAspectJAnnotationFactory { return ann; } + public static Annotation createDeclareParentsAnnotation(String childPattern, String parentPatterns, boolean isExtends, int pos) { + char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,declareParents}; + long[] positions = new long[typeName.length]; + for (int i = 0; i < positions.length; i++) positions[i] = pos; + TypeReference annType = new QualifiedTypeReference(typeName,positions); + NormalAnnotation ann = new NormalAnnotation(annType,pos); + Expression targetExpression = new StringLiteral(childPattern.toCharArray(),pos,pos); + Expression parentsExpression = new StringLiteral(parentPatterns.toCharArray(),pos,pos); + Expression isExtendsExpression; + if (isExtends) { + isExtendsExpression = new TrueLiteral(pos,pos); + } else { + isExtendsExpression = new FalseLiteral(pos,pos); + } + MemberValuePair[] mvps = new MemberValuePair[3]; + mvps[0] = new MemberValuePair("targetTypePattern".toCharArray(),pos,pos,targetExpression); + mvps[1] = new MemberValuePair("parentTypes".toCharArray(),pos,pos,parentsExpression); + mvps[2] = new MemberValuePair("isExtends".toCharArray(),pos,pos,isExtendsExpression); + ann.memberValuePairs = mvps; + return ann; + } + + public static Annotation createDeclareSoftAnnotation(String pointcutExpression, String exceptionType, int pos) { + char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,declareSoft}; + long[] positions = new long[typeName.length]; + for (int i = 0; i < positions.length; i++) positions[i] = pos; + TypeReference annType = new QualifiedTypeReference(typeName,positions); + NormalAnnotation ann = new NormalAnnotation(annType,pos); + Expression pcutExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos); + Expression exExpr = new StringLiteral(exceptionType.toCharArray(),pos,pos); + MemberValuePair[] mvps = new MemberValuePair[2]; + mvps[0] = new MemberValuePair("pointcut".toCharArray(),pos,pos,pcutExpr); + mvps[1] = new MemberValuePair("exceptionType".toCharArray(),pos,pos,exExpr); + ann.memberValuePairs = mvps; + return ann; + } + + public static Annotation createDeclareAnnAnnotation(String patternString, String annString, String kind, int pos) { + char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,declareAnnotation}; + long[] positions = new long[typeName.length]; + for (int i = 0; i < positions.length; i++) positions[i] = pos; + TypeReference annType = new QualifiedTypeReference(typeName,positions); + NormalAnnotation ann = new NormalAnnotation(annType,pos); + Expression pattExpr = new StringLiteral(patternString.toCharArray(),pos,pos); + Expression annExpr = new StringLiteral(annString.toCharArray(),pos,pos); + Expression kindExpr = new StringLiteral(kind.toCharArray(),pos,pos); + MemberValuePair[] mvps = new MemberValuePair[3]; + mvps[0] = new MemberValuePair("pattern".toCharArray(),pos,pos,pattExpr); + mvps[1] = new MemberValuePair("annotation".toCharArray(),pos,pos,annExpr); + mvps[2] = new MemberValuePair("kind".toCharArray(),pos,pos,kindExpr); + ann.memberValuePairs = mvps; + return ann; + } + + public static Annotation createDeclarePrecedenceAnnotation(String pointcutExpression, int pos) { + char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,declarePrecedence}; + return makeSingleStringMemberAnnotation(typeName, pos, pointcutExpression); + + } + private static Annotation makeSingleStringMemberAnnotation(char[][] name, int pos, String annValue) { long[] positions = new long[name.length]; for (int i = 0; i < positions.length; i++) positions[i] = pos; @@ -163,7 +228,7 @@ public class AtAspectJAnnotationFactory { return ann; } - public static void addAnnotation(AjMethodDeclaration decl, Annotation annotation) { + public static void addAnnotation(AjMethodDeclaration decl, Annotation annotation, BlockScope scope) { if (decl.annotations == null) { decl.annotations = new Annotation[] { annotation }; } else { @@ -173,7 +238,9 @@ public class AtAspectJAnnotationFactory { decl.annotations[old.length] = annotation; } if (decl.binding!= null) { - decl.binding.tagBits -= TagBits.AnnotationResolved; + if ((decl.binding.tagBits & TagBits.AnnotationResolved) != 0) { + annotation.resolve(scope); + } } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java index e9988b6e0..d0d62dffb 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java @@ -15,6 +15,9 @@ package org.aspectj.ajdt.internal.compiler.ast; //import java.util.List; +import java.util.Collection; +import java.util.Iterator; + import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope; import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; @@ -25,6 +28,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser; import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.DeclareErrorOrWarning; @@ -58,19 +62,38 @@ public class DeclareDeclaration extends AjMethodDeclaration { public void addAtAspectJAnnotations() { Annotation annotation = null; if (declareDecl instanceof DeclareAnnotation) { - + DeclareAnnotation da = (DeclareAnnotation) declareDecl; + String patternString = da.getPatternAsString(); + String annString = da.getAnnotationString(); + String kind = da.getKind().toString(); + annotation = AtAspectJAnnotationFactory.createDeclareAnnAnnotation( + patternString,annString,kind,declarationSourceStart); } else if (declareDecl instanceof DeclareErrorOrWarning) { DeclareErrorOrWarning dd = (DeclareErrorOrWarning) declareDecl; annotation = AtAspectJAnnotationFactory .createDeclareErrorOrWarningAnnotation(dd.getPointcut().toString(),dd.getMessage(),dd.isError(),declarationSourceStart); } else if (declareDecl instanceof DeclareParents) { - + DeclareParents dp = (DeclareParents) declareDecl; + String childPattern = dp.getChild().toString(); + Collection parentPatterns = dp.getParents().getExactTypes(); + StringBuffer parents = new StringBuffer(); + for (Iterator iter = parentPatterns.iterator(); iter.hasNext();) { + UnresolvedType urt = ((UnresolvedType) iter.next()); + parents.append(urt.getName()); + if (iter.hasNext()) parents.append(", "); + } + annotation = AtAspectJAnnotationFactory + .createDeclareParentsAnnotation(childPattern,parents.toString(),dp.isExtends(),declarationSourceStart); } else if (declareDecl instanceof DeclarePrecedence) { - + DeclarePrecedence dp = (DeclarePrecedence) declareDecl; + String precedenceList = dp.getPatterns().toString(); + annotation = AtAspectJAnnotationFactory.createDeclarePrecedenceAnnotation(precedenceList,declarationSourceStart); } else if (declareDecl instanceof DeclareSoft) { - + DeclareSoft ds = (DeclareSoft) declareDecl; + annotation = AtAspectJAnnotationFactory + .createDeclareSoftAnnotation(ds.getPointcut().toString(),ds.getException().getExactType().getName(),declarationSourceStart); } - if (annotation != null) AtAspectJAnnotationFactory.addAnnotation(this,annotation); + if (annotation != null) AtAspectJAnnotationFactory.addAnnotation(this,annotation,this.scope); } /** diff --git a/tests/bugs150/pr101047.aj b/tests/bugs150/pr101047.aj new file mode 100644 index 000000000..f64bd6ebc --- /dev/null +++ b/tests/bugs150/pr101047.aj @@ -0,0 +1,30 @@ +aspect Test { + before() : ( execution(* Foo.foo(..) ) ) { + System.out.println("before"); + + } +} + +class Foo { + private String myString = "A String"; + + public static void main(String[] args) { + new Foo().foo(); + } + + private void foo() { + String myLocal = myString; + + if (myLocal.endsWith("X")) { + String local1 = "local1"; + System.out.println(local1); + } else if (myLocal.endsWith("Y")) { + String local2 = "local2"; + System.out.println(local2); + } else { + String local1 = "local3"; + System.out.println(local1); + } + } +} + diff --git a/tests/java5/ataspectj/annotationGen/DeclareAnnotationTest.aj b/tests/java5/ataspectj/annotationGen/DeclareAnnotationTest.aj new file mode 100644 index 000000000..0c3e4608d --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/DeclareAnnotationTest.aj @@ -0,0 +1,77 @@ +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; +import java.lang.annotation.*; + +public aspect DeclareAnnotationTest { + + declare @type : a.b.c..* : @MyAnnotation("ady 1"); + + declare @method : * *(String) : @MyAnnotation("ady 2"); + + declare @field : java.io.Serializable+ * : @MyClassRetentionAnnotation("ady 3"); + + declare @constructor : new(String,..) : @MyAnnotation; + + public static void main(String[] args) throws ClassNotFoundException { + AjType<DeclareAnnotationTest> myType = AjTypeSystem.getAjType(DeclareAnnotationTest.class); + DeclareAnnotation[] decAs = myType.getDeclareAnnotations(); + if (decAs.length != 4) throw new RuntimeException("Expecting 4 members, got " + decAs.length); + // should be in declaration order... + checkAtType(decAs[0]); + checkAtMethod(decAs[1]); + checkAtField(decAs[2]); + checkAtConstructor(decAs[3]); + } + + + private static void checkAtType(DeclareAnnotation da) { + if (da.getKind() != DeclareAnnotation.Kind.Type) throw new RuntimeException("expecting @type"); + if (da.getSignaturePattern() != null) throw new RuntimeException("not expecting a signature pattern"); + if (!da.getTypePattern().asString().equals("a.b.c..*")) throw new RuntimeException("expecting 'a.b.c..*' but got '" + da.getTypePattern().asString() + "'"); + if (da.getDeclaringType().getJavaClass() != DeclareAnnotationTest.class) throw new RuntimeException("bad declaring type: " + da.getDeclaringType()); + MyAnnotation ma = (MyAnnotation) da.getAnnotation(); + if (!ma.value().equals("ady 1")) throw new RuntimeException("bad value: " + ma.value()); + if (!da.getAnnotationAsText().equals("@MyAnnotation(\"ady 1\")")) throw new RuntimeException("bad annotation text: " + da.getAnnotationAsText()); + } + + private static void checkAtMethod(DeclareAnnotation da) { + if (da.getKind() != DeclareAnnotation.Kind.Method) throw new RuntimeException("expecting @method"); + if (da.getTypePattern() != null) throw new RuntimeException("not expecting a type pattern"); + if (!da.getSignaturePattern().asString().equals("* *(java.lang.String)")) throw new RuntimeException("expecting '* *(java.lang.String)' but got '" + da.getSignaturePattern().asString() + "'"); + if (da.getDeclaringType().getJavaClass() != DeclareAnnotationTest.class) throw new RuntimeException("bad declaring type: " + da.getDeclaringType()); + MyAnnotation ma = (MyAnnotation) da.getAnnotation(); + if (!ma.value().equals("ady 2")) throw new RuntimeException("bad value: " + ma.value()); + if (!da.getAnnotationAsText().equals("@MyAnnotation(\"ady 2\")")) throw new RuntimeException("bad annotation text: " + da.getAnnotationAsText()); + } + + private static void checkAtField(DeclareAnnotation da) { + if (da.getKind() != DeclareAnnotation.Kind.Field) throw new RuntimeException("expecting @field"); + if (da.getTypePattern() != null) throw new RuntimeException("not expecting a type pattern"); + if (!da.getSignaturePattern().asString().equals("java.io.Serializable+ *")) throw new RuntimeException("expecting 'java.io.Serializable+ *' but got '" + da.getSignaturePattern().asString() + "'"); + if (da.getDeclaringType().getJavaClass() != DeclareAnnotationTest.class) throw new RuntimeException("bad declaring type: " + da.getDeclaringType()); + if (da.getAnnotation() != null) throw new RuntimeException("expecting null annotation, but got " + da.getAnnotation()); + if (!da.getAnnotationAsText().equals("@MyClassRetentionAnnotation(\"ady 3\")")) throw new RuntimeException("bad annotation text: " + da.getAnnotationAsText()); + } + + private static void checkAtConstructor(DeclareAnnotation da) { + if (da.getKind() != DeclareAnnotation.Kind.Constructor) throw new RuntimeException("expecting @constructor"); + if (da.getTypePattern() != null) throw new RuntimeException("not expecting a type pattern"); + if (!da.getSignaturePattern().asString().equals("new(java.lang.String, ..)")) throw new RuntimeException("expecting 'new(java.lang.String,..)' but got '" + da.getSignaturePattern().asString() + "'"); + if (da.getDeclaringType().getJavaClass() != DeclareAnnotationTest.class) throw new RuntimeException("bad declaring type: " + da.getDeclaringType()); + MyAnnotation ma = (MyAnnotation) da.getAnnotation(); + if (!ma.value().equals("some value")) throw new RuntimeException("bad value: " + ma.value()); + if (!da.getAnnotationAsText().equals("@MyAnnotation")) throw new RuntimeException("bad annotation text: " + da.getAnnotationAsText()); + } + +} + +@Retention(RetentionPolicy.RUNTIME) +@interface MyAnnotation { + + String value() default "some value"; + +} + +@interface MyClassRetentionAnnotation { + String value(); +} diff --git a/tests/java5/ataspectj/annotationGen/DeclareParentsTest.aj b/tests/java5/ataspectj/annotationGen/DeclareParentsTest.aj new file mode 100644 index 000000000..0a0da6769 --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/DeclareParentsTest.aj @@ -0,0 +1,56 @@ +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; + +public aspect DeclareParentsTest { + + declare parents : B || C extends A; + + declare parents : A implements I,J; + + public static void main(String[] args) throws ClassNotFoundException { + AjType<DeclareParentsTest> myType = AjTypeSystem.getAjType(DeclareParentsTest.class); + DeclareParents[] decPs = myType.getDeclareParents(); + if (decPs.length != 2) throw new RuntimeException("Expecting 2 members, got " + decPs.length); + if (decPs[0].isExtends()) { + checkExtends(decPs[0]); + checkImplements(decPs[1]); + } else { + checkExtends(decPs[1]); + checkImplements(decPs[0]); + } + } + + private static void checkExtends(DeclareParents extendsDecP) throws ClassNotFoundException { + if (!extendsDecP.isExtends()) throw new RuntimeException("Should be extends"); + AjType declaring = extendsDecP.getDeclaringType(); + if (declaring.getJavaClass() != DeclareParentsTest.class) throw new RuntimeException("wrong declaring type"); + TypePattern tp = extendsDecP.getTargetTypesPattern(); + if (!tp.asString().equals("(B || C)")) throw new RuntimeException("expecting (B || C) but got '" + tp.asString() + "'"); + Type[] parentTypes = extendsDecP.getParentTypes(); + if (parentTypes.length != 1) throw new RuntimeException("expecting 1 parent type"); + if (((AjType<?>)parentTypes[0]).getJavaClass() != A.class) throw new RuntimeException("expecting parent to be A but was '" + ((AjType<?>)parentTypes[0]).getName() + "'"); + } + + private static void checkImplements(DeclareParents implementsDecP) throws ClassNotFoundException { + if (!implementsDecP.isImplements()) throw new RuntimeException("Should be implements"); + AjType declaring = implementsDecP.getDeclaringType(); + if (declaring.getJavaClass() != DeclareParentsTest.class) throw new RuntimeException("wrong declaring type"); + TypePattern tp = implementsDecP.getTargetTypesPattern(); + if (!tp.asString().equals("A")) throw new RuntimeException("expecting A but got '" + tp.asString() + "'"); + Type[] parentTypes = implementsDecP.getParentTypes(); + if (parentTypes.length != 2) throw new RuntimeException("expecting 2 parent types"); + if (((AjType<?>)parentTypes[0]).getJavaClass() != I.class) throw new RuntimeException("expecting parent to be I but was '" + ((AjType<?>)parentTypes[0]).getName() + "'"); + if (((AjType<?>)parentTypes[1]).getJavaClass() != J.class) throw new RuntimeException("expecting parent to be J but was '" + ((AjType<?>)parentTypes[0]).getName() + "'"); + } +} + + +class A {} + +class B {} + +class C {} + +interface I {} + +interface J {}
\ No newline at end of file diff --git a/tests/java5/ataspectj/annotationGen/DeclareParentsTestAdvanced.aj b/tests/java5/ataspectj/annotationGen/DeclareParentsTestAdvanced.aj new file mode 100644 index 000000000..12d516e94 --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/DeclareParentsTestAdvanced.aj @@ -0,0 +1,39 @@ +package a.b.c; + +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; + +public class DeclareParentsTestAdvanced { + + public static void main(String[] args) throws ClassNotFoundException { + AjType<ConcreteAspect> aType = AjTypeSystem.getAjType(ConcreteAspect.class); + DeclareParents[] decPs = aType.getDeclareParents(); + if (decPs.length != 1) throw new RuntimeException("should see decp from super"); + DeclareParents dp = decPs[0]; + if (!dp.isImplements()) throw new RuntimeException("Expecting implements"); + if (dp.getDeclaringType().getJavaClass() != AbstractAspect.class) { + throw new RuntimeException("Expecting declaring class to be AbstractAspect"); + } + TypePattern tp = dp.getTargetTypesPattern(); + if (!tp.asString().equals("a.b.c.A")) { + throw new RuntimeException("expecting 'a.b.c.A' but was '" + tp.asString() + "'"); + } + Type[] parents = dp.getParentTypes(); + if (parents.length != 1) throw new RuntimeException("expecting 1 parent"); + if (((AjType)parents[0]).getJavaClass() != B.class) { + throw new RuntimeException("expecting 'B' but was '" + parents[0].toString() + "'"); + } + } +} + +abstract aspect AbstractAspect { + + declare parents : A implements B; + +} + +aspect ConcreteAspect extends AbstractAspect {} + +class A {} + +class B {}
\ No newline at end of file diff --git a/tests/java5/ataspectj/annotationGen/DeclarePrecedenceTest.aj b/tests/java5/ataspectj/annotationGen/DeclarePrecedenceTest.aj new file mode 100644 index 000000000..d8cda81a1 --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/DeclarePrecedenceTest.aj @@ -0,0 +1,35 @@ +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; + +@org.aspectj.lang.annotation.DeclarePrecedence("DeclarePrecedenceTest,*") +public aspect DeclarePrecedenceTest { + + declare precedence : org.xyz..*, org.abc..*; + + declare precedence : org.abc..*, org.def..*; + + + public static void main(String[] args) throws ClassNotFoundException { + AjType<DeclarePrecedenceTest> myType = AjTypeSystem.getAjType(DeclarePrecedenceTest.class); + DeclarePrecedence[] decPs = myType.getDeclarePrecedence(); + if (decPs.length != 3) throw new RuntimeException("Expecting 3 members, got " + decPs.length); + for(int i = 0; i < decPs.length; i++) { + validateDecP(decPs[i]); + } + } + + private static void validateDecP(DeclarePrecedence dp) { + TypePattern[] tps = dp.getPrecedenceOrder(); + if (tps.length != 2) throw new RuntimeException("Expecting 2 type patterns, got " + tps.length); + if (tps[0].asString().equals("DeclarePrecedenceTest")) { + if (!tps[1].asString().equals("*")) throw new RuntimeException("Excepting '*', got '" + tps[1].asString() + "'"); + } else if (tps[0].asString().equals("org.xyz..*")) { + if (!tps[1].asString().equals("org.abc..*")) throw new RuntimeException("Excepting 'org.abc..*', got '" + tps[1].asString() + "'"); + } else if (tps[0].asString().equals("org.abc..*")) { + if (!tps[1].asString().equals("org.def..*")) throw new RuntimeException("Excepting 'org.def..*', got '" + tps[1].asString() + "'"); + } else { + throw new RuntimeException("Unexpected type pattern: " + tps[0].asString()); + } + } + +} diff --git a/tests/java5/ataspectj/annotationGen/DeclareSoftTest.aj b/tests/java5/ataspectj/annotationGen/DeclareSoftTest.aj new file mode 100644 index 000000000..0dd4c1f6f --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/DeclareSoftTest.aj @@ -0,0 +1,22 @@ +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; + +public aspect DeclareSoftTest { + + declare soft : ClassNotFoundException : call(* Class.forName(..)); + + + public static void main(String[] args) throws ClassNotFoundException { + AjType<DeclareSoftTest> myType = AjTypeSystem.getAjType(DeclareSoftTest.class); + DeclareSoft[] decSs = myType.getDeclareSofts(); + if (decSs.length != 1) throw new RuntimeException("Expecting 1 members, got " + decSs.length); + if (decSs[0].getDeclaringType() != myType) throw new RuntimeException("Bad declaring type: " + decSs[0].getDeclaringType()); + String pc = decSs[0].getPointcutExpression().asString(); + if (!pc.equals("call(* java.lang.Class.forName(..))")) throw new RuntimeException("Bad pcut: " + pc); + AjType exType = decSs[0].getSoftenedExceptionType(); + if (exType != AjTypeSystem.getAjType(ClassNotFoundException.class)) { + throw new RuntimeException("Bad ex type: " + exType); + } + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index c909bb204..b91a3714d 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -2408,7 +2408,7 @@ </ajc-test> <ajc-test dir="java5/annotations/declare" title="declare @type - covering enum and class element values - binary weaving"> - <weave aspectsFiles="EnumAndClassValues.aj" classesFiles="FunkyAnnotations.java" options="-1.5" xlintfile="ignoreTypeNotExposed.properties"/> + <weave aspectsFiles="EnumAndClassValues.aj" classesFiles="FunkyAnnotations.java" options="-1.5 -Xdev:Pinpoint" xlintfile="ignoreTypeNotExposed.properties"/> <run class="FunkyAnnotations"> <stderr> <line text="advice running: Red"/> diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java index ba6717b95..c3711841f 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java @@ -130,5 +130,25 @@ public class AtAjAnnotationGenTests extends XMLBasedAjcTestCase { public void testRuntimePointcutsReferencingCompiledPointcuts() { runTest("runtime pointcut resolution referencing compiled pointcuts"); } + + public void testDecP() { + runTest("ann gen for decp"); + } + + public void testDecPAdvanced() { + runTest("ann gen for decp 2"); + } + + public void testDecS() { + runTest("ann gen for decs"); + } + + public void testDecPrecedence() { + runTest("ann gen for dec precedence"); + } + + public void testDecAnnotation() { + runTest("ann gen for dec annotation"); + } } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml index aa87be080..3e74a541a 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml @@ -148,5 +148,34 @@ </compile> <run class="RuntimePointcuts" classpath="../lib/bcel/bcel.jar"/> </ajc-test> + + <ajc-test dir="java5/ataspectj/annotationGen" title="ann gen for decp"> + <compile files="DeclareParentsTest.aj" options="-1.5"> + </compile> + <run class="DeclareParentsTest"/> + </ajc-test> + + <ajc-test dir="java5/ataspectj/annotationGen" title="ann gen for decp 2"> + <compile files="DeclareParentsTestAdvanced.aj" options="-1.5"> + </compile> + <run class="a.b.c.DeclareParentsTestAdvanced"/> + </ajc-test> + <ajc-test dir="java5/ataspectj/annotationGen" title="ann gen for decs"> + <compile files="DeclareSoftTest.aj" options="-1.5"> + </compile> + <run class="DeclareSoftTest"/> + </ajc-test> + + <ajc-test dir="java5/ataspectj/annotationGen" title="ann gen for dec precedence"> + <compile files="DeclarePrecedenceTest.aj" options="-1.5"> + </compile> + <run class="DeclarePrecedenceTest"/> + </ajc-test> + + <ajc-test dir="java5/ataspectj/annotationGen" title="ann gen for dec annotation"> + <compile files="DeclareAnnotationTest.aj" options="-1.5"> + </compile> + <run class="DeclareAnnotationTest"/> + </ajc-test> </suite>
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java index 0841f4dd3..2c1db8191 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java @@ -35,16 +35,18 @@ public class DeclareParents extends Declare { private TypePattern child; private TypePatternList parents; private boolean isWildChild = false; + private boolean isExtends = true; // private String[] typeVariablesInScope = new String[0]; // AspectJ 5 extension for generic types - public DeclareParents(TypePattern child, List parents) { - this(child, new TypePatternList(parents)); + public DeclareParents(TypePattern child, List parents, boolean isExtends) { + this(child, new TypePatternList(parents),isExtends); } - private DeclareParents(TypePattern child, TypePatternList parents) { + private DeclareParents(TypePattern child, TypePatternList parents, boolean isExtends) { this.child = child; this.parents = parents; + this.isExtends = isExtends; if (child instanceof WildTypePattern) isWildChild = true; } @@ -75,7 +77,8 @@ public class DeclareParents extends Declare { DeclareParents ret = new DeclareParents( child.parameterizeWith(typeVariableBindingMap), - parents.parameterizeWith(typeVariableBindingMap)); + parents.parameterizeWith(typeVariableBindingMap), + isExtends); ret.copyLocationFrom(this); return ret; } @@ -84,7 +87,7 @@ public class DeclareParents extends Declare { StringBuffer buf = new StringBuffer(); buf.append("declare parents: "); buf.append(child); - buf.append(" extends "); //extends and implements are treated equivalently + buf.append(isExtends ? " extends " : " implements "); //extends and implements are treated equivalently buf.append(parents); buf.append(";"); return buf.toString(); @@ -117,7 +120,7 @@ public class DeclareParents extends Declare { } public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException { - DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context)); + DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context),true); // if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { // int numTypeVariablesInScope = s.readInt(); // ret.typeVariablesInScope = new String[numTypeVariablesInScope]; @@ -161,6 +164,11 @@ public class DeclareParents extends Declare { return child; } + // note - will always return true after deserialization, this doesn't affect weaver + public boolean isExtends() { + return this.isExtends; + } + public boolean isAdviceLike() { return false; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java index 8bd7ccb4b..ede05652f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java @@ -202,6 +202,7 @@ public class PatternParser { if (!(t.getString().equals("extends") || t.getString().equals("implements"))) { throw new ParserException("extends or implements", t); } + boolean isExtends = t.getString().equals("extends"); List l = new ArrayList(); do { @@ -210,7 +211,7 @@ public class PatternParser { //XXX somewhere in the chain we need to enforce that we have only ExactTypePatterns - DeclareParents decp = new DeclareParents(p, l); + DeclareParents decp = new DeclareParents(p, l,isExtends); return decp; } |