@Override protected Class<?> getFieldType(Object field) { return ((NodeFieldAccessor) field).getType(); }
@Override protected Class<?> getFieldType(Object field) { return ((NodeFieldAccessor) field).getType(); }
@Override protected boolean isCloneableField(Object field) { return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(((NodeFieldAccessor) field).getType()); }
@Override protected boolean isCloneableField(Object field) { return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(((NodeFieldAccessor) field).getType()); }
/** * Determines whether a proposed child replacement would be safe: structurally and type. */ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChild) { assert newChild != null; if (parent != null) { final NodeFieldAccessor field = findChildField(parent, oldChild); if (field != null) { switch (field.getKind()) { case CHILD: return field.getType().isAssignableFrom(newChild.getClass()); case CHILDREN: return field.getType().getComponentType().isAssignableFrom(newChild.getClass()); default: throw new IllegalStateException(); } } } return false; }
private static boolean assertAssignable(NodeFieldAccessor field, Object newValue) { if (newValue == null) { return true; } if (field.getKind() == NodeFieldKind.CHILD) { if (field.getType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } else if (field.getKind() == NodeFieldKind.CHILDREN) { if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } throw new IllegalArgumentException(); }
private void deserializeChildFields(Node parent, NodeFieldAccessor[] nodeFields) { for (int i = nodeFields.length - 1; i >= 0; i--) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILD) { unsafe.putObject(parent, field.getOffset(), popNode(parent, field.getType())); } } }
private void deserializeChildrenFields(Node parent, NodeFieldAccessor[] nodeFields) { for (int i = nodeFields.length - 1; i >= 0; i--) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILDREN) { unsafe.putObject(parent, field.getOffset(), popArray(parent, field.getType())); } } }
private void deserializeDataFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.DATA) { Class<?> fieldClass = field.getType(); long offset = field.getOffset(); // source sections are not serialized // TODO add support for source sections if (field.getType().isAssignableFrom(SourceSection.class)) { continue; } int cpi = buffer.get(); if (cpi == VariableLengthIntBuffer.NULL) { deserializeDataFieldsLengthNull(nodeInstance, fieldClass, offset); } else { deserializeDataFieldsDefault(nodeInstance, fieldClass, offset, cpi); } } } }
private void serializeChildrenFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILDREN) { Object childArrayObject = unsafe.getObject(nodeInstance, field.getOffset()); if (childArrayObject != null && !(childArrayObject instanceof Node[])) { throw new AssertionError("Node children must be instanceof Node[]"); } buffer.put(cp.putClass(field.getType())); Node[] childArray = (Node[]) childArrayObject; if (childArray == null) { buffer.put(VariableLengthIntBuffer.NULL); } else { buffer.put(cp.putInt(childArray.length)); for (int j = 0; j < childArray.length; j++) { serialize(buffer, childArray[j]); } } } } }