package edu.ucsd.arcum.interpreter.transformation; import org.eclipse.jdt.core.dom.*; import edu.ucsd.arcum.exceptions.ArcumError; import edu.ucsd.arcum.interpreter.ast.ASTUtil; import edu.ucsd.arcum.interpreter.fragments.ModifierElement; import edu.ucsd.arcum.interpreter.query.Entity; import edu.ucsd.arcum.util.StringUtil; public class Conversion { public static <T extends ASTNode> T cleanseASTNode(AST ast, T node) { T result = node; if (ast != result.getAST() || result.getParent() != null) { result = Entity.copySubtree(ast, result); } return result; } public static Type typeBindingtoASTNode(AST ast, ITypeBinding typeBinding) { Type result = ASTUtil.buildTypeNode(ast, typeBinding); return cleanseASTNode(ast, result); } // Returns null if the element itself exists only implicitly, like the "package" // modifier Arcum uses in the absence of public/private/protected. public static ASTNode toPossibleEmptyNode(AST ast, StructuralPropertyDescriptor edge, Object value) { if (value instanceof ASTNode) { return cleanseASTNode(ast, (ASTNode)value); } else if (value instanceof ITypeBinding) { return typeBindingtoASTNode(ast, (ITypeBinding)value); } else if (value instanceof ModifierElement) { return modifierToASTNode(ast, (ModifierElement)value); } else if (value instanceof String){ if (edge.isChildProperty()) { ChildPropertyDescriptor cpd = (ChildPropertyDescriptor)edge; Class childType = cpd.getChildType(); if (childType == SimpleName.class) { return ast.newSimpleName((String)value); } } ArcumError.fatalError("Unhandled case: %s%n", StringUtil.debugDisplay(value)); return null; } else { ArcumError.fatalError("Unhandled case: %s%n", StringUtil.debugDisplay(value)); return null; } } private static ASTNode modifierToASTNode(AST ast, ModifierElement modifierElement) { if (modifierElement == ModifierElement.MOD_PACKAGE) { return null; } else { Modifier result = modifierElement.asModifierASTNode(ast); return cleanseASTNode(ast, result); } } public static Object toSimpleProperty(Object value) { if (value instanceof SimpleName) { SimpleName name = (SimpleName)value; return name.getIdentifier(); } return value; } public static ASTNode unbox(AST ast, StructuralPropertyDescriptor property, ASTNode node) { if (property.isChildProperty()) { ChildPropertyDescriptor astProperty = (ChildPropertyDescriptor)property; Class childType = astProperty.getChildType(); if (childType.isAssignableFrom(node.getClass())) { // no conversion needed return node; } else { if (node instanceof SimpleType && childType.isAssignableFrom(Name.class)) { SimpleType simpleType = (SimpleType)node; Name name = simpleType.getName(); // unparent "name" return Entity.copySubtree(ast, name); } else if (node instanceof ParameterizedType && childType.isAssignableFrom(Name.class)) { ParameterizedType parameterizedType = (ParameterizedType)node; Type baseType = parameterizedType.getType(); if (baseType instanceof SimpleType) { SimpleType simpleType = (SimpleType)baseType; Name name = simpleType.getName(); // unparent "name" return Entity.copySubtree(ast, name); } else { ArcumError.fatalError("Conversion ase not supported yet for: %s", baseType); } } return node; } } // otherwise, probably no conversion is needed return node; } }