@@ -1,18 +1,49 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<classpath> | |||
<classpathentry kind="src" path="src"/> | |||
<classpathentry kind="src" path="testsrc"/> | |||
<classpathentry kind="src" path="/runtime"/> | |||
<classpathentry kind="lib" path="/lib/junit/junit.jar" sourcepath="/lib/junit/src.jar"/> | |||
<classpathentry kind="src" path="/util"/> | |||
<classpathentry kind="src" path="/testing-util"/> | |||
<classpathentry kind="src" path="/bridge"/> | |||
<classpathentry kind="src" path="/asm"/> | |||
<classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/> | |||
<classpathentry kind="lib" path="/lib/commons/commons.jar" sourcepath="/lib/commons/commons-src.zip"/> | |||
<classpathentry kind="lib" path="/lib/bcel/bcel.jar" sourcepath="/lib/bcel/bcel-src.zip"/> | |||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> | |||
<classpathentry combineaccessrules="false" kind="src" path="/org.aspectj.matcher"/> | |||
<classpathentry kind="lib" path="/lib/asm/asm-7.0-beta.renamed.jar"/> | |||
<classpathentry kind="output" path="bin"/> | |||
<classpathentry kind="src" output="target/classes" path="src/main/java"> | |||
<attributes> | |||
<attribute name="optional" value="true"/> | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> | |||
<attributes> | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> | |||
<attributes> | |||
<attribute name="optional" value="true"/> | |||
<attribute name="maven.pomderived" value="true"/> | |||
<attribute name="test" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> | |||
<attributes> | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | |||
<attributes> | |||
<attribute name="maven.pomderived" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="src" path="target/generated-sources/annotations"> | |||
<attributes> | |||
<attribute name="optional" value="true"/> | |||
<attribute name="maven.pomderived" value="true"/> | |||
<attribute name="ignore_optional_problems" value="true"/> | |||
<attribute name="m2e-apt" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations"> | |||
<attributes> | |||
<attribute name="optional" value="true"/> | |||
<attribute name="maven.pomderived" value="true"/> | |||
<attribute name="ignore_optional_problems" value="true"/> | |||
<attribute name="m2e-apt" value="true"/> | |||
<attribute name="test" value="true"/> | |||
</attributes> | |||
</classpathentry> | |||
<classpathentry kind="output" path="target/classes"/> | |||
</classpath> |
@@ -1,6 +0,0 @@ | |||
out | |||
bin | |||
default.lst | |||
default.ajsym | |||
.clover | |||
bintest |
@@ -1 +0,0 @@ | |||
@@ -3,11 +3,6 @@ | |||
<name>weaver</name> | |||
<comment></comment> | |||
<projects> | |||
<project>asm</project> | |||
<project>bridge</project> | |||
<project>runtime</project> | |||
<project>testing-util</project> | |||
<project>util</project> | |||
</projects> | |||
<buildSpec> | |||
<buildCommand> | |||
@@ -15,8 +10,14 @@ | |||
<arguments> | |||
</arguments> | |||
</buildCommand> | |||
<buildCommand> | |||
<name>org.eclipse.m2e.core.maven2Builder</name> | |||
<arguments> | |||
</arguments> | |||
</buildCommand> | |||
</buildSpec> | |||
<natures> | |||
<nature>org.eclipse.jdt.core.javanature</nature> | |||
<nature>org.eclipse.m2e.core.maven2Nature</nature> | |||
</natures> | |||
</projectDescription> |
@@ -0,0 +1,5 @@ | |||
eclipse.preferences.version=1 | |||
encoding//src/main/java=UTF-8 | |||
encoding//src/main/resources=UTF-8 | |||
encoding//src/test/java=UTF-8 | |||
encoding/<project>=UTF-8 |
@@ -0,0 +1,2 @@ | |||
eclipse.preferences.version=1 | |||
org.eclipse.jdt.apt.aptEnabled=false |
@@ -1,11 +1,7 @@ | |||
eclipse.preferences.version=1 | |||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | |||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 | |||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | |||
org.eclipse.jdt.core.compiler.compliance=1.7 | |||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | |||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | |||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | |||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | |||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | |||
org.eclipse.jdt.core.compiler.source=1.7 | |||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | |||
org.eclipse.jdt.core.compiler.compliance=1.8 | |||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | |||
org.eclipse.jdt.core.compiler.processAnnotations=disabled | |||
org.eclipse.jdt.core.compiler.release=disabled | |||
org.eclipse.jdt.core.compiler.source=1.8 |
@@ -1,3 +0,0 @@ | |||
#Thu Sep 22 08:32:30 PDT 2005 | |||
eclipse.preferences.version=1 | |||
internal.default.compliance=default |
@@ -0,0 +1,4 @@ | |||
activeProfiles= | |||
eclipse.preferences.version=1 | |||
resolveWorkspaceProjects=true | |||
version=1 |
@@ -1,6 +0,0 @@ | |||
<?xml version="1.0"?> | |||
<!-- see ../build/*.html for explanation --> | |||
<project name="weaver" default="test" basedir="."> | |||
<import file="${basedir}/../build/build.xml"/> | |||
</project> | |||
@@ -0,0 +1,85 @@ | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>aspectj-parent</artifactId> | |||
<version>1.9.3.BUILD-SNAPSHOT</version> | |||
<relativePath>..</relativePath> | |||
</parent> | |||
<artifactId>weaver</artifactId> | |||
<packaging>jar</packaging> | |||
<name>weaver</name> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>util</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>runtime</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>util</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>testing-util</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>bridge</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>asm</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>org.aspectj.matcher</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>runtime</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>org.aspectj.matcher</artifactId> | |||
<version>${project.version}</version> | |||
<type>test-jar</type> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.aspectj</groupId> | |||
<artifactId>bcel-builder</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons</groupId> | |||
<artifactId>commons</artifactId> | |||
<version>1.0</version> | |||
<scope>system</scope> | |||
<systemPath>${project.basedir}/../lib/commons/commons.jar</systemPath> | |||
</dependency> | |||
<dependency> | |||
<groupId>asm</groupId> | |||
<artifactId>asm</artifactId> | |||
<version>1.0</version> | |||
<scope>system</scope> | |||
<systemPath>${project.basedir}/../lib/asm/asm-7.0-beta.renamed.jar</systemPath> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -97,8 +97,7 @@ public class ClassPathManager { | |||
if (!f.isDirectory()) { | |||
if (!f.isFile()) { | |||
if (!lc.endsWith(".jar") || lc.endsWith(".zip")) { | |||
// heuristic-only: ending with .jar or .zip means probably a | |||
// zip file | |||
// heuristic-only: ending with .jar or .zip means probably a zip file | |||
MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_MISSING, name)); | |||
} else { | |||
MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.DIRECTORY_ENTRY_MISSING, name)); |
@@ -0,0 +1,26 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005-2017 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.weaver.reflect; | |||
import java.lang.reflect.Member; | |||
/** | |||
* @author Adrian Colyer | |||
* @author Andy Clement | |||
*/ | |||
public interface ArgNameFinder { | |||
/** | |||
* Attempt to discover the parameter names for a reflectively obtained member. | |||
* @param forMember the member for which parameter names are being looked up | |||
* @return parameter names or null if names can't be determined | |||
*/ | |||
String[] getParameterNames(Member forMember); | |||
} |
@@ -0,0 +1,35 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2006 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 org.aspectj.weaver.ResolvedPointcutDefinition; | |||
import org.aspectj.weaver.UnresolvedType; | |||
/** | |||
* When a Java15ReflectionBasedDelegate gets the pointcuts for a given class it tries to resolve them before returning. This can | |||
* cause problems if the resolution of one pointcut in the type depends on another pointcut in the same type. Therefore the | |||
* algorithm proceeds in two phases, first we create and store instances of this class in the pointcuts array, and once that is | |||
* done, we come back round and resolve the actual pointcut expression. This means that if we recurse doing resolution, we will find | |||
* the named pointcut we are looking for! | |||
* | |||
* @author adrian colyer | |||
* | |||
*/ | |||
public class DeferredResolvedPointcutDefinition extends ResolvedPointcutDefinition { | |||
public DeferredResolvedPointcutDefinition(UnresolvedType declaringType, int modifiers, String name, | |||
UnresolvedType[] parameterTypes) { | |||
super(declaringType, modifiers, name, parameterTypes, UnresolvedType.VOID, null); | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2006 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 org.aspectj.weaver.patterns.Pointcut; | |||
import org.aspectj.weaver.tools.PointcutParameter; | |||
import org.aspectj.weaver.tools.PointcutParser; | |||
public class InternalUseOnlyPointcutParser extends PointcutParser { | |||
public InternalUseOnlyPointcutParser(ClassLoader classLoader, ReflectionWorld world) { | |||
super(); | |||
setClassLoader(classLoader); | |||
setWorld(world); | |||
} | |||
public InternalUseOnlyPointcutParser(ClassLoader classLoader) { | |||
super(); | |||
setClassLoader(classLoader); | |||
} | |||
public Pointcut resolvePointcutExpression( | |||
String expression, | |||
Class inScope, | |||
PointcutParameter[] formalParameters) { | |||
return super.resolvePointcutExpression(expression, inScope, formalParameters); | |||
} | |||
public Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) { | |||
return super.concretizePointcutExpression(pc, inScope, formalParameters); | |||
} | |||
} |
@@ -0,0 +1,386 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2005, 2017 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.weaver.reflect; | |||
import java.lang.annotation.Annotation; | |||
import java.lang.reflect.AccessibleObject; | |||
import java.lang.reflect.Constructor; | |||
import java.lang.reflect.Field; | |||
import java.lang.reflect.Member; | |||
import java.lang.reflect.Method; | |||
import org.aspectj.apache.bcel.classfile.AnnotationDefault; | |||
import org.aspectj.apache.bcel.classfile.Attribute; | |||
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.ClassLoaderRepository; | |||
import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; | |||
import org.aspectj.apache.bcel.util.Repository; | |||
import org.aspectj.weaver.AnnotationAJ; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.bcel.BcelAnnotation; | |||
import org.aspectj.weaver.bcel.BcelWeakClassLoaderReference; | |||
/** | |||
* | |||
* @author Adrian Colyer | |||
* @author Andy Clement | |||
*/ | |||
public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { | |||
public static final ResolvedType[][] NO_PARAMETER_ANNOTATIONS = new ResolvedType[][] {}; | |||
private Repository bcelRepository; | |||
private BcelWeakClassLoaderReference classLoaderRef; | |||
private World world; | |||
private static boolean useCachingClassLoaderRepository; | |||
static { | |||
try { | |||
useCachingClassLoaderRepository = System.getProperty("Xset:bcelRepositoryCaching","true").equalsIgnoreCase("true"); | |||
} catch (Throwable t) { | |||
useCachingClassLoaderRepository = false; | |||
} | |||
} | |||
// must have no-arg constructor for reflective construction | |||
public Java15AnnotationFinder() { | |||
} | |||
public void setClassLoader(ClassLoader aLoader) { | |||
this.classLoaderRef = new BcelWeakClassLoaderReference(aLoader); | |||
if (useCachingClassLoaderRepository) { | |||
this.bcelRepository = new ClassLoaderRepository(classLoaderRef); | |||
} else { | |||
this.bcelRepository = new NonCachingClassLoaderRepository(classLoaderRef); | |||
} | |||
} | |||
public void setWorld(World aWorld) { | |||
this.world = aWorld; | |||
} | |||
public Object getAnnotation(ResolvedType annotationType, Object onObject) { | |||
try { | |||
Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) Class.forName(annotationType.getName(), | |||
false, getClassLoader()); | |||
if (onObject.getClass().isAnnotationPresent(annotationClass)) { | |||
return onObject.getClass().getAnnotation(annotationClass); | |||
} | |||
} catch (ClassNotFoundException ex) { | |||
// just return null | |||
} | |||
return null; | |||
} | |||
public Object getAnnotationFromClass(ResolvedType annotationType, Class aClass) { | |||
try { | |||
Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) Class.forName(annotationType.getName(), | |||
false, getClassLoader()); | |||
if (aClass.isAnnotationPresent(annotationClass)) { | |||
return aClass.getAnnotation(annotationClass); | |||
} | |||
} catch (ClassNotFoundException ex) { | |||
// just return null | |||
} | |||
return null; | |||
} | |||
public Object getAnnotationFromMember(ResolvedType annotationType, Member aMember) { | |||
if (!(aMember instanceof AccessibleObject)) | |||
return null; | |||
AccessibleObject ao = (AccessibleObject) aMember; | |||
try { | |||
Class annotationClass = Class.forName(annotationType.getName(), false, getClassLoader()); | |||
if (ao.isAnnotationPresent(annotationClass)) { | |||
return ao.getAnnotation(annotationClass); | |||
} | |||
} catch (ClassNotFoundException ex) { | |||
// just return null | |||
} | |||
return null; | |||
} | |||
private ClassLoader getClassLoader() { | |||
return classLoaderRef.getClassLoader(); | |||
} | |||
public AnnotationAJ getAnnotationOfType(UnresolvedType ofType, Member onMember) { | |||
if (!(onMember instanceof AccessibleObject)) | |||
return null; | |||
// here we really want both the runtime visible AND the class visible | |||
// annotations | |||
// so we bail out to Bcel and then chuck away the JavaClass so that we | |||
// don't hog | |||
// memory. | |||
try { | |||
JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); | |||
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0]; | |||
if (onMember instanceof Method) { | |||
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); | |||
if (bcelMethod == null) { | |||
// pr220430 | |||
// System.err.println( | |||
// "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '" | |||
// + | |||
// onMember.getName()+"' in class '"+jc.getClassName()+"'"); | |||
} else { | |||
anns = bcelMethod.getAnnotations(); | |||
} | |||
} else if (onMember instanceof Constructor) { | |||
org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); | |||
anns = bcelCons.getAnnotations(); | |||
} else if (onMember instanceof Field) { | |||
org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember); | |||
anns = bcelField.getAnnotations(); | |||
} | |||
// the answer is cached and we don't want to hold on to memory | |||
bcelRepository.clear(); | |||
// OPTIMIZE make constant 0 size array for sharing | |||
if (anns == null) | |||
anns = new org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[0]; | |||
// convert to our Annotation type | |||
for (int i = 0; i < anns.length; i++) { | |||
if (anns[i].getTypeSignature().equals(ofType.getSignature())) { | |||
return new BcelAnnotation(anns[i], world); | |||
} | |||
} | |||
return null; | |||
} catch (ClassNotFoundException cnfEx) { | |||
// just use reflection then | |||
} | |||
return null; | |||
} | |||
public String getAnnotationDefaultValue(Member onMember) { | |||
try { | |||
JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); | |||
if (onMember instanceof Method) { | |||
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); | |||
if (bcelMethod == null) { | |||
// pr220430 | |||
// System.err.println( | |||
// "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '" | |||
// + | |||
// onMember.getName()+"' in class '"+jc.getClassName()+"'"); | |||
} else { | |||
Attribute[] attrs = bcelMethod.getAttributes(); | |||
for (int i = 0; i < attrs.length; i++) { | |||
Attribute attribute = attrs[i]; | |||
if (attribute.getName().equals("AnnotationDefault")) { | |||
AnnotationDefault def = (AnnotationDefault) attribute; | |||
return def.getElementValue().stringifyValue(); | |||
} | |||
} | |||
return null; | |||
} | |||
} | |||
} catch (ClassNotFoundException cnfEx) { | |||
// just use reflection then | |||
} | |||
return null; | |||
} | |||
public ResolvedType[] getAnnotations(Member onMember, boolean areRuntimeAnnotationsSufficient) { | |||
if (!(onMember instanceof AccessibleObject)) { | |||
return ResolvedType.NONE; | |||
} | |||
// If annotations with class level retention are required then we need to open | |||
// open the class file. If only runtime retention annotations are required | |||
// we can just use reflection. | |||
if (!areRuntimeAnnotationsSufficient) { | |||
try { | |||
JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); | |||
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = null; | |||
if (onMember instanceof Method) { | |||
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); | |||
if (bcelMethod != null) { | |||
anns = bcelMethod.getAnnotations(); | |||
} | |||
} else if (onMember instanceof Constructor) { | |||
org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); | |||
anns = bcelCons.getAnnotations(); | |||
} else if (onMember instanceof Field) { | |||
org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field) onMember); | |||
anns = bcelField.getAnnotations(); | |||
} | |||
// the answer is cached and we don't want to hold on to memory | |||
bcelRepository.clear(); | |||
if (anns == null || anns.length == 0) { | |||
return ResolvedType.NONE; | |||
} | |||
ResolvedType[] annotationTypes = new ResolvedType[anns.length]; | |||
for (int i = 0; i < anns.length; i++) { | |||
annotationTypes[i] = world.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())); | |||
} | |||
return annotationTypes; | |||
} catch (ClassNotFoundException cnfEx) { | |||
// just use reflection then | |||
} | |||
} | |||
AccessibleObject ao = (AccessibleObject) onMember; | |||
Annotation[] anns = ao.getDeclaredAnnotations(); | |||
if (anns.length == 0) { | |||
return ResolvedType.NONE; | |||
} | |||
ResolvedType[] annotationTypes = new ResolvedType[anns.length]; | |||
for (int i = 0; i < anns.length; i++) { | |||
annotationTypes[i] = UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world); | |||
} | |||
return annotationTypes; | |||
} | |||
public ResolvedType[] getAnnotations(Class forClass, World inWorld) { | |||
// here we really want both the runtime visible AND the class visible | |||
// annotations so we bail out to Bcel and then chuck away the JavaClass so that we | |||
// don't hog memory. | |||
try { | |||
JavaClass jc = bcelRepository.loadClass(forClass); | |||
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[] anns = jc.getAnnotations(); | |||
bcelRepository.clear(); | |||
if (anns == null) { | |||
return ResolvedType.NONE; | |||
} else { | |||
ResolvedType[] ret = new ResolvedType[anns.length]; | |||
for (int i = 0; i < ret.length; i++) { | |||
ret[i] = inWorld.resolve(UnresolvedType.forSignature(anns[i].getTypeSignature())); | |||
} | |||
return ret; | |||
} | |||
} catch (ClassNotFoundException cnfEx) { | |||
// just use reflection then | |||
} | |||
Annotation[] classAnnotations = forClass.getAnnotations(); | |||
ResolvedType[] ret = new ResolvedType[classAnnotations.length]; | |||
for (int i = 0; i < classAnnotations.length; i++) { | |||
ret[i] = inWorld.resolve(classAnnotations[i].annotationType().getName()); | |||
} | |||
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) { | |||
if (lvt == null) | |||
return null;// pr222987 - prevent NPE | |||
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; | |||
} | |||
public ResolvedType[][] getParameterAnnotationTypes(Member onMember) { | |||
if (!(onMember instanceof AccessibleObject)) | |||
return NO_PARAMETER_ANNOTATIONS; | |||
// here we really want both the runtime visible AND the class visible | |||
// annotations | |||
// so we bail out to Bcel and then chuck away the JavaClass so that we | |||
// don't hog | |||
// memory. | |||
try { | |||
JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); | |||
org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[][] anns = null; | |||
if (onMember instanceof Method) { | |||
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); | |||
if (bcelMethod == null) { | |||
// pr220430 | |||
// System.err.println( | |||
// "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '" | |||
// + | |||
// onMember.getName()+"' in class '"+jc.getClassName()+"'"); | |||
} else { | |||
anns = bcelMethod.getParameterAnnotations(); | |||
} | |||
} else if (onMember instanceof Constructor) { | |||
org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); | |||
anns = bcelCons.getParameterAnnotations(); | |||
} else if (onMember instanceof Field) { | |||
// anns = null; | |||
} | |||
// the answer is cached and we don't want to hold on to memory | |||
bcelRepository.clear(); | |||
if (anns == null) | |||
return NO_PARAMETER_ANNOTATIONS; | |||
ResolvedType[][] result = new ResolvedType[anns.length][]; | |||
// CACHING?? | |||
for (int i = 0; i < anns.length; i++) { | |||
if (anns[i] != null) { | |||
result[i] = new ResolvedType[anns[i].length]; | |||
for (int j = 0; j < anns[i].length; j++) { | |||
result[i][j] = world.resolve(UnresolvedType.forSignature(anns[i][j].getTypeSignature())); | |||
} | |||
} | |||
} | |||
return result; | |||
} catch (ClassNotFoundException cnfEx) { | |||
// just use reflection then | |||
} | |||
// reflection... | |||
AccessibleObject ao = (AccessibleObject) onMember; | |||
Annotation[][] anns = null; | |||
if (onMember instanceof Method) { | |||
anns = ((Method) ao).getParameterAnnotations(); | |||
} else if (onMember instanceof Constructor) { | |||
anns = ((Constructor) ao).getParameterAnnotations(); | |||
} else if (onMember instanceof Field) { | |||
// anns = null; | |||
} | |||
if (anns == null) | |||
return NO_PARAMETER_ANNOTATIONS; | |||
ResolvedType[][] result = new ResolvedType[anns.length][]; | |||
// CACHING?? | |||
for (int i = 0; i < anns.length; i++) { | |||
if (anns[i] != null) { | |||
result[i] = new ResolvedType[anns[i].length]; | |||
for (int j = 0; j < anns[i].length; j++) { | |||
result[i][j] = UnresolvedType.forName(anns[i][j].annotationType().getName()).resolve(world); | |||
} | |||
} | |||
} | |||
return result; | |||
} | |||
} |
@@ -0,0 +1,103 @@ | |||
/* ******************************************************************* | |||
* 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.Constructor; | |||
import java.lang.reflect.Field; | |||
import java.lang.reflect.Member; | |||
import java.lang.reflect.Method; | |||
import java.lang.reflect.Type; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* Uses Java 1.5 reflection APIs to determine generic signatures | |||
*/ | |||
public class Java15GenericSignatureInformationProvider implements | |||
GenericSignatureInformationProvider { | |||
private final World world; | |||
public Java15GenericSignatureInformationProvider(World forWorld) { | |||
this.world = forWorld; | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericParameterTypes(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl) | |||
*/ | |||
public UnresolvedType[] getGenericParameterTypes( | |||
ReflectionBasedResolvedMemberImpl resolvedMember) { | |||
JavaLangTypeToResolvedTypeConverter typeConverter = new JavaLangTypeToResolvedTypeConverter(world); | |||
Type[] pTypes = new Type[0]; | |||
Member member = resolvedMember.getMember(); | |||
if (member instanceof Method) { | |||
pTypes = ((Method)member).getGenericParameterTypes(); | |||
} else if (member instanceof Constructor) { | |||
pTypes = ((Constructor)member).getGenericParameterTypes(); | |||
} | |||
return typeConverter.fromTypes(pTypes); | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericReturnType(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl) | |||
*/ | |||
public UnresolvedType getGenericReturnType( | |||
ReflectionBasedResolvedMemberImpl resolvedMember) { | |||
JavaLangTypeToResolvedTypeConverter typeConverter = new JavaLangTypeToResolvedTypeConverter(world); | |||
Member member = resolvedMember.getMember(); | |||
if (member instanceof Field) { | |||
return typeConverter.fromType(((Field)member).getGenericType()); | |||
} else if (member instanceof Method) { | |||
return typeConverter.fromType(((Method)member).getGenericReturnType()); | |||
} else if (member instanceof Constructor) { | |||
return typeConverter.fromType(((Constructor)member).getDeclaringClass()); | |||
} else { | |||
throw new IllegalStateException("unexpected member type: " + member); | |||
} | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isBridge() | |||
*/ | |||
public boolean isBridge(ReflectionBasedResolvedMemberImpl resolvedMember) { | |||
Member member = resolvedMember.getMember(); | |||
if (member instanceof Method) { | |||
return ((Method)member).isBridge(); | |||
} else { | |||
return false; | |||
} | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isVarArgs() | |||
*/ | |||
public boolean isVarArgs(ReflectionBasedResolvedMemberImpl resolvedMember) { | |||
Member member = resolvedMember.getMember(); | |||
if (member instanceof Method) { | |||
return ((Method)member).isVarArgs(); | |||
} else if (member instanceof Constructor) { | |||
return ((Constructor)member).isVarArgs(); | |||
} else { | |||
return false; | |||
} | |||
} | |||
/* (non-Javadoc) | |||
* @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isSynthetic() | |||
*/ | |||
public boolean isSynthetic(ReflectionBasedResolvedMemberImpl resolvedMember) { | |||
Member member = resolvedMember.getMember(); | |||
return member.isSynthetic(); | |||
} | |||
} |
@@ -0,0 +1,389 @@ | |||
/* ******************************************************************* | |||
* 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.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.util.Iterator; | |||
import java.util.Set; | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.reflect.AjType; | |||
import org.aspectj.lang.reflect.AjTypeSystem; | |||
import org.aspectj.lang.reflect.Pointcut; | |||
import org.aspectj.weaver.AnnotationAJ; | |||
import org.aspectj.weaver.ReferenceType; | |||
import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.TypeVariable; | |||
import org.aspectj.weaver.TypeVariableReferenceType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.tools.PointcutDesignatorHandler; | |||
import org.aspectj.weaver.tools.PointcutParameter; | |||
/** | |||
* Provides Java 5 behaviour in reflection based delegates (overriding 1.4 behaviour from superclass where | |||
* appropriate) | |||
* | |||
* @author Adrian Colyer | |||
* @author Andy Clement | |||
*/ | |||
public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedReferenceTypeDelegate { | |||
private AjType<?> myType; | |||
private ResolvedType[] annotations; | |||
private ResolvedMember[] pointcuts; | |||
private ResolvedMember[] methods; | |||
private ResolvedMember[] fields; | |||
private TypeVariable[] typeVariables; | |||
private ResolvedType superclass; | |||
private ResolvedType[] superInterfaces; | |||
private String genericSignature = null; | |||
private JavaLangTypeToResolvedTypeConverter typeConverter; | |||
private Java15AnnotationFinder annotationFinder = null; | |||
private ArgNameFinder argNameFinder = null; | |||
public Java15ReflectionBasedReferenceTypeDelegate() { | |||
} | |||
@Override | |||
public void initialize(ReferenceType aType, Class aClass, ClassLoader classLoader, World aWorld) { | |||
super.initialize(aType, aClass, classLoader, aWorld); | |||
myType = AjTypeSystem.getAjType(aClass); | |||
annotationFinder = new Java15AnnotationFinder(); | |||
argNameFinder = annotationFinder; | |||
annotationFinder.setClassLoader(this.classLoaderReference.getClassLoader()); | |||
annotationFinder.setWorld(aWorld); | |||
this.typeConverter = new JavaLangTypeToResolvedTypeConverter(aWorld); | |||
} | |||
@Override | |||
public ReferenceType buildGenericType() { | |||
return (ReferenceType) UnresolvedType.forGenericTypeVariables(getResolvedTypeX().getSignature(), getTypeVariables()) | |||
.resolve(getWorld()); | |||
} | |||
@Override | |||
public AnnotationAJ[] getAnnotations() { | |||
// AMC - we seem not to need to implement this method... | |||
// throw new UnsupportedOperationException( | |||
// "getAnnotations on Java15ReflectionBasedReferenceTypeDelegate is not implemented yet" | |||
// ); | |||
// FIXME is this the right implementation in the reflective case? | |||
return super.getAnnotations(); | |||
} | |||
@Override | |||
public ResolvedType[] getAnnotationTypes() { | |||
if (annotations == null) { | |||
annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); | |||
} | |||
return annotations; | |||
} | |||
@Override | |||
public boolean hasAnnotations() { | |||
if (annotations == null) { | |||
annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); | |||
} | |||
return annotations.length != 0; | |||
} | |||
@Override | |||
public boolean hasAnnotation(UnresolvedType ofType) { | |||
ResolvedType[] myAnns = getAnnotationTypes(); | |||
ResolvedType toLookFor = ofType.resolve(getWorld()); | |||
for (int i = 0; i < myAnns.length; i++) { | |||
if (myAnns[i] == toLookFor) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
// use the MAP to ensure that any aj-synthetic fields are filtered out | |||
@Override | |||
public ResolvedMember[] getDeclaredFields() { | |||
if (fields == null) { | |||
Field[] reflectFields = this.myType.getDeclaredFields(); | |||
ResolvedMember[] rFields = new ResolvedMember[reflectFields.length]; | |||
for (int i = 0; i < reflectFields.length; i++) { | |||
rFields[i] = createGenericFieldMember(reflectFields[i]); | |||
} | |||
this.fields = rFields; | |||
} | |||
return fields; | |||
} | |||
@Override | |||
public String getDeclaredGenericSignature() { | |||
if (this.genericSignature == null && isGeneric()) { | |||
// BUG? what the hell is this doing - see testcode in MemberTestCase15.testMemberSignatureCreation() and run it | |||
// off a Reflection World | |||
} | |||
return genericSignature; | |||
} | |||
@Override | |||
public ResolvedType[] getDeclaredInterfaces() { | |||
if (superInterfaces == null) { | |||
Type[] genericInterfaces = getBaseClass().getGenericInterfaces(); | |||
this.superInterfaces = typeConverter.fromTypes(genericInterfaces); | |||
} | |||
return superInterfaces; | |||
} | |||
@Override | |||
public ResolvedType getSuperclass() { | |||
// Superclass of object is null | |||
if (superclass == null && getBaseClass() != Object.class) { | |||
Type t = this.getBaseClass().getGenericSuperclass(); | |||
if (t != null) { | |||
superclass = typeConverter.fromType(t); | |||
} | |||
if (t == null) { | |||
// If the superclass is null, return Object - same as bcel does | |||
superclass = getWorld().resolve(UnresolvedType.OBJECT); | |||
} | |||
} | |||
return superclass; | |||
} | |||
@Override | |||
public TypeVariable[] getTypeVariables() { | |||
TypeVariable[] workInProgressSetOfVariables = getResolvedTypeX().getWorld().getTypeVariablesCurrentlyBeingProcessed( | |||
getBaseClass()); | |||
if (workInProgressSetOfVariables != null) { | |||
return workInProgressSetOfVariables; | |||
} | |||
if (this.typeVariables == null) { | |||
java.lang.reflect.TypeVariable[] tVars = this.getBaseClass().getTypeParameters(); | |||
TypeVariable[] rTypeVariables = new TypeVariable[tVars.length]; | |||
// basic initialization | |||
for (int i = 0; i < tVars.length; i++) { | |||
rTypeVariables[i] = new TypeVariable(tVars[i].getName()); | |||
} | |||
// stash it | |||
this.getResolvedTypeX().getWorld().recordTypeVariablesCurrentlyBeingProcessed(getBaseClass(), rTypeVariables); | |||
// now fill in the details... | |||
for (int i = 0; i < tVars.length; i++) { | |||
TypeVariableReferenceType tvrt = ((TypeVariableReferenceType) typeConverter.fromType(tVars[i])); | |||
TypeVariable tv = tvrt.getTypeVariable(); | |||
rTypeVariables[i].setSuperclass(tv.getSuperclass()); | |||
rTypeVariables[i].setAdditionalInterfaceBounds(tv.getSuperInterfaces()); | |||
rTypeVariables[i].setDeclaringElement(tv.getDeclaringElement()); | |||
rTypeVariables[i].setDeclaringElementKind(tv.getDeclaringElementKind()); | |||
rTypeVariables[i].setRank(tv.getRank()); | |||
} | |||
this.typeVariables = rTypeVariables; | |||
this.getResolvedTypeX().getWorld().forgetTypeVariablesCurrentlyBeingProcessed(getBaseClass()); | |||
} | |||
return this.typeVariables; | |||
} | |||
// overrides super method since by using the MAP we can filter out advice | |||
// methods that really shouldn't be seen in this list | |||
@Override | |||
public ResolvedMember[] getDeclaredMethods() { | |||
if (methods == null) { | |||
Method[] reflectMethods = this.myType.getDeclaredMethods(); | |||
Constructor[] reflectCons = this.myType.getDeclaredConstructors(); | |||
ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length]; | |||
for (int i = 0; i < reflectMethods.length; i++) { | |||
rMethods[i] = createGenericMethodMember(reflectMethods[i]); | |||
} | |||
for (int i = 0; i < reflectCons.length; i++) { | |||
rMethods[i + reflectMethods.length] = createGenericConstructorMember(reflectCons[i]); | |||
} | |||
this.methods = rMethods; | |||
} | |||
return methods; | |||
} | |||
/** | |||
* Returns the generic type, regardless of the resolvedType we 'know about' | |||
*/ | |||
public ResolvedType getGenericResolvedType() { | |||
ResolvedType rt = getResolvedTypeX(); | |||
if (rt.isParameterizedType() || rt.isRawType()) { | |||
return rt.getGenericType(); | |||
} | |||
return rt; | |||
} | |||
private ResolvedMember createGenericMethodMember(Method forMethod) { | |||
ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, | |||
getGenericResolvedType(), forMethod.getModifiers(), typeConverter.fromType(forMethod.getReturnType()), | |||
forMethod.getName(), typeConverter.fromTypes(forMethod.getParameterTypes()), typeConverter.fromTypes(forMethod | |||
.getExceptionTypes()), forMethod); | |||
ret.setAnnotationFinder(this.annotationFinder); | |||
ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld())); | |||
return ret; | |||
} | |||
private ResolvedMember createGenericConstructorMember(Constructor forConstructor) { | |||
ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, | |||
getGenericResolvedType(), forConstructor.getModifiers(), | |||
// to return what BCEL returns the return type is void | |||
UnresolvedType.VOID,// getGenericResolvedType(), | |||
"<init>", typeConverter.fromTypes(forConstructor.getParameterTypes()), typeConverter.fromTypes(forConstructor | |||
.getExceptionTypes()), forConstructor); | |||
ret.setAnnotationFinder(this.annotationFinder); | |||
ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld())); | |||
return ret; | |||
} | |||
private ResolvedMember createGenericFieldMember(Field forField) { | |||
ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.FIELD, | |||
getGenericResolvedType(), forField.getModifiers(), typeConverter.fromType(forField.getType()), forField.getName(), | |||
new UnresolvedType[0], forField); | |||
ret.setAnnotationFinder(this.annotationFinder); | |||
ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld())); | |||
return ret; | |||
} | |||
@Override | |||
public ResolvedMember[] getDeclaredPointcuts() { | |||
if (pointcuts == null) { | |||
Pointcut[] pcs = this.myType.getDeclaredPointcuts(); | |||
pointcuts = new ResolvedMember[pcs.length]; | |||
InternalUseOnlyPointcutParser parser = null; | |||
World world = getWorld(); | |||
if (world instanceof ReflectionWorld) { | |||
parser = new InternalUseOnlyPointcutParser(classLoaderReference.getClassLoader(), (ReflectionWorld) getWorld()); | |||
} else { | |||
parser = new InternalUseOnlyPointcutParser(classLoaderReference.getClassLoader()); | |||
} | |||
Set additionalPointcutHandlers = world.getRegisteredPointcutHandlers(); | |||
for (Iterator handlerIterator = additionalPointcutHandlers.iterator(); handlerIterator.hasNext();) { | |||
PointcutDesignatorHandler handler = (PointcutDesignatorHandler) handlerIterator.next(); | |||
parser.registerPointcutDesignatorHandler(handler); | |||
} | |||
// phase 1, create legitimate entries in pointcuts[] before we | |||
// attempt to resolve *any* of the pointcuts | |||
// resolution can sometimes cause us to recurse, and this two stage | |||
// process allows us to cope with that | |||
for (int i = 0; i < pcs.length; i++) { | |||
AjType<?>[] ptypes = pcs[i].getParameterTypes(); | |||
UnresolvedType[] weaverPTypes = new UnresolvedType[ptypes.length]; | |||
for (int j = 0; j < weaverPTypes.length; j++) { | |||
weaverPTypes[j] = this.typeConverter.fromType(ptypes[j].getJavaClass()); | |||
} | |||
pointcuts[i] = new DeferredResolvedPointcutDefinition(getResolvedTypeX(), pcs[i].getModifiers(), pcs[i].getName(), | |||
weaverPTypes); | |||
} | |||
// phase 2, now go back round and resolve in-place all of the | |||
// pointcuts | |||
PointcutParameter[][] parameters = new PointcutParameter[pcs.length][]; | |||
for (int i = 0; i < pcs.length; i++) { | |||
AjType<?>[] ptypes = pcs[i].getParameterTypes(); | |||
String[] pnames = pcs[i].getParameterNames(); | |||
if (pnames.length != ptypes.length) { | |||
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()); | |||
} | |||
} | |||
parameters[i] = new PointcutParameter[ptypes.length]; | |||
for (int j = 0; j < parameters[i].length; j++) { | |||
parameters[i][j] = parser.createPointcutParameter(pnames[j], ptypes[j].getJavaClass()); | |||
} | |||
String pcExpr = pcs[i].getPointcutExpression().toString(); | |||
org.aspectj.weaver.patterns.Pointcut pc = parser.resolvePointcutExpression(pcExpr, getBaseClass(), parameters[i]); | |||
((ResolvedPointcutDefinition) pointcuts[i]).setParameterNames(pnames); | |||
((ResolvedPointcutDefinition) pointcuts[i]).setPointcut(pc); | |||
} | |||
// phase 3, now concretize them all | |||
for (int i = 0; i < pointcuts.length; i++) { | |||
ResolvedPointcutDefinition rpd = (ResolvedPointcutDefinition) pointcuts[i]; | |||
rpd.setPointcut(parser.concretizePointcutExpression(rpd.getPointcut(), getBaseClass(), parameters[i])); | |||
} | |||
} | |||
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; | |||
} | |||
@Override | |||
public boolean isAnnotation() { | |||
return getBaseClass().isAnnotation(); | |||
} | |||
@Override | |||
public boolean isAnnotationStyleAspect() { | |||
return getBaseClass().isAnnotationPresent(Aspect.class); | |||
} | |||
@Override | |||
public boolean isAnnotationWithRuntimeRetention() { | |||
if (!isAnnotation()) { | |||
return false; | |||
} | |||
if (getBaseClass().isAnnotationPresent(Retention.class)) { | |||
Retention retention = (Retention) getBaseClass().getAnnotation(Retention.class); | |||
RetentionPolicy policy = retention.value(); | |||
return policy == RetentionPolicy.RUNTIME; | |||
} else { | |||
return false; | |||
} | |||
} | |||
@Override | |||
public boolean isAspect() { | |||
return this.myType.isAspect(); | |||
} | |||
@Override | |||
public boolean isEnum() { | |||
return getBaseClass().isEnum(); | |||
} | |||
@Override | |||
public boolean isGeneric() { | |||
// return false; // for now | |||
return getBaseClass().getTypeParameters().length > 0; | |||
} | |||
@Override | |||
public boolean isAnonymous() { | |||
return this.myClass.isAnonymousClass(); | |||
} | |||
@Override | |||
public boolean isNested() { | |||
return this.myClass.isMemberClass(); | |||
} | |||
@Override | |||
public ResolvedType getOuterClass() { | |||
return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld( | |||
myClass.getEnclosingClass(),world); | |||
} | |||
} |
@@ -0,0 +1,134 @@ | |||
/* ******************************************************************* | |||
* 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 | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.reflect; | |||
import java.lang.reflect.GenericArrayType; | |||
import java.lang.reflect.ParameterizedType; | |||
import java.lang.reflect.Type; | |||
import java.lang.reflect.WildcardType; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.aspectj.weaver.BoundedReferenceType; | |||
import org.aspectj.weaver.ReferenceType; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.TypeFactory; | |||
import org.aspectj.weaver.TypeVariable; | |||
import org.aspectj.weaver.TypeVariableReferenceType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* Handles the translation of java.lang.reflect.Type objects into AspectJ UnresolvedTypes. | |||
* | |||
* @author Adrian Colyer | |||
*/ | |||
public class JavaLangTypeToResolvedTypeConverter { | |||
// Used to prevent recursion - we record what we are working on and return it if asked again *whilst* working on it | |||
private Map<Type, TypeVariableReferenceType> typeVariablesInProgress = new HashMap<Type, TypeVariableReferenceType>(); | |||
private final World world; | |||
public JavaLangTypeToResolvedTypeConverter(World aWorld) { | |||
this.world = aWorld; | |||
} | |||
private World getWorld() { | |||
return this.world; | |||
} | |||
public ResolvedType fromType(Type type) { | |||
if (type instanceof Class) { | |||
Class clazz = (Class) type; | |||
String name = clazz.getName(); | |||
/** | |||
* getName() can return: | |||
* | |||
* 1. If this class object represents a reference type that is not an | |||
* array type then the binary name of the class is returned | |||
* 2. If this class object represents a primitive type or void, then | |||
* the name returned is a String equal to the Java language keyword | |||
* corresponding to the primitive type or void. | |||
* 3. If this class object represents a class of arrays, then the internal | |||
* form of the name consists of the name of the element type preceded by | |||
* one or more '[' characters representing the depth of the array nesting. | |||
*/ | |||
if (clazz.isArray()) { | |||
UnresolvedType ut = UnresolvedType.forSignature(name.replace('.', '/')); | |||
return getWorld().resolve(ut); | |||
} else { | |||
return getWorld().resolve(name); | |||
} | |||
} else if (type instanceof ParameterizedType) { | |||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=509327 | |||
// TODO should deal with the ownerType if it set, indicating this is possibly an inner type of a parameterized type | |||
Type ownerType = ((ParameterizedType) type).getOwnerType(); | |||
ParameterizedType parameterizedType = (ParameterizedType) type; | |||
ResolvedType baseType = fromType(parameterizedType.getRawType()); | |||
Type[] typeArguments = parameterizedType.getActualTypeArguments(); | |||
if (baseType.isSimpleType() && typeArguments.length == 0 && ownerType != null) { | |||
// 'type' is an inner type of some outer parameterized type | |||
// For now just return the base type - in future create the parameterized form of the outer | |||
// and use it with the inner. We return the base type to be compatible with what the | |||
// code does that accesses the info from the bytecode (unlike this code which accesses it | |||
// reflectively). | |||
return baseType; | |||
} | |||
ResolvedType[] resolvedTypeArguments = fromTypes(typeArguments); | |||
return TypeFactory.createParameterizedType(baseType, resolvedTypeArguments, getWorld()); | |||
} else if (type instanceof java.lang.reflect.TypeVariable) { | |||
TypeVariableReferenceType inprogressVar = typeVariablesInProgress.get(type); | |||
if (inprogressVar != null) { | |||
return inprogressVar; | |||
} | |||
java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) type; | |||
TypeVariable rt_tv = new TypeVariable(tv.getName()); | |||
TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv, getWorld()); | |||
typeVariablesInProgress.put(type, tvrt); // record what we are working on, for recursion case | |||
Type[] bounds = tv.getBounds(); | |||
ResolvedType[] resBounds = fromTypes(bounds); | |||
ResolvedType upperBound = resBounds[0]; | |||
ResolvedType[] additionalBounds = new ResolvedType[0]; | |||
if (resBounds.length > 1) { | |||
additionalBounds = new ResolvedType[resBounds.length - 1]; | |||
System.arraycopy(resBounds, 1, additionalBounds, 0, additionalBounds.length); | |||
} | |||
rt_tv.setUpperBound(upperBound); | |||
rt_tv.setAdditionalInterfaceBounds(additionalBounds); | |||
typeVariablesInProgress.remove(type); // we have finished working on it | |||
return tvrt; | |||
} else if (type instanceof WildcardType) { | |||
WildcardType wildType = (WildcardType) type; | |||
Type[] lowerBounds = wildType.getLowerBounds(); | |||
Type[] upperBounds = wildType.getUpperBounds(); | |||
ResolvedType bound = null; | |||
boolean isExtends = lowerBounds.length == 0; | |||
if (isExtends) { | |||
bound = fromType(upperBounds[0]); | |||
} else { | |||
bound = fromType(lowerBounds[0]); | |||
} | |||
return new BoundedReferenceType((ReferenceType) bound, isExtends, getWorld()); | |||
} else if (type instanceof GenericArrayType) { | |||
GenericArrayType genericArrayType = (GenericArrayType) type; | |||
Type componentType = genericArrayType.getGenericComponentType(); | |||
return UnresolvedType.makeArray(fromType(componentType), 1).resolve(getWorld()); | |||
} | |||
return ResolvedType.MISSING; | |||
} | |||
public ResolvedType[] fromTypes(Type[] types) { | |||
ResolvedType[] ret = new ResolvedType[types.length]; | |||
for (int i = 0; i < ret.length; i++) { | |||
ret[i] = fromType(types[i]); | |||
} | |||
return ret; | |||
} | |||
} |
@@ -0,0 +1,127 @@ | |||
/******************************************************************************* | |||
* Copyright (c) 2006 IBM Corporation and others. | |||
* 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: | |||
* Matthew Webster - initial implementation | |||
*******************************************************************************/ | |||
package org.aspectj.weaver.tools; | |||
import java.util.logging.Handler; | |||
import java.util.logging.Level; | |||
import java.util.logging.Logger; | |||
// OPTIMIZE move out for now? check what doc says about using these variants on trace (commons/14) | |||
public class Jdk14Trace extends AbstractTrace { | |||
private Logger logger; | |||
private String name; | |||
public Jdk14Trace (Class clazz) { | |||
super(clazz); | |||
this.name = clazz.getName(); | |||
this.logger = Logger.getLogger(name); | |||
} | |||
public void enter(String methodName, Object thiz, Object[] args) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.entering(name,methodName,formatObj(thiz)); | |||
if (args != null && logger.isLoggable(Level.FINER)) { | |||
logger.entering(name,methodName,formatObjects(args)); | |||
} | |||
} | |||
} | |||
public void enter(String methodName, Object thiz) { | |||
enter(methodName,thiz,null); | |||
} | |||
public void exit(String methodName, Object ret) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.exiting(name,methodName,formatObj(ret)); | |||
} | |||
} | |||
public void exit(String methodName, Throwable th) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.exiting(name,methodName,th); | |||
} | |||
} | |||
public void exit(String methodName) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.exiting(name,methodName); | |||
} | |||
} | |||
public void event(String methodName, Object thiz, Object[] args) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.logp(Level.FINER,name,methodName,"EVENT",formatObj(thiz)); | |||
if (args != null && logger.isLoggable(Level.FINER)) { | |||
logger.logp(Level.FINER,name,methodName,"EVENT",formatObjects(args)); | |||
} | |||
} | |||
} | |||
public void event(String methodName) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.logp(Level.FINER,name,methodName,"EVENT"); | |||
} | |||
} | |||
public boolean isTraceEnabled() { | |||
return logger.isLoggable(Level.FINER); | |||
} | |||
public void setTraceEnabled (boolean b) { | |||
if (b) { | |||
logger.setLevel(Level.FINER); | |||
Handler[] handlers = logger.getHandlers(); | |||
if (handlers.length == 0) { | |||
Logger parent = logger.getParent(); | |||
if (parent != null) handlers = parent.getHandlers(); | |||
} | |||
for (int i = 0; i < handlers.length; i++) { | |||
Handler handler = handlers[i]; | |||
handler.setLevel(Level.FINER); | |||
} | |||
} | |||
else { | |||
logger.setLevel(Level.INFO); | |||
} | |||
} | |||
public void debug (String message) { | |||
if (logger.isLoggable(Level.FINE)) { | |||
logger.fine(message); | |||
} | |||
} | |||
public void info(String message) { | |||
if (logger.isLoggable(Level.INFO)) { | |||
logger.info(message); | |||
} | |||
} | |||
public void warn (String message, Throwable th) { | |||
if (logger.isLoggable(Level.WARNING)) { | |||
logger.log(Level.WARNING,message,th); | |||
} | |||
} | |||
public void error (String message, Throwable th) { | |||
if (logger.isLoggable(Level.SEVERE)) { | |||
logger.log(Level.SEVERE,message,th); | |||
} | |||
} | |||
public void fatal (String message, Throwable th) { | |||
if (logger.isLoggable(Level.SEVERE)) { | |||
logger.log(Level.SEVERE,message,th); | |||
} | |||
} | |||
} |
@@ -0,0 +1,20 @@ | |||
/******************************************************************************* | |||
* Copyright (c) 2006 IBM Corporation and others. | |||
* 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: | |||
* Matthew Webster - initial implementation | |||
*******************************************************************************/ | |||
package org.aspectj.weaver.tools; | |||
public class Jdk14TraceFactory extends TraceFactory { | |||
@Override | |||
public Trace getTrace(Class clazz) { | |||
return new Jdk14Trace(clazz); | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
/******************************************************************************* | |||
* 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://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - initial API and implementation | |||
*******************************************************************************/ | |||
import java.io.Serializable; | |||
import java.lang.reflect.InvocationHandler; | |||
import java.lang.reflect.Proxy; | |||
public class $Proxy1 extends Proxy implements MessageService { | |||
protected $Proxy1(InvocationHandler arg0) { | |||
super(arg0); | |||
} | |||
public Object get1(Long t) { | |||
return null; | |||
} | |||
public Object get2(Serializable s) { | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2008 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: | |||
* Andy Clement initial implementation | |||
* ******************************************************************/ | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.annotation.Before; | |||
import org.aspectj.lang.annotation.Pointcut; | |||
/** | |||
* Created to enable PointcutDesignatorHandlerTests.testParsingBeanInReferencePointcut01 and 02 to run | |||
* | |||
* @author Andy Clement | |||
*/ | |||
@Aspect | |||
public class CounterAspect { | |||
int count; | |||
@Before("execution(* set*(..)) && bean(testBean1)") | |||
public void increment1ForAnonymousPointcut() { | |||
count++; | |||
} | |||
@Pointcut("execution(* toString(..)) && bean(testBean1)") | |||
public void testBean1toString() { | |||
} | |||
@Pointcut("execution(* setAge(..)) && bean(testBean1)") | |||
public void testBean1SetAge() { | |||
} | |||
@Pointcut("execution(* setAge(..)) && bean(testBean2)") | |||
public void testBean2SetAge() { | |||
} | |||
@Before("testBean1SetAge()") | |||
public void increment1() { | |||
count++; | |||
} | |||
@Before("testBean2SetAge()") | |||
public void increment2() { | |||
count++; | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
/******************************************************************************* | |||
* 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://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - initial API and implementation | |||
*******************************************************************************/ | |||
import java.io.Serializable; | |||
public interface GenericService<T extends Serializable> { | |||
Object get1(T t); | |||
Object get2(Serializable s); | |||
} |
@@ -0,0 +1,15 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2008 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 | |||
* Andy Clement | |||
* ******************************************************************/ | |||
public @interface MA { | |||
} |
@@ -0,0 +1,15 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2008 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 | |||
* Andy Clement | |||
* ******************************************************************/ | |||
public @interface MB { | |||
} |
@@ -0,0 +1,15 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2008 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 | |||
* Andy Clement | |||
* ******************************************************************/ | |||
public @interface MC { | |||
} |