support runtime-visible annotations and java.lang.reflect.Proxy

This commit is contained in:
Joel Dice
2009-09-18 18:01:54 -06:00
parent a2a33c259e
commit 7aa906d97b
23 changed files with 1278 additions and 169 deletions

View File

@ -10,9 +10,17 @@
package java.lang.reflect;
public abstract class AccessibleObject {
import java.lang.annotation.Annotation;
public abstract class AccessibleObject implements AnnotatedElement {
protected static final int Accessible = 1 << 0;
public boolean isAnnotationPresent
(Class<? extends Annotation> class_)
{
return getAnnotation(class_) != null;
}
public abstract boolean isAccessible();
public abstract void setAccessible(boolean v);

View File

@ -0,0 +1,23 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang.reflect;
import java.lang.annotation.Annotation;
public interface AnnotatedElement {
public boolean isAnnotationPresent(Class<? extends Annotation> class_);
public <T extends Annotation> T getAnnotation(Class<T> class_);
public Annotation[] getAnnotations();
public Annotation[] getDeclaredAnnotations();
}

View File

@ -10,6 +10,8 @@
package java.lang.reflect;
import java.lang.annotation.Annotation;
public class Constructor<T> extends AccessibleObject
implements Member, GenericDeclaration
{
@ -52,6 +54,18 @@ public class Constructor<T> extends AccessibleObject
return method.isSynthetic();
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
return method.getAnnotation(class_);
}
public Annotation[] getAnnotations() {
return method.getAnnotations();
}
public Annotation[] getDeclaredAnnotations() {
return method.getDeclaredAnnotations();
}
public TypeVariable<Constructor<T>>[] getTypeParameters() {
throw new UnsupportedOperationException();
}

View File

@ -10,6 +10,10 @@
package java.lang.reflect;
import avian.AnnotationInvocationHandler;
import java.lang.annotation.Annotation;
public class Field<T> extends AccessibleObject {
private static final int VoidField = 0;
private static final int ByteField = 1;
@ -27,7 +31,8 @@ public class Field<T> extends AccessibleObject {
private short flags;
private short offset;
private byte[] name;
private byte[] spec;
public byte[] spec;
public Addendum addendum;
private Class<T> class_;
private Field() { }
@ -195,6 +200,45 @@ public class Field<T> extends AccessibleObject {
}
}
private Annotation getAnnotation(Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
return (T) getAnnotation(a);
}
}
}
return null;
}
public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = addendum.annotationTable;
Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]);
}
return array;
} else {
return new Annotation[0];
}
}
public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}
public boolean isEnumConstant() {
throw new UnsupportedOperationException();
}
@ -210,4 +254,8 @@ public class Field<T> extends AccessibleObject {
private static native void setObject
(Object instance, int offset, Object value);
public static class Addendum {
public Object[] annotationTable;
}
}

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang.reflect;
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] arguments);
}

View File

@ -10,6 +10,10 @@
package java.lang.reflect;
import avian.AnnotationInvocationHandler;
import java.lang.annotation.Annotation;
public class Method<T> extends AccessibleObject
implements Member, GenericDeclaration
{
@ -21,7 +25,8 @@ public class Method<T> extends AccessibleObject
private short offset;
private int nativeID;
private byte[] name;
private byte[] spec;
public byte[] spec;
public Addendum addendum;
private Class<T> class_;
private Object code;
private long compiled;
@ -142,6 +147,45 @@ public class Method<T> extends AccessibleObject
throw new RuntimeException();
}
private Annotation getAnnotation(Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
return (T) getAnnotation(a);
}
}
}
return null;
}
public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = addendum.annotationTable;
Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]);
}
return array;
} else {
return new Annotation[0];
}
}
public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}
public boolean isSynthetic() {
throw new UnsupportedOperationException();
}
@ -165,4 +209,8 @@ public class Method<T> extends AccessibleObject
public TypeVariable<Method<T>>[] getTypeParameters() {
throw new UnsupportedOperationException();
}
public static class Addendum {
public Object[] annotationTable;
}
}

View File

@ -0,0 +1,54 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang.reflect;
public class Proxy {
private static int nextNumber;
protected InvocationHandler h;
public static Class getProxyClass(ClassLoader loader,
Class ... interfaces)
{
for (Class c: interfaces) {
if (! c.isInterface()) {
throw new IllegalArgumentException();
}
}
int number;
synchronized (Proxy.class) {
number = nextNumber++;
}
return makeClass
(loader, interfaces, ("Proxy-" + number + "\0").getBytes());
}
private static native Class makeClass(ClassLoader loader,
Class[] interfaces,
byte[] name);
public static Object newProxyInstance(ClassLoader loader,
Class[] interfaces,
InvocationHandler handler)
{
try {
return Proxy.getProxyClass(loader, interfaces)
.getConstructor(new Class[] { InvocationHandler.class })
.newInstance(new Object[] { handler });
} catch (Exception e) {
AssertionError error = new AssertionError();
error.initCause(e);
throw error;
}
}
}