/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.frontend.treecopy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import abs.frontend.ast.ASTNode;
public class ParseTreeCopyHelper {
/**
* creates a copy of the given node
*
* in contrast to fullCopy this method only copies the parse tree as
* it is produced by the parser. It does not try to copy attributes
* or other information in the AST (results from typechecking).
*
*/
public static <T extends ASTNode<S>, S extends ASTNode<?>> T parseTreeCopy(T node) {
try {
Class<? extends T> nodeClass = (Class<? extends T>) node.getClass();
T copy = nodeClass.newInstance();
// set children
for (int i=0; i<node.getNumChildNoTransform(); i++) {
S child = node.getChildNoTransform(i);
S childCopy = (S) child.parseTreeCopy();
copy.setChild(childCopy, i);
}
// set other fields (no ASTNodes; Strings, etc.)
setOtherFields(node, copy, nodeClass, nodeClass);
// set position
copy.setPositionFromNode(node);
return copy;
} catch (Exception e) {
throw new Error(e);
}
}
/**
* searches for fields named "token<Type>_<Name>" in searchClass
* and uses set and get methods from nodeClass to copy the values from node to copy
*/
private static <T> void setOtherFields(T node, T copy, Class<? extends T> nodeClass, Class<?> searchClass) throws Exception {
Field[] fields = searchClass.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
if (fieldName.startsWith("token") && fieldName.contains("_")) {
String name = fieldName.substring(fieldName.indexOf('_')+1);
Class<?> fieldType = field.getType();
Method getMethod = nodeClass.getMethod("get" + name);
Method setMethod = nodeClass.getMethod("set" + name, fieldType);
// value = node.getName();
Object value = getMethod.invoke(node);
// copy.setName(value);
setMethod.invoke(copy, value);
}
}
if (searchClass.getSuperclass() != null) {
setOtherFields(node, copy, nodeClass, searchClass.getSuperclass());
}
}
}