summaryrefslogtreecommitdiff
path: root/tutorial/examples/rtrefl
diff options
context:
space:
mode:
Diffstat (limited to 'tutorial/examples/rtrefl')
-rw-r--r--tutorial/examples/rtrefl/Point.java107
-rw-r--r--tutorial/examples/rtrefl/Point.oj35
-rw-r--r--tutorial/examples/rtrefl/PointUser.java25
-rw-r--r--tutorial/examples/rtrefl/PointUser.oj19
-rw-r--r--tutorial/examples/rtrefl/RTMetaLevel.java6
-rw-r--r--tutorial/examples/rtrefl/RTMetaObject.java81
-rw-r--r--tutorial/examples/rtrefl/RTReflClass.java229
-rw-r--r--tutorial/examples/rtrefl/RTReflClass.oj247
-rw-r--r--tutorial/examples/rtrefl/VerboseRTMetaObject.java38
9 files changed, 787 insertions, 0 deletions
diff --git a/tutorial/examples/rtrefl/Point.java b/tutorial/examples/rtrefl/Point.java
new file mode 100644
index 0000000..708c5ea
--- /dev/null
+++ b/tutorial/examples/rtrefl/Point.java
@@ -0,0 +1,107 @@
+/*
+ * This code was generated by ojc.
+ */
+/*
+ * Point.oj
+ */
+package examples.rtrefl;
+
+
+public class Point implements examples.rtrefl.RTMetaLevel
+{
+
+ public int x;
+
+ public int y;
+
+ public String name;
+
+ public Point( String name, int x, int y )
+ {
+ this.x = x;
+ this.y = y;
+ this.name = name;
+ }
+
+ public Point( int x, int y )
+ {
+ this( "DefaultName", x, y );
+ }
+
+ public String org_toString()
+ {
+ return "(" + x + "," + y + ")";
+ }
+
+ public void org_move( int dx, int dy )
+ {
+ x += dx;
+ y += dy;
+ }
+
+ public double org_distanceFromOrigin()
+ {
+ return Math.sqrt( (double) x * x + y * y );
+ }
+
+
+ public examples.rtrefl.RTMetaObject mt;
+
+
+ public java.lang.String toString()
+ {
+ return (java.lang.String) mt.trapMethodCall( "org_toString", new java.lang.Class[]{ }, new java.lang.Object[]{ } );
+ }
+
+
+ public void move( int oj_param0, int oj_param1 )
+ {
+ mt.trapMethodCall( "org_move", new java.lang.Class[]{ int.class, int.class }, new java.lang.Object[]{ new java.lang.Integer( oj_param0 ), new java.lang.Integer( oj_param1 ) } );
+ }
+
+
+ public double distanceFromOrigin()
+ {
+ return ((java.lang.Double) mt.trapMethodCall( "org_distanceFromOrigin", new java.lang.Class[]{ }, new java.lang.Object[]{ } )).doubleValue();
+ }
+
+
+ public int read_x()
+ {
+ return ((java.lang.Integer) mt.trapFieldRead( "x" )).intValue();
+ }
+
+
+ public int write_x( int oj_param0 )
+ {
+ mt.trapFieldWrite( "x", new java.lang.Integer( oj_param0 ) );
+ return oj_param0;
+ }
+
+
+ public int read_y()
+ {
+ return ((java.lang.Integer) mt.trapFieldRead( "y" )).intValue();
+ }
+
+
+ public int write_y( int oj_param0 )
+ {
+ mt.trapFieldWrite( "y", new java.lang.Integer( oj_param0 ) );
+ return oj_param0;
+ }
+
+
+ public java.lang.String read_name()
+ {
+ return (java.lang.String) mt.trapFieldRead( "name" );
+ }
+
+
+ public java.lang.String write_name( java.lang.String oj_param0 )
+ {
+ mt.trapFieldWrite( "name", oj_param0 );
+ return oj_param0;
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/Point.oj b/tutorial/examples/rtrefl/Point.oj
new file mode 100644
index 0000000..e15b607
--- /dev/null
+++ b/tutorial/examples/rtrefl/Point.oj
@@ -0,0 +1,35 @@
+/*
+ * Point.oj
+ */
+package examples.rtrefl;
+
+
+public class Point instantiates RTReflClass
+{
+ public int x, y;
+ public String name;
+
+ public Point( String name, int x, int y ) {
+ this.x = x;
+ this.y = y;
+ this.name = name;
+ }
+
+ public Point( int x, int y ) {
+ this( "DefaultName", x, y );
+ }
+
+ public String toString() {
+ return "(" + x + "," + y + ")";
+ }
+
+ public void move( int dx, int dy ) {
+ x += dx;
+ y += dy;
+ }
+
+ public double distanceFromOrigin() {
+ return Math.sqrt( (double) x * x + y * y );
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/PointUser.java b/tutorial/examples/rtrefl/PointUser.java
new file mode 100644
index 0000000..42ddee8
--- /dev/null
+++ b/tutorial/examples/rtrefl/PointUser.java
@@ -0,0 +1,25 @@
+/*
+ * This code was generated by ojc.
+ */
+/*
+ * PointUser.oj
+ */
+package examples.rtrefl;
+
+
+public class PointUser
+{
+
+ public static void main( String[] args )
+ {
+ Point p = new Point( 1, 2 ){
+ };
+ p.mt = new VerboseRTMetaObject( p ){
+ };
+ p.write_name( "MyFavorite" );
+ int x = p.read_x() + 1;
+ p.write_y( x * 2 + p.read_y() );
+ System.out.println( "distance = " + p.distanceFromOrigin() );
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/PointUser.oj b/tutorial/examples/rtrefl/PointUser.oj
new file mode 100644
index 0000000..3ab9edc
--- /dev/null
+++ b/tutorial/examples/rtrefl/PointUser.oj
@@ -0,0 +1,19 @@
+/*
+ * PointUser.oj
+ */
+package examples.rtrefl;
+
+
+public class PointUser
+{
+
+ public static void main( String[] args ) {
+ Point p = new Point( 1, 2 );
+ p.mt = new VerboseRTMetaObject( p );
+ p.name = "MyFavorite";
+ int x = p.x + 1;
+ p.y = x * 2 + p.y;
+ System.out.println( "distance = " + p.distanceFromOrigin() );
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/RTMetaLevel.java b/tutorial/examples/rtrefl/RTMetaLevel.java
new file mode 100644
index 0000000..0daf0be
--- /dev/null
+++ b/tutorial/examples/rtrefl/RTMetaLevel.java
@@ -0,0 +1,6 @@
+package examples.rtrefl;
+
+
+public interface RTMetaLevel
+{
+}
diff --git a/tutorial/examples/rtrefl/RTMetaObject.java b/tutorial/examples/rtrefl/RTMetaObject.java
new file mode 100644
index 0000000..13486ae
--- /dev/null
+++ b/tutorial/examples/rtrefl/RTMetaObject.java
@@ -0,0 +1,81 @@
+package examples.rtrefl;
+
+
+import java.lang.reflect.*;
+
+
+/**
+ * The class RTMetaObject
+ * Exception handling is not implemented.
+ */
+public class RTMetaObject
+{
+ private RTMetaLevel baseObj;
+
+ public RTMetaObject(RTMetaLevel base_obj) {
+ this.baseObj = base_obj;
+ }
+
+ public Object trapMethodCall(String name, Class[] paramTypes, Object[] args)
+ {
+ try {
+ Method method = baseObj.getClass().getMethod(name, paramTypes);
+ return method.invoke(baseObj, args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public Object trapFieldRead(String name) {
+ try {
+ Field field = baseObj.getClass().getField(name);
+ return field.get(baseObj);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void trapFieldWrite(String name, Object rvalue) {
+ try {
+ Field field = baseObj.getClass().getField(name);
+ field.set(baseObj, rvalue);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+
+/*****
+class Foo {
+ int f(int a) {}
+ int l;
+}
+...
+Foo foo; foo.l = expr; a = foo.l;
+
+->
+
+class Foo implements Metalevel {
+ public examples.rtrefl.RTMetaObject mt;
+ int org_f(int a) {}
+ int f(int a) {
+ Object[] args = new Object[]{ new Integer(a) };
+ Class[] argTypes = new Class[]{ int.class };
+ Object result = mt.trapMethodCall("org_f", argTypes, args);
+ return ((Integer) result).intValue();
+ }
+ int read_l() {
+ Object result = mt.trapFieldRead("l");
+ return ((Integer) result).intValue();
+ }
+ int write_l(int rvalue) {
+ mt.trapFieldWrite("l", new Integer(rvalue));
+ return rvalue;
+ }
+}
+...
+Foo foo; foo.write_l(expr); a = foo.read_l();
+*****/
diff --git a/tutorial/examples/rtrefl/RTReflClass.java b/tutorial/examples/rtrefl/RTReflClass.java
new file mode 100644
index 0000000..4486241
--- /dev/null
+++ b/tutorial/examples/rtrefl/RTReflClass.java
@@ -0,0 +1,229 @@
+/*
+ * This code was generated by ojc.
+ */
+/*
+ * RTReflClass.oj
+ *
+ * Oct 29, 1999 by Michiaki Tatsubori
+ */
+package examples.rtrefl;
+
+
+import openjava.mop.*;
+import openjava.ptree.*;
+import openjava.syntax.*;
+
+
+/**
+ * The class <code>RTReflClass</code> is a metaclass which
+ * provides hooks for runtime class metaobject.
+ * <p>
+ * All the fields in the class are hidden instead the readers and
+ * writers methods for fields are provided. Furthermore, accesses
+ * to fields of the class is to be replaced with these methods.
+ * Note that member accesses in its class body are not captured.
+ */
+public class RTReflClass extends OJClass
+{
+
+ protected static String RTMETAOBJ_FIELD = "mt";
+
+ protected static Expression METAFIELD_ACCESS = new FieldAccess( RTMETAOBJ_FIELD );
+
+ protected static final String originalMethodName( String name )
+ {
+ return "org_" + name;
+ }
+
+ protected static final String fieldReaderName( String name )
+ {
+ return "read_" + name;
+ }
+
+ protected static final String fieldWriterName( String name )
+ {
+ return "write_" + name;
+ }
+
+ /** Overrides to translate definition */
+ public void translateDefinition()
+ throws MOPException
+ {
+ addInterface( openjava.mop.OJClass.forClass( RTMetaLevel.class ) );
+ OJMethod[] methods = getDeclaredMethods();
+ OJField[] fields = getDeclaredFields();
+ OJField rtmobj_field = new OJField( this, OJModifier.forModifier( OJModifier.PUBLIC ), openjava.mop.OJClass.forClass( RTMetaObject.class ), RTMETAOBJ_FIELD );
+ addField( rtmobj_field );
+ for (int i = 0; i < methods.length; ++i) {
+ OJModifier modif = methods[i].getModifiers();
+ if (modif.isPublic()) {
+ provideMethod( methods[i] );
+ }
+ }
+ for (int i = 0; i < fields.length; ++i) {
+ OJModifier modif = fields[i].getModifiers();
+ if (modif.isPublic()) {
+ provideField( fields[i] );
+ }
+ }
+ }
+
+ private void provideMethod( OJMethod method )
+ throws MOPException
+ {
+ System.err.println( "Providing a method : " + method.toString() );
+ OJMethod trapper = OJMethod.makePrototype( method );
+ method.setName( originalMethodName( method.getName() ) );
+ addMethod( trapper );
+ Expression trapexpr = generateTrappingMethodCall( trapper );
+ StatementList body = new StatementList();
+ OJClass retType = trapper.getReturnType();
+ if (retType == OJSystem.VOID) {
+ body.add( new ExpressionStatement( trapexpr ) );
+ } else {
+ Expression unwrapexpr = generateUnwrapping( retType, trapexpr );
+ body.add( new ReturnStatement( unwrapexpr ) );
+ }
+ trapper.setBody( body );
+ }
+
+ private static MethodCall generateTrappingMethodCall( OJMethod method )
+ throws MOPException
+ {
+ ExpressionList params = method.getParameterVariables();
+ OJClass[] paramTypes = method.getParameterTypes();
+ ExpressionList typeinfo_args = new ExpressionList();
+ ExpressionList args = new ExpressionList();
+ for (int i = 0; i < paramTypes.length; ++i) {
+ typeinfo_args.add( new ClassLiteral( paramTypes[i] ) );
+ args.add( generateWrapping( paramTypes[i], params.get( i ) ) );
+ }
+ Expression namearg = Literal.makeLiteral( originalMethodName( method.getName() ) );
+ Expression mrsld_typearg = new ArrayAllocationExpression( openjava.mop.OJClass.forClass( java.lang.Class.class ), new ExpressionList( null ), new ArrayInitializer( typeinfo_args ) );
+ Expression mrsld_arg = new ArrayAllocationExpression( openjava.mop.OJClass.forClass( java.lang.Object.class ), new ExpressionList( null ), new ArrayInitializer( args ) );
+ ExpressionList metaargs = new ExpressionList( namearg, mrsld_typearg, mrsld_arg );
+ return new MethodCall( METAFIELD_ACCESS, "trapMethodCall", metaargs );
+ }
+
+ private void provideField( OJField field )
+ throws MOPException
+ {
+ System.err.println( "Providing a field : " + field.toString() );
+ generateReaderMethod( field );
+ generateWriterMethod( field );
+ }
+
+ /**
+ * int read_l() {
+ * return ((Integer) mt.trapFieldRead("l")).intValue();
+ * }
+ */
+ private void generateReaderMethod( OJField field )
+ throws MOPException
+ {
+ Expression metafld = new FieldAccess( RTMETAOBJ_FIELD );
+ ExpressionList args = new ExpressionList( Literal.makeLiteral( field.getName() ) );
+ Expression trapexpr = new MethodCall( METAFIELD_ACCESS, "trapFieldRead", args );
+ Expression unwrapping = generateUnwrapping( field.getType(), trapexpr );
+ OJMethod reader = new OJMethod( this, field.getModifiers(), field.getType(), fieldReaderName( field.getName() ), (OJClass[]) null, null, new StatementList( new ReturnStatement( unwrapping ) ) );
+ addMethod( reader );
+ }
+
+ /**
+ * int write_l(int rvalue) {
+ * mt.trapFieldWrite("l", new Integer(rvalue));
+ * return rvalue;
+ * }
+ */
+ private void generateWriterMethod( OJField field )
+ throws MOPException
+ {
+ OJMethod writer = new OJMethod( this, field.getModifiers(), field.getType(), fieldWriterName( field.getName() ), new OJClass[]{ field.getType() }, null, null );
+ Expression param = writer.getParameterVariables().get( 0 );
+ ExpressionList args = new ExpressionList( Literal.makeLiteral( field.getName() ), generateWrapping( field.getType(), param ) );
+ Expression trapexpr = new MethodCall( METAFIELD_ACCESS, "trapFieldWrite", args );
+ StatementList body = new StatementList( new ExpressionStatement( trapexpr ), new ReturnStatement( param ) );
+ writer.setBody( body );
+ addMethod( writer );
+ }
+
+ /** new Integer(expr) for expr */
+ private static Expression generateWrapping( OJClass realType, Expression expr )
+ {
+ if (!realType.isPrimitive()) {
+ return expr;
+ }
+ OJClass wrapperType = realType.primitiveWrapper();
+ return new AllocationExpression( wrapperType, new ExpressionList( expr ) );
+ }
+
+ /** ((Integer) expr).intValue() for expr */
+ private static Expression generateUnwrapping( OJClass realType, Expression expr )
+ {
+ expr = new CastExpression( realType.primitiveWrapper(), expr );
+ if (!realType.isPrimitive()) {
+ return expr;
+ }
+ return new MethodCall( expr, realType.getName() + "Value", null );
+ }
+
+ /** Allows references to private fields */
+ public OJField resolveException( NoSuchMemberException e, String name )
+ throws NoSuchMemberException
+ {
+ try {
+ return getDeclaredField( name );
+ } catch ( NoSuchMemberException e2 ) {
+ }
+ return super.resolveException( e, name );
+ }
+
+ /** Overrides to expand fields to be read */
+ public Expression expandFieldRead( Environment env, FieldAccess expr )
+ {
+ if (expr.getName().equals( RTMETAOBJ_FIELD )) {
+ return expr;
+ }
+ Expression ref = expr.getReferenceExpr();
+ String name = fieldReaderName( expr.getName() );
+ Expression result;
+ if (ref != null) {
+ result = new MethodCall( ref, name, null );
+ } else {
+ result = new MethodCall( expr.getReferenceType(), name, null );
+ }
+ System.err.println( "Patch FR : " + expr + "\tto\t" + result );
+ return result;
+ }
+
+ /** Overrides to expand fields to be written */
+ public Expression expandFieldWrite( Environment env, AssignmentExpression expr )
+ {
+ FieldAccess fldac = (FieldAccess) expr.getLeft();
+ if (fldac.getName().equals( RTMETAOBJ_FIELD )) {
+ return expr;
+ }
+ ExpressionList args = new ExpressionList( expr.getRight() );
+ Expression ref = fldac.getReferenceExpr();
+ String name = fieldWriterName( fldac.getName() );
+ Expression result;
+ if (ref != null) {
+ result = new MethodCall( ref, name, args );
+ } else {
+ result = new MethodCall( fldac.getReferenceType(), name, args );
+ }
+ System.err.println( "Patch FW : " + expr + "\tto\t" + result );
+ return result;
+ }
+
+ public RTReflClass( openjava.mop.Environment oj_param0, openjava.mop.OJClass oj_param1, openjava.ptree.ClassDeclaration oj_param2 )
+ {
+ super( oj_param0, oj_param1, oj_param2 );
+ }
+
+ public RTReflClass( java.lang.Class oj_param0, openjava.mop.MetaInfo oj_param1 )
+ {
+ super( oj_param0, oj_param1 );
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/RTReflClass.oj b/tutorial/examples/rtrefl/RTReflClass.oj
new file mode 100644
index 0000000..a75760b
--- /dev/null
+++ b/tutorial/examples/rtrefl/RTReflClass.oj
@@ -0,0 +1,247 @@
+/*
+ * RTReflClass.oj
+ *
+ * Oct 29, 1999 by Michiaki Tatsubori
+ */
+package examples.rtrefl;
+
+
+import openjava.mop.*;
+import openjava.ptree.*;
+import openjava.syntax.*;
+
+
+/**
+ * The class <code>RTReflClass</code> is a metaclass which
+ * provides hooks for runtime class metaobject.
+ * <p>
+ * All the fields in the class are hidden instead the readers and
+ * writers methods for fields are provided. Furthermore, accesses
+ * to fields of the class is to be replaced with these methods.
+ * Note that member accesses in its class body are not captured.
+ */
+public class RTReflClass instantiates Metaclass extends OJClass
+{
+ protected static String RTMETAOBJ_FIELD = "mt";
+ protected static Expression METAFIELD_ACCESS
+ = new FieldAccess( RTMETAOBJ_FIELD );
+
+ protected static final String originalMethodName( String name ) {
+ return "org_" + name;
+ }
+
+ protected static final String fieldReaderName( String name ) {
+ return "read_" + name;
+ }
+
+ protected static final String fieldWriterName( String name ) {
+ return "write_" + name;
+ }
+
+ /** Overrides to translate definition */
+ public convenient void translateDefinition() throws MOPException {
+ addInterface( RTMetaLevel.class );
+
+ /* Gets all the declared fields and methods */
+ OJMethod[] methods = getDeclaredMethods();
+ OJField[] fields = getDeclaredFields();
+
+ OJField rtmobj_field
+ = new OJField( this, OJModifier.forModifier( OJModifier.PUBLIC ),
+ RTMetaObject.class, RTMETAOBJ_FIELD );
+ addField( rtmobj_field );
+
+ /* Generates trapping methods for each public method */
+ for (int i = 0; i < methods.length; ++i) {
+ OJModifier modif = methods[i].getModifiers();
+ if (modif.isPublic()) provideMethod( methods[i] );
+ }
+
+ /* Generates wrappers for each public field */
+ for (int i = 0; i < fields.length; ++i) {
+ OJModifier modif = fields[i].getModifiers();
+ if (modif.isPublic()) provideField( fields[i] );
+ }
+ }
+
+ private void provideMethod( OJMethod method ) throws MOPException {
+ System.err.println( "Providing a method : " + method.toString() );
+ OJMethod trapper = OJMethod.makePrototype( method );
+ method.setName( originalMethodName( method.getName() ) );
+ addMethod( trapper );
+
+ /* marshalling and trapping */
+ Expression trapexpr = generateTrappingMethodCall( trapper );
+
+ StatementList body = new StatementList();
+ OJClass retType = trapper.getReturnType();
+ if (retType == OJSystem.VOID) {
+ body.add( new ExpressionStatement( trapexpr ) );
+ } else {
+ Expression unwrapexpr = generateUnwrapping( retType, trapexpr );
+ body.add( new ReturnStatement( unwrapexpr ) );
+ }
+ trapper.setBody( body );
+ }
+
+ private static convenient MethodCall
+ generateTrappingMethodCall( OJMethod method ) throws MOPException {
+ ExpressionList params = method.getParameterVariables();
+ OJClass[] paramTypes = method.getParameterTypes();
+
+ /* wrapping arguments */
+ ExpressionList typeinfo_args = new ExpressionList();
+ ExpressionList args = new ExpressionList();
+ for (int i = 0; i < paramTypes.length; ++i) {
+ typeinfo_args.add( new ClassLiteral( paramTypes[i] ) );
+ args.add( generateWrapping( paramTypes[i], params.get( i ) ));
+ }
+
+ /* marshalling arguments */
+ Expression namearg
+ = Literal.makeLiteral( originalMethodName( method.getName() ) );
+ Expression mrsld_typearg = new ArrayAllocationExpression(
+ java.lang.Class.class, new ExpressionList( null ),
+ new ArrayInitializer( typeinfo_args )
+ );
+ Expression mrsld_arg = new ArrayAllocationExpression(
+ java.lang.Object.class, new ExpressionList( null ),
+ new ArrayInitializer( args )
+ );
+
+ ExpressionList metaargs
+ = new ExpressionList( namearg, mrsld_typearg, mrsld_arg );
+ return new MethodCall( METAFIELD_ACCESS, "trapMethodCall", metaargs );
+ }
+
+ private void provideField( OJField field ) throws MOPException {
+ System.err.println( "Providing a field : " + field.toString() );
+ generateReaderMethod( field );
+ generateWriterMethod( field );
+ }
+
+ /**
+ * int read_l() {
+ * return ((Integer) mt.trapFieldRead("l")).intValue();
+ * }
+ */
+ private void generateReaderMethod( OJField field ) throws MOPException {
+ //Expression trapexpr = makeExpression(
+ // "mt.trapFieldRead(\"" + field.getName() + "\")"
+ //);
+ Expression metafld = new FieldAccess( RTMETAOBJ_FIELD );
+ ExpressionList args = new ExpressionList(
+ Literal.makeLiteral( field.getName() )
+ );
+ Expression trapexpr
+ = new MethodCall( METAFIELD_ACCESS, "trapFieldRead", args );
+ Expression unwrapping
+ = generateUnwrapping( field.getType(), trapexpr );
+ OJMethod reader = new OJMethod( this,
+ field.getModifiers(), field.getType(),
+ fieldReaderName( field.getName() ),
+ (OJClass[]) null, null,
+ new StatementList( new ReturnStatement( unwrapping ) )
+ );
+ addMethod( reader );
+ }
+
+ /**
+ * int write_l(int rvalue) {
+ * mt.trapFieldWrite("l", new Integer(rvalue));
+ * return rvalue;
+ * }
+ */
+ private void generateWriterMethod( OJField field ) throws MOPException {
+ OJMethod writer = new OJMethod( this,
+ field.getModifiers(), field.getType(),
+ fieldWriterName( field.getName() ),
+ new OJClass[]{ field.getType() }, null, null
+ );
+ Expression param = writer.getParameterVariables().get( 0 );
+ //StatementList body = makeStatementList( writer.getEnvironment(),
+ // "mt.trapFieldWrite(\"" + field.getName() + "\");" +
+ // "return " + field.getName() + "=" + param + ";"
+ // );
+ ExpressionList args = new ExpressionList(
+ Literal.makeLiteral( field.getName() ),
+ generateWrapping( field.getType(), param )
+ );
+ Expression trapexpr
+ = new MethodCall( METAFIELD_ACCESS, "trapFieldWrite", args );
+ StatementList body = new StatementList(
+ new ExpressionStatement( trapexpr ),
+ new ReturnStatement( param )
+ );
+ writer.setBody( body );
+ addMethod( writer );
+ }
+
+ /** new Integer(expr) for expr */
+ private static Expression
+ generateWrapping(OJClass realType, Expression expr) {
+ if (! realType.isPrimitive()) return expr;
+ OJClass wrapperType = realType.primitiveWrapper();
+ return new AllocationExpression( wrapperType,
+ new ExpressionList( expr ) );
+ }
+
+ /** ((Integer) expr).intValue() for expr */
+ private static Expression
+ generateUnwrapping(OJClass realType, Expression expr) {
+ expr = new CastExpression( realType.primitiveWrapper(), expr );
+ if (! realType.isPrimitive()) return expr;
+ return new MethodCall( expr, realType.getName() + "Value", null );
+ }
+
+ /* overrides */
+
+ /** Allows references to private fields */
+ public OJField resolveException(NoSuchMemberException e, String name)
+ throws NoSuchMemberException
+ {
+ try {
+ return getDeclaredField( name );
+ } catch ( NoSuchMemberException e2 ) {}
+ return super.resolveException( e, name );
+ }
+
+ /** Overrides to expand fields to be read */
+ public Expression expandFieldRead(
+ Environment env,
+ FieldAccess expr )
+ {
+ if (expr.getName().equals( RTMETAOBJ_FIELD )) return expr;
+ Expression ref = expr.getReferenceExpr();
+ String name = fieldReaderName( expr.getName() );
+ Expression result;
+ if (ref != null) {
+ result = new MethodCall( ref, name, null );
+ } else {
+ result = new MethodCall( expr.getReferenceType(), name, null );
+ }
+ System.err.println( "Patch FR : " + expr + "\tto\t" + result );
+ return result;
+ }
+
+ /** Overrides to expand fields to be written */
+ public Expression expandFieldWrite(
+ Environment env,
+ AssignmentExpression expr )
+ {
+ FieldAccess fldac = (FieldAccess) expr.getLeft();
+ if (fldac.getName().equals( RTMETAOBJ_FIELD )) return expr;
+ ExpressionList args = new ExpressionList( expr.getRight() );
+ Expression ref = fldac.getReferenceExpr();
+ String name = fieldWriterName( fldac.getName() );
+ Expression result;
+ if (ref != null) {
+ result = new MethodCall( ref, name, args );
+ } else {
+ result = new MethodCall( fldac.getReferenceType(), name, args );
+ }
+ System.err.println( "Patch FW : " + expr + "\tto\t" + result );
+ return result;
+ }
+
+}
diff --git a/tutorial/examples/rtrefl/VerboseRTMetaObject.java b/tutorial/examples/rtrefl/VerboseRTMetaObject.java
new file mode 100644
index 0000000..2870eab
--- /dev/null
+++ b/tutorial/examples/rtrefl/VerboseRTMetaObject.java
@@ -0,0 +1,38 @@
+package examples.rtrefl;
+
+
+import java.lang.reflect.*;
+
+
+/**
+ * The class VerboseRTMetaObject
+ * Exception handling is not implemented.
+ */
+public class VerboseRTMetaObject extends RTMetaObject
+{
+ RTMetaLevel baseObj;
+
+ public VerboseRTMetaObject(RTMetaLevel base_obj) {
+ super(base_obj);
+ this.baseObj = base_obj;
+ }
+
+ public Object trapMethodCall(String name, Class[] paramTypes, Object[] args)
+ {
+ System.out.println(baseObj.getClass().getName() + "." +
+ name + "()" + " is called." );
+ return super.trapMethodCall(name, paramTypes, args);
+ }
+
+ public Object trapFieldRead(String name) {
+ System.out.println(baseObj.getClass().getName() + "." +
+ name + " is read." );
+ return super.trapFieldRead(name);
+ }
+
+ public void trapFieldWrite(String name, Object rvalue) {
+ System.out.println(baseObj.getClass().getName() + "." +
+ name + " is written." );
+ super.trapFieldWrite(name, rvalue);
+ }
+}