From: Andy Clement Date: Thu, 24 Jan 2019 20:36:00 +0000 (-0800) Subject: mavenizing runtime module - merged in aspectj5rt X-Git-Tag: V1_9_3RC1~90 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=52c4cbfa1b8bcc0d2c7ac50c77203e516b335205;p=aspectj.git mavenizing runtime module - merged in aspectj5rt --- diff --git a/runtime/aspectj5rt.mf.txt b/runtime/aspectj5rt.mf.txt new file mode 100644 index 000000000..dcc05a161 --- /dev/null +++ b/runtime/aspectj5rt.mf.txt @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Automatic-Module-Name: org.aspectj.runtime + +Name: org/aspectj/lang/ +Specification-Title: AspectJ Runtime Classes +Specification-Version: @build.version.base@ +Specification-Vendor: @company.name@ +Implementation-Title: org.aspectj.tools +Implementation-Version: @build.version@ +Implementation-Vendor: @company.name@ +Bundle-Name: AspectJ Runtime +Bundle-Version: @build.version@ +Bundle-Copyright: (C) Copyright 1999-2001 Xerox Corporation, 2002 Palo + Alto Research Center, Incorporated (PARC), 2003-2009 Contributors. + All Rights Reserved. diff --git a/runtime/pom.xml b/runtime/pom.xml index 683d24aba..2abf9ec1b 100644 --- a/runtime/pom.xml +++ b/runtime/pom.xml @@ -14,4 +14,13 @@ jar runtime + + + + org.aspectj + testing-util + ${project.version} + + + diff --git a/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareAnnotation.java new file mode 100644 index 000000000..5835f3767 --- /dev/null +++ b/runtime/src/main/java/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/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareEoW.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareEoW.java new file mode 100644 index 000000000..e349d603e --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareEoW.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 declare soft declarations + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcDeclareEoW { + String message(); + String pointcut(); + boolean isError(); +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareParents.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareParents.java new file mode 100644 index 000000000..14860e006 --- /dev/null +++ b/runtime/src/main/java/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/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclarePrecedence.java new file mode 100644 index 000000000..ef6197557 --- /dev/null +++ b/runtime/src/main/java/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/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java new file mode 100644 index 000000000..f97de09e2 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcDeclareSoft.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * 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 declare soft declarations + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcDeclareSoft { + String exceptionType(); + String pointcut(); +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcITD.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcITD.java new file mode 100644 index 000000000..e67a25f1e --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcITD.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 ITDs + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ajcITD { + int modifiers(); + String targetType(); + String name(); +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcPrivileged.java b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcPrivileged.java new file mode 100644 index 000000000..78ca43e05 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/annotation/ajcPrivileged.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * 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 privileged aspects. + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ajcPrivileged {} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/AdviceImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/AdviceImpl.java new file mode 100644 index 000000000..77b30223f --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/AdviceImpl.java @@ -0,0 +1,187 @@ +/* ******************************************************************* + * 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.Method; +import java.lang.reflect.Type; + +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceKind; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +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; + this.adviceMethod = method; + 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; + } + + public String getName() { + String adviceName = adviceMethod.getName(); + if (adviceName.startsWith("ajc$")) { + adviceName = ""; + AdviceName name = adviceMethod.getAnnotation(AdviceName.class); + if (name != null) adviceName = name.value(); + } + return adviceName; + } + + public PointcutExpression getPointcutExpression() { + 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/AjTypeImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/AjTypeImpl.java new file mode 100644 index 000000000..5c04def2c --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/AjTypeImpl.java @@ -0,0 +1,1179 @@ +/* ******************************************************************* + * 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 java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.Arrays; +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.ajcITD; +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.DeclareError; +import org.aspectj.lang.annotation.DeclareWarning; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceKind; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.DeclareAnnotation; +import org.aspectj.lang.reflect.DeclareErrorOrWarning; +import org.aspectj.lang.reflect.DeclareParents; +import org.aspectj.lang.reflect.DeclarePrecedence; +import org.aspectj.lang.reflect.DeclareSoft; +import org.aspectj.lang.reflect.InterTypeConstructorDeclaration; +import org.aspectj.lang.reflect.InterTypeFieldDeclaration; +import org.aspectj.lang.reflect.InterTypeMethodDeclaration; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; +import org.aspectj.lang.reflect.Pointcut; + + +/** + * @author colyer + * + */ +public class AjTypeImpl implements AjType { + + private static final String ajcMagic = "ajc$"; + + private Class clazz; + private Pointcut[] declaredPointcuts = null; + private Pointcut[] pointcuts = null; + private Advice[] declaredAdvice = null; + private Advice[] advice = null; + private InterTypeMethodDeclaration[] declaredITDMethods = null; + private InterTypeMethodDeclaration[] itdMethods = null; + private InterTypeFieldDeclaration[] declaredITDFields = null; + private InterTypeFieldDeclaration[] itdFields = null; + private InterTypeConstructorDeclaration[] itdCons = null; + private InterTypeConstructorDeclaration[] declaredITDCons = null; + + public AjTypeImpl(Class fromClass) { + this.clazz = fromClass; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getName() + */ + public String getName() { + return clazz.getName(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getPackage() + */ + public Package getPackage() { + return clazz.getPackage(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getInterfaces() + */ + public AjType[] getInterfaces() { + Class[] baseInterfaces = clazz.getInterfaces(); + return toAjTypeArray(baseInterfaces); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getModifiers() + */ + public int getModifiers() { + return clazz.getModifiers(); + } + + public Class getJavaClass() { + return clazz; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getSupertype() + */ + public AjType getSupertype() { + Class superclass = clazz.getSuperclass(); + return superclass==null ? null : (AjType) new AjTypeImpl(superclass); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getGenericSupertype() + */ + public Type getGenericSupertype() { + return clazz.getGenericSuperclass(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getEnclosingMethod() + */ + public Method getEnclosingMethod() { + return clazz.getEnclosingMethod(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getEnclosingConstructor() + */ + public Constructor getEnclosingConstructor() { + return clazz.getEnclosingConstructor(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getEnclosingType() + */ + public AjType getEnclosingType() { + Class enc = clazz.getEnclosingClass(); + return enc != null ? new AjTypeImpl(enc) : null; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaringType() + */ + public AjType getDeclaringType() { + Class dec = clazz.getDeclaringClass(); + return dec != null ? new AjTypeImpl(dec) : null; + } + + public PerClause getPerClause() { + if (isAspect()) { + Aspect aspectAnn = clazz.getAnnotation(Aspect.class); + String perClause = aspectAnn.value(); + if (perClause.equals("")) { + if (getSupertype().isAspect()) { + return getSupertype().getPerClause(); + } + return new PerClauseImpl(PerClauseKind.SINGLETON); + } else if (perClause.startsWith("perthis(")) { + return new PointcutBasedPerClauseImpl(PerClauseKind.PERTHIS,perClause.substring("perthis(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertarget(")) { + return new PointcutBasedPerClauseImpl(PerClauseKind.PERTARGET,perClause.substring("pertarget(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflow(")) { + return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOW,perClause.substring("percflow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflowbelow(")) { + return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOWBELOW,perClause.substring("percflowbelow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertypewithin")) { + return new TypePatternBasedPerClauseImpl(PerClauseKind.PERTYPEWITHIN,perClause.substring("pertypewithin(".length(),perClause.length() - 1)); + } else { + throw new IllegalStateException("Per-clause not recognized: " + perClause); + } + } else { + return null; + } + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isAnnotationPresent(java.lang.Class) + */ + public boolean isAnnotationPresent(Class annotationType) { + return clazz.isAnnotationPresent(annotationType); + } + + public A getAnnotation(Class annotationType) { + return clazz.getAnnotation(annotationType); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getAnnotations() + */ + public Annotation[] getAnnotations() { + return clazz.getAnnotations(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAnnotations() + */ + public Annotation[] getDeclaredAnnotations() { + return clazz.getDeclaredAnnotations(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getAspects() + */ + public AjType[] getAjTypes() { + Class[] classes = clazz.getClasses(); + return toAjTypeArray(classes); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAspects() + */ + public AjType[] getDeclaredAjTypes() { + Class[] classes = clazz.getDeclaredClasses(); + return toAjTypeArray(classes); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getConstructor(java.lang.Class...) + */ + public Constructor getConstructor(AjType... parameterTypes) throws NoSuchMethodException { + return clazz.getConstructor(toClassArray(parameterTypes)); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getConstructors() + */ + public Constructor[] getConstructors() { + return clazz.getConstructors(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredConstructor(java.lang.Class...) + */ + public Constructor getDeclaredConstructor(AjType... parameterTypes) throws NoSuchMethodException { + return clazz.getDeclaredConstructor(toClassArray(parameterTypes)); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredConstructors() + */ + public Constructor[] getDeclaredConstructors() { + return clazz.getDeclaredConstructors(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredField(java.lang.String) + */ + public Field getDeclaredField(String name) throws NoSuchFieldException { + Field f = clazz.getDeclaredField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredFields() + */ + public Field[] getDeclaredFields() { + Field[] fields = clazz.getDeclaredFields(); + List filteredFields = new ArrayList(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic) + && !field.isAnnotationPresent(DeclareWarning.class) + && !field.isAnnotationPresent(DeclareError.class)) { + filteredFields.add(field); + } + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getField(java.lang.String) + */ + public Field getField(String name) throws NoSuchFieldException { + Field f = clazz.getField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getFields() + */ + public Field[] getFields() { + Field[] fields = clazz.getFields(); + List filteredFields = new ArrayList(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic) + && !field.isAnnotationPresent(DeclareWarning.class) + && !field.isAnnotationPresent(DeclareError.class)) { + filteredFields.add(field); + } + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredMethod(java.lang.String, java.lang.Class...) + */ + public Method getDeclaredMethod(String name, AjType... parameterTypes) throws NoSuchMethodException { + Method m = clazz.getDeclaredMethod(name,toClassArray(parameterTypes)); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getMethod(java.lang.String, java.lang.Class...) + */ + public Method getMethod(String name, AjType... parameterTypes) throws NoSuchMethodException { + Method m = clazz.getMethod(name,toClassArray(parameterTypes)); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredMethods() + */ + public Method[] getDeclaredMethods() { + Method[] methods = clazz.getDeclaredMethods(); + List filteredMethods = new ArrayList(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getMethods() + */ + public Method[] getMethods() { + Method[] methods = clazz.getMethods(); + List filteredMethods = new ArrayList(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; + } + + private boolean isReallyAMethod(Method method) { + if (method.getName().startsWith(ajcMagic)) return false; + if (method.getAnnotations().length==0) return true; + if (method.isAnnotationPresent(org.aspectj.lang.annotation.Pointcut.class)) return false; + if (method.isAnnotationPresent(Before.class)) return false; + if (method.isAnnotationPresent(After.class)) return false; + if (method.isAnnotationPresent(AfterReturning.class)) return false; + if (method.isAnnotationPresent(AfterThrowing.class)) return false; + if (method.isAnnotationPresent(Around.class)) return false; + return true; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcut(java.lang.String) + */ + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getDeclaredPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getPointcut(java.lang.String) + */ + public Pointcut getPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcuts() + */ + public Pointcut[] getDeclaredPointcuts() { + if (declaredPointcuts != null) return declaredPointcuts; + List pointcuts = new ArrayList(); + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pointcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pointcuts.size()]; + pointcuts.toArray(ret); + declaredPointcuts = ret; + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getPointcuts() + */ + public Pointcut[] getPointcuts() { + if (pointcuts != null) return pointcuts; + List pcuts = new ArrayList(); + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pcuts.size()]; + pcuts.toArray(ret); + pointcuts = ret; + return ret; + } + + private Pointcut asPointcut(Method method) { + org.aspectj.lang.annotation.Pointcut pcAnn = method.getAnnotation(org.aspectj.lang.annotation.Pointcut.class); + if (pcAnn != null) { + String name = method.getName(); + if (name.startsWith(ajcMagic)) { + // extract real name + int nameStart = name.indexOf("$$"); + name = name.substring(nameStart +2,name.length()); + int nextDollar = name.indexOf("$"); + if (nextDollar != -1) name = name.substring(0,nextDollar); + } + return new PointcutImpl(name,pcAnn.value(),method,AjTypeSystem.getAjType(method.getDeclaringClass()),pcAnn.argNames()); + } else { + return null; + } + } + + + public Advice[] getDeclaredAdvice(AdviceKind... ofType) { + Set types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceKind.class); + } else { + types = EnumSet.noneOf(AdviceKind.class); + types.addAll(Arrays.asList(ofType)); + } + return getDeclaredAdvice(types); + } + + public Advice[] getAdvice(AdviceKind... ofType) { + Set types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceKind.class); + } else { + types = EnumSet.noneOf(AdviceKind.class); + types.addAll(Arrays.asList(ofType)); + } + return getAdvice(types); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) + */ + private Advice[] getDeclaredAdvice(Set ofAdviceTypes) { + if (declaredAdvice == null) initDeclaredAdvice(); + List adviceList = new ArrayList(); + for (Advice a : declaredAdvice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; + } + + private void initDeclaredAdvice() { + Method[] methods = clazz.getDeclaredMethods(); + List adviceList = new ArrayList(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + declaredAdvice = new Advice[adviceList.size()]; + adviceList.toArray(declaredAdvice); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) + */ + private Advice[] getAdvice(Set ofAdviceTypes) { + if (advice == null) initAdvice(); + List adviceList = new ArrayList(); + for (Advice a : advice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; + } + + private void initAdvice() { + Method[] methods = clazz.getMethods(); + List adviceList = new ArrayList(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + advice = new Advice[adviceList.size()]; + adviceList.toArray(advice); + } + + + public Advice getAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (advice == null) initAdvice(); + for (Advice a : advice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (declaredAdvice == null) initDeclaredAdvice(); + for (Advice a : declaredAdvice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + private Advice asAdvice(Method method) { + if (method.getAnnotations().length == 0) return null; + Before beforeAnn = method.getAnnotation(Before.class); + if (beforeAnn != null) return new AdviceImpl(method,beforeAnn.value(),AdviceKind.BEFORE); + After afterAnn = method.getAnnotation(After.class); + if (afterAnn != null) return new AdviceImpl(method,afterAnn.value(),AdviceKind.AFTER); + AfterReturning afterReturningAnn = method.getAnnotation(AfterReturning.class); + if (afterReturningAnn != null) { + String pcExpr = afterReturningAnn.pointcut(); + if (pcExpr.equals("")) pcExpr = afterReturningAnn.value(); + 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,afterThrowingAnn.throwing()); + } + Around aroundAnn = method.getAnnotation(Around.class); + if (aroundAnn != null) return new AdviceImpl(method,aroundAnn.value(),AdviceKind.AROUND); + return null; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDMethod(java.lang.String, java.lang.Class, java.lang.Class...) + */ + public InterTypeMethodDeclaration getDeclaredITDMethod(String name, + AjType target, AjType... parameterTypes) throws NoSuchMethodException { + InterTypeMethodDeclaration[] itdms = getDeclaredITDMethods(); + outer: for (InterTypeMethodDeclaration itdm : itdms) { + try { + if (!itdm.getName().equals(name)) continue; + AjType itdTarget = itdm.getTargetType(); + if (itdTarget.equals(target)) { + AjType[] ptypes = itdm.getParameterTypes(); + if (ptypes.length == parameterTypes.length) { + for (int i = 0; i < ptypes.length; i++) { + if (!ptypes[i].equals(parameterTypes[i])) + continue outer; + } + return itdm; + } + } + } catch (ClassNotFoundException cnf) { + // just move on to the next one + } + } + throw new NoSuchMethodException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDMethods() + */ + public InterTypeMethodDeclaration[] getDeclaredITDMethods() { + if (this.declaredITDMethods == null) { + List itdms = new ArrayList(); + Method[] baseMethods = clazz.getDeclaredMethods(); + for (Method m : baseMethods) { + if (!m.getName().contains("ajc$interMethodDispatch1$")) continue; + if (m.isAnnotationPresent(ajcITD.class)) { + ajcITD ann = m.getAnnotation(ajcITD.class); + InterTypeMethodDeclaration itdm = + new InterTypeMethodDeclarationImpl( + this,ann.targetType(),ann.modifiers(), + ann.name(),m); + itdms.add(itdm); + } + } + addAnnotationStyleITDMethods(itdms,false); + this.declaredITDMethods = new InterTypeMethodDeclaration[itdms.size()]; + itdms.toArray(this.declaredITDMethods); + } + return this.declaredITDMethods; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDMethod(java.lang.String, java.lang.Class, java.lang.Class...) + */ + public InterTypeMethodDeclaration getITDMethod(String name, AjType target, + AjType... parameterTypes) + throws NoSuchMethodException { + InterTypeMethodDeclaration[] itdms = getITDMethods(); + outer: for (InterTypeMethodDeclaration itdm : itdms) { + try { + if (!itdm.getName().equals(name)) continue; + AjType itdTarget = itdm.getTargetType(); + if (itdTarget.equals(target)) { + AjType[] ptypes = itdm.getParameterTypes(); + if (ptypes.length == parameterTypes.length) { + for (int i = 0; i < ptypes.length; i++) { + if (!ptypes[i].equals(parameterTypes[i])) + continue outer; + } + return itdm; + } + } + } catch (ClassNotFoundException cnf) { + // just move on to the next one + } + } + throw new NoSuchMethodException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDMethods() + */ + public InterTypeMethodDeclaration[] getITDMethods() { + if (this.itdMethods == null) { + List itdms = new ArrayList(); + Method[] baseMethods = clazz.getDeclaredMethods(); + for (Method m : baseMethods) { + if (!m.getName().contains("ajc$interMethod$")) continue; + if (m.isAnnotationPresent(ajcITD.class)) { + ajcITD ann = m.getAnnotation(ajcITD.class); + if (!Modifier.isPublic(ann.modifiers())) continue; + InterTypeMethodDeclaration itdm = + new InterTypeMethodDeclarationImpl( + this,ann.targetType(),ann.modifiers(), + ann.name(),m); + itdms.add(itdm); + } + } + addAnnotationStyleITDMethods(itdms,true); + this.itdMethods = new InterTypeMethodDeclaration[itdms.size()]; + itdms.toArray(this.itdMethods); + } + return this.itdMethods; + } + + private void addAnnotationStyleITDMethods(List toList, boolean publicOnly) { + if (isAspect()) { + for (Field f : clazz.getDeclaredFields()) { + if (!f.getType().isInterface()) continue; + if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { + Class decPAnnClass = org.aspectj.lang.annotation.DeclareParents.class; + org.aspectj.lang.annotation.DeclareParents decPAnn = f.getAnnotation(decPAnnClass); + if (decPAnn.defaultImpl() == decPAnnClass) continue; // doesn't contribute members... + for (Method itdM : f.getType().getDeclaredMethods()) { + if (!Modifier.isPublic(itdM.getModifiers()) && publicOnly) continue; + InterTypeMethodDeclaration itdm = new InterTypeMethodDeclarationImpl( + this, AjTypeSystem.getAjType(f.getType()), itdM, + Modifier.PUBLIC + ); + toList.add(itdm); + } + } + } + } + } + + private void addAnnotationStyleITDFields(List toList, boolean publicOnly) { + //AV: I think it is meaningless + //@AJ decp is interface driven ie no field + return; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDConstructor(java.lang.Class, java.lang.Class...) + */ + public InterTypeConstructorDeclaration getDeclaredITDConstructor( + AjType target, AjType... parameterTypes) throws NoSuchMethodException { + InterTypeConstructorDeclaration[] itdcs = getDeclaredITDConstructors(); + outer: for (InterTypeConstructorDeclaration itdc : itdcs) { + try { + AjType itdTarget = itdc.getTargetType(); + if (itdTarget.equals(target)) { + AjType[] ptypes = itdc.getParameterTypes(); + if (ptypes.length == parameterTypes.length) { + for (int i = 0; i < ptypes.length; i++) { + if (!ptypes[i].equals(parameterTypes[i])) + continue outer; + } + return itdc; + } + } + } catch (ClassNotFoundException cnf) { + // just move on to the next one + } + } + throw new NoSuchMethodException(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDConstructors() + */ + public InterTypeConstructorDeclaration[] getDeclaredITDConstructors() { + if (this.declaredITDCons == null) { + List itdcs = new ArrayList(); + Method[] baseMethods = clazz.getDeclaredMethods(); + for (Method m : baseMethods) { + if (!m.getName().contains("ajc$postInterConstructor")) continue; + if (m.isAnnotationPresent(ajcITD.class)) { + ajcITD ann = m.getAnnotation(ajcITD.class); + InterTypeConstructorDeclaration itdc = + new InterTypeConstructorDeclarationImpl(this,ann.targetType(),ann.modifiers(),m); + itdcs.add(itdc); + } + } + this.declaredITDCons = new InterTypeConstructorDeclaration[itdcs.size()]; + itdcs.toArray(this.declaredITDCons); + } + return this.declaredITDCons; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDConstructor(java.lang.Class, java.lang.Class...) + */ + public InterTypeConstructorDeclaration getITDConstructor(AjType target, + AjType... parameterTypes) throws NoSuchMethodException { + InterTypeConstructorDeclaration[] itdcs = getITDConstructors(); + outer: for (InterTypeConstructorDeclaration itdc : itdcs) { + try { + AjType itdTarget = itdc.getTargetType(); + if (itdTarget.equals(target)) { + AjType[] ptypes = itdc.getParameterTypes(); + if (ptypes.length == parameterTypes.length) { + for (int i = 0; i < ptypes.length; i++) { + if (!ptypes[i].equals(parameterTypes[i])) + continue outer; + } + return itdc; + } + } + } catch (ClassNotFoundException cnf) { + // just move on to the next one + } + } + throw new NoSuchMethodException(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDConstructors() + */ + public InterTypeConstructorDeclaration[] getITDConstructors() { + if (this.itdCons == null) { + List itdcs = new ArrayList(); + Method[] baseMethods = clazz.getMethods(); + for (Method m : baseMethods) { + if (!m.getName().contains("ajc$postInterConstructor")) continue; + if (m.isAnnotationPresent(ajcITD.class)) { + ajcITD ann = m.getAnnotation(ajcITD.class); + if (!Modifier.isPublic(ann.modifiers())) continue; + InterTypeConstructorDeclaration itdc = + new InterTypeConstructorDeclarationImpl(this,ann.targetType(),ann.modifiers(),m); + itdcs.add(itdc); + } + } + this.itdCons = new InterTypeConstructorDeclaration[itdcs.size()]; + itdcs.toArray(this.itdCons); + } + return this.itdCons; } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDField(java.lang.String, java.lang.Class) + */ + public InterTypeFieldDeclaration getDeclaredITDField(String name, + AjType target) throws NoSuchFieldException { + InterTypeFieldDeclaration[] itdfs = getDeclaredITDFields(); + for (InterTypeFieldDeclaration itdf : itdfs) { + if (itdf.getName().equals(name)) { + try { + AjType itdTarget = itdf.getTargetType(); + if (itdTarget.equals(target)) return itdf; + } catch (ClassNotFoundException cnfEx) { + // move on to next field + } + } + } + throw new NoSuchFieldException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclaredITDFields() + */ + public InterTypeFieldDeclaration[] getDeclaredITDFields() { + List itdfs = new ArrayList(); + if (this.declaredITDFields == null) { + Method[] baseMethods = clazz.getDeclaredMethods(); + for(Method m : baseMethods) { + if (m.isAnnotationPresent(ajcITD.class)) { + if (!m.getName().contains("ajc$interFieldInit")) continue; + ajcITD ann = m.getAnnotation(ajcITD.class); + String interFieldInitMethodName = m.getName(); + String interFieldGetDispatchMethodName = + interFieldInitMethodName.replace("FieldInit","FieldGetDispatch"); + try { + Method dispatch = clazz.getDeclaredMethod(interFieldGetDispatchMethodName, m.getParameterTypes()); + InterTypeFieldDeclaration itdf = new InterTypeFieldDeclarationImpl( + this,ann.targetType(),ann.modifiers(),ann.name(), + AjTypeSystem.getAjType(dispatch.getReturnType()), + dispatch.getGenericReturnType()); + itdfs.add(itdf); + } catch (NoSuchMethodException nsmEx) { + throw new IllegalStateException("Can't find field get dispatch method for " + m.getName()); + } + } + } + addAnnotationStyleITDFields(itdfs, false); + this.declaredITDFields = new InterTypeFieldDeclaration[itdfs.size()]; + itdfs.toArray(this.declaredITDFields); + } + return this.declaredITDFields; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDField(java.lang.String, java.lang.Class) + */ + public InterTypeFieldDeclaration getITDField(String name, AjType target) + throws NoSuchFieldException { + InterTypeFieldDeclaration[] itdfs = getITDFields(); + for (InterTypeFieldDeclaration itdf : itdfs) { + if (itdf.getName().equals(name)) { + try { + AjType itdTarget = itdf.getTargetType(); + if (itdTarget.equals(target)) return itdf; + } catch (ClassNotFoundException cnfEx) { + // move on to next field + } + } + } + throw new NoSuchFieldException(name); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getITDFields() + */ + public InterTypeFieldDeclaration[] getITDFields() { + List itdfs = new ArrayList(); + if (this.itdFields == null) { + Method[] baseMethods = clazz.getMethods(); + for(Method m : baseMethods) { + if (m.isAnnotationPresent(ajcITD.class)) { + ajcITD ann = m.getAnnotation(ajcITD.class); + if (!m.getName().contains("ajc$interFieldInit")) continue; + if (!Modifier.isPublic(ann.modifiers())) continue; + String interFieldInitMethodName = m.getName(); + String interFieldGetDispatchMethodName = + interFieldInitMethodName.replace("FieldInit","FieldGetDispatch"); + try { + Method dispatch = m.getDeclaringClass().getDeclaredMethod(interFieldGetDispatchMethodName, m.getParameterTypes()); + InterTypeFieldDeclaration itdf = new InterTypeFieldDeclarationImpl( + this,ann.targetType(),ann.modifiers(),ann.name(), + AjTypeSystem.getAjType(dispatch.getReturnType()), + dispatch.getGenericReturnType()); + itdfs.add(itdf); + } catch (NoSuchMethodException nsmEx) { + throw new IllegalStateException("Can't find field get dispatch method for " + m.getName()); + } + } + } + addAnnotationStyleITDFields(itdfs, true); + this.itdFields = new InterTypeFieldDeclaration[itdfs.size()]; + itdfs.toArray(this.itdFields); + } + return this.itdFields; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclareErrorOrWarnings() + */ + public DeclareErrorOrWarning[] getDeclareErrorOrWarnings() { + List deows = new ArrayList(); + for (Field field : clazz.getDeclaredFields()) { + try { + if (field.isAnnotationPresent(DeclareWarning.class)) { + DeclareWarning dw = field.getAnnotation(DeclareWarning.class); + if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { + String message = (String) field.get(null); + DeclareErrorOrWarningImpl deow = new DeclareErrorOrWarningImpl(dw.value(),message,false,this); + deows.add(deow); + } + } else if (field.isAnnotationPresent(DeclareError.class)) { + DeclareError de = field.getAnnotation(DeclareError.class); + if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { + String message = (String) field.get(null); + DeclareErrorOrWarningImpl deow = new DeclareErrorOrWarningImpl(de.value(),message,true,this); + deows.add(deow); + } + } + } catch (IllegalArgumentException e) { + // just move on to the next field + } catch (IllegalAccessException e) { + // just move on to the next field + } + } + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(ajcDeclareEoW.class)) { + ajcDeclareEoW deowAnn = method.getAnnotation(ajcDeclareEoW.class); + DeclareErrorOrWarning deow = new DeclareErrorOrWarningImpl(deowAnn.pointcut(),deowAnn.message(),deowAnn.isError(),this); + deows.add(deow); + } + } + DeclareErrorOrWarning[] ret = new DeclareErrorOrWarning[deows.size()]; + deows.toArray(ret); + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclareParents() + */ + public DeclareParents[] getDeclareParents() { + 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); + } + } + addAnnotationStyleDeclareParents(decps); + if (getSupertype().isAspect()) { + decps.addAll(Arrays.asList(getSupertype().getDeclareParents())); + } + DeclareParents[] ret = new DeclareParents[decps.size()]; + decps.toArray(ret); + return ret; + } + + private void addAnnotationStyleDeclareParents(List toList) { + for (Field f : clazz.getDeclaredFields()) { + if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { + if (!f.getType().isInterface()) continue; + org.aspectj.lang.annotation.DeclareParents ann = f.getAnnotation(org.aspectj.lang.annotation.DeclareParents.class); + String parentType = f.getType().getName(); + DeclareParentsImpl decp = new DeclareParentsImpl( + ann.value(), + parentType, + false, + this + ); + toList.add(decp); + } + } + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getDeclareSofts() + */ + public DeclareSoft[] getDeclareSofts() { + 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() { + 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() { + 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) + * @see org.aspectj.lang.reflect.AjType#getEnumConstants() + */ + public T[] getEnumConstants() { + return clazz.getEnumConstants(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#getTypeParameters() + */ + public TypeVariable>[] getTypeParameters() { + return clazz.getTypeParameters(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isEnum() + */ + public boolean isEnum() { + return clazz.isEnum(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isInstance(java.lang.Object) + */ + public boolean isInstance(Object o) { + return clazz.isInstance(o); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isInterface() + */ + public boolean isInterface() { + return clazz.isInterface(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isLocalClass() + */ + public boolean isLocalClass() { + return clazz.isLocalClass() && !isAspect(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isMemberClass() + */ + public boolean isMemberClass() { + return clazz.isMemberClass() && !isAspect(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isArray() + */ + public boolean isArray() { + return clazz.isArray(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isPrimitive() + */ + public boolean isPrimitive() { + return clazz.isPrimitive(); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isAspect() + */ + public boolean isAspect() { + return clazz.getAnnotation(Aspect.class) != null; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.AjType#isMemberAspect() + */ + public boolean isMemberAspect() { + return clazz.isMemberClass() && isAspect(); + } + + public boolean isPrivileged() { + return isAspect() && clazz.isAnnotationPresent(ajcPrivileged.class); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AjTypeImpl)) return false; + AjTypeImpl other = (AjTypeImpl) obj; + return other.clazz.equals(clazz); + } + + @Override + public int hashCode() { + return clazz.hashCode(); + } + + private AjType[] toAjTypeArray(Class[] classes) { + AjType[] ajtypes = new AjType[classes.length]; + for (int i = 0; i < ajtypes.length; i++) { + ajtypes[i] = AjTypeSystem.getAjType(classes[i]); + } + return ajtypes; + } + + private Class[] toClassArray(AjType[] ajTypes) { + Class[] classes = new Class[ajTypes.length]; + for (int i = 0; i < classes.length; i++) { + classes[i] = ajTypes[i].getJavaClass(); + } + return classes; + } + + public String toString() { return getName(); } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareAnnotationImpl.java new file mode 100644 index 000000000..bcc91b987 --- /dev/null +++ b/runtime/src/main/java/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/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java new file mode 100644 index 000000000..5420f8274 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareErrorOrWarningImpl.java @@ -0,0 +1,71 @@ +/* ******************************************************************* + * 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.DeclareErrorOrWarning; +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +public class DeclareErrorOrWarningImpl implements DeclareErrorOrWarning { + + private PointcutExpression pc; + private String msg; + private boolean isError; + private AjType declaringType; + + public DeclareErrorOrWarningImpl(String pointcut, String message, boolean isError, AjType decType) { + this.pc = new PointcutExpressionImpl(pointcut); + this.msg = message; + this.isError = isError; + this.declaringType = decType; + } + + public AjType getDeclaringType() { return this.declaringType; } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareErrorOrWarning#getPointcutExpression() + */ + public PointcutExpression getPointcutExpression() { + return pc; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareErrorOrWarning#getMessage() + */ + public String getMessage() { + return msg; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.DeclareErrorOrWarning#isError() + */ + 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java new file mode 100644 index 000000000..4f5720667 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java @@ -0,0 +1,98 @@ +/* ******************************************************************* + * 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.Type; + +import org.aspectj.lang.reflect.AjType; +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; + try { + this.parents = StringToType.commaSeparatedListToTypeArray(parentsAsString, declaring.getJavaClass()); + } catch (ClassNotFoundException cnfEx) { + this.parentsError = true; + this.firstMissingTypeName = cnfEx.getMessage(); + } + } + + /* (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; + } + + 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclarePrecedenceImpl.java new file mode 100644 index 000000000..7188606c6 --- /dev/null +++ b/runtime/src/main/java/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/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java new file mode 100644 index 000000000..4c8ea4ead --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/DeclareSoftImpl.java @@ -0,0 +1,76 @@ +/* ******************************************************************* + * 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 { + ClassLoader cl = declaringType.getJavaClass().getClassLoader(); + this.exceptionType = AjTypeSystem.getAjType(Class.forName(exceptionTypeName,false,cl)); + } 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java new file mode 100644 index 000000000..9b80263a3 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java @@ -0,0 +1,100 @@ +/* ******************************************************************* + * 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.Method; +import java.lang.reflect.Type; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.InterTypeConstructorDeclaration; + +/** + * @author colyer + * + */ +public class InterTypeConstructorDeclarationImpl extends + InterTypeDeclarationImpl implements InterTypeConstructorDeclaration { + + private Method baseMethod; + + /** + * @param decType + * @param target + * @param mods + */ + public InterTypeConstructorDeclarationImpl(AjType decType, + String target, int mods, Method baseMethod) { + super(decType, target, mods); + this.baseMethod = baseMethod; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeConstructorDeclaration#getParameters() + */ + public AjType[] getParameterTypes() { + Class[] baseTypes = baseMethod.getParameterTypes(); + AjType[] ret = new AjType[baseTypes.length-1]; + for (int i = 1; i < baseTypes.length; i++) { + ret[i-1] = AjTypeSystem.getAjType(baseTypes[i]); + } + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeConstructorDeclaration#getGenericParameters() + */ + public Type[] getGenericParameterTypes() { + Type[] baseTypes = baseMethod.getGenericParameterTypes(); + Type[] ret = new AjType[baseTypes.length-1]; + for (int i = 1; i < baseTypes.length; i++) { + if (baseTypes[i] instanceof Class) { + ret[i-1] = AjTypeSystem.getAjType((Class)baseTypes[i]); + } else { + ret[i-1] = baseTypes[i]; + } + } + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeConstructorDeclaration#getDeclaredExceptionTypes() + */ + public AjType[] getExceptionTypes() { + Class[] baseTypes = baseMethod.getExceptionTypes(); + AjType[] ret = new AjType[baseTypes.length]; + for (int i = 0; i < baseTypes.length; i++) { + ret[i] = AjTypeSystem.getAjType(baseTypes[i]); + } + return ret; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(java.lang.reflect.Modifier.toString(getModifiers())); + sb.append(" "); + sb.append(this.targetTypeName); + sb.append(".new"); + sb.append("("); + AjType[] pTypes = getParameterTypes(); + for(int i = 0; i < (pTypes.length - 1); i++) { + sb.append(pTypes[i].toString()); + sb.append(", "); + } + if (pTypes.length > 0) { + sb.append(pTypes[pTypes.length -1].toString()); + } + sb.append(")"); + return sb.toString(); + } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java new file mode 100644 index 000000000..b4bb23aab --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java @@ -0,0 +1,68 @@ +/* ******************************************************************* + * 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.InterTypeDeclaration; + +/** + * @author colyer + * + */ +public class InterTypeDeclarationImpl implements InterTypeDeclaration { + + private AjType declaringType; + protected String targetTypeName; + private AjType targetType; + private int modifiers; + + public InterTypeDeclarationImpl(AjType decType, String target, int mods) { + this.declaringType = decType; + this.targetTypeName = target; + this.modifiers = mods; + try { + this.targetType = (AjType) StringToType.stringToType(target, decType.getJavaClass()); + } catch (ClassNotFoundException cnf) { + // we'll only report this later if the user asks for the target type. + } + } + + public InterTypeDeclarationImpl(AjType decType, AjType targetType, int mods) { + this.declaringType = decType; + this.targetType = targetType; + this.targetTypeName = targetType.getName(); + this.modifiers = mods; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeDeclaration#getDeclaringType() + */ + public AjType getDeclaringType() { + return this.declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeDeclaration#getTargetType() + */ + public AjType getTargetType() throws ClassNotFoundException { + if (this.targetType == null) throw new ClassNotFoundException(this.targetTypeName); + return this.targetType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeDeclaration#getModifiers() + */ + public int getModifiers() { + return this.modifiers; + } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java new file mode 100644 index 000000000..2370919c0 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java @@ -0,0 +1,90 @@ +/* ******************************************************************* + * 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.Field; +import java.lang.reflect.Type; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.InterTypeFieldDeclaration; + +/** + * @author colyer + * + */ +public class InterTypeFieldDeclarationImpl extends InterTypeDeclarationImpl + implements InterTypeFieldDeclaration { + + private String name; + private AjType type; + private Type genericType; + + /** + * @param decType + * @param target + * @param mods + */ + public InterTypeFieldDeclarationImpl(AjType decType, String target, + int mods, String name, AjType type, Type genericType) { + super(decType, target, mods); + this.name = name; + this.type = type; + this.genericType = genericType; + } + + public InterTypeFieldDeclarationImpl(AjType decType, AjType targetType, Field base) { + super(decType,targetType,base.getModifiers()); + this.name = base.getName(); + this.type = AjTypeSystem.getAjType(base.getType()); + Type gt = base.getGenericType(); + if (gt instanceof Class) { + this.genericType = AjTypeSystem.getAjType((Class)gt); + } else { + this.genericType = gt; + } + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeFieldDeclaration#getName() + */ + public String getName() { + return this.name; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeFieldDeclaration#getType() + */ + public AjType getType() { + return this.type; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeFieldDeclaration#getGenericType() + */ + public Type getGenericType() { + return this.genericType; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(java.lang.reflect.Modifier.toString(getModifiers())); + sb.append(" "); + sb.append(getType().toString()); + sb.append(" "); + sb.append(this.targetTypeName); + sb.append("."); + sb.append(getName()); + return sb.toString(); + } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java new file mode 100644 index 000000000..eb085a055 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java @@ -0,0 +1,148 @@ +/* ******************************************************************* + * 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.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.InterTypeMethodDeclaration; + +/** + * @author colyer + * + */ +public class InterTypeMethodDeclarationImpl extends InterTypeDeclarationImpl + implements InterTypeMethodDeclaration { + + private String name; + private Method baseMethod; + private int parameterAdjustmentFactor = 1; // no of fake params at start of baseMethod + private AjType[] parameterTypes; + private Type[] genericParameterTypes; + private AjType returnType; + private Type genericReturnType; + private AjType[] exceptionTypes; + + /** + * @param decType + * @param target + * @param mods + */ + public InterTypeMethodDeclarationImpl(AjType decType, String target, + int mods, String name, Method itdInterMethod) { + super(decType, target, mods); + this.name = name; + this.baseMethod = itdInterMethod; + } + + public InterTypeMethodDeclarationImpl(AjType decType, AjType targetType, Method base, int modifiers) { + super(decType,targetType,modifiers); + this.parameterAdjustmentFactor = 0; + this.name = base.getName(); + this.baseMethod = base; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getName() + */ + public String getName() { + return this.name; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getReturnType() + */ + public AjType getReturnType() { + return AjTypeSystem.getAjType(baseMethod.getReturnType()); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getGenericReturnType() + */ + public Type getGenericReturnType() { + Type gRet = baseMethod.getGenericReturnType(); + if (gRet instanceof Class) { + return AjTypeSystem.getAjType((Class)gRet); + } + return gRet; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getParameters() + */ + public AjType[] getParameterTypes() { + Class[] baseTypes = baseMethod.getParameterTypes(); + AjType[] ret = new AjType[baseTypes.length -parameterAdjustmentFactor]; + for (int i = parameterAdjustmentFactor; i < baseTypes.length; i++) { + ret[i-parameterAdjustmentFactor] = AjTypeSystem.getAjType(baseTypes[i]); + } + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getGenericParameters() + */ + public Type[] getGenericParameterTypes() { + Type[] baseTypes = baseMethod.getGenericParameterTypes(); + Type[] ret = new AjType[baseTypes.length-parameterAdjustmentFactor]; + for (int i = parameterAdjustmentFactor; i < baseTypes.length; i++) { + if (baseTypes[i] instanceof Class) { + ret[i-parameterAdjustmentFactor] = AjTypeSystem.getAjType((Class)baseTypes[i]); + } else { + ret[i-parameterAdjustmentFactor] = baseTypes[i]; + } + } + return ret; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.InterTypeMethodDeclaration#getTypeParameters() + */ + public TypeVariable[] getTypeParameters() { + return baseMethod.getTypeParameters(); + } + + public AjType[] getExceptionTypes() { + Class[] baseTypes = baseMethod.getExceptionTypes(); + AjType[] ret = new AjType[baseTypes.length]; + for (int i = 0; i < baseTypes.length; i++) { + ret[i] = AjTypeSystem.getAjType(baseTypes[i]); + } + return ret; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(java.lang.reflect.Modifier.toString(getModifiers())); + sb.append(" "); + sb.append(getReturnType().toString()); + sb.append(" "); + sb.append(this.targetTypeName); + sb.append("."); + sb.append(getName()); + sb.append("("); + AjType[] pTypes = getParameterTypes(); + for(int i = 0; i < (pTypes.length - 1); i++) { + sb.append(pTypes[i].toString()); + sb.append(", "); + } + if (pTypes.length > 0) { + sb.append(pTypes[pTypes.length -1].toString()); + } + sb.append(")"); + return sb.toString(); + } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/PerClauseImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PerClauseImpl.java new file mode 100644 index 000000000..663a44c20 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PerClauseImpl.java @@ -0,0 +1,39 @@ +/* ******************************************************************* + * 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.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; + +/** + * @author colyer + * + */ +public class PerClauseImpl implements PerClause { + + private final PerClauseKind kind; + + protected PerClauseImpl(PerClauseKind kind) { + this.kind = kind; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.PerClause#getKind() + */ + public PerClauseKind getKind() { + return kind; + } + + public String toString() { + return "issingleton()"; + } +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java new file mode 100644 index 000000000..5049d3a42 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutBasedPerClauseImpl.java @@ -0,0 +1,49 @@ +/* ******************************************************************* + * 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.PerClauseKind; +import org.aspectj.lang.reflect.PointcutBasedPerClause; +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +public class PointcutBasedPerClauseImpl extends PerClauseImpl implements + PointcutBasedPerClause { + + private final PointcutExpression pointcutExpression; + + public PointcutBasedPerClauseImpl(PerClauseKind kind, + String pointcutExpression) { + super(kind); + this.pointcutExpression = new PointcutExpressionImpl(pointcutExpression); + } + + public PointcutExpression getPointcutExpression() { + 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutExpressionImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutExpressionImpl.java new file mode 100644 index 000000000..facf7d99d --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutExpressionImpl.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.reflect; + +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +public class PointcutExpressionImpl implements PointcutExpression { + private String expression; + + public PointcutExpressionImpl(String aPointcutExpression) { + this.expression = aPointcutExpression; + } + + public String asString() { + return expression; + } + + public String toString() { return asString(); } +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutImpl.java new file mode 100644 index 000000000..b94f1c864 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/PointcutImpl.java @@ -0,0 +1,100 @@ +/* ******************************************************************* + * 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.Method; +import java.util.StringTokenizer; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.Pointcut; +import org.aspectj.lang.reflect.PointcutExpression; + +/** + * @author colyer + * + */ +public class PointcutImpl implements Pointcut { + + private final String name; + private final PointcutExpression pc; + private final Method baseMethod; + private final AjType declaringType; + private String[] parameterNames = new String[0]; + + protected PointcutImpl(String name, String pc, Method method, AjType declaringType, String pNames) { + this.name = name; + this.pc = new PointcutExpressionImpl(pc); + this.baseMethod = method; + this.declaringType = declaringType; + this.parameterNames = splitOnComma(pNames); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.Pointcut#getPointcutExpression() + */ + public PointcutExpression getPointcutExpression() { + return pc; + } + + public String getName() { + return name; + } + + public int getModifiers() { + return baseMethod.getModifiers(); + } + + public AjType[] getParameterTypes() { + Class[] baseParamTypes = baseMethod.getParameterTypes(); + AjType[] ajParamTypes = new AjType[baseParamTypes.length]; + for (int i = 0; i < ajParamTypes.length; i++) { + ajParamTypes[i] = AjTypeSystem.getAjType(baseParamTypes[i]); + } + return ajParamTypes; + } + + public AjType getDeclaringType() { + return declaringType; + } + + public String[] getParameterNames() { + return parameterNames; + } + + private String[] splitOnComma(String s) { + StringTokenizer strTok = new StringTokenizer(s,","); + String[] ret = new String[strTok.countTokens()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = strTok.nextToken().trim(); + } + 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/runtime/src/main/java/org/aspectj/internal/lang/reflect/SignaturePatternImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/SignaturePatternImpl.java new file mode 100644 index 000000000..9820667d8 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/SignaturePatternImpl.java @@ -0,0 +1,37 @@ +/* ******************************************************************* + * 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.SignaturePattern; + +/** + * Basic implementation of signature pattern + * + */ +public class SignaturePatternImpl implements SignaturePattern { + + private String sigPattern; + + public SignaturePatternImpl(String pattern) { + this.sigPattern = pattern; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.SignaturePattern#asString() + */ + public String asString() { + return sigPattern; + } + + public String toString() { return asString(); } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/StringToType.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/StringToType.java new file mode 100644 index 000000000..4be9fd71e --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/StringToType.java @@ -0,0 +1,83 @@ +/* ******************************************************************* + * 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.AjTypeSystem; + +/** + * @author colyer + * Helper class for converting type representations in Strings into java.lang.reflect.Types. + */ +public class StringToType { + + public static Type[] commaSeparatedListToTypeArray(String typeNames, Class classScope) + throws ClassNotFoundException { + StringTokenizer strTok = new StringTokenizer(typeNames,","); + Type[] ret = new Type[strTok.countTokens()]; + int index = 0; + //outer: + while (strTok.hasMoreTokens()) { + String typeName = strTok.nextToken().trim(); + ret[index++] = stringToType(typeName, classScope); + } + return ret; + } + + public static Type stringToType(String typeName, Class classScope) + throws ClassNotFoundException { + try { + if (typeName.indexOf("<") == -1) { + return AjTypeSystem.getAjType(Class.forName(typeName,false,classScope.getClassLoader())); + } else { + return makeParameterizedType(typeName,classScope); + } + } catch (ClassNotFoundException e) { + // could be a type variable + TypeVariable[] tVars = classScope.getTypeParameters(); + for (int i = 0; i < tVars.length; i++) { + if (tVars[i].getName().equals(typeName)) { + return tVars[i]; + } + } + throw new ClassNotFoundException(typeName); + } + } + + private static Type makeParameterizedType(String typeName, Class classScope) + throws ClassNotFoundException { + int paramStart = typeName.indexOf('<'); + String baseName = typeName.substring(0, paramStart); + final Class baseClass = Class.forName(baseName,false,classScope.getClassLoader()); + int paramEnd = typeName.lastIndexOf('>'); + String params = typeName.substring(paramStart+1,paramEnd); + final Type[] typeParams = commaSeparatedListToTypeArray(params,classScope); + return new ParameterizedType() { + + public Type[] getActualTypeArguments() { + return typeParams; + } + + public Type getRawType() { + return baseClass; + } + + public Type getOwnerType() { + return baseClass.getEnclosingClass(); + } + }; + } +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java new file mode 100644 index 000000000..e9bb08573 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternBasedPerClauseImpl.java @@ -0,0 +1,43 @@ +/* ******************************************************************* + * 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.PerClauseKind; +import org.aspectj.lang.reflect.TypePattern; +import org.aspectj.lang.reflect.TypePatternBasedPerClause; + +/** + * @author colyer + * + */ +public class TypePatternBasedPerClauseImpl extends PerClauseImpl implements + TypePatternBasedPerClause { + + private TypePattern typePattern; + + public TypePatternBasedPerClauseImpl(PerClauseKind kind, String pattern) { + super(kind); + this.typePattern = new TypePatternImpl(pattern); + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.TypePatternBasedPerClause#getTypePattern() + */ + public TypePattern getTypePattern() { + return this.typePattern; + } + + public String toString() { + return "pertypewithin(" + typePattern.asString() + ")"; + } + +} diff --git a/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternImpl.java b/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternImpl.java new file mode 100644 index 000000000..9973ed3bf --- /dev/null +++ b/runtime/src/main/java/org/aspectj/internal/lang/reflect/TypePatternImpl.java @@ -0,0 +1,37 @@ +/* ******************************************************************* + * 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.TypePattern; + +/** + * Default impl of a type pattern. + * + */ +public class TypePatternImpl implements TypePattern { + + private String typePattern; + + public TypePatternImpl(String pattern) { + this.typePattern = pattern; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.TypePattern#asString() + */ + public String asString() { + return this.typePattern; + } + + public String toString() { return asString(); } + +} diff --git a/runtime/src/main/java/org/aspectj/lang/Aspects.java b/runtime/src/main/java/org/aspectj/lang/Aspects.java new file mode 100644 index 000000000..e82320c2e --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/Aspects.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + * generic signature update Adrian Colyer + *******************************************************************************/ +package org.aspectj.lang; + + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.InvocationTargetException; + +/** + * Handles generic aspectOf method when those are not available in the aspects but added later on + * thru load time weaving. + *

+ * Aspects.aspectOf(..) is doing reflective calls to the aspect aspectOf, so for better performance + * consider using ajc compilation of the aspects and using them as a binary dependancies in your project. + * + * @author Alexandre Vasseur + */ +public class Aspects { + + private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; + private final static Class[] PEROBJECT_CLASS_ARRAY = new Class[]{Object.class}; + private final static Class[] PERTYPEWITHIN_CLASS_ARRAY = new Class[]{Class.class}; + private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + private final static String ASPECTOF = "aspectOf"; + private final static String HASASPECT = "hasAspect"; + + /** + * Returns the singleton aspect or the percflow / percflowbelow associated with the current thread + * + * @param aspectClass + * @return + * @throws NoAspectBoundException if no such aspect + */ + public static T aspectOf(Class aspectClass) throws NoAspectBoundException { + try { + return (T) getSingletonOrThreadAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY); + } catch (InvocationTargetException e) { + //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns the perthis / pertarget aspect + * @param aspectClass + * @param perObject + * @return + * @throws NoAspectBoundException if no such aspect, or no aspect bound + */ + public static T aspectOf(Class aspectClass, Object perObject) throws NoAspectBoundException { + try { + return (T) getPerObjectAspectOf(aspectClass).invoke(null, new Object[]{perObject}); + } catch (InvocationTargetException e) { + //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns the pertypewithin aspect + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if no such aspect, or no aspect bound + */ + public static T aspectOf(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { + try { + return (T) getPerTypeWithinAspectOf(aspectClass).invoke(null, new Object[]{perTypeWithin}); + } catch (InvocationTargetException e) { +// FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns true if singleton aspect or percflow / percflowbelow aspect is bound + * + * @param aspectClass + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass) throws NoAspectBoundException { + try { + return ((Boolean)getSingletonOrThreadHasAspect(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY)).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the perthis / pertarget aspect is bound + * @param aspectClass + * @param perObject + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Object perObject) throws NoAspectBoundException { + try { + return ((Boolean)getPerObjectHasAspect(aspectClass).invoke(null, new Object[]{perObject})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the pertypewithin aspect is bound + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { + try { + return ((Boolean)getPerTypeWithinHasAspect(aspectClass).invoke(null, new Object[]{perTypeWithin})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + // -- aspectOf + + private static Method getSingletonOrThreadAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, EMPTY_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method getPerObjectAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, PEROBJECT_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method getPerTypeWithinAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, PERTYPEWITHIN_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method checkAspectOf(Method method, Class aspectClass) throws NoSuchMethodException { + method.setAccessible(true); + if (!method.isAccessible() + || !Modifier.isPublic(method.getModifiers()) + || !Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException(aspectClass.getName() + ".aspectOf(..) is not accessible public static"); + } + return method; + } + + // -- hasAspect + + private static Method getSingletonOrThreadHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, EMPTY_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerObjectHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PEROBJECT_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerTypeWithinHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PERTYPEWITHIN_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method checkHasAspect(Method method, Class aspectClass) throws NoSuchMethodException { + method.setAccessible(true); + if (!method.isAccessible() + || !Modifier.isPublic(method.getModifiers()) + || !Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException(aspectClass.getName() + ".hasAspect(..) is not accessible public static"); + } + return method; + } +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/AdviceName.java b/runtime/src/main/java/org/aspectj/lang/annotation/AdviceName.java new file mode 100644 index 000000000..779e7fee6 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/AdviceName.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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer initial implementation + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * Used to annotated code-style advice to name it + * Name is used by reflection api if present, may in future be used in adviceexecution() pcd. + * It is an error to use the @AdviceName annotation on an annotation-style advice declaration. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AdviceName { + + /** + * The name of the advice + */ + String value(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/After.java b/runtime/src/main/java/org/aspectj/lang/annotation/After.java new file mode 100644 index 000000000..286f9c7e5 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/After.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * After finally advice + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface After { + + /** + * The pointcut expression where to bind the advice + */ + String value(); + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the advice declaration are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/AfterReturning.java b/runtime/src/main/java/org/aspectj/lang/annotation/AfterReturning.java new file mode 100644 index 000000000..397c48fc6 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/AfterReturning.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * After returning advice + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AfterReturning { + + /** + * The pointcut expression where to bind the advice + */ + String value() default ""; + + /** + * The pointcut expression where to bind the advice, overrides "value" when specified + */ + String pointcut() default ""; + + /** + * The name of the argument in the advice signature to bind the returned value to + */ + String returning() default ""; + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the advice declaration are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/AfterThrowing.java b/runtime/src/main/java/org/aspectj/lang/annotation/AfterThrowing.java new file mode 100644 index 000000000..7b4d8212c --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/AfterThrowing.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * After throwing advice + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AfterThrowing { + + /** + * The pointcut expression where to bind the advice + */ + String value() default ""; + + /** + * The pointcut expression where to bind the advice, overrides "value" when specified + */ + String pointcut() default ""; + + /** + * The name of the argument in the advice signature to bind the thrown exception to + */ + String throwing() default ""; + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the advice declaration are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/Around.java b/runtime/src/main/java/org/aspectj/lang/annotation/Around.java new file mode 100644 index 000000000..253e865f6 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/Around.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Around advice + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Around { + + /** + * The pointcut expression where to bind the advice + */ + String value(); + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the advice declaration are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/Aspect.java b/runtime/src/main/java/org/aspectj/lang/annotation/Aspect.java new file mode 100644 index 000000000..d45e85c84 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/Aspect.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Aspect declaration + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Aspect { + + /** + * Per clause expression, defaults to singleton aspect + *

+ * Valid values are "" (singleton), "perthis(...)", etc + */ + public String value() default ""; +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/Before.java b/runtime/src/main/java/org/aspectj/lang/annotation/Before.java new file mode 100644 index 000000000..fe4b372c1 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/Before.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Before advice + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Before { + + /** + * The pointcut expression where to bind the advice + */ + String value(); + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the advice declaration are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclareAnnotation.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareAnnotation.java new file mode 100644 index 000000000..ffecb91a2 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareAnnotation.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: + * Alexandre Vasseur initial implementation + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) +public @interface DeclareAnnotation { + + /** + * pointcut (type pattern for type, or method/ctor/field signature pattern) + */ + public String value(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclareError.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareError.java new file mode 100644 index 000000000..9f3a045ee --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareError.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author colyer + * Annotation for declare error... + * + * usage: @DeclareError("somePcut()") + * private static final String "a message"; + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DeclareError { + /** + * The pointcut expression where to bind the error (don't use if, formal bindings, cflow etc) + */ + String value(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclareMixin.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareMixin.java new file mode 100644 index 000000000..f44c68195 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareMixin.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * initial implementation Andy Clement + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * DeclareMixin annotation - see design and usage in https://bugs.eclipse.org/bugs/show_bug.cgi?id=266552 + * + *

+ * Attached to a factory method, this annotation indicates that any types matching the pattern specified in the annotation value + * will have new methods mixed in. The methods will be selected based on a combination of the return type of the factory method, + * possibly sub-setted by any list of interfaces specified in the interfaces annotation value. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface DeclareMixin { + + /** + * The target types expression + */ + String value(); + + /** + * Array of interfaces that are to be mixed in. This is optional and if not specified the return type of the annotated method + * will be used to determine the interface to mix in. + */ + Class[] interfaces() default { Object.class }; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclareParents.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareParents.java new file mode 100644 index 000000000..b7c2452e2 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareParents.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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: + * initial implementation Adrian Colyer + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Declare parents mixin annotation + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DeclareParents { + + /** + * The target types expression + */ + String value(); + + /** + * Optional class defining default implementation + * of interface members (equivalent to defining + * a set of interface member ITDs for the + * public methods of the interface). + */ + Class defaultImpl() default DeclareParents.class; + + // note - a default of "null" is not allowed, + // hence the strange default given above. +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclarePrecedence.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclarePrecedence.java new file mode 100644 index 000000000..e1a048819 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclarePrecedence.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Aspect precedence declaration + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface DeclarePrecedence { + + /** + * The precedence pattern list + */ + String value(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/DeclareWarning.java b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareWarning.java new file mode 100644 index 000000000..446ac786a --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/DeclareWarning.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author colyer + * Annotation for declare warning... + * + * usage: @DeclareWarning("somePcut()") + * private static final String "a message"; + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DeclareWarning { + /** + * The pointcut expression where to bind the error (don't use if, formal bindings, cflow etc) + */ + String value(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/Pointcut.java b/runtime/src/main/java/org/aspectj/lang/annotation/Pointcut.java new file mode 100644 index 000000000..6fae1e8b9 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/Pointcut.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Pointcut declaration + * + * @author Alexandre Vasseur + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Pointcut { + + /** + * The pointcut expression + * We allow "" as default for abstract pointcut + */ + String value() default ""; + + /** + * When compiling without debug info, or when interpreting pointcuts at runtime, + * the names of any arguments used in the pointcut are not available. + * Under these circumstances only, it is necessary to provide the arg names in + * the annotation - these MUST duplicate the names used in the annotated method. + * Format is a simple comma-separated list. + */ + String argNames() default ""; +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/RequiredTypes.java b/runtime/src/main/java/org/aspectj/lang/annotation/RequiredTypes.java new file mode 100644 index 000000000..d83b1bb73 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/RequiredTypes.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * Copyright (c) 2014 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 + * ******************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Can be specified on an aspect to ensure that particular types must be accessible before + * the aspect will be 'activated'. The array value should be a list of fully qualified + * type names as strings, for example "com.foo.Bar". Useful in an aspect library that + * includes a number of aspects, only a few of which should ever be active depending + * upon what is on the classpath. + * + * @author Andy Clement + * @since 1.8.3 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface RequiredTypes { + String[] value(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/SuppressAjWarnings.java b/runtime/src/main/java/org/aspectj/lang/annotation/SuppressAjWarnings.java new file mode 100644 index 000000000..8fa9c6a16 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/SuppressAjWarnings.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: + * Wes Isberg initial implementation + * Andy Clement fleshed out to match SuppressWarnings + * ******************************************************************/ + + +package org.aspectj.lang.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Annotate members to avoid AspectJ error messages. + * Currently supported: + *

    + *
  • advice that might not run (-Xlint TODO message id)
  • + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface SuppressAjWarnings { + String[] value() default ""; +} diff --git a/runtime/src/main/java/org/aspectj/lang/annotation/control/CodeGenerationHint.java b/runtime/src/main/java/org/aspectj/lang/annotation/control/CodeGenerationHint.java new file mode 100644 index 000000000..7fe9dea24 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/annotation/control/CodeGenerationHint.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 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: + * initial implementation Andy Clement + *******************************************************************************/ +package org.aspectj.lang.annotation.control; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Provide code generation hints to the compiler (e.g. names to use for generated members). + * + * @author Andy Clement + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface CodeGenerationHint { + + /** + * Defines the name suffix to use for a generated member representing an if pointcut (prefix will be 'ajc$if$'). + * If left blank, a suffix will be generated. + */ + String ifNameSuffix() default ""; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/internal/lang/PlaceHolder.java b/runtime/src/main/java/org/aspectj/lang/internal/lang/PlaceHolder.java new file mode 100644 index 000000000..9edd4bcdf --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/internal/lang/PlaceHolder.java @@ -0,0 +1,18 @@ +/* ******************************************************************* + * 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: + * Wes Isberg initial implementation + * ******************************************************************/ + + +package org.aspectj.lang.internal.lang; + +class PlaceHolder { + private static final long L = 1l; +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/Advice.java b/runtime/src/main/java/org/aspectj/lang/reflect/Advice.java new file mode 100644 index 000000000..03be6c7f1 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/Advice.java @@ -0,0 +1,59 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.Type; + +/** + * Runtime representation of an advice declaration inside an aspect + */ +public interface Advice { + + /** + * The declaring aspect + */ + AjType getDeclaringType(); + + /** + * The kind of advice (before, after-returning, after-throwing, etc.) + */ + AdviceKind getKind(); + + /** + * Returns the advice name, or the empty string if the advice is anonymous. + * If using the @AspectJ annotations, the advice name is the name of the + * annotated advice method. If using the code style, the advice is + * anonymous, unless the advice is annotated with the @AdviceName annotation, + * in which case the name given in the annotation is returned. + */ + 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/runtime/src/main/java/org/aspectj/lang/reflect/AdviceKind.java b/runtime/src/main/java/org/aspectj/lang/reflect/AdviceKind.java new file mode 100644 index 000000000..82351db88 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/AdviceKind.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * The different kinds of advice in AspectJ + */ +public enum AdviceKind { + BEFORE, + AFTER, + AFTER_RETURNING, + AFTER_THROWING, + AROUND; +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/AjType.java b/runtime/src/main/java/org/aspectj/lang/reflect/AjType.java new file mode 100644 index 000000000..5e26a7d27 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/AjType.java @@ -0,0 +1,380 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +/** + * The runtime representation of a type (Aspect, Class, Interface, Annotation, Enum, or Array) in an AspectJ + * program. + */ +public interface AjType extends Type, AnnotatedElement { + + /** + * The name of this type, in the same format as returned by Class.getName() + */ + public String getName(); + + /** + * The package in which this type is declared + */ + public Package getPackage(); + + /** + * The interfaces implemented by this type + */ + public AjType[] getInterfaces(); + + /** + * The modifiers declared for this type. The return value can be interpreted + * using java.lang.reflect.Modifier + */ + public int getModifiers(); + + /** + * The java.lang.Class that corresponds to this AjType + */ + public Class getJavaClass(); + + // scope + + /** + * The supertype of this type. If this type represents Object or a primitive type + * then null is returned. + */ + public AjType getSupertype(); + + /** + * The generic supertype of this type, as defined by Class.getGenericSupertype + */ + public Type getGenericSupertype(); + + /** + * If this type represents a local or anonymous type declared within a method, return + * then enclosing Method object. + */ + public Method getEnclosingMethod(); + + /** + * If this type represents a local or anonymous type declared within a constructor, return + * then enclosing Method object. + */ + public Constructor getEnclosingConstructor(); + + /** + * Returns the immediately enclosing type of this type. + */ + public AjType getEnclosingType(); + + /** + * If this type is a member of another type, return the AjType representing the type + * in which it was declared. + */ + public AjType getDeclaringType(); + + /** + * If this type represents an aspect, returns the associated per-clause. + * Returns null for non-aspect types. + */ + public PerClause getPerClause(); + + // inner types + /** + * Returns an array containing all the public types that are members of this type + */ + public AjType[] getAjTypes(); + + /** + * Returns an array containing all the types declared by this type + */ + public AjType[] getDeclaredAjTypes(); + + // constructors + + /** + * Returns the constructor object for the specified public constructor of this type + */ + public Constructor getConstructor(AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Returns all of the public constructors of this type + */ + public Constructor[] getConstructors(); + + /** + * Returns the constructor object for the specified constructor of this type + */ + public Constructor getDeclaredConstructor(AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Returns all the constructors declared in this type + */ + public Constructor[] getDeclaredConstructors(); + + // fields + + /** + * Return the field declared in this type with the given name + */ + public Field getDeclaredField(String name) throws NoSuchFieldException; + + /** + * Returns all the fields declared in this type + */ + public Field[] getDeclaredFields(); + + /** + * Return the public field with the given name + */ + public Field getField(String name) throws NoSuchFieldException; + + /** + * Return the public fields declared by this type + */ + public Field[] getFields(); + + // methods + + /** + * Return the method object for the specified method declared in this type + */ + public Method getDeclaredMethod(String name, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Return the method object for the specified public method declared in this type + */ + public Method getMethod(String name, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Return all the methods declared by this type + */ + public Method[] getDeclaredMethods(); + + /** + * Returns all the public methods of this type + */ + public Method[] getMethods(); + + // pointcuts + + /** + * Return the pointcut object representing the specified pointcut declared by this type + */ + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException; + + /** + * Return the pointcut object representing the specified public pointcut + */ + public Pointcut getPointcut(String name) throws NoSuchPointcutException; + + /** + * Returns all of the pointcuts declared by this type + */ + public Pointcut[] getDeclaredPointcuts(); + + /** + * Returns all of the public pointcuts of this type + */ + public Pointcut[] getPointcuts(); + + // advice + + /** + * Returns all of the advice declared by this type, of an advice kind contained in the + * parameter list. + */ + public Advice[] getDeclaredAdvice(AdviceKind... ofTypes); + + /** + * Returns all of the advice for this type, of an advice kind contained in the parameter + * list. + */ + public Advice[] getAdvice(AdviceKind... ofTypes); + + /** + * Returns the advice with the given name. For an @AspectJ declared advice member, + * this is the name of the annotated method. For a code-style advice declaration, this + * is the name given in the @AdviceName annotation if present. + */ + public Advice getAdvice(String name) throws NoSuchAdviceException; + + /** + * Returns the advice declared in this type with the given name. For an @AspectJ declared advice member, + * this is the name of the annotated method. For a code-style advice declaration, this + * is the name given in the @AdviceName annotation if present. + */ + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException; + + // inter-type declarations + + /** + * Return the inter-type method declared by this type matching the given specification + */ + public InterTypeMethodDeclaration getDeclaredITDMethod(String name, AjType target, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Return all of the inter-type methods declared by this type + */ + public InterTypeMethodDeclaration[] getDeclaredITDMethods(); + + /** + * Return the public inter-type method of this type matching the given specification + */ + public InterTypeMethodDeclaration getITDMethod(String name, AjType target, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Return all of the public inter-type declared methods of this type + */ + public InterTypeMethodDeclaration[] getITDMethods(); + + /** + * Return the inter-type constructor declared by this type matching the given specification + */ + public InterTypeConstructorDeclaration getDeclaredITDConstructor(AjType target, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Returns all of the inter-type constructors declared by this type + */ + public InterTypeConstructorDeclaration[] getDeclaredITDConstructors(); + + /** + * Return the public inter-type constructor matching the given specification + */ + public InterTypeConstructorDeclaration getITDConstructor(AjType target, AjType... parameterTypes) throws NoSuchMethodException; + + /** + * Return all of the public inter-type constructors of this type + */ + public InterTypeConstructorDeclaration[] getITDConstructors(); + + /** + * Return the inter-type field declared in this type with the given specification + */ + public InterTypeFieldDeclaration getDeclaredITDField(String name, AjType target) throws NoSuchFieldException; + + /** + * Return all of the inter-type fields declared in this type + */ + public InterTypeFieldDeclaration[] getDeclaredITDFields(); + + /** + * Return the public inter-type field matching the given specification + */ + public InterTypeFieldDeclaration getITDField(String name, AjType target) throws NoSuchFieldException; + + /** + * Return all of the public inter-type fields for this type + */ + public InterTypeFieldDeclaration[] getITDFields(); + + // declare statements + /** + * Returns all of the declare error and declare warning members of this type, + * including declare error/warning members inherited from super-types + */ + public DeclareErrorOrWarning[] getDeclareErrorOrWarnings(); + + /** + * Returns all of the declare parents members of this type, including + * declare parent members inherited from super-types + */ + public DeclareParents[] getDeclareParents(); + + /** + * Return all of the declare soft members of this type, including declare + * soft members inherited from super-types + */ + public DeclareSoft[] getDeclareSofts(); + + /** + * Return all of the declare annotation members of this type, including declare + * annotation members inherited from super-types + */ + public DeclareAnnotation[] getDeclareAnnotations(); + + /** + * Return all of the declare precedence members of this type, including declare + * precedence members inherited from super-types + */ + public DeclarePrecedence[] getDeclarePrecedence(); + + // misc + + /** + * Returns the elements of this enum class, or null if this type does not represent + * an enum type. + */ + public T[] getEnumConstants(); + + /** + * Returns an array of TypeVariable objects that represent the type variables declared by + * this type (if any) + */ + public TypeVariable>[] getTypeParameters(); + + /** + * True if this is an enum type + */ + public boolean isEnum(); + + /** + * True if the given object is assignment-compatible with an object of the type represented + * by this AjType + */ + public boolean isInstance(Object o); + + /** + * True if this is an interface type + */ + public boolean isInterface(); + + /** + * Returns true if and only if the underlying type is a local class + */ + public boolean isLocalClass(); + + /** + * Returns true if and only if the underlying type is a member class + */ + public boolean isMemberClass(); + + /** + * Return true if this is an array type + */ + public boolean isArray(); + + /** + * Return true if this object represents a primitive type + */ + public boolean isPrimitive(); + + /** + * Return true if this is an aspect type + */ + public boolean isAspect(); + + /** + * Returns true if and only if the underlying type is a member aspect + */ + public boolean isMemberAspect(); + + /** + * Returns true if and only if the underlying type is a privileged aspect + */ + public boolean isPrivileged(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/AjTypeSystem.java b/runtime/src/main/java/org/aspectj/lang/reflect/AjTypeSystem.java new file mode 100644 index 000000000..6999dac19 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/AjTypeSystem.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; + +import org.aspectj.internal.lang.reflect.AjTypeImpl; + +/** + * This is the anchor for the AspectJ runtime type system. + * Typical usage to get the AjType representation of a given type + * at runtime is to call AjType fooType = AjTypeSystem.getAjType(Foo.class); + */ +public class AjTypeSystem { + + private static Map> ajTypes = + Collections.synchronizedMap(new WeakHashMap>()); + + /** + * Return the AspectJ runtime type representation of the given Java type. + * Unlike java.lang.Class, AjType understands pointcuts, advice, declare statements, + * and other AspectJ type members. AjType is the recommended reflection API for + * AspectJ programs as it offers everything that java.lang.reflect does, with + * AspectJ-awareness on top. + */ + public static AjType getAjType(Class fromClass) { + WeakReference weakRefToAjType = ajTypes.get(fromClass); + if (weakRefToAjType!=null) { + AjType theAjType = weakRefToAjType.get(); + if (theAjType != null) { + return theAjType; + } else { + theAjType = new AjTypeImpl(fromClass); + ajTypes.put(fromClass, new WeakReference(theAjType)); + return theAjType; + } + } + // neither key nor value was found + AjType theAjType = new AjTypeImpl(fromClass); + ajTypes.put(fromClass, new WeakReference(theAjType)); + return theAjType; + } +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/DeclareAnnotation.java b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareAnnotation.java new file mode 100644 index 000000000..faee5d495 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareAnnotation.java @@ -0,0 +1,56 @@ +/* ******************************************************************* + * 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.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/runtime/src/main/java/org/aspectj/lang/reflect/DeclareErrorOrWarning.java b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareErrorOrWarning.java new file mode 100644 index 000000000..a6a5abc53 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareErrorOrWarning.java @@ -0,0 +1,40 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a declare error or declare warning member + * in an aspect. + */ +public interface DeclareErrorOrWarning { + + /** + * The type that declared this declare warning or declare error member. + */ + AjType getDeclaringType(); + + /** + * The pointcut expression associated with the warning or error + */ + PointcutExpression getPointcutExpression(); + + /** + * The message associated with the declare warning / declare error + */ + String getMessage(); + + /** + * True if this is a declare error member, false if it is declare warning + */ + boolean isError(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/DeclareParents.java b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareParents.java new file mode 100644 index 000000000..8d3c98b78 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareParents.java @@ -0,0 +1,47 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.Type; + +/** + * A declare parents member defined inside an aspect + */ +public interface DeclareParents { + + /** + * The declaring aspect + */ + AjType getDeclaringType(); + + /** + * The target type pattern + */ + TypePattern getTargetTypesPattern(); + + /** + * True if this is a declare parents...extends member declaration + */ + boolean isExtends(); + + /** + * True if this is a declare parents...implements member declaration + */ + boolean isImplements(); + + /** + * The set of types that the types matching getTargetTypesPattern are + * declared to implement or extend + */ + Type[] getParentTypes() throws ClassNotFoundException; + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/DeclarePrecedence.java b/runtime/src/main/java/org/aspectj/lang/reflect/DeclarePrecedence.java new file mode 100644 index 000000000..894580b70 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/DeclarePrecedence.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.lang.reflect; + +/** + * AspectJ runtime representation of a declare precedence statement as + * declared in an aspect. + */ +public interface DeclarePrecedence { + + /** + * The declaring aspect + */ + AjType getDeclaringType(); + + /** + * Returns an ordered set of type patterns. An aspect matching + * a type pattern at a lower index in the array takes precedence + * over an aspect that only matches a type pattern at a higher + * index in the array. + */ + TypePattern[] getPrecedenceOrder(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/DeclareSoft.java b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareSoft.java new file mode 100644 index 000000000..cc607d680 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/DeclareSoft.java @@ -0,0 +1,34 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a declare soft member within an aspect. + */ +public interface DeclareSoft { + + /** + * The aspect that declared this member + */ + AjType getDeclaringType(); + + /** + * The softened exception type + */ + AjType getSoftenedExceptionType() throws ClassNotFoundException; + + /** + * The pointcut determining the join points at which the exception is to be softened. + */ + PointcutExpression getPointcutExpression(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java new file mode 100644 index 000000000..8db4505e3 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java @@ -0,0 +1,36 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.Type; + +/** + * Runtime representation of an inter-type constructor member declared within an + * aspect. + */ +public interface InterTypeConstructorDeclaration extends InterTypeDeclaration { + + /** + * The constructor parameters + */ + AjType[] getParameterTypes(); + + /** + * The generic constructor parameters + */ + Type[] getGenericParameterTypes(); + + /** + * The declared exceptions thrown by this constructor + */ + AjType[] getExceptionTypes(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeDeclaration.java b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeDeclaration.java new file mode 100644 index 000000000..c00461011 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeDeclaration.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * Represents an inter-type method, field, or constructor declared in an aspect. + */ +public interface InterTypeDeclaration { + + /** + * The declaring aspect + */ + AjType getDeclaringType(); + + /** + * The target type of this ITD + */ + AjType getTargetType() throws ClassNotFoundException; + + /** + * Member modifiers, can be interpreted using java.lang.reflect.Modifier + */ + int getModifiers(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java new file mode 100644 index 000000000..5a8acd76c --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java @@ -0,0 +1,36 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.Type; + +/** + * Represents an inter-type field declaration declared in an aspect. + */ +public interface InterTypeFieldDeclaration extends InterTypeDeclaration { + + /** + * The field name + */ + String getName(); + + /** + * The field type + */ + AjType getType(); + + /** + * The generic field type + */ + Type getGenericType(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java new file mode 100644 index 000000000..e570d8d2d --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java @@ -0,0 +1,57 @@ +/* ******************************************************************* + * 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.lang.reflect; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +/** + * Represents an inter-type method declaration member within an aspect. + */ +public interface InterTypeMethodDeclaration extends InterTypeDeclaration { + + /** + * The name of this method + */ + String getName(); + + /** + * The method return type + */ + AjType getReturnType(); + + /** + * The generic return type + */ + Type getGenericReturnType(); + + /** + * The method parameters + */ + AjType[] getParameterTypes(); + + /** + * The generic method parameters + */ + Type[] getGenericParameterTypes(); + + /** + * The type variables declared by this method + */ + TypeVariable[] getTypeParameters(); + + /** + * The declared exceptions thrown by this method + */ + AjType[] getExceptionTypes(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchAdviceException.java b/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchAdviceException.java new file mode 100644 index 000000000..6b1ca8fa0 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchAdviceException.java @@ -0,0 +1,34 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * Thrown when AjType.getDeclaredAdvice is called with an advice name and no matching + * advice declaration can be found. + */ +public class NoSuchAdviceException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchAdviceException(String name) { + this.name = name; + } + + /** + * The advice name that could not be found. + */ + public String getName() { + return name; + } + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchPointcutException.java b/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchPointcutException.java new file mode 100644 index 000000000..0274b74b4 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/NoSuchPointcutException.java @@ -0,0 +1,34 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * Thrown when AjType.getDeclaredPointcut is called with a pointcut name, and no + * matching pointcut declaration can be found. + */ +public class NoSuchPointcutException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchPointcutException(String name) { + this.name = name; + } + + /** + * The name of the pointcut that could not be found. + */ + public String getName() { + return name; + } + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/PerClause.java b/runtime/src/main/java/org/aspectj/lang/reflect/PerClause.java new file mode 100644 index 000000000..c16feda33 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/PerClause.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of the per-clause associated with an aspect. + */ +public interface PerClause { + /** + * The kind of per-clause (singleton, perthis, pertarget,...) + */ + PerClauseKind getKind(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/PerClauseKind.java b/runtime/src/main/java/org/aspectj/lang/reflect/PerClauseKind.java new file mode 100644 index 000000000..1e2d42ecd --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/PerClauseKind.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.lang.reflect; + +/** + * The different per-clauses (aspect instantiation models) + * supported by AspectJ + */ +public enum PerClauseKind { + SINGLETON, + PERTHIS, + PERTARGET, + PERCFLOW, + PERCFLOWBELOW, + PERTYPEWITHIN; +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/Pointcut.java b/runtime/src/main/java/org/aspectj/lang/reflect/Pointcut.java new file mode 100644 index 000000000..dfec7ccbd --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/Pointcut.java @@ -0,0 +1,52 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a pointcut member inside a class or aspect. + */ +public interface Pointcut { + + /** + * The declared name of the pointcut. + */ + String getName(); + + /** + * The modifiers associated with the pointcut declaration. + * Use java.lang.reflect.Modifier to interpret the return value + */ + int getModifiers(); + + /** + * The pointcut parameter types. + */ + AjType[] getParameterTypes(); + + /** + * The pointcut parameter names. Returns an array of empty strings + * of length getParameterTypes().length if parameter names are not + * available at runtime. + */ + String[] getParameterNames(); + + /** + * The type that declared this pointcut + */ + AjType getDeclaringType(); + + /** + * The pointcut expression associated with this pointcut. + */ + PointcutExpression getPointcutExpression(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/PointcutBasedPerClause.java b/runtime/src/main/java/org/aspectj/lang/reflect/PointcutBasedPerClause.java new file mode 100644 index 000000000..db040ea62 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/PointcutBasedPerClause.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.lang.reflect; + +/** + * Representation of a pointcut based per-clause associated with an aspect + * (perthis/target/cflow/cflowbelow) + * + */ +public interface PointcutBasedPerClause extends PerClause { + + /** + * Get the associated pointcut expression + */ + PointcutExpression getPointcutExpression(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/PointcutExpression.java b/runtime/src/main/java/org/aspectj/lang/reflect/PointcutExpression.java new file mode 100644 index 000000000..e229ba1f0 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/PointcutExpression.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * Represents an anonymous pointcut expression as used in pointcuts, advice declarations, + * declares, and per-clauses + */ +public interface PointcutExpression { + + /** + * Returns a String representation of the pointcut expression + */ + String asString(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/SignaturePattern.java b/runtime/src/main/java/org/aspectj/lang/reflect/SignaturePattern.java new file mode 100644 index 000000000..99ba44dda --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/SignaturePattern.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a signature pattern as used in various + * aspect members (for example, declare @method, declare @field). + */ +public interface SignaturePattern { + + /** return a String representation of this pattern */ + String asString(); + +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/TypePattern.java b/runtime/src/main/java/org/aspectj/lang/reflect/TypePattern.java new file mode 100644 index 000000000..f3b69b421 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/TypePattern.java @@ -0,0 +1,22 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a type pattern as used in member declarations + * such as declare parents. + */ +public interface TypePattern { + + /** a string representation of the pattern */ + String asString(); +} diff --git a/runtime/src/main/java/org/aspectj/lang/reflect/TypePatternBasedPerClause.java b/runtime/src/main/java/org/aspectj/lang/reflect/TypePatternBasedPerClause.java new file mode 100644 index 000000000..402b883b9 --- /dev/null +++ b/runtime/src/main/java/org/aspectj/lang/reflect/TypePatternBasedPerClause.java @@ -0,0 +1,26 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * AspectJ runtime representation of a type pattern based per-clause associated + * with an aspect (pertypewithin). + * + */ +public interface TypePatternBasedPerClause { + + /** + * Get the associated type pattern + */ + TypePattern getTypePattern(); + +} diff --git a/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeTest.java b/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeTest.java new file mode 100644 index 000000000..542de36d5 --- /dev/null +++ b/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeTest.java @@ -0,0 +1,327 @@ +/* ******************************************************************* + * 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.io.Serializable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import junit.framework.TestCase; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; + +public class AjTypeTest extends TestCase { + + private AjType stringType; + + @Override + protected void setUp() throws Exception { + super.setUp(); + stringType = AjTypeSystem.getAjType(String.class); + } + + public void testCreateAjType() { + assertNotNull("should find type",stringType); + } + + public void testGetName() { + assertEquals(String.class.getName(),stringType.getName()); + } + + public void testGetPackage() { + assertEquals(String.class.getPackage(),stringType.getPackage()); + } + + public void testGetInterfaces() { + Class[] i1 = String.class.getInterfaces(); + AjType[] i2 = stringType.getInterfaces(); + assertEquals(i1.length,i2.length); + for (int i = 0; i < i1.length; i++) + assertEquals(i1[i],i2[i].getJavaClass()); + } + + public void testGetModifiers() { + assertEquals(String.class.getModifiers(),stringType.getModifiers()); + } + + public void testGetSupertype() { + Class stringSuper = String.class.getSuperclass(); + AjType ajSuper = stringType.getSupertype(); + assertEquals(AjTypeSystem.getAjType(stringSuper),ajSuper); + } + + public void testObjectSupertype() { + AjType objectSuper = AjTypeSystem.getAjType(Object.class).getSupertype(); + assertNull(objectSuper); + } + + public void testInterfaceSupertype() { + AjType serializableSuper = AjTypeSystem.getAjType(Serializable.class).getSupertype(); + assertNull(serializableSuper); + } + + public void testGetGenericSupertype() { + Type t = AjTypeSystem.getAjType(Goo.class).getGenericSupertype(); + assertEquals(Foo.class,t); + } + + public void testGetEnclosingMethod() { + new Goo().foo(); + } + + public void testGetEnclosingConstructor() { + new Goo(); + } + + public void testGetEnclosingType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getEnclosingType().getName()); + } + + public void testGetDeclaringType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getDeclaringType().getName()); + } + + public void testIsAnnotationPresent() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType goo = AjTypeSystem.getAjType(Goo.class); + assertTrue(foo.isAnnotationPresent(SomeAnn.class)); + assertFalse(goo.isAnnotationPresent(SomeAnn.class)); + } + + public void testGetAnnotation() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType goo = AjTypeSystem.getAjType(Goo.class); + assertNotNull(foo.getAnnotation(SomeAnn.class)); + assertNull(goo.getAnnotation(SomeAnn.class)); + } + + public void testGetAnnotations() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(1,foo.getAnnotations().length); + assertEquals(0,goo.getAnnotations().length); + } + + public void testGetDeclaredAnnotations() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(0,goo.getDeclaredAnnotations().length); + assertEquals(1,foo.getDeclaredAnnotations().length); + } + + public void testGetAjTypes() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getAjTypes(); + assertEquals(1,fooTypes.length); + assertEquals("org.aspectj.internal.lang.reflect.Foo$Z",fooTypes[0].getName()); + } + + public void testGetDeclaredAjTypes() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getDeclaredAjTypes(); + assertEquals(2,fooTypes.length); + // Alex -> Adrian: looks like you can not make assumption on the ordering + String s = " " + fooTypes[0].getName() + " " + fooTypes[1].getName(); + assertTrue(s.indexOf(" org.aspectj.internal.lang.reflect.Foo$Z") >= 0); + assertTrue(s.indexOf(" org.aspectj.internal.lang.reflect.Foo$XX") >= 0); + } + + public void testGetConstructor() throws Exception { + Constructor c1 = String.class.getConstructor(String.class); + Constructor c2 = stringType.getConstructor(stringType); + assertEquals(c1,c2); + } + + public void testGetConstructors() { + Constructor[] c1 = String.class.getConstructors(); + Constructor[] c2 = stringType.getConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredConstructor() throws Exception { + Constructor c1 = String.class.getDeclaredConstructor(String.class); + Constructor c2 = stringType.getDeclaredConstructor(stringType); + assertEquals(c1,c2); + } + + public void testGetDeclaredConstructors() { + Constructor[] c1 = String.class.getDeclaredConstructors(); + Constructor[] c2 = stringType.getDeclaredConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredField() throws Exception { + Field f1 = String.class.getDeclaredField("value"); + Field f2 = stringType.getDeclaredField("value"); + assertEquals(f1,f2); + } + + public void testGetDeclaredFields() { + Field[] f1 = String.class.getDeclaredFields(); + Field[] f2 = stringType.getDeclaredFields(); + assertEquals(f1.length,f2.length); + for (int i = 0; i < f1.length; i++) + assertEquals(f1[i],f2[i]); + } + + public void testGetField() throws Exception { + AjType goo = AjTypeSystem.getAjType(Goo.class); + assertEquals("g",goo.getField("g").getName()); + } + + public void testGetFields() { + AjType goo = AjTypeSystem.getAjType(Goo.class); + Field[] fields = goo.getFields(); + assertEquals(1,fields.length); + assertEquals("g",fields[0].getName()); + + } + + public void testGetDeclaredMethod() throws Exception { + Method m1 = String.class.getDeclaredMethod("toUpperCase"); + Method m2 = stringType.getDeclaredMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetMethod() throws Exception { + Method m1 = String.class.getMethod("toUpperCase"); + Method m2 = stringType.getMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetDeclaredMethods() { + Method[] m1 = String.class.getDeclaredMethods(); + Method[] m2 = stringType.getDeclaredMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetMethods() { + Method[] m1 = String.class.getMethods(); + Method[] m2 = stringType.getMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetEnumConstants() { + AjType e = AjTypeSystem.getAjType(E.class); + Object[] consts = e.getEnumConstants(); + assertEquals(3,consts.length); + } + + public void testGetTypeParameters() { + AjType foo = AjTypeSystem.getAjType(Foo.class); + TypeVariable>[] tvs = foo.getTypeParameters(); + assertEquals(1,tvs.length); + assertEquals("T",tvs[0].getName()); + } + + public void testIsEnum() { + assertFalse(stringType.isEnum()); + } + + public void testIsInstance() { + assertTrue(stringType.isInstance("I am")); + } + + public void testIsInterface() { + assertFalse(stringType.isInterface()); + assertTrue(AjTypeSystem.getAjType(Serializable.class).isInterface()); + } + + public void testIsLocalClass() { + assertFalse(stringType.isLocalClass()); + } + + public void testIsArray() { + assertFalse(stringType.isArray()); + assertTrue(AjTypeSystem.getAjType(Integer[].class).isArray()); + } + + public void testIsPrimitive() { + assertFalse(stringType.isPrimitive()); + assertTrue(AjTypeSystem.getAjType(boolean.class).isPrimitive()); + } + + public void testIsAspect() { + assertFalse(stringType.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(stringType.isMemberAspect()); + } + + public void testIsPrivileged() { + assertFalse(stringType.isPrivileged()); + } + + public void testEquals() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertTrue(stringType.equals(stringTypeTwo)); + } + + public void testHashCode() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertEquals(stringType.hashCode(),stringTypeTwo.hashCode()); + } + +} + +@Retention(RetentionPolicy.RUNTIME) +@interface SomeAnn {} + +@SomeAnn +class Foo { + + public Foo() { + class Y { int y; } + AjType t = AjTypeSystem.getAjType(Y.class); + Constructor c = t.getEnclosingConstructor(); + if (!c.getName().equals("org.aspectj.internal.lang.reflect.Foo")) throw new RuntimeException("should have been Foo"); + } + public void foo() { + class X { int x; } + AjType t = AjTypeSystem.getAjType(X.class); + Method m = t.getEnclosingMethod(); + if (!m.getName().equals("foo")) throw new RuntimeException("should have been foo"); + } + public class Z { int z; } + class XX { int xx; } +} + +class Goo extends Foo { + @interface IX {} + + public Goo() { + super(); + } + + public int g; + int g2; + +} + +enum E { A,B,C; } diff --git a/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeWithAspectsTest.java b/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeWithAspectsTest.java new file mode 100644 index 000000000..af72d26f5 --- /dev/null +++ b/runtime/src/test/java/org/aspectj/internal/lang/reflect/AjTypeWithAspectsTest.java @@ -0,0 +1,449 @@ +/* ******************************************************************* + * 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.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import junit.framework.TestCase; + +import org.aspectj.internal.lang.annotation.ajcDeclareEoW; +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.DeclareError; +import org.aspectj.lang.annotation.DeclareWarning; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceKind; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.DeclareErrorOrWarning; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; +import org.aspectj.lang.reflect.Pointcut; +import org.aspectj.lang.reflect.PointcutBasedPerClause; +import org.aspectj.lang.reflect.TypePatternBasedPerClause; + +public class AjTypeWithAspectsTest extends TestCase { + + private AjType sa; + + protected void setUp() throws Exception { + super.setUp(); + sa = AjTypeSystem.getAjType(SimpleAspect.class); + } + + public void testGetPerClause() { + AjType perThisA = AjTypeSystem.getAjType(PerThisAspect.class); + AjType perTargetA = AjTypeSystem.getAjType(PerTargetAspect.class); + AjType perCflowA = AjTypeSystem.getAjType(PerCflowAspect.class); + AjType perCflowbelowA = AjTypeSystem.getAjType(PerCflowbelowAspect.class); + AjType perTypeWithinA = AjTypeSystem.getAjType(PerTypeWithin.class); + + 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()); + + } + + public void testGetDeclaredField() throws Exception{ + Field f = sa.getDeclaredField("s"); + try { + Field f2 = sa.getDeclaredField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetField() throws Exception { + Field f = sa.getField("s"); + try { + Field f2 = sa.getField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetDeclaredFields() { + Field[] fields = sa.getDeclaredFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetFields() { + Field[] fields = sa.getFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetDeclaredMethod() throws Exception { + Method m = sa.getDeclaredMethod("aMethod"); + try { + Method m2 = sa.getDeclaredMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getDeclaredMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetMethod() throws Exception { + Method m = sa.getMethod("aMethod"); + try { + Method m2 = sa.getMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetDeclaredMethods() { + Method[] ms = sa.getDeclaredMethods(); + assertEquals(1,ms.length); + assertEquals("aMethod",ms[0].getName()); + } + + public void testGetMethods() { + Method[] ms = sa.getMethods(); + assertEquals(10,ms.length); + //AV was corrupted, cannot rely on ordering + String match = ""; + for (int i = 0; i < ms.length; i++) { + match = match + "--" + ms[i].getName(); + } + assertTrue(match.indexOf("aMethod") >=0); + } + + public void testGetDeclaredPointcut() throws Exception { + 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())); + Pointcut p2 = sa.getDeclaredPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression().asString()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getDeclaredPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetPointcut() throws Exception { + Pointcut p1 = sa.getPointcut("simpleAspectMethodExecution"); + assertEquals("simpleAspectMethodExecution",p1.getName()); + assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression().asString()); + assertEquals(sa,p1.getDeclaringType()); + assertEquals(0,p1.getParameterTypes().length); + assertTrue(Modifier.isPublic(p1.getModifiers())); + Pointcut p2 = sa.getDeclaredPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression().asString()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetDeclaredPointcuts() { + Pointcut[] pcs = sa.getDeclaredPointcuts(); + assertEquals(2,pcs.length); + // AV was corrupted, cannot rely on ordering + String match = "simpleAspectMethodExecution--simpleAspectCall"; + assertTrue(match.indexOf(pcs[0].getName()) >= 0); + assertTrue(match.indexOf(pcs[1].getName()) >= 0); + } + + public void testGetPointcuts() { + Pointcut[] pcs = sa.getPointcuts(); + assertEquals(1,pcs.length); + assertEquals("simpleAspectMethodExecution",pcs[0].getName()); + } + + public void testGetDeclaredAdvice() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.BEFORE,AdviceKind.AFTER); + assertEquals(4,advice.length); + + advice = sa.getDeclaredAdvice(AdviceKind.BEFORE); + // AV: corrupted test: cannot rely on ordering since a Set is used behind + Advice aone, atwo; + if (advice[0].getName()!=null && advice[0].getName().length()>0) { + aone = advice[0]; + atwo = advice[1]; + } else { + aone = advice[1]; + 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() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceKind.BEFORE,AdviceKind.AFTER); + assertEquals(4,advice.length); + } + + public void testGetNamedAdvice() throws Exception { + Advice a = sa.getAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceKind.AROUND,a.getKind()); + a = sa.getAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceKind.AROUND,a.getKind()); + try { + a = sa.getAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testGetNamedDeclaredAdvice() throws Exception { + Advice a = sa.getDeclaredAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceKind.AROUND,a.getKind()); + a = sa.getDeclaredAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceKind.AROUND,a.getKind()); + try { + a = sa.getDeclaredAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getDeclaredAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testIsPrivileged() { + assertFalse(sa.isPrivileged()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isPrivileged()); + } + + public void testIsAspect() { + assertTrue(sa.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isMemberAspect()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.MemberAspect.class).isMemberAspect()); + + } + + public void testGetDeclareEoWarnings() { + DeclareErrorOrWarning[] deows = sa.getDeclareErrorOrWarnings(); + assertEquals(4,deows.length); + boolean foundCodeWarning = false; + boolean foundCodeError = false; + boolean foundAnnWarning = false; + boolean foundAnnError = false; + for (DeclareErrorOrWarning deow : deows) { + if (deow.isError()) { + 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 { + if (deow.getMessage().equals("dont call this method code")) foundCodeWarning = true; + if (deow.getMessage().equals("dont call this method ann")) foundAnnWarning = true; + assertEquals("call(* DontDoIt.*(..))",deow.getPointcutExpression().toString()); + } + } + assertTrue(foundCodeWarning && foundAnnWarning && foundCodeError && foundAnnError); + } + +} + + +@Aspect +class SimpleAspect { + + // regular field + public String s; + + // synthetic field + public String ajc$xyz$s; + + // regular method + public void aMethod() {} + + // advice method, annotation style + @Before("execution(* SimpleAspect.*(..))") + public void logEntry() {} + + // advice method, code style + @Before("execution(* SimpleAspect.*(..))") + public void ajc$before$123() {} + + // advice method, annotation style + @After("execution(* SimpleAspect.*(..))") + public void logFinally() {} + + // advice method, code style + @After("execution(* SimpleAspect.*(..))") + public void ajc$after$123() {} + + // advice method, annotation style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void logExit() {} + + // advice method, code style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void ajc$afterReturning$123() {} + + // advice method, annotation style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void logException() {} + + // advice method, code style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void ajc$afterThrowing$123() {} + + // advice method, annotation style + @Around("execution(* SimpleAspect.*(..))") + public void logItAll() {} + + // advice method, code style + @Around("execution(* SimpleAspect.*(..))") + @AdviceName("whatGoesAround") + public void ajc$around$123() {} + + // pointcut, annotation style + @org.aspectj.lang.annotation.Pointcut("execution(* SimpleAspect.*(..))") + public void simpleAspectMethodExecution() {}; + + // pointcut, code style + @org.aspectj.lang.annotation.Pointcut("call(* SimpleAspect.*(..))") + private void ajc$pointcut$$simpleAspectCall$123(SimpleAspect target) {}; + + // decw, ann style + @DeclareWarning("call(* DontDoIt.*(..))") + public static final String dontDoIt = "dont call this method ann"; + + // decw, code style + @ajcDeclareEoW(pointcut="call(* DontDoIt.*(..))",message="dont call this method code",isError=false) + private void ajc$declare_eow$123() {} + + // dec., ann style + @DeclareError("call(* DontDoIt.*(..))") + public static final String dontDoItISaid = "dont call this method ann"; + + // decw, code style + @ajcDeclareEoW(pointcut="call(* DontDoIt.*(..))",message="dont call this method code",isError=true) + private void ajc$declare_eow$124() {} +} + +@Aspect +@ajcPrivileged +class SimplePrivilegedAspect { + + @Aspect + static class MemberAspect {} + +} + +@Aspect("perthis(pc())") +class PerThisAspect {} + +@Aspect("pertarget(pc())") +class PerTargetAspect {} + +@Aspect("percflow(pc())") +class PerCflowAspect {} + +@Aspect("percflowbelow(pc())") +class PerCflowbelowAspect {} + +@Aspect("pertypewithin(org.aspectj..*)") +class PerTypeWithin {} diff --git a/runtime/src/test/java/org/aspectj/internal/lang/reflect/InterTypeTest.java b/runtime/src/test/java/org/aspectj/internal/lang/reflect/InterTypeTest.java new file mode 100644 index 000000000..128993d67 --- /dev/null +++ b/runtime/src/test/java/org/aspectj/internal/lang/reflect/InterTypeTest.java @@ -0,0 +1,88 @@ +/* ******************************************************************* + * 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.Method; +import java.lang.reflect.Type; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.InterTypeConstructorDeclaration; +import org.aspectj.lang.reflect.InterTypeDeclaration; +import org.aspectj.lang.reflect.InterTypeFieldDeclaration; +import org.aspectj.lang.reflect.InterTypeMethodDeclaration; + +import junit.framework.TestCase; + +/** + * @author colyer + * + */ +public class InterTypeTest extends TestCase { + + public void testITDImpl() throws ClassNotFoundException { + AjType thisClass = AjTypeSystem.getAjType(InterTypeTest.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + InterTypeDeclaration itd = new InterTypeDeclarationImpl(thisClass,"java.lang.Runnable",5); + assertEquals(thisClass,itd.getDeclaringType()); + assertEquals(runnable,itd.getTargetType()); + assertEquals(5, itd.getModifiers()); + } + + public void testITDField() throws ClassNotFoundException { + AjType thisClass = AjTypeSystem.getAjType(InterTypeTest.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + InterTypeDeclaration itd = new InterTypeDeclarationImpl(thisClass,"java.lang.Runnable",5); + AjType stringType = AjTypeSystem.getAjType(java.lang.String.class); + Type t = Type.class; + InterTypeFieldDeclaration itdf = new InterTypeFieldDeclarationImpl(thisClass,"java.lang.Runnable",5,"f",stringType,t); + assertEquals("f",itdf.getName()); + assertEquals(stringType,itdf.getType()); + assertEquals(t,itdf.getGenericType()); + } + + public void testITDCons() throws ClassNotFoundException, NoSuchMethodException { + AjType thisClass = AjTypeSystem.getAjType(InterTypeTest.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + Method base = InterTypeTest.class.getDeclaredMethod("interCons",InterTypeTest.class,String.class,int.class); + InterTypeConstructorDeclaration itdc = + new InterTypeConstructorDeclarationImpl(thisClass,"java.lang.Runnable",5,base); + assertEquals(2,itdc.getParameterTypes().length); + assertEquals(String.class,itdc.getParameterTypes()[0].getJavaClass()); + assertEquals(int.class,itdc.getParameterTypes()[1].getJavaClass()); + assertEquals(2,itdc.getGenericParameterTypes().length); + assertEquals(base.getGenericParameterTypes()[1],((AjType)itdc.getGenericParameterTypes()[0]).getJavaClass()); + assertEquals(base.getGenericParameterTypes()[2],((AjType)itdc.getGenericParameterTypes()[1]).getJavaClass()); + assertEquals(0,itdc.getExceptionTypes().length); + } + + public void testITDMethod() throws NoSuchMethodException { + AjType thisClass = AjTypeSystem.getAjType(InterTypeTest.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + Method base = InterTypeTest.class.getDeclaredMethod("interMethod",InterTypeTest.class,String.class,int.class); + InterTypeMethodDeclaration itdm = new InterTypeMethodDeclarationImpl(thisClass,"java.lang.Runnable",5,"foo",base); + assertEquals("foo",itdm.getName()); + assertEquals(int.class,itdm.getReturnType().getJavaClass()); + assertEquals(int.class,((AjType)itdm.getGenericReturnType()).getJavaClass()); + assertEquals(2,itdm.getParameterTypes().length); + assertEquals(String.class,itdm.getParameterTypes()[0].getJavaClass()); + assertEquals(int.class,itdm.getParameterTypes()[1].getJavaClass()); + assertEquals(2,itdm.getGenericParameterTypes().length); + assertEquals(base.getGenericParameterTypes()[1],((AjType)itdm.getGenericParameterTypes()[0]).getJavaClass()); + assertEquals(base.getGenericParameterTypes()[2],((AjType)itdm.getGenericParameterTypes()[1]).getJavaClass()); + assertEquals(0,itdm.getExceptionTypes().length); + } + + public static void interCons(InterTypeTest itt, String s, int i) { } + + public static int interMethod(InterTypeTest itt, String s, int i) { return 5; } +}