From b305f9ee512015657cad0ea722b8180d884b1f72 Mon Sep 17 00:00:00 2001 From: acolyer Date: Tue, 4 Oct 2005 13:56:38 +0000 Subject: [PATCH] itd support in the MAP --- .../internal/lang/annotation/ajcITD.java | 31 ++ .../internal/lang/reflect/AjTypeImpl.java | 333 ++++++++++++++++-- .../lang/reflect/DeclareParentsImpl.java | 65 +--- .../InterTypeConstructorDeclarationImpl.java | 81 +++++ .../reflect/InterTypeDeclarationImpl.java | 68 ++++ .../InterTypeFieldDeclarationImpl.java | 78 ++++ .../InterTypeMethodDeclarationImpl.java | 126 +++++++ .../internal/lang/reflect/StringToType.java | 82 +++++ .../lang/annotation/DeclareParents.java | 31 ++ .../org/aspectj/lang/reflect/AjType.java | 12 +- .../InterTypeConstructorDeclaration.java | 20 +- .../lang/reflect/InterTypeDeclaration.java | 17 + .../reflect/InterTypeFieldDeclaration.java | 22 +- .../reflect/InterTypeMethodDeclaration.java | 41 +++ .../Aspectj5rt15ModuleTests.java | 2 + .../lang/reflect/AjTypeTestsWithAspects.java | 1 + .../internal/lang/reflect/InterTypeTests.java | 88 +++++ lib/aspectj/lib/aspectjrt.jar | Bin 145821 -> 165911 bytes lib/test/aspectjrt.jar | Bin 145821 -> 165911 bytes .../ast/AddAtAspectJAnnotationsVisitor.java | 2 + .../ast/AtAspectJAnnotationFactory.java | 19 + .../compiler/ast/InterTypeDeclaration.java | 10 + .../java5/ataspectj/annotationGen/ITDTest.aj | 181 ++++++++++ .../org/aspectj/systemtest/ajc150/ajc150.xml | 54 +-- .../ataspectj/AtAjAnnotationGenTests.java | 4 + .../ajc150/ataspectj/annotationgen.xml | 8 +- 26 files changed, 1247 insertions(+), 129 deletions(-) create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcITD.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java create mode 100644 aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/StringToType.java create mode 100644 aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareParents.java create mode 100644 aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/InterTypeTests.java create mode 100644 tests/java5/ataspectj/annotationGen/ITDTest.aj diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcITD.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcITD.java new file mode 100644 index 000000000..e67a25f1e --- /dev/null +++ b/aspectj5rt/java5-src/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/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java index 7ecebd13b..ca179ad6d 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java @@ -29,6 +29,7 @@ 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; @@ -70,6 +71,12 @@ public class AjTypeImpl implements AjType { 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; @@ -547,101 +554,346 @@ public class AjTypeImpl implements AjType { * @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) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; + if (this.declaredITDMethods == 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); + 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) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; + 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()) { + Class[] classes = clazz.getDeclaredClasses(); + for(Class c : classes) { + if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { + if (c.getInterfaces().length == 0) continue; + AjType targetType = AjTypeSystem.getAjType((Class)c.getInterfaces()[0]); + Method[] meths = c.getDeclaredMethods(); + for (Method m : meths) { + if (!Modifier.isPublic(m.getModifiers()) && publicOnly) continue; + InterTypeMethodDeclaration itdm = + new InterTypeMethodDeclarationImpl( + this,targetType,m); + toList.add(itdm); + } + } + } + } } + private void addAnnotationStyleITDFields(List toList, boolean publicOnly) { + if (isAspect()) { + Class[] classes = clazz.getDeclaredClasses(); + for(Class c : classes) { + if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { + if (c.getInterfaces().length == 0) continue; + AjType targetType = AjTypeSystem.getAjType((Class)c.getInterfaces()[0]); + Field[] fields = c.getDeclaredFields(); + for (Field f : fields) { + if (!Modifier.isPublic(f.getModifiers()) && publicOnly) continue; + InterTypeFieldDeclaration itdf = + new InterTypeFieldDeclarationImpl( + this,targetType,f); + toList.add(itdf); + } + } + } + } + } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredITDConstructor(java.lang.Class, java.lang.Class...) */ public InterTypeConstructorDeclaration getDeclaredITDConstructor( - AjType target, AjType... parameterTypes) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; + 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) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; - } + 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) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; + 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) { - // TODO Auto-generated method stub - return null; + 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() { - // TODO Auto-generated method stub - return null; + 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) @@ -701,6 +953,7 @@ public class AjTypeImpl implements AjType { decps.add(decp); } } + addAnnotationStyleDeclareParents(decps); if (getSupertype().isAspect()) { decps.addAll(Arrays.asList(getSupertype().getDeclareParents())); } @@ -708,6 +961,24 @@ public class AjTypeImpl implements AjType { decps.toArray(ret); return ret; } + + private void addAnnotationStyleDeclareParents(List toList) { + Class[] classes = clazz.getDeclaredClasses(); + for (Class c : classes) { + if (c.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { + org.aspectj.lang.annotation.DeclareParents ann = c.getAnnotation(org.aspectj.lang.annotation.DeclareParents.class); + if (c.getInterfaces().length == 0) continue; + String parentType = c.getInterfaces()[0].getName(); + DeclareParentsImpl decp = new DeclareParentsImpl( + ann.value(), + parentType, + false, + this + ); + toList.add(decp); + } + } + } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclareSofts() diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java index 1a04fc507..4f5720667 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/DeclareParentsImpl.java @@ -11,13 +11,9 @@ * ******************************************************************/ package org.aspectj.internal.lang.reflect; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.StringTokenizer; import org.aspectj.lang.reflect.AjType; -import org.aspectj.lang.reflect.AjTypeSystem; import org.aspectj.lang.reflect.DeclareParents; import org.aspectj.lang.reflect.TypePattern; @@ -45,7 +41,12 @@ public class DeclareParentsImpl implements DeclareParents { this.isExtends = isExtends; this.declaringType = declaring; this.parentsString = parentsAsString; - this.parents = commaSeparatedListToTypeArray(parentsAsString); + try { + this.parents = StringToType.commaSeparatedListToTypeArray(parentsAsString, declaring.getJavaClass()); + } catch (ClassNotFoundException cnfEx) { + this.parentsError = true; + this.firstMissingTypeName = cnfEx.getMessage(); + } } /* (non-Javadoc) @@ -85,60 +86,6 @@ public class DeclareParentsImpl implements DeclareParents { } return this.parents; } - - private Type[] commaSeparatedListToTypeArray(String typeNames) { - StringTokenizer strTok = new StringTokenizer(typeNames,","); - Type[] ret = new Type[strTok.countTokens()]; - int index = 0; - outer: while (strTok.hasMoreTokens()) { - String parentTypeName = strTok.nextToken().trim(); - try { - if (parentTypeName.indexOf("<") == -1) { - ret[index] = AjTypeSystem.getAjType(Class.forName(parentTypeName)); - } else { - ret[index] = makeParameterizedType(parentTypeName); - } - } catch (ClassNotFoundException e) { - // could be a type variable - TypeVariable[] tVars = this.declaringType.getJavaClass().getTypeParameters(); - for (int i = 0; i < tVars.length; i++) { - if (tVars[i].getName().equals(parentTypeName)) { - ret[index] = tVars[i]; - continue outer; - } - } - ret[index] = null; - if (this.firstMissingTypeName == null) this.firstMissingTypeName = parentTypeName; - this.parentsError = true; - } - index++; - } - return ret; - } - - private Type makeParameterizedType(String typeName) - throws ClassNotFoundException { - int paramStart = typeName.indexOf('<'); - String baseName = typeName.substring(0, paramStart); - final Class baseClass = Class.forName(baseName); - int paramEnd = typeName.lastIndexOf('>'); - String params = typeName.substring(paramStart+1,paramEnd); - final Type[] typeParams = commaSeparatedListToTypeArray(params); - return new ParameterizedType() { - - public Type[] getActualTypeArguments() { - return typeParams; - } - - public Type getRawType() { - return baseClass; - } - - public Type getOwnerType() { - return baseClass.getEnclosingClass(); - } - }; - } public String toString() { StringBuffer sb = new StringBuffer(); diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java new file mode 100644 index 000000000..7a84c7d12 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeConstructorDeclarationImpl.java @@ -0,0 +1,81 @@ +/* ******************************************************************* + * 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; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeDeclarationImpl.java new file mode 100644 index 000000000..a3def1030 --- /dev/null +++ b/aspectj5rt/java5-src/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; + private 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/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java new file mode 100644 index 000000000..5cca0b360 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeFieldDeclarationImpl.java @@ -0,0 +1,78 @@ +/* ******************************************************************* + * 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; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java new file mode 100644 index 000000000..25688441d --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/InterTypeMethodDeclarationImpl.java @@ -0,0 +1,126 @@ +/* ******************************************************************* + * 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) { + super(decType,targetType,base.getModifiers()); + 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; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/StringToType.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/StringToType.java new file mode 100644 index 000000000..7cf35ffb7 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/StringToType.java @@ -0,0 +1,82 @@ +/* ******************************************************************* + * 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)); + } 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); + 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/aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareParents.java b/aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareParents.java new file mode 100644 index 000000000..3dec04f27 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/annotation/DeclareParents.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: + * 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.TYPE) +public @interface DeclareParents { + + /** + * The target types expression + */ + String value(); + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java index e2db1407f..5e26a7d27 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java @@ -224,7 +224,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the inter-type method declared by this type matching the given specification */ - public InterTypeMethodDeclaration getDeclaredITDMethod(String name, AjType target, AjType... parameterTypes); + public InterTypeMethodDeclaration getDeclaredITDMethod(String name, AjType target, AjType... parameterTypes) throws NoSuchMethodException; /** * Return all of the inter-type methods declared by this type @@ -234,7 +234,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the public inter-type method of this type matching the given specification */ - public InterTypeMethodDeclaration getITDMethod(String name, AjType target, AjType... parameterTypes); + public InterTypeMethodDeclaration getITDMethod(String name, AjType target, AjType... parameterTypes) throws NoSuchMethodException; /** * Return all of the public inter-type declared methods of this type @@ -244,7 +244,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the inter-type constructor declared by this type matching the given specification */ - public InterTypeConstructorDeclaration getDeclaredITDConstructor(AjType target, AjType... parameterTypes); + public InterTypeConstructorDeclaration getDeclaredITDConstructor(AjType target, AjType... parameterTypes) throws NoSuchMethodException; /** * Returns all of the inter-type constructors declared by this type @@ -254,7 +254,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the public inter-type constructor matching the given specification */ - public InterTypeConstructorDeclaration getITDConstructor(AjType target, AjType... parameterTypes); + public InterTypeConstructorDeclaration getITDConstructor(AjType target, AjType... parameterTypes) throws NoSuchMethodException; /** * Return all of the public inter-type constructors of this type @@ -264,7 +264,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the inter-type field declared in this type with the given specification */ - public InterTypeFieldDeclaration getDeclaredITDField(String name, AjType target); + public InterTypeFieldDeclaration getDeclaredITDField(String name, AjType target) throws NoSuchFieldException; /** * Return all of the inter-type fields declared in this type @@ -274,7 +274,7 @@ public interface AjType extends Type, AnnotatedElement { /** * Return the public inter-type field matching the given specification */ - public InterTypeFieldDeclaration getITDField(String name, AjType target); + public InterTypeFieldDeclaration getITDField(String name, AjType target) throws NoSuchFieldException; /** * Return all of the public inter-type fields for this type diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java index d20440a83..8db4505e3 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeConstructorDeclaration.java @@ -11,10 +11,26 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import java.lang.reflect.Type; + /** - * @author colyer - * + * 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/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeDeclaration.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeDeclaration.java index 510135813..c00461011 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeDeclaration.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeDeclaration.java @@ -11,6 +11,23 @@ * ******************************************************************/ 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/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java index 99045798c..5a8acd76c 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeFieldDeclaration.java @@ -11,10 +11,26 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import java.lang.reflect.Type; + /** - * @author colyer - * + * Represents an inter-type field declaration declared in an aspect. */ -public interface InterTypeFieldDeclaration { +public interface InterTypeFieldDeclaration extends InterTypeDeclaration { + + /** + * The field name + */ + String getName(); + + /** + * The field type + */ + AjType getType(); + + /** + * The generic field type + */ + Type getGenericType(); } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java index 3fac5c186..e570d8d2d 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/InterTypeMethodDeclaration.java @@ -11,6 +11,47 @@ * ******************************************************************/ 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/aspectj5rt/java5-testsrc/Aspectj5rt15ModuleTests.java b/aspectj5rt/java5-testsrc/Aspectj5rt15ModuleTests.java index b0ab7d1fe..c1d54dc67 100644 --- a/aspectj5rt/java5-testsrc/Aspectj5rt15ModuleTests.java +++ b/aspectj5rt/java5-testsrc/Aspectj5rt15ModuleTests.java @@ -18,6 +18,7 @@ import junit.framework.TestSuite; import org.aspectj.internal.lang.reflect.AjTypeTests; import org.aspectj.internal.lang.reflect.AjTypeTestsWithAspects; +import org.aspectj.internal.lang.reflect.InterTypeTests; public class Aspectj5rt15ModuleTests extends TestCase { @@ -25,6 +26,7 @@ public class Aspectj5rt15ModuleTests extends TestCase { TestSuite suite = new TestSuite("Aspectj5rt module tests"); suite.addTestSuite(AjTypeTests.class); suite.addTestSuite(AjTypeTestsWithAspects.class); + suite.addTestSuite(InterTypeTests.class); return suite; } diff --git a/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java index 7b15d3e64..d2fad06b0 100644 --- a/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java +++ b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java @@ -17,6 +17,7 @@ import java.lang.reflect.Modifier; import junit.framework.TestCase; import org.aspectj.internal.lang.annotation.ajcDeclareEoW; +import org.aspectj.internal.lang.annotation.ajcITD; import org.aspectj.internal.lang.annotation.ajcPrivileged; import org.aspectj.lang.annotation.AdviceName; import org.aspectj.lang.annotation.After; diff --git a/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/InterTypeTests.java b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/InterTypeTests.java new file mode 100644 index 000000000..ae7939bb6 --- /dev/null +++ b/aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/InterTypeTests.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 InterTypeTests extends TestCase { + + public void testITDImpl() throws ClassNotFoundException { + AjType thisClass = AjTypeSystem.getAjType(InterTypeTests.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(InterTypeTests.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(InterTypeTests.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + Method base = InterTypeTests.class.getDeclaredMethod("interCons",InterTypeTests.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(InterTypeTests.class); + AjType runnable = AjTypeSystem.getAjType(java.lang.Runnable.class); + Method base = InterTypeTests.class.getDeclaredMethod("interMethod",InterTypeTests.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(InterTypeTests itt, String s, int i) { } + + public static int interMethod(InterTypeTests itt, String s, int i) { return 5; } +} diff --git a/lib/aspectj/lib/aspectjrt.jar b/lib/aspectj/lib/aspectjrt.jar index 9c65f72d7e0161efcfff71d75a94db7083d59f61..0dbc1d49b9fe0d9132b23a4deedb4024268f188b 100644 GIT binary patch delta 54279 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 P2$upIXOBJtTMrBXj7;Kj diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar index 9c65f72d7e0161efcfff71d75a94db7083d59f61..0dbc1d49b9fe0d9132b23a4deedb4024268f188b 100644 GIT binary patch delta 54279 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 P2$upIXOBJtTMrBXj7;Kj diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java index 35ae2fb9b..bc709cc2b 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AddAtAspectJAnnotationsVisitor.java @@ -67,6 +67,8 @@ public class AddAtAspectJAnnotationsVisitor extends ASTVisitor { ((PointcutDeclaration)methodDeclaration).addAtAspectJAnnotations(); } else if (methodDeclaration instanceof DeclareDeclaration) { ((DeclareDeclaration)methodDeclaration).addAtAspectJAnnotations(); + } else if (methodDeclaration instanceof InterTypeDeclaration) { + ((InterTypeDeclaration)methodDeclaration).addAtAspectJAnnotations(); } return false; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java index 79fdb87be..35fccc856 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AtAspectJAnnotationFactory.java @@ -13,6 +13,7 @@ package org.aspectj.ajdt.internal.compiler.ast; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.IntLiteral; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; @@ -49,6 +50,7 @@ public class AtAspectJAnnotationFactory { static final char[] declareSoft = "ajcDeclareSoft".toCharArray(); static final char[] declarePrecedence = "ajcDeclarePrecedence".toCharArray(); static final char[] declareAnnotation = "ajcDeclareAnnotation".toCharArray(); + static final char[] itdAnnotation = "ajcITD".toCharArray(); /** * Create an @Aspect annotation for a code style aspect declaration starting at @@ -210,6 +212,23 @@ public class AtAspectJAnnotationFactory { return ann; } + public static Annotation createITDAnnotation(char[] targetTypeName, int modifiers, char[] name, int pos) { + char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,itdAnnotation}; + long[] positions = new long[typeName.length]; + for (int i = 0; i < positions.length; i++) positions[i] = pos; + TypeReference annType = new QualifiedTypeReference(typeName,positions); + NormalAnnotation ann = new NormalAnnotation(annType,pos); + Expression targetExpr = new StringLiteral(targetTypeName,pos,pos); + Expression nameExpr = new StringLiteral(name,pos,pos); + Expression modsExpr = new IntLiteral(Integer.toString(modifiers).toCharArray(),pos,pos); + MemberValuePair[] mvps = new MemberValuePair[3]; + mvps[0] = new MemberValuePair("targetType".toCharArray(),pos,pos,targetExpr); + mvps[1] = new MemberValuePair("name".toCharArray(),pos,pos,nameExpr); + mvps[2] = new MemberValuePair("modifiers".toCharArray(),pos,pos,modsExpr); + ann.memberValuePairs = mvps; + return ann; + } + public static Annotation createDeclarePrecedenceAnnotation(String pointcutExpression, int pos) { char[][] typeName = new char[][] {org,aspectj,internal,lang,annotation,declarePrecedence}; return makeSingleStringMemberAnnotation(typeName, pos, pointcutExpression); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java index 81c47a4d9..bd159aa17 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeDeclaration.java @@ -26,6 +26,7 @@ import org.aspectj.bridge.context.ContextToken; import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile; import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -93,6 +94,15 @@ public abstract class InterTypeDeclaration extends AjMethodDeclaration { // return the selector prefix for this itd that is to be used before resolution replaces it with a "proper" name protected abstract char[] getPrefix(); + + public void addAtAspectJAnnotations() { + if (munger == null) return; + Annotation ann = AtAspectJAnnotationFactory.createITDAnnotation( + munger.getSignature().getDeclaringType().getName().toCharArray(), + declaredModifiers,declaredSelector,declarationSourceStart); + AtAspectJAnnotationFactory.addAnnotation(this,ann,this.scope); + } + /** * Checks that the target for the ITD is not an annotation. If it is, an error message * is signaled. We return true if it is annotation so the caller knows to stop processing. diff --git a/tests/java5/ataspectj/annotationGen/ITDTest.aj b/tests/java5/ataspectj/annotationGen/ITDTest.aj new file mode 100644 index 000000000..841af326b --- /dev/null +++ b/tests/java5/ataspectj/annotationGen/ITDTest.aj @@ -0,0 +1,181 @@ +package a.b.c; + +import org.aspectj.lang.reflect.*; +import java.lang.reflect.*; +import org.aspectj.lang.annotation.*; + +public aspect ITDTest { + + public void A.a(String s) {} + + private void A.b(String s) {} + + int A.c(String s) { return 1; } + + public A.new(String s) {} + + private A.new(String s,String s2) {} + + A.new(String s, Object o) {} + + public int A.f ; + + private int A.g; + + int A.h; + + public static void main(String[] args) throws ClassNotFoundException { + AjType myType = AjTypeSystem.getAjType(ITDTest.class); + checkITDMs(myType); + checkITDFs(myType); + checkITDCs(myType); + checkAnnStyle(); + } + + private static void checkITDMs(AjType itdTest) throws ClassNotFoundException { + InterTypeMethodDeclaration[] itdms = itdTest.getDeclaredITDMethods(); + assertEquals("expecting 3 declared methods, got: ",3,itdms.length); + assertEquals("expecting method name a, got: ","a",itdms[0].getName()); + assertEquals("expecting method name b, got: ","b",itdms[1].getName()); + assertEquals("expecting method name c, got: ","c",itdms[2].getName()); + assertEquals("expecting AjType",AjTypeSystem.getAjType(A.class),itdms[0].getTargetType()); + assertEquals("expecting public method, got:",true,Modifier.isPublic(itdms[0].getModifiers())); + assertEquals("expecting private method, got:",true,Modifier.isPrivate(itdms[1].getModifiers())); + assertEquals("expecting non-public method, got:",false,Modifier.isPublic(itdms[2].getModifiers())); + assertEquals("one param, got: ",1,itdms[0].getParameterTypes().length); + assertEquals("expecting String, got: ",String.class,itdms[0].getParameterTypes()[0].getJavaClass()); + assertEquals("nothing thrown, but: ",0,itdms[1].getExceptionTypes().length); + assertEquals("expecting int, got: ",int.class,itdms[2].getReturnType().getJavaClass()); + itdms = itdTest.getITDMethods(); + assertEquals("expecting 1 method, got: ",1,itdms.length); + assertEquals("expecting method name a, got: ","a",itdms[0].getName()); + try { + InterTypeMethodDeclaration m = itdTest.getDeclaredITDMethod("b",AjTypeSystem.getAjType(A.class),AjTypeSystem.getAjType(String.class)); + assertEquals("expecting b, got: ","b",m.getName()); + } catch (NoSuchMethodException ex) { throw new RuntimeException("didn't find expected itdm"); } + try { + InterTypeMethodDeclaration m = itdTest.getITDMethod("d",AjTypeSystem.getAjType(A.class),AjTypeSystem.getAjType(String.class)); + throw new RuntimeException("Expected NoSuchMethodException not thrown"); + } catch (NoSuchMethodException ex) { } + } + + private static void checkITDFs(AjType itdTest) throws ClassNotFoundException { + InterTypeFieldDeclaration[] itdfs = itdTest.getDeclaredITDFields(); + assertEquals("expecting 3 declared fields, got: ",3, itdfs.length); + assertEquals("expecting field name f, got: ","f",itdfs[0].getName()); + assertEquals("expecting field name g, got: ","g",itdfs[1].getName()); + assertEquals("expecting field name h, got: ","h",itdfs[2].getName()); + assertEquals("expecting AjType",AjTypeSystem.getAjType(A.class),itdfs[0].getTargetType()); + assertEquals("expecting public field, got:",true,Modifier.isPublic(itdfs[0].getModifiers())); + assertEquals("expecting private field, got:",true,Modifier.isPrivate(itdfs[1].getModifiers())); + assertEquals("expecting non-public field, got:",false,Modifier.isPublic(itdfs[2].getModifiers())); + assertEquals("expecting int, got: ",int.class,itdfs[2].getType().getJavaClass()); + itdfs = itdTest.getITDFields(); + assertEquals("expecting 1 field, got: ",1, itdfs.length); + assertEquals("expecting field name f, got: ","f",itdfs[0].getName()); + try { + InterTypeFieldDeclaration f = itdTest.getDeclaredITDField("f",AjTypeSystem.getAjType(A.class)); + assertEquals("expecting f, got: ","f",f.getName()); + } catch(NoSuchFieldException ex) { throw new RuntimeException("didn't find expected itdf"); } + try { + InterTypeFieldDeclaration g = itdTest.getITDField("g",AjTypeSystem.getAjType(A.class)); + throw new RuntimeException("Expected NoSuchFieldException not thrown"); + } catch (NoSuchFieldException ex) { } + } + + private static void checkITDCs(AjType itdTest) throws ClassNotFoundException { + InterTypeConstructorDeclaration[] itdcs = itdTest.getDeclaredITDConstructors(); + assertEquals("expecting 3 declared constructors, got: ",3, itdcs.length); + InterTypeConstructorDeclaration pubDec = findPublicCons(itdcs); + InterTypeConstructorDeclaration privDec = findPrivateCons(itdcs); + InterTypeConstructorDeclaration defDec = findDefaultCons(itdcs); + if (pubDec == null || privDec == null || defDec == null) throw new RuntimeException("failed to find expected constructors"); + assertEquals("two params, got: ",2,defDec.getParameterTypes().length); + assertEquals("expecting String, got: ",String.class,defDec.getParameterTypes()[0].getJavaClass()); + assertEquals("expecting Object, got: ",Object.class,defDec.getParameterTypes()[1].getJavaClass()); + assertEquals("nothing thrown, but: ",0,privDec.getExceptionTypes().length); + itdcs = itdTest.getITDConstructors(); + assertEquals("expecting 1 cons, got: ",1,itdcs.length); + try { + InterTypeConstructorDeclaration c = itdTest.getDeclaredITDConstructor(AjTypeSystem.getAjType(A.class),AjTypeSystem.getAjType(String.class)); + } catch (NoSuchMethodException ex) { throw new RuntimeException("didn't find expected itdm"); } + try { + InterTypeConstructorDeclaration c = itdTest.getITDConstructor(AjTypeSystem.getAjType(A.class),AjTypeSystem.getAjType(String.class),AjTypeSystem.getAjType(Object.class)); + throw new RuntimeException("Expected NoSuchMethodException not thrown"); + } catch (NoSuchMethodException ex) { } + } + + private static InterTypeConstructorDeclaration findPublicCons(InterTypeConstructorDeclaration[] itcds) { + for( InterTypeConstructorDeclaration i : itcds) { + if (Modifier.isPublic(i.getModifiers())) { + return i; + } + } + return null; + } + + private static InterTypeConstructorDeclaration findPrivateCons(InterTypeConstructorDeclaration[] itcds) { + for( InterTypeConstructorDeclaration i : itcds) { + if (Modifier.isPrivate(i.getModifiers())) { + return i; + } + } + return null; + } + + private static InterTypeConstructorDeclaration findDefaultCons(InterTypeConstructorDeclaration[] itcds) { + for( InterTypeConstructorDeclaration i : itcds) { + if (!Modifier.isPublic(i.getModifiers()) && !Modifier.isPrivate(i.getModifiers())) { + return i; + } + } + return null; + } + + private static void checkAnnStyle() { + AjType x = AjTypeSystem.getAjType(X.class); + org.aspectj.lang.reflect.DeclareParents[] decps = x.getDeclareParents(); + assertEquals("1 declare parents",1,decps.length); + assertEquals("implements",true,decps[0].isImplements()); + assertEquals("X",x,decps[0].getDeclaringType()); + assertEquals("org.xyz..*, got: ","org.xyz..*",decps[0].getTargetTypesPattern().asString()); + try { + assertEquals("1: ",1,decps[0].getParentTypes().length); + assertEquals("I: ",I.class,((AjType)decps[0].getParentTypes()[0]).getJavaClass()); + } catch (ClassNotFoundException cnf) { + throw new RuntimeException(cnf); + } + assertEquals("1: ",1,x.getDeclaredITDFields().length); + assertEquals("i: ","i",x.getDeclaredITDFields()[0].getName()); + assertEquals("1: ",1,x.getITDMethods().length); + assertEquals("getNumber: ","getNumber",x.getITDMethods()[0].getName()); + } + + private static void assertEquals(String msg, Object expected, Object actual) { + if (!expected.equals(actual)) throw new RuntimeException(msg + " " + actual.toString()); + } +} + + +class A {} + +@Aspect +class X { + + @org.aspectj.lang.annotation.DeclareParents("org.xyz..*") + public static class Mixin implements I { + + private int i = 0; + + public int getNumber() { return i; } + + } + +} + +interface I { + + int getNumber(); + +} + diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index ef3f9fcd4..3c0335717 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -4586,7 +4586,7 @@ - + @@ -4617,7 +4617,7 @@ - + @@ -4626,7 +4626,7 @@ - + @@ -4635,7 +4635,7 @@ - + @@ -4644,7 +4644,7 @@ - + @@ -4653,7 +4653,7 @@ - + @@ -4662,7 +4662,7 @@ - + @@ -4671,7 +4671,7 @@ - + @@ -4680,7 +4680,7 @@ - + @@ -4689,7 +4689,7 @@ - + @@ -4698,7 +4698,7 @@ - + @@ -4707,7 +4707,7 @@ - + @@ -4716,7 +4716,7 @@ - + @@ -4725,7 +4725,7 @@ - + @@ -4734,7 +4734,7 @@ - + @@ -4743,7 +4743,7 @@ - + @@ -4752,7 +4752,7 @@ - + @@ -4761,7 +4761,7 @@ - + @@ -4770,7 +4770,7 @@ - + @@ -4779,7 +4779,7 @@ - + @@ -4788,7 +4788,7 @@ - + @@ -4798,7 +4798,7 @@ - + @@ -4807,7 +4807,7 @@ - + @@ -4816,7 +4816,7 @@ - + @@ -4825,7 +4825,7 @@ - + @@ -4834,7 +4834,7 @@ - + @@ -4843,7 +4843,7 @@ - + diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java index c3711841f..27b562d62 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java @@ -150,5 +150,9 @@ public class AtAjAnnotationGenTests extends XMLBasedAjcTestCase { public void testDecAnnotation() { runTest("ann gen for dec annotation"); } + + public void testITDs() { + runTest("ann gen for itds"); + } } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml index 3e74a541a..33c28dbb3 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml @@ -177,5 +177,11 @@ - + + + + + + + \ No newline at end of file -- 2.39.5