You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/04/14 00:24:04 UTC

svn commit: r1091959 - /tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java

Author: hlship
Date: Wed Apr 13 22:24:04 2011
New Revision: 1091959

URL: http://svn.apache.org/viewvc?rev=1091959&view=rev
Log:
TAP5-853: Strip out the remaining old-style ClassFactory code

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java?rev=1091959&r1=1091958&r2=1091959&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java Wed Apr 13 22:24:04 2011
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008, 2009, 2010 The Apache Software Foundation
+// Copyright 2007, 2008, 2009, 2010, 2011 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -35,11 +35,9 @@ import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 import org.antlr.runtime.ANTLRInputStream;
@@ -56,9 +54,6 @@ import org.apache.tapestry5.ioc.internal
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.GenericsUtils;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.services.ClassFab;
-import org.apache.tapestry5.ioc.services.ClassFabUtils;
-import org.apache.tapestry5.ioc.services.ClassFactory;
 import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
 import org.apache.tapestry5.ioc.services.MethodSignature;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
@@ -66,7 +61,6 @@ import org.apache.tapestry5.ioc.services
 import org.apache.tapestry5.ioc.services.PropertyAdapter;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.ioc.util.AvailableValues;
-import org.apache.tapestry5.ioc.util.BodyBuilder;
 import org.apache.tapestry5.ioc.util.UnknownValueException;
 import org.apache.tapestry5.plastic.Condition;
 import org.apache.tapestry5.plastic.InstructionBuilder;
@@ -88,12 +82,6 @@ public class PropertyConduitSourceImpl i
     private static final MethodDescription SET = getMethodDescription(PropertyConduit.class, "set", Object.class,
             Object.class);
 
-    private static final MethodSignature GET_SIGNATURE = new MethodSignature(Object.class, "get", new Class[]
-    { Object.class }, null);
-
-    private static final MethodSignature SET_SIGNATURE = new MethodSignature(void.class, "set", new Class[]
-    { Object.class, Object.class }, null);
-
     private static final MethodDescription GET_ANNOTATION = getMethodDescription(AnnotationProvider.class,
             "getAnnotation", Class.class);
 
@@ -148,37 +136,6 @@ public class PropertyConduitSourceImpl i
 
     private final AnnotationProvider nullAnnotationProvider = new NullAnnotationProvider();
 
-    private static class ConstructorParameter
-    {
-        private final String fieldName;
-
-        private final Class type;
-
-        private final Object value;
-
-        ConstructorParameter(String fieldName, Class type, Object value)
-        {
-            this.fieldName = fieldName;
-            this.type = type;
-            this.value = value;
-        }
-
-        public String getFieldName()
-        {
-            return fieldName;
-        }
-
-        public Class getType()
-        {
-            return type;
-        }
-
-        public Object getValue()
-        {
-            return value;
-        }
-    }
-
     /**
      * Describes all the gory details of one term (one property or method
      * invocation) from within the expression.
@@ -254,29 +211,18 @@ public class PropertyConduitSourceImpl i
         IGNORE
     }
 
-    private class GeneratedTerm
+    /**
+     * One term in an expression. Expressions start with some root type and each term advances
+     * to a new type.
+     */
+    private class PlasticTerm
     {
-        final Type type;
-
-        final String termReference;
-
         /**
-         * @param type
-         *            type of variable
-         * @param termReference
-         *            name of variable, or a constant value
+         * The generic type of the term.
          */
-        private GeneratedTerm(Type type, String termReference)
-        {
-            this.type = type;
-            this.termReference = termReference;
-        }
-    }
-
-    private class PlasticTerm
-    {
         final Type type;
 
+        /** Callback that will implement the term. */
         final InstructionBuilderCallback callback;
 
         PlasticTerm(Type type, InstructionBuilderCallback callback)
@@ -288,8 +234,6 @@ public class PropertyConduitSourceImpl i
 
     private final PropertyAccess access;
 
-    private final ClassFactory classFactory;
-
     private final PlasticProxyFactory proxyFactory;
 
     private final TypeCoercer typeCoercer;
@@ -297,13 +241,6 @@ public class PropertyConduitSourceImpl i
     private final StringInterner interner;
 
     /**
-     * Because of stuff like Hibernate, we sometimes start with a subclass in
-     * some inaccessible class loader and need to
-     * work up to a base class from a common class loader.
-     */
-    private final Map<Class, Class> classToEffectiveClass = CollectionFactory.newConcurrentMap();
-
-    /**
      * Keyed on combination of root class and expression.
      */
     private final Map<MultiKey, PropertyConduit> cache = CollectionFactory.newConcurrentMap();
@@ -335,14 +272,12 @@ public class PropertyConduitSourceImpl i
 
     /**
      * Encapsulates the process of building a PropertyConduit instance from an
-     * expression.
+     * expression, as an {@link PlasticClassTransformer}.
      */
     class PropertyConduitBuilder implements PlasticClassTransformer
     {
         private final Class rootType;
 
-        private final ClassFab classFab;
-
         private final String expression;
 
         private final Tree tree;
@@ -353,14 +288,6 @@ public class PropertyConduitSourceImpl i
 
         private AnnotationProvider annotationProvider = nullAnnotationProvider;
 
-        // Used to create unique variable names.
-
-        private int variableIndex = 0;
-
-        private final List<ConstructorParameter> parameters = CollectionFactory.newList();
-
-        private final BodyBuilder navBuilder = new BodyBuilder();
-
         private PlasticField delegateField;
 
         private PlasticClass plasticClass;
@@ -372,10 +299,6 @@ public class PropertyConduitSourceImpl i
             this.rootType = rootType;
             this.expression = expression;
             this.tree = tree;
-
-            String name = ClassFabUtils.generateClassName("PropertyConduit");
-
-            this.classFab = classFactory.newClass(name, PropertyConduitDelegate.class);
         }
 
         public void transform(PlasticClass plasticClass)
@@ -387,20 +310,22 @@ public class PropertyConduitSourceImpl i
             // Create the various methods; also determine the conduit's property type, property name and identify
             // the annotation provider.
 
-            createPlasticAccessors();
+            implementNavMethodAndAccessors();
 
-            addDelegateMethods();
+            implementDelegateMethods();
 
             plasticClass.addToString(String.format("PropertyConduit[%s %s]", rootType.getName(), expression));
         }
 
-        private void addDelegateMethods()
+        private void implementDelegateMethods()
         {
             PropertyConduitDelegate delegate = new PropertyConduitDelegate(conduitPropertyType, conduitPropertyName,
                     annotationProvider, typeCoercer);
 
             delegateField.inject(delegate);
 
+            // TODO: These can easily be injected into the proxy, and not require delegate access.
+
             plasticClass.introduceMethod(GET_ANNOTATION).delegateTo(delegateField);
             plasticClass.introduceMethod(GET_PROPERTY_TYPE).delegateTo(delegateField);
             plasticClass.introduceMethod(GET_PROPERTY_NAME).delegateTo(delegateField);
@@ -410,7 +335,7 @@ public class PropertyConduitSourceImpl i
          * Creates a method that does a conversion from Object to the expected root type, with
          * a null check.
          */
-        private void createPlasticGetRoot()
+        private void implementGetRoot()
         {
             getRootMethod = plasticClass.introducePrivateMethod(PlasticUtils.toTypeName(rootType), "getRoot",
                     SINGLE_OBJECT_ARGUMENT, null);
@@ -433,87 +358,6 @@ public class PropertyConduitSourceImpl i
             });
         }
 
-        PropertyConduit createInstance()
-        {
-            createAccessors();
-
-            Object[] parameters = createConstructor();
-
-            Class conduitClass = classFab.createClass();
-
-            try
-            {
-                return (PropertyConduit) conduitClass.getConstructors()[0].newInstance(parameters);
-            }
-            catch (Exception ex)
-            {
-                throw new RuntimeException(ex);
-            }
-        }
-
-        private Object[] createConstructor()
-        {
-            List<Class> types = CollectionFactory.newList();
-
-            // $1, $2, $3, $4, $5 ...
-
-            types.add(Class.class);
-            types.add(String.class);
-            types.add(AnnotationProvider.class);
-            types.add(String.class);
-            types.add(TypeCoercer.class);
-
-            List<Object> values = CollectionFactory.newList();
-
-            values.add(conduitPropertyType);
-            values.add(conduitPropertyName);
-            values.add(annotationProvider);
-            values.add(interner.format("PropertyConduit[%s %s]", rootType.getName(), expression));
-            values.add(typeCoercer);
-
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            builder.addln("super($1,$2,$3,$4,$5);");
-
-            int index = 6;
-
-            for (ConstructorParameter p : parameters)
-            {
-                types.add(p.getType());
-                values.add(p.getValue());
-
-                builder.addln("%s = $%d;", p.getFieldName(), index++);
-            }
-
-            builder.end();
-
-            Class[] arrayOfTypes = types.toArray(new Class[0]);
-
-            classFab.addConstructor(arrayOfTypes, null, builder.toString());
-
-            return values.toArray();
-        }
-
-        private String addInjection(Class fieldType, Object fieldValue)
-        {
-            String fieldName = String.format("injected_%s_%d", toSimpleName(fieldType), parameters.size());
-
-            classFab.addField(fieldName, Modifier.PRIVATE | Modifier.FINAL, fieldType);
-
-            parameters.add(new ConstructorParameter(fieldName, fieldType, fieldValue));
-
-            return fieldName;
-        }
-
-        private void createNoOp(ClassFab classFab, MethodSignature signature, String format, Object... values)
-        {
-            String message = String.format(format, values);
-
-            String body = String.format("throw new RuntimeException(\"%s\");", message);
-
-            classFab.addMethod(Modifier.PUBLIC, signature, body);
-        }
-
         private boolean isLeaf(Tree node)
         {
             int type = node.getType();
@@ -521,34 +365,9 @@ public class PropertyConduitSourceImpl i
             return type != DEREF && type != SAFEDEREF;
         }
 
-        private void createGetRoot()
+        private void implementNavMethodAndAccessors()
         {
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            builder.addln("%s root = (%<s) $1;", ClassFabUtils.toJavaClassName(rootType));
-
-            builder.addln(
-                    "if (root == null) throw new NullPointerException(\"Root object of property expression '%s' is null.\");",
-                    expression);
-
-            builder.addln("return root;");
-
-            builder.end();
-
-            MethodSignature sig = new MethodSignature(rootType, "getRoot", new Class[]
-            { Object.class }, null);
-
-            classFab.addMethod(Modifier.PRIVATE, sig, builder.toString());
-        }
-
-        private void addRootVariable(BodyBuilder builder)
-        {
-            builder.addln("%s root = getRoot($1);", ClassFabUtils.toJavaClassName(rootType));
-        }
-
-        private void createPlasticAccessors()
-        {
-            createPlasticGetRoot();
+            implementGetRoot();
 
             // First, create the navigate method.
 
@@ -594,47 +413,10 @@ public class PropertyConduitSourceImpl i
                 }
             });
 
-            createPlasticGetterAndSetter(activeClass, node);
-        }
-
-        private void createAccessors()
-        {
-            createGetRoot();
-
-            navBuilder.begin();
-
-            String previousReference = "$1";
-            Type activeType = rootType;
-
-            Tree node = tree;
-
-            while (!isLeaf(node))
-            {
-                GeneratedTerm term = processDerefNode(navBuilder, activeType, node, previousReference, "$1");
-
-                activeType = term.type;
-
-                previousReference = term.termReference;
-
-                // Second term is the continuation, possibly another chained
-                // DEREF, etc.
-                node = node.getChild(1);
-            }
-
-            navBuilder.addln("return %s;", previousReference);
-
-            navBuilder.end();
-            Class activeClass = GenericsUtils.asClass(activeType);
-
-            MethodSignature sig = new MethodSignature(activeClass, "navigate", new Class[]
-            { rootType }, null);
-
-            classFab.addMethod(Modifier.PRIVATE, sig, navBuilder.toString());
-
-            createGetterAndSetter(activeClass, sig, node);
+            implementAccessors(activeClass, node);
         }
 
-        private void createPlasticGetterAndSetter(Class activeType, Tree node)
+        private void implementAccessors(Class activeType, Tree node)
         {
             switch (node.getType())
             {
@@ -649,67 +431,8 @@ public class PropertyConduitSourceImpl i
 
                     ExpressionTermInfo info = infoForMember(activeType, node);
 
-                    createPlasticSetter(activeType, info);
-                    createPlasticGetter(activeType, info, node);
-
-                    conduitPropertyType = GenericsUtils.asClass(info.getType());
-                    conduitPropertyName = info.getPropertyName();
-                    annotationProvider = info;
-
-                    return;
-
-                case RANGEOP:
-
-                    // As currently implemented, RANGEOP can only appear as the
-                    // top level, which
-                    // means we didn't need the navigate method after all.
-
-                    createPlasticRangeOpGetter(node);
-                    createPlasticNoOpSetter();
-
-                    conduitPropertyType = IntegerRange.class;
-
-                    return;
-
-                case LIST:
-
-                    createPlasticListGetter(node);
-                    createPlasticNoOpSetter();
-
-                    conduitPropertyType = List.class;
-
-                    return;
-
-                case NOT:
-                    createPlasticNotOpGetter(node);
-                    createPlasticNoOpSetter();
-
-                    conduitPropertyType = boolean.class;
-
-                    return;
-
-                default:
-                    throw unexpectedNodeType(node, IDENTIFIER, INVOKE, RANGEOP, LIST, NOT);
-            }
-        }
-
-        private void createGetterAndSetter(Class activeType, MethodSignature navigateMethod, Tree node)
-        {
-            switch (node.getType())
-            {
-                case IDENTIFIER:
-                case INVOKE:
-
-                    // So, a this point, we have the navigation method written
-                    // and it covers all but the terminal
-                    // de-reference. node is an IDENTIFIER or INVOKE. We're
-                    // ready to use the navigation
-                    // method to implement get() and set().
-
-                    ExpressionTermInfo info = infoForMember(activeType, node);
-
-                    createSetter(navigateMethod, info);
-                    createGetter(navigateMethod, node, info);
+                    implementSetter(activeType, info);
+                    implementGetter(activeType, info, node);
 
                     conduitPropertyType = GenericsUtils.asClass(info.getType());
                     conduitPropertyName = info.getPropertyName();
@@ -723,8 +446,8 @@ public class PropertyConduitSourceImpl i
                     // top level, which
                     // means we didn't need the navigate method after all.
 
-                    createRangeOpGetter(node, "root");
-                    createNoOpSetter();
+                    implementRangeOpGetter(node);
+                    implementNoOpSetter();
 
                     conduitPropertyType = IntegerRange.class;
 
@@ -732,16 +455,16 @@ public class PropertyConduitSourceImpl i
 
                 case LIST:
 
-                    createListGetter(node, "root");
-                    createNoOpSetter();
+                    implementListGetter(node);
+                    implementNoOpSetter();
 
                     conduitPropertyType = List.class;
 
                     return;
 
                 case NOT:
-                    createNotOpGetter(node, "root");
-                    createNoOpSetter();
+                    implementNotOpGetter(node);
+                    implementNoOpSetter();
 
                     conduitPropertyType = boolean.class;
 
@@ -752,7 +475,7 @@ public class PropertyConduitSourceImpl i
             }
         }
 
-        private void createPlasticRangeOpGetter(final Tree rangeNode)
+        private void implementRangeOpGetter(final Tree rangeNode)
         {
             plasticClass.introduceMethod(GET, new InstructionBuilderCallback()
             {
@@ -769,29 +492,11 @@ public class PropertyConduitSourceImpl i
             });
         }
 
-        private Object foo(PropertyConduitDelegate d)
-        {
-            return d.range(1, 99);
-        }
-
-        private void createRangeOpGetter(Tree node, String rootName)
-        {
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            addRootVariable(builder);
-
-            builder.addln("return %s;", createMethodInvocation(builder, node, rootName, 0, DelegateMethods.RANGE));
-
-            builder.end();
-
-            classFab.addMethod(Modifier.PUBLIC, GET_SIGNATURE, builder.toString());
-        }
-
         /**
          * @param node
          *            subexpression to invert
          */
-        private void createPlasticNotOpGetter(final Tree node)
+        private void implementNotOpGetter(final Tree node)
         {
             // Implement get() as navigate, then do a method invocation based on node
             // then, then pass (wrapped) result to delegate.invert()
@@ -800,7 +505,7 @@ public class PropertyConduitSourceImpl i
             {
                 public void doBuild(InstructionBuilder builder)
                 {
-                    Class expressionType = buildPlasticNotExpression(builder, node);
+                    Class expressionType = implementNotExpression(builder, node);
 
                     // Yes, we know this will always be the case, for now.
 
@@ -822,7 +527,18 @@ public class PropertyConduitSourceImpl i
             builder.dupe().when(Condition.NULL, RETURN_NULL);
         }
 
-        private Class buildSubexpression(InstructionBuilder builder, Class activeType, Tree node)
+        /**
+         * Uses the builder to add instructions for a subexpression.
+         * 
+         * @param builder
+         *            used to add instructions
+         * @param activeType
+         *            type of value on top of the stack when this code will execute, or null if no value on stack
+         * @param node
+         *            defines the expression
+         * @return the expression type
+         */
+        private Class implementSubexpression(InstructionBuilder builder, Class activeType, Tree node)
         {
             while (node != null)
             {
@@ -889,11 +605,11 @@ public class PropertyConduitSourceImpl i
 
                     case LIST:
 
-                        return createPlasticListConstructor(builder, node);
+                        return implementListConstructor(builder, node);
 
                     case NOT:
 
-                        return buildPlasticNotExpression(builder, node);
+                        return implementNotExpression(builder, node);
 
                     default:
                         throw unexpectedNodeType(node, TRUE, FALSE, INTEGER, DECIMAL, STRING, DEREF, SAFEDEREF,
@@ -909,33 +625,20 @@ public class PropertyConduitSourceImpl i
             builder.loadThis().loadArgument(0).invokeVirtual(getRootMethod);
         }
 
-        private void createNotOpGetter(Tree node, String rootName)
-        {
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            addRootVariable(builder);
-
-            builder.addln("return ($w) %s;", createMethodInvocation(builder, node, rootName, 0, DelegateMethods.INVERT));
-
-            builder.end();
-
-            classFab.addMethod(Modifier.PUBLIC, GET_SIGNATURE, builder.toString());
-        }
-
-        private void createPlasticListGetter(final Tree listNode)
+        private void implementListGetter(final Tree listNode)
         {
             plasticClass.introduceMethod(GET, new InstructionBuilderCallback()
             {
                 public void doBuild(InstructionBuilder builder)
                 {
-                    createPlasticListConstructor(builder, listNode);
+                    implementListConstructor(builder, listNode);
 
                     builder.returnResult();
                 }
             });
         }
 
-        private Class createPlasticListConstructor(InstructionBuilder builder, Tree listNode)
+        private Class implementListConstructor(InstructionBuilder builder, Tree listNode)
         {
             // First, create an empty instance of ArrayList
 
@@ -948,7 +651,7 @@ public class PropertyConduitSourceImpl i
             {
                 builder.dupe(); // the ArrayList
 
-                Class expressionType = buildSubexpression(builder, null, listNode.getChild(i));
+                Class expressionType = implementSubexpression(builder, null, listNode.getChild(i));
 
                 boxIfPrimitive(builder, expressionType);
 
@@ -959,174 +662,13 @@ public class PropertyConduitSourceImpl i
             return ArrayList.class;
         }
 
-        private void createListGetter(Tree node, String rootName)
-        {
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            addRootVariable(builder);
-
-            builder.addln("return %s;", createListConstructor(builder, node, rootName));
-
-            builder.end();
-
-            classFab.addMethod(Modifier.PUBLIC, GET_SIGNATURE, builder.toString());
-        }
-
-        private String createListConstructor(BodyBuilder builder, Tree node, String rootName)
-        {
-            String listName = nextVariableName(List.class);
-
-            int count = node.getChildCount();
-
-            builder.addln("java.util.List %s = new java.util.ArrayList(%d);", listName, count);
-
-            for (int i = 0; i < count; i++)
-            {
-                GeneratedTerm generatedTerm = subexpression(builder, node.getChild(i), rootName);
-
-                builder.addln("%s.add(($w) %s);", listName, generatedTerm.termReference);
-            }
-
-            return listName;
-        }
-
-        private String createNotOp(BodyBuilder builder, Tree node, String rootName)
-        {
-            String flagName = nextVariableName(Boolean.class);
-            GeneratedTerm term = subexpression(builder, node.getChild(0), rootName);
-
-            builder.addln("boolean %s = invert(($w) %s);", flagName, term.termReference);
-
-            return flagName;
-        }
-
-        /**
-         * Evalutates the node as a sub expression, storing the result into a
-         * new variable, whose name is returned.
-         * 
-         * @param builder
-         *            to receive generated code
-         * @param node
-         *            root of tree of nodes to be evaluated
-         * @param rootName
-         *            name of variable holding reference to root object of
-         *            expression
-         * @return GeneratedTerm identifying the name of the variable and its
-         *         type
-         */
-        private GeneratedTerm subexpression(BodyBuilder builder, Tree node, String rootName)
-        {
-            String previousReference = rootName;
-            Class activeType = rootType;
-
-            while (node != null)
-            {
-                switch (node.getType())
-                {
-                    case TRUE:
-                    case FALSE:
-
-                        previousReference = node.getType() == TRUE ? "true" : "false";
-                        activeType = boolean.class;
-
-                        node = null;
-                        break;
-
-                    case INTEGER:
-
-                        long integerValue = Long.parseLong(node.getText());
-
-                        previousReference = String.format("%dL", integerValue);
-                        activeType = long.class;
-
-                        node = null;
-
-                        break;
-
-                    case DECIMAL:
-
-                        double decimalValue = Double.parseDouble(node.getText());
-
-                        previousReference = String.format(Locale.ENGLISH, "%fd", decimalValue);
-                        activeType = double.class;
-
-                        node = null;
-
-                        break;
-
-                    case STRING:
-
-                        String stringValue = node.getText();
-                        // Injecting is easier; don't have to fuss with escaping
-                        // quotes or such.
-                        previousReference = addInjection(String.class, stringValue);
-                        activeType = String.class;
-
-                        node = null;
-
-                        break;
-
-                    case DEREF:
-                    case SAFEDEREF:
-
-                        GeneratedTerm generated = processDerefNode(builder, activeType, node, previousReference,
-                                rootName);
-
-                        previousReference = generated.termReference;
-                        activeType = GenericsUtils.asClass(generated.type);
-
-                        node = node.getChild(1);
-
-                        break;
-
-                    case IDENTIFIER:
-                    case INVOKE:
-
-                        generated = addAccessForMember(builder, activeType, node, previousReference, rootName,
-                                NullHandling.IGNORE);
-
-                        previousReference = generated.termReference;
-                        activeType = GenericsUtils.asClass(generated.type);
-                        if (activeType.isPrimitive())
-                            activeType = ClassFabUtils.getWrapperType(activeType);
-                        node = null;
-
-                        break;
-
-                    case NOT:
-
-                        previousReference = createNotOp(builder, node, rootName);
-                        activeType = boolean.class;
-
-                        node = null;
-
-                        break;
-
-                    case LIST:
-
-                        previousReference = createListConstructor(builder, node, rootName);
-                        activeType = List.class;
-
-                        node = null;
-
-                        break;
-
-                    default:
-                        throw unexpectedNodeType(node, TRUE, FALSE, INTEGER, DECIMAL, STRING, DEREF, SAFEDEREF,
-                                IDENTIFIER, INVOKE, LIST);
-                }
-            }
-
-            return new GeneratedTerm(activeType, previousReference);
-        }
-
-        private void createPlasticSetter(final Class activeType, final ExpressionTermInfo info)
+        private void implementSetter(final Class activeType, final ExpressionTermInfo info)
         {
             final Method method = info.getWriteMethod();
 
             if (method == null && !info.isField())
             {
-                createPlasticNoOpSetter();
+                implementNoOpSetter();
                 return;
             }
 
@@ -1156,57 +698,12 @@ public class PropertyConduitSourceImpl i
             });
         }
 
-        private void createSetter(MethodSignature navigateMethod, ExpressionTermInfo info)
+        private void implementNoOpSetter()
         {
-            // A write method will only be identified if the info is a writable
-            // property.
-            // Other alternatives: a method as the final term, or a read-only
-            // property.
-
-            Method method = info.getWriteMethod();
-
-            if (method == null && !info.isField())
-            {
-                createNoOpSetter();
-                return;
-            }
-
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            addRootVariable(builder);
-
-            builder.addln("%s target = navigate(root);", ClassFabUtils.toJavaClassName(navigateMethod.getReturnType()));
-
-            // I.e. due to ?. operator. The navigate method will already have
-            // checked for nulls
-            // if they are not allowed.
-
-            builder.addln("if (target == null) return;");
-
-            String propertyTypeName = ClassFabUtils.toJavaClassName(GenericsUtils.asClass(info.getType()));
-
-            String reference = ClassFabUtils.castReference("$2", propertyTypeName);
-
-            if (info.isField())
-            {
-                builder.add("target.%s = %s;", info.getPropertyName(), reference);
-            }
-            else
-            {
-                builder.addln("target.%s(%s);", method.getName(), reference);
-            }
-
-            builder.end();
-
-            classFab.addMethod(Modifier.PUBLIC, SET_SIGNATURE, builder.toString());
-        }
-
-        private void createPlasticNoOpSetter()
-        {
-            createNoOpMethod(SET, "Expression '%s' for class %s is read-only.", expression, rootType.getName());
+            implementNoOpMethod(SET, "Expression '%s' for class %s is read-only.", expression, rootType.getName());
         }
 
-        public void createNoOpMethod(MethodDescription method, String format, Object... arguments)
+        public void implementNoOpMethod(MethodDescription method, String format, Object... arguments)
         {
             final String message = String.format(format, arguments);
 
@@ -1219,14 +716,8 @@ public class PropertyConduitSourceImpl i
             });
         }
 
-        private void createNoOpSetter()
-        {
-            createNoOp(classFab, SET_SIGNATURE, "Expression '%s' for class %s is read-only.", expression,
-                    rootType.getName());
-        }
-
         /**
-         * Creates the get() method, using the navigate method.
+         * Implements the get() method, using the navigate method.
          * 
          * @param activeType
          *            the type containing the property to read (may be the root type for simple
@@ -1234,11 +725,11 @@ public class PropertyConduitSourceImpl i
          * @param info
          *            describes the property to read
          */
-        private void createPlasticGetter(final Class activeType, final ExpressionTermInfo info, final Tree node)
+        private void implementGetter(final Class activeType, final ExpressionTermInfo info, final Tree node)
         {
             if (info.getReadMethod() == null && !info.isField())
             {
-                createNoOpMethod(GET, "Expression %s for class %s is write-only.", expression, rootType.getName());
+                implementNoOpMethod(GET, "Expression %s for class %s is write-only.", expression, rootType.getName());
                 return;
             }
 
@@ -1313,7 +804,7 @@ public class PropertyConduitSourceImpl i
 
             for (int i = 0; i < parameterTypes.length; i++)
             {
-                Class expressionType = buildSubexpression(builder, null, node.getChild(i + childOffset));
+                Class expressionType = implementSubexpression(builder, null, node.getChild(i + childOffset));
 
                 // The value left on the stack is not primitive, and expressionType represents
                 // its real type.
@@ -1351,144 +842,9 @@ public class PropertyConduitSourceImpl i
                     method.getParameterTypes());
         }
 
-        private void createGetter(MethodSignature navigateMethod, Tree node, ExpressionTermInfo info)
-        {
-            Method method = info.getReadMethod();
-
-            if (method == null && !info.isField())
-            {
-                createNoOp(classFab, GET_SIGNATURE, "Expression %s for class %s is write-only.", expression,
-                        rootType.getName());
-                return;
-            }
-
-            BodyBuilder builder = new BodyBuilder().begin();
-
-            addRootVariable(builder);
-
-            builder.addln("%s target = navigate(root);", ClassFabUtils.toJavaClassName(navigateMethod.getReturnType()));
-
-            // I.e. due to ?. operator. The navigate method will already have
-            // checked for nulls
-            // if they are not allowed.
-
-            builder.addln("if (target == null) return null;");
-
-            String reference = info.isField() ? info.getPropertyName() : createMethodInvocation(builder, node, "root",
-                    method);
-
-            builder.addln("return ($w) target.%s;", reference);
-
-            builder.end();
-
-            classFab.addMethod(Modifier.PUBLIC, GET_SIGNATURE, builder.toString());
-        }
-
-        /**
-         * Creates a method invocation call for the given node (an INVOKE node).
-         * 
-         * @param bodyBuilder
-         *            may receive new code to define variables for some
-         *            sub-expressions
-         * @param node
-         *            the INVOKE node; child #1 and up are parameter expressions
-         *            to the method being invoked
-         * @param rootName
-         *            name of variable holding reference to root object of
-         *            expression
-         * @param method
-         *            defines the name and parameter types of the method to
-         *            invoke
-         * @return method invocation string (the name of the method and any
-         *         parameters, ready to be added to a method
-         *         body)
-         */
-        private String createMethodInvocation(BodyBuilder bodyBuilder, Tree node, String rootName, Method method)
-        {
-            return createMethodInvocation(bodyBuilder, node, rootName, 1, method);
-        }
-
         /**
-         * Creates a method invocation call for the given node
-         * 
-         * @param bodyBuilder
-         *            may receive new code to define variables for some
-         *            sub-expressions
-         * @param node
-         *            the node containing child nodes for the parameters
-         * @param rootName
-         *            name of variable holding reference to root object of
-         *            expression
-         * @param childOffset
-         *            the offset to the first parameter (for example, this is 1
-         *            for an INVOKE node)
-         * @param method
-         *            defines the name and parameter types of the method to
-         *            invoke
-         * @return method invocation string (the name of the method and any
-         *         parameters, ready to be added to a method
-         *         body)
-         */
-        private String createMethodInvocation(BodyBuilder bodyBuilder, Tree node, String rootName, int childOffset,
-                Method method)
-        {
-            Class[] parameterTypes = method.getParameterTypes();
-
-            StringBuilder builder = new StringBuilder();
-
-            builder.append(method.getName());
-            builder.append("(");
-
-            for (int i = 0; i < parameterTypes.length; i++)
-            {
-                // child(0) is the method name, child(1) is the first parameter,
-                // etc.
-
-                GeneratedTerm generatedTerm = subexpression(bodyBuilder, node.getChild(i + childOffset), rootName);
-                String currentReference = generatedTerm.termReference;
-
-                Class actualType = GenericsUtils.asClass(generatedTerm.type);
-
-                Class parameterType = parameterTypes[i];
-
-                boolean needsUnwrap = false;
-
-                if (!parameterType.isAssignableFrom(actualType))
-                {
-                    String coerced = nextVariableName(parameterType);
-
-                    String call = String.format("coerce(($w) %s, %s)", currentReference,
-                            addInjection(Class.class, parameterType));
-
-                    String parameterTypeName = ClassFabUtils.toJavaClassName(parameterType);
-
-                    bodyBuilder.addln("%s %s = %s;", parameterTypeName, coerced,
-                            ClassFabUtils.castReference(call, parameterTypeName));
-
-                    currentReference = coerced;
-                }
-                else
-                {
-                    needsUnwrap = parameterType.isPrimitive() && !actualType.isPrimitive();
-                }
-
-                if (i > 0)
-                    builder.append(", ");
-
-                builder.append(currentReference);
-
-                if (needsUnwrap)
-                {
-                    builder.append(".").append(ClassFabUtils.getUnwrapMethodName(parameterType)).append("()");
-                }
-            }
-
-            return builder.append(")").toString();
-        }
-
-        /**
-         * Extends the navigate method for a node, which will be a DEREF or
-         * SAFEDERF.
+         * Analyzes a DEREF or SAFEDEREF node, proving back a term that identifies its type and provides a callback to
+         * peform the dereference.
          * 
          * @return a term indicating the type of the expression to this point, and a {@link InstructionBuilderCallback}
          *         to advance the evaluation of the expression form the previous value to the current
@@ -1504,50 +860,6 @@ public class PropertyConduitSourceImpl i
             return buildTerm(activeType, term, allowNull ? NullHandling.ALLOW : NullHandling.FORBID);
         }
 
-        /**
-         * Extends the navigate method for a node, which will be a DEREF or
-         * SAFEDERF.
-         */
-        private GeneratedTerm processDerefNode(BodyBuilder builder, Type activeType, Tree node,
-                String previousVariableName, String rootName)
-        {
-            // The first child is the term.
-
-            Tree term = node.getChild(0);
-
-            boolean allowNull = node.getType() == SAFEDEREF;
-
-            // Returns the type of the method/property ... this is the wrapped
-            // (i.e. java.lang.Integer) type if
-            // the real type is primitive. It also reflects generics information
-            // that may have been associated
-            // with the underlying method.
-
-            return addAccessForMember(builder, activeType, term, previousVariableName, rootName,
-                    allowNull ? NullHandling.ALLOW : NullHandling.FORBID);
-        }
-
-        private String nextVariableName(Class type)
-        {
-            return String.format("var_%s_%d", toSimpleName(type), variableIndex++);
-        }
-
-        private String toSimpleName(Class type)
-        {
-            if (type.isArray())
-            {
-                Class<?> componentType = type.getComponentType();
-
-                while (componentType.isArray())
-                {
-                    componentType = componentType.getComponentType();
-                }
-
-                return InternalUtils.lastTerm(componentType.getName()) + "_array";
-            }
-            return InternalUtils.lastTerm(type.getName());
-        }
-
         private PlasticTerm buildTerm(Type activeType, final Tree term, final NullHandling nullHandling)
         {
             assertNodeType(term, IDENTIFIER, INVOKE);
@@ -1626,70 +938,6 @@ public class PropertyConduitSourceImpl i
             return new PlasticTerm(termType, callback);
         }
 
-        private GeneratedTerm addAccessForMember(BodyBuilder builder, Type activeType, Tree term,
-                String previousVariableName, String rootName, NullHandling nullHandling)
-        {
-            assertNodeType(term, IDENTIFIER, INVOKE);
-
-            // Get info about this property or method.
-
-            final ExpressionTermInfo info = infoForMember(activeType, term);
-
-            final Method method = info.getReadMethod();
-            final Class activeClass = GenericsUtils.asClass(activeType);
-            if (method == null && !info.isField())
-                throw new RuntimeException(String.format(
-                        "Property '%s' of class %s is not readable (it has no read accessor method).",
-                        info.getDescription(), activeClass.getName()));
-
-            Type termType = info.getType();
-
-            Class termClass = GenericsUtils.asClass(termType);
-
-            final Class wrappedType = ClassFabUtils.getWrapperType(termClass);
-
-            String wrapperTypeName = ClassFabUtils.toJavaClassName(wrappedType);
-
-            final String variableName = nextVariableName(wrappedType);
-
-            String reference = info.isField() ? info.getPropertyName() : createMethodInvocation(builder, term,
-                    rootName, method);
-
-            builder.add("%s %s = ", wrapperTypeName, variableName);
-
-            // Casts are needed for primitives, and for the case where
-            // generics are involved.
-
-            if (termClass.isPrimitive())
-            {
-                builder.add(" ($w) ");
-            }
-            else if (info.isCastRequired())
-            {
-                builder.add(" (%s) ", wrapperTypeName);
-            }
-
-            builder.addln("%s.%s;", previousVariableName, reference);
-
-            switch (nullHandling)
-            {
-                case ALLOW:
-                    builder.addln("if (%s == null) return null;", variableName);
-                    break;
-
-                case FORBID:
-                    // Perform a null check on intermediate terms.
-                    builder.addln("if (%s == null) %s.nullTerm(\"%s\", \"%s\", $1);", variableName,
-                            PropertyConduitSourceImpl.class.getName(), info.getDescription(), expression);
-                    break;
-
-                default:
-                    break;
-            }
-
-            return new GeneratedTerm(termType, variableName);
-        }
-
         private void assertNodeType(Tree node, int... expected)
         {
             int type = node.getType();
@@ -1904,9 +1152,9 @@ public class PropertyConduitSourceImpl i
                 builder.boxPrimitive(termType.getName());
         }
 
-        public Class buildPlasticNotExpression(InstructionBuilder builder, final Tree notNode)
+        public Class implementNotExpression(InstructionBuilder builder, final Tree notNode)
         {
-            Class expressionType = buildSubexpression(builder, null, notNode.getChild(0));
+            Class expressionType = implementSubexpression(builder, null, notNode.getChild(0));
 
             boxIfPrimitive(builder, expressionType);
 
@@ -1921,11 +1169,9 @@ public class PropertyConduitSourceImpl i
     }
 
     public PropertyConduitSourceImpl(PropertyAccess access, @ComponentLayer
-    ClassFactory classFactory, @ComponentLayer
     PlasticProxyFactory proxyFactory, TypeCoercer typeCoercer, StringInterner interner)
     {
         this.access = access;
-        this.classFactory = classFactory;
         this.proxyFactory = proxyFactory;
         this.typeCoercer = typeCoercer;
         this.interner = interner;
@@ -1939,35 +1185,20 @@ public class PropertyConduitSourceImpl i
     {
         assert rootClass != null;
         assert InternalUtils.isNonBlank(expression);
-        Class effectiveClass = toEffectiveClass(rootClass);
 
-        MultiKey key = new MultiKey(effectiveClass, expression);
+        MultiKey key = new MultiKey(rootClass, expression);
 
         PropertyConduit result = cache.get(key);
 
         if (result == null)
         {
-            result = build(effectiveClass, expression);
+            result = build(rootClass, expression);
             cache.put(key, result);
         }
 
         return result;
     }
 
-    private Class toEffectiveClass(Class rootClass)
-    {
-        Class result = classToEffectiveClass.get(rootClass);
-
-        if (result == null)
-        {
-            result = classFactory.importClass(rootClass);
-
-            classToEffectiveClass.put(rootClass, result);
-        }
-
-        return result;
-    }
-
     /**
      * Clears its caches when the component class loader is invalidated; this is
      * because it will be common to generate
@@ -1978,7 +1209,6 @@ public class PropertyConduitSourceImpl i
     public void objectWasInvalidated()
     {
         cache.clear();
-        classToEffectiveClass.clear();
     }
 
     /**
@@ -2134,20 +1364,6 @@ public class PropertyConduitSourceImpl i
         }
     }
 
-    private Class processConstant(InstructionBuilder builder, Tree integerNode)
-    {
-        long value = Long.parseLong(integerNode.getText());
-
-        if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE)
-        {
-            builder.loadConstant((int) value);
-            return int.class;
-        }
-
-        builder.loadConstant(value);
-        return long.class;
-    }
-
     /**
      * May be invoked from fabricated PropertyConduit instances.
      */