Mercurial > hg > truffle
diff truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @ 22399:efbc311e9ff2
Turning NodeClass into abstract class to allow its independent implementations.
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Fri, 20 Nov 2015 10:36:52 +0100 |
parents | 07c98b5a9496 |
children | 5033b980cc68 |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java Thu Nov 19 18:49:55 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java Fri Nov 20 10:36:52 2015 +0100 @@ -24,23 +24,15 @@ */ package com.oracle.truffle.api.nodes; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; - -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; /** * Information about a {@link Node} class. A single instance of this class is allocated for every * subclass of {@link Node} that is used. */ -public final class NodeClass { +public abstract class NodeClass { private static final ClassValue<NodeClass> nodeClasses = new ClassValue<NodeClass>() { @SuppressWarnings("unchecked") @Override @@ -48,25 +40,12 @@ assert Node.class.isAssignableFrom(clazz); return AccessController.doPrivileged(new PrivilegedAction<NodeClass>() { public NodeClass run() { - return new NodeClass((Class<? extends Node>) clazz); + return new NodeClassImpl((Class<? extends Node>) clazz); } }); } }; - private static final NodeFieldAccessor[] EMPTY_NODE_FIELD_ARRAY = new NodeFieldAccessor[0]; - - // The comprehensive list of all fields. - private final NodeFieldAccessor[] fields; - // Separate arrays for the frequently accessed fields. - private final NodeFieldAccessor parentField; - private final NodeFieldAccessor nodeClassField; - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; - private final NodeFieldAccessor[] cloneableFields; - - private final Class<? extends Node> clazz; - public static NodeClass get(Class<? extends Node> clazz) { return nodeClasses.get(clazz); } @@ -75,199 +54,20 @@ return node.getNodeClass(); } - NodeClass(Class<? extends Node> clazz) { - if (!Node.class.isAssignableFrom(clazz)) { - throw new IllegalArgumentException(); - } - - List<NodeFieldAccessor> fieldsList = new ArrayList<>(); - NodeFieldAccessor parentFieldTmp = null; - NodeFieldAccessor nodeClassFieldTmp = null; - List<NodeFieldAccessor> childFieldList = new ArrayList<>(); - List<NodeFieldAccessor> childrenFieldList = new ArrayList<>(); - List<NodeFieldAccessor> cloneableFieldList = new ArrayList<>(); - - try { - Field field = Node.class.getDeclaredField("parent"); - assert Node.class.isAssignableFrom(field.getType()); - parentFieldTmp = NodeFieldAccessor.create(NodeFieldKind.PARENT, field); - field = Node.class.getDeclaredField("nodeClass"); - assert NodeClass.class.isAssignableFrom(field.getType()); - nodeClassFieldTmp = NodeFieldAccessor.create(NodeFieldKind.NODE_CLASS, field); - } catch (NoSuchFieldException e) { - throw new AssertionError("Node field not found", e); - } - - collectInstanceFields(clazz, fieldsList, childFieldList, childrenFieldList, cloneableFieldList); - - this.fields = fieldsList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.nodeClassField = nodeClassFieldTmp; - this.parentField = parentFieldTmp; - this.childFields = childFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.childrenFields = childrenFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.cloneableFields = cloneableFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.clazz = clazz; - } - - private static void collectInstanceFields(Class<? extends Object> clazz, List<NodeFieldAccessor> fieldsList, List<NodeFieldAccessor> childFieldList, List<NodeFieldAccessor> childrenFieldList, - List<NodeFieldAccessor> cloneableFieldList) { - if (clazz.getSuperclass() != null) { - collectInstanceFields(clazz.getSuperclass(), fieldsList, childFieldList, childrenFieldList, cloneableFieldList); - } - Field[] declaredFields = clazz.getDeclaredFields(); - for (Field field : declaredFields) { - if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { - continue; - } - - NodeFieldAccessor nodeField; - if (field.getDeclaringClass() == Node.class && (field.getName().equals("parent") || field.getName().equals("nodeClass"))) { - continue; - } else if (field.getAnnotation(Child.class) != null) { - checkChildField(field); - nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILD, field); - childFieldList.add(nodeField); - } else if (field.getAnnotation(Children.class) != null) { - checkChildrenField(field); - nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILDREN, field); - childrenFieldList.add(nodeField); - } else { - nodeField = NodeFieldAccessor.create(NodeFieldKind.DATA, field); - if (NodeCloneable.class.isAssignableFrom(field.getType())) { - cloneableFieldList.add(nodeField); - } - } - fieldsList.add(nodeField); - } - } - - public NodeFieldAccessor getNodeClassField() { - return nodeClassField; - } - - public NodeFieldAccessor[] getCloneableFields() { - return cloneableFields; - } - - private static boolean isNodeType(Class<?> clazz) { - return Node.class.isAssignableFrom(clazz) || (clazz.isInterface() && NodeInterface.class.isAssignableFrom(clazz)); - } - - private static void checkChildField(Field field) { - if (!isNodeType(field.getType())) { - throw new AssertionError("@Child field type must be a subclass of Node or an interface extending NodeInterface (" + field + ")"); - } - if (Modifier.isFinal(field.getModifiers())) { - throw new AssertionError("@Child field must not be final (" + field + ")"); - } - } - - private static void checkChildrenField(Field field) { - if (!(field.getType().isArray() && isNodeType(field.getType().getComponentType()))) { - throw new AssertionError("@Children field type must be an array of a subclass of Node or an interface extending NodeInterface (" + field + ")"); - } - if (!Modifier.isFinal(field.getModifiers())) { - throw new AssertionError("@Children field must be final (" + field + ")"); - } + protected NodeClass() { } - public NodeFieldAccessor[] getFields() { - return fields; - } - - public NodeFieldAccessor getParentField() { - return parentField; - } - - public NodeFieldAccessor[] getChildFields() { - return childFields; - } - - public NodeFieldAccessor[] getChildrenFields() { - return childrenFields; - } - - @Override - public int hashCode() { - return clazz.hashCode(); - } + public abstract NodeFieldAccessor getNodeClassField(); - @Override - public boolean equals(Object obj) { - if (obj instanceof NodeClass) { - NodeClass other = (NodeClass) obj; - return clazz.equals(other.clazz); - } - return false; - } - - public Iterator<Node> makeIterator(Node node) { - assert clazz.isInstance(node); - return new NodeIterator(this, node); - } + public abstract NodeFieldAccessor[] getCloneableFields(); - private static final class NodeIterator implements Iterator<Node> { - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; - private final Node node; - private final int childrenCount; - private int index; - - protected NodeIterator(NodeClass nodeClass, Node node) { - this.childFields = nodeClass.getChildFields(); - this.childrenFields = nodeClass.getChildrenFields(); - this.node = node; - this.childrenCount = childrenCount(); - this.index = 0; - } + public abstract NodeFieldAccessor[] getFields(); - private int childrenCount() { - int nodeCount = childFields.length; - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] children = ((Object[]) childrenField.getObject(node)); - if (children != null) { - nodeCount += children.length; - } - } - return nodeCount; - } + public abstract NodeFieldAccessor getParentField(); + + public abstract NodeFieldAccessor[] getChildFields(); - private Node nodeAt(int idx) { - int nodeCount = childFields.length; - if (idx < nodeCount) { - return (Node) childFields[idx].getObject(node); - } else { - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] nodeArray = (Object[]) childrenField.getObject(node); - if (idx < nodeCount + nodeArray.length) { - return (Node) nodeArray[idx - nodeCount]; - } - nodeCount += nodeArray.length; - } - } - return null; - } + public abstract NodeFieldAccessor[] getChildrenFields(); - private void forward() { - if (index < childrenCount) { - index++; - } - } - - public boolean hasNext() { - return index < childrenCount; - } - - public Node next() { - try { - return nodeAt(index); - } finally { - forward(); - } - } - - public void remove() { - throw new UnsupportedOperationException(); - } - } + public abstract Iterator<Node> makeIterator(Node node); }