@@ -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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} |