From 0fae66242efd3fd91dc7ace349cdcf7e5ebc2ade Mon Sep 17 00:00:00 2001 From: acolyer Date: Mon, 3 Oct 2005 16:17:15 +0000 Subject: [PATCH] completes all of the MAP bar ITDs --- .../lang/annotation/ajcDeclareAnnotation.java | 25 +++ .../lang/annotation/ajcDeclareParents.java | 31 ++++ .../lang/annotation/ajcDeclarePrecedence.java | 32 ++++ .../lang/annotation/ajcDeclareSoft.java | 2 +- .../internal/lang/reflect/AdviceImpl.java | 126 +++++++++++++++ .../internal/lang/reflect/AjTypeImpl.java | 114 +++++++++++-- .../lang/reflect/DeclareAnnotationImpl.java | 115 +++++++++++++ .../reflect/DeclareErrorOrWarningImpl.java | 12 ++ .../lang/reflect/DeclareParentsImpl.java | 151 ++++++++++++++++++ .../lang/reflect/DeclarePrecedenceImpl.java | 62 +++++++ .../lang/reflect/DeclareSoftImpl.java | 75 +++++++++ .../internal/lang/reflect/PerClauseImpl.java | 3 + .../reflect/PointcutBasedPerClauseImpl.java | 12 ++ .../internal/lang/reflect/PointcutImpl.java | 18 +++ .../TypePatternBasedPerClauseImpl.java | 4 + .../org/aspectj/lang/reflect/Advice.java | 17 ++ .../lang/reflect/DeclareAnnotation.java | 38 ++++- .../aspectj/lang/reflect/DeclareParents.java | 4 +- .../org/aspectj/lang/reflect/DeclareSoft.java | 2 +- .../lang/reflect/AjTypeTestsWithAspects.java | 13 +- lib/aspectj/lib/aspectjrt.jar | Bin 114037 -> 145821 bytes lib/test/aspectjrt.jar | Bin 114037 -> 145821 bytes .../compiler/ast/AdviceDeclaration.java | 2 +- .../ast/AtAspectJAnnotationFactory.java | 71 +++++++- .../compiler/ast/DeclareDeclaration.java | 33 +++- tests/bugs150/pr101047.aj | 30 ++++ .../annotationGen/DeclareAnnotationTest.aj | 77 +++++++++ .../annotationGen/DeclareParentsTest.aj | 56 +++++++ .../DeclareParentsTestAdvanced.aj | 39 +++++ .../annotationGen/DeclarePrecedenceTest.aj | 35 ++++ .../annotationGen/DeclareSoftTest.aj | 22 +++ .../org/aspectj/systemtest/ajc150/ajc150.xml | 2 +- .../ataspectj/AtAjAnnotationGenTests.java | 20 +++ .../ajc150/ataspectj/annotationgen.xml | 29 ++++ .../weaver/patterns/DeclareParents.java | 20 ++- .../weaver/patterns/PatternParser.java | 3 +- 36 files changed, 1265 insertions(+), 30 deletions(-) create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclareParents.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java create mode 100644 tests/bugs150/pr101047.aj create mode 100644 tests/java5/ataspectj/annotationGen/DeclareAnnotationTest.aj create mode 100644 tests/java5/ataspectj/annotationGen/DeclareParentsTest.aj create mode 100644 tests/java5/ataspectj/annotationGen/DeclareParentsTestAdvanced.aj create mode 100644 tests/java5/ataspectj/annotationGen/DeclarePrecedenceTest.aj create mode 100644 tests/java5/ataspectj/annotationGen/DeclareSoftTest.aj 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 implements AjType { 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 implements AjType { * @see org.aspectj.lang.reflect.AjType#getDeclareParents() */ public DeclareParents[] getDeclareParents() { - // TODO Auto-generated method stub - return null; + List decps = new ArrayList(); + 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 decs = new ArrayList(); + 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 decAs = new ArrayList(); + 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 decps = new ArrayList(); + + // @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 implements AjType { } 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 */ @@ -35,6 +37,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. */ 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 index 2d53746c761378400e65abfcdc0ab1e18a33b254..9c65f72d7e0161efcfff71d75a94db7083d59f61 100644 GIT binary patch delta 61951 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 diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar index 2d53746c761378400e65abfcdc0ab1e18a33b254..9c65f72d7e0161efcfff71d75a94db7083d59f61 100644 GIT binary patch delta 61951 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 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 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 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 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 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 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 @@ - + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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; } -- 2.39.5