/** * Copyright (C) 2010 STMicroelectronics * * This file is part of "Mind Compiler" is free software: you can redistribute * it and/or modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact: mind@ow2.org * * Authors: Matthieu Leclercq * Contributors: */ package org.ow2.mind; import org.objectweb.fractal.adl.CompilerError; import org.objectweb.fractal.adl.Node; import org.objectweb.fractal.adl.NodeFactory; import org.objectweb.fractal.adl.error.GenericErrors; import org.objectweb.fractal.adl.merger.MergeException; import org.objectweb.fractal.adl.merger.NodeMerger; /** * Common AST helper methods. */ public final class CommonASTHelper { private CommonASTHelper() { } /** * Returns a new AST node created with the given nodeFactory. * * @param <T> the type of the returned node. * @param nodeFactory the {@link NodeFactory} to use to create the node. * @param nodeType the {@link Node#astGetType() node type}. * @param nodeItf one interface implemented by the created node. The return * type of this method is an instance of this class. * @param itfs the node interfaces that are implemented by the node to create. * @return a new AST node. */ public static <T extends Node> T newNode(final NodeFactory nodeFactory, final String nodeType, final Class<T> nodeItf, final Class<?>... itfs) { final String[] itfNames = new String[itfs.length + 1]; itfNames[0] = nodeItf.getName(); for (int i = 0; i < itfs.length; i++) { itfNames[i + 1] = itfs[i].getName(); } try { return nodeItf.cast(nodeFactory.newNode(nodeType, itfNames)); } catch (final ClassNotFoundException e) { throw new CompilerError(GenericErrors.INTERNAL_ERROR, e, "Unexpected error."); } } /** * Transforms the given node to a node that implements the * <code>nodeItf</code> interface. If the node already implements the * interface, this method simply cast it. Otherwise this method use the given * node factory and node merger to create a copy of the given node that * implements the <code>nodeItf</code> interface. * * @param <T> the type of the returned node. * @param node the node to transform. * @param nodeItf the interface that the give node must implement * @param nodeFactory the {@link NodeFactory} to use. * @param nodeMerger the {@link NodeMerger} to use. * @return either the given node casted in the <code>nodeItf</code> interface, * or a copy of the given node that implements the * <code>nodeItf</code> interface. */ public static <T extends Node> T turnsTo(final Node node, final Class<T> nodeItf, final NodeFactory nodeFactory, final NodeMerger nodeMerger) { if (nodeItf.isInstance(node)) return nodeItf.cast(node); // the given node does not implements the desired interface. // Create a node that implements it and merge it with the given node. try { final Node n = newNode(nodeFactory, node.astGetType(), nodeItf); return nodeItf.cast(nodeMerger.merge(node, n, null)); } catch (final MergeException e) { throw new CompilerError(GenericErrors.INTERNAL_ERROR, e, "Node merge error"); } } }