From d1304320e905040d73d479b2cccaea0124718c01 Mon Sep 17 00:00:00 2001 From: acolyer Date: Fri, 7 Apr 2006 12:44:53 +0000 Subject: [PATCH] for pointcuts in @AspectJ aspects compiled by javac, try a bit harder to find the pointcut parameter names --- .../aspectj/weaver/reflect/ArgNameFinder.java | 29 ++++++++++++++ .../reflect/Java15AnnotationFinder.java | 40 ++++++++++++++++++- ...5ReflectionBasedReferenceTypeDelegate.java | 21 ++++++++-- 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java new file mode 100644 index 000000000..dc295eb2b --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/ArgNameFinder.java @@ -0,0 +1,29 @@ +/* ******************************************************************* + * 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.weaver.reflect; + +import java.lang.reflect.Member; + +/** + * @author Adrian + * + */ +public interface ArgNameFinder { + + /** + * Attempt to discover the parameter names for a reflectively obtained member + * @param forMember + * @return null if names can't be determined + */ + String[] getParameterNames(Member forMember); + +} diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java index 1453e05ff..6202e9c94 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java @@ -22,6 +22,8 @@ import java.util.HashSet; import java.util.Set; import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.LocalVariable; +import org.aspectj.apache.bcel.classfile.LocalVariableTable; import org.aspectj.apache.bcel.util.Repository; import org.aspectj.apache.bcel.util.ClassLoaderRepository; import org.aspectj.weaver.ResolvedType; @@ -32,7 +34,7 @@ import org.aspectj.weaver.World; * Find the given annotation (if present) on the given object * */ -public class Java15AnnotationFinder implements AnnotationFinder { +public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { private Repository bcelRepository; private ClassLoader classLoader; @@ -160,4 +162,40 @@ public class Java15AnnotationFinder implements AnnotationFinder { return ret; } + public String[] getParameterNames(Member forMember) { + if (!(forMember instanceof AccessibleObject)) return null; + + try { + JavaClass jc = bcelRepository.loadClass(forMember.getDeclaringClass()); + LocalVariableTable lvt = null; + int numVars = 0; + if (forMember instanceof Method) { + org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method)forMember); + lvt = bcelMethod.getLocalVariableTable(); + numVars = bcelMethod.getArgumentTypes().length; + } else if (forMember instanceof Constructor) { + org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor)forMember); + lvt = bcelCons.getLocalVariableTable(); + numVars = bcelCons.getArgumentTypes().length; + } + return getParameterNamesFromLVT(lvt,numVars); + } catch (ClassNotFoundException cnfEx) { + ; // no luck + } + + return null; + } + + private String[] getParameterNamesFromLVT(LocalVariableTable lvt, int numVars) { + LocalVariable[] vars = lvt.getLocalVariableTable(); + if (vars.length < numVars) { + // basic error, we can't get the names... + return null; + } + String[] ret = new String[numVars]; + for(int i = 0; i < numVars; i++) { + ret[i] = vars[i+1].getName(); + } + return ret; + } } diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java index 2ba28c9a4..a19457166 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java @@ -54,6 +54,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends private String genericSignature = null; private JavaLangTypeToResolvedTypeConverter typeConverter; private Java15AnnotationFinder annotationFinder = null; + private ArgNameFinder argNameFinder = null; public Java15ReflectionBasedReferenceTypeDelegate() {} @@ -63,6 +64,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends super.initialize(aType, aClass, classLoader, aWorld); myType = AjTypeSystem.getAjType(aClass); annotationFinder = new Java15AnnotationFinder(); + argNameFinder = annotationFinder; annotationFinder.setClassLoader(classLoader); this.typeConverter = new JavaLangTypeToResolvedTypeConverter(aWorld); } @@ -133,8 +135,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends } return superclass; } - - + public TypeVariable[] getTypeVariables() { TypeVariable[] workInProgressSetOfVariables = (TypeVariable[])getResolvedTypeX().getWorld().getTypeVariablesCurrentlyBeingProcessed(getBaseClass()); if (workInProgressSetOfVariables!=null) { @@ -253,7 +254,10 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends AjType[] ptypes = pcs[i].getParameterTypes(); String[] pnames = pcs[i].getParameterNames(); if (pnames.length != ptypes.length) { - throw new IllegalStateException("Required parameter names not available when parsing pointcut " + pcs[i].getName() + " in type " + getResolvedTypeX().getName()); + pnames = tryToDiscoverParameterNames(pcs[i]); + if (pnames == null || (pnames.length != ptypes.length)) { + throw new IllegalStateException("Required parameter names not available when parsing pointcut " + pcs[i].getName() + " in type " + getResolvedTypeX().getName()); + } } PointcutParameter[] parameters = new PointcutParameter[ptypes.length]; for (int j = 0; j < parameters.length; j++) { @@ -272,6 +276,17 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends return pointcuts; } + // for @AspectJ pointcuts compiled by javac only... + private String[] tryToDiscoverParameterNames(Pointcut pcut) { + Method[] ms = pcut.getDeclaringType().getJavaClass().getDeclaredMethods(); + for(Method m : ms) { + if (m.getName().equals(pcut.getName())) { + return argNameFinder.getParameterNames(m); + } + } + return null; + } + public boolean isAnnotation() { return getBaseClass().isAnnotation(); } -- 2.39.5