/* * Copyright (c) 2013 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available 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. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.util.groovy.ast; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Vertex; /** * Utilities for dealing with an AST graph. * * @author Simon Templer */ public class ASTGraphUtil implements ASTGraphConstants { /** * Find the AST node vertex with the deepest level possible that either * contains or directly precedes the given position. * * @param vertices the (root) vertices to start search from * @param line the position line (1-based) * @param col the position column (1-based) * @return the vertex or <code>null</code> if none could be found */ public static Vertex findAt(Iterable<Vertex> vertices, final int line, final int col) { for (Vertex v : vertices) { final int vStartLine = v.getProperty(P_START_LINE); final int vStartCol = v.getProperty(P_START_COL); final int vEndLine = v.getProperty(P_END_LINE); final int vEndCol = v.getProperty(P_END_COL); // Valid in the sense that a position is set, i.e. the vertex is // "visible" // Vertices can not be visible, but still have visible children! boolean validNode = vStartLine != -1 && vEndLine != -1; boolean afterStart = (line == vStartLine && col > vStartCol) || line > vStartLine; boolean beforeEnd = (line == vEndLine && col <= vEndCol) || line < vEndLine; // Check children of invalid, and of valid&fitting vertices if (!validNode || (afterStart && beforeEnd)) { Vertex match = findAt(v.getVertices(Direction.OUT, E_CHILD), line, col); // Return closer match or, if valid, this vertex if (match != null) return match; else if (validNode) return v; } } return null; } }