1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 package org.graalvm.graphio; 26 27 import java.util.Collection; 28 import java.util.Map; 29 30 /** 31 * Interface that defines structure of a compiler graph. The structure of a graph is composed from 32 * nodes with properties, the classes of individual nodes, and ports associated with each node that 33 * may contain edges to other nodes. The structure of a graph is assumed to be immutable for the 34 * time of {@link GraphOutput operations} on it. 35 * 36 * @param <G> the type of the (root node of a) graph 37 * @param <N> the type of nodes 38 * @param <C> the type of node classes 39 * @param <P> the type of node ports 40 */ 41 public interface GraphStructure<G, N, C, P> { 42 /** 43 * Casts {@code obj} to graph, if possible. If the given object <code>obj</code> can be seen as 44 * a graph or sub-graph of a graph, then return the properly typed instance. Otherwise return 45 * <code>null</code> 46 * 47 * @param currentGraph the currently processed graph 48 * @param obj an object to check and view as a graph 49 * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph 50 */ graph(G currentGraph, Object obj)51 G graph(G currentGraph, Object obj); 52 53 /** 54 * Nodes of a graph. Each graph is composed from a fixed set of nodes. This method returns an 55 * iterable which provides access to all of them - the number of nodes provided by the iterable 56 * must match the number returned by {@link #nodesCount(java.lang.Object)} method. 57 * 58 * @see #nodesCount(java.lang.Object) 59 * @param graph the graph to query for nodes 60 * @return iterable with all the graph's nodes 61 */ nodes(G graph)62 Iterable<? extends N> nodes(G graph); 63 64 /** 65 * Number of nodes in a graph. The number must match the content returned by 66 * {@link #nodes(java.lang.Object)} method. 67 * 68 * @param graph the graph to query 69 * @return the number of nodes that will be returned by {@link #nodes(java.lang.Object)} 70 */ nodesCount(G graph)71 int nodesCount(G graph); 72 73 /** 74 * Id of {@code node}. Each node in the graph is uniquely identified by an integer value. If two 75 * nodes have the same id, then they shall be <code>==</code> to each other. 76 * 77 * @param node the node to query for an id 78 * @return the id of the node 79 */ nodeId(N node)80 int nodeId(N node); 81 82 /** 83 * Checks if there is a predecessor for a node. 84 * 85 * @param node the node to check 86 * @return <code>true</code> if it has a predecessor, <code>false</code> otherwise 87 */ nodeHasPredecessor(N node)88 boolean nodeHasPredecessor(N node); 89 90 /** 91 * Collects node properties. Each node can be associated with additional properties identified 92 * by their name. This method shall copy them into the provided map. 93 * 94 * @param graph the current graph 95 * @param node the node to collect properties for 96 * @param properties the map to put the properties to 97 */ nodeProperties(G graph, N node, Map<String, ? super Object> properties)98 void nodeProperties(G graph, N node, Map<String, ? super Object> properties); 99 100 /** 101 * Finds a node for {@code obj}, if possible. If the given object <code>obj</code> can be seen 102 * as an instance of node return the properly typed instance of the node class. Otherwise return 103 * <code>null</code>. 104 * 105 * @param obj an object to find node for 106 * @return appropriate graph object or <code>null</code> if the object doesn't represent a node 107 */ node(Object obj)108 N node(Object obj); 109 110 /** 111 * Finds a node class for {@code obj}, if possible. If the given object <code>obj</code> can be 112 * seen as an instance of node class return the properly typed instance of the node class. 113 * Otherwise return <code>null</code>. 114 * 115 * @param obj an object to find node class for 116 * @return appropriate graph object or <code>null</code> if the object doesn't represent a node 117 * class 118 */ nodeClass(Object obj)119 C nodeClass(Object obj); 120 121 /** 122 * Finds a node class for {@code node}. 123 * 124 * @param node an instance of node in this graph 125 * @return the node's node class, never <code>null</code> 126 */ classForNode(N node)127 C classForNode(N node); 128 129 /** 130 * The template used to build the name of nodes of this class. The template may use references 131 * to inputs ({i#inputName}) and its properties ({p#propertyName}). 132 * 133 * @param nodeClass the node class to find name template for 134 * @return the string representing the template 135 */ nameTemplate(C nodeClass)136 String nameTemplate(C nodeClass); 137 138 /** 139 * Java class for a node class. 140 * 141 * @param nodeClass the node class 142 * @return the {@link Class} or other type representation of the node class 143 */ nodeClassType(C nodeClass)144 Object nodeClassType(C nodeClass); 145 146 /** 147 * Input ports of a node class. Each node class has a fixed set of ports where individual edges 148 * can attach to. 149 * 150 * @param nodeClass the node class 151 * @return input ports for the node class 152 */ portInputs(C nodeClass)153 P portInputs(C nodeClass); 154 155 /** 156 * Output ports of a node class. Each node class has a fixed set of ports from where individual 157 * edges can point to other nodes. 158 * 159 * @param nodeClass the node class 160 * @return output ports for the node class 161 */ portOutputs(C nodeClass)162 P portOutputs(C nodeClass); 163 164 /** 165 * The number of edges in a port. The protocol will then call methods 166 * {@link #edgeDirect(java.lang.Object, int)}, {@link #edgeName(java.lang.Object, int)}, 167 * {@link #edgeType(java.lang.Object, int)} and 168 * {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} for indexes 169 * from <code>0</code> to <code>portSize - 1</code> 170 * 171 * @param port the port 172 * @return number of edges in this port 173 */ portSize(P port)174 int portSize(P port); 175 176 /** 177 * Checks whether an edge is direct. Direct edge shall have exactly one 178 * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) node} - it 179 * is an error to return more than one for such an edge from the 180 * {@linkplain #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int) method}. 181 * 182 * @param port the port 183 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 184 * <code>1</code> 185 * @return <code>true</code> if only one node can be returned from 186 * {@link #edgeNodes(java.lang.Object, java.lang.Object, java.lang.Object, int)} method 187 */ edgeDirect(P port, int index)188 boolean edgeDirect(P port, int index); 189 190 /** 191 * The name of an edge. 192 * 193 * @param port the port 194 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 195 * <code>1</code> 196 * @return the name of the edge 197 */ edgeName(P port, int index)198 String edgeName(P port, int index); 199 200 /** 201 * Type of an edge. The type must be a graph 202 * <q>enum</q> - e.g. either real instance of {@link Enum} subclass, or something that the 203 * {@link GraphOutput.Builder} can recognize as 204 * <q>enum</q>. 205 * 206 * @param port 207 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 208 * <code>1</code> 209 * @return any {@link Enum} representing type of the edge 210 */ edgeType(P port, int index)211 Object edgeType(P port, int index); 212 213 /** 214 * Nodes where the edges for a port lead to/from. This method is called for both 215 * {@link #edgeDirect(java.lang.Object, int) direct/non-direct edges}. In case of a direct edge 216 * the returned collection must have exactly one element. 217 * 218 * @param graph the graph 219 * @param node the node in the graph 220 * @param port port of the node class 221 * @param index index from <code>0</code> to {@link #portSize(java.lang.Object)} minus 222 * <code>1</code> 223 * @return <code>null</code> if there are no edges associated with given port or collection of 224 * nodes where to/from the edges lead to 225 */ edgeNodes(G graph, N node, P port, int index)226 Collection<? extends N> edgeNodes(G graph, N node, P port, int index); 227 } 228