1 /*
   2  * Copyright (c) 2011, 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 package org.graalvm.compiler.graph.test;
  24 
  25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
  26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
  27 import static org.junit.Assert.assertEquals;
  28 import static org.junit.Assert.assertFalse;
  29 import static org.junit.Assert.assertNotNull;
  30 import static org.junit.Assert.assertTrue;
  31 import static org.junit.Assert.fail;
  32 
  33 import java.util.Iterator;
  34 
  35 import org.junit.Test;
  36 import org.graalvm.compiler.api.test.Graal;
  37 import org.graalvm.compiler.graph.Graph;
  38 import org.graalvm.compiler.graph.IterableNodeType;
  39 import org.graalvm.compiler.graph.Node;
  40 import org.graalvm.compiler.graph.NodeClass;
  41 import org.graalvm.compiler.nodeinfo.NodeInfo;
  42 import org.graalvm.compiler.options.OptionValues;
  43 
  44 public class TypedNodeIteratorTest extends GraphTest {
  45 
  46     @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
  47     static final class TestNode extends Node implements IterableNodeType, TestNodeInterface {
  48 
  49         public static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class);
  50         protected final String name;
  51 
  52         protected TestNode(String name) {
  53             super(TYPE);
  54             this.name = name;
  55         }
  56 
  57         @Override
  58         public String getName() {
  59             return name;
  60         }
  61     }
  62 
  63     @Test
  64     public void singleNodeTest() {
  65         getOptions();
  66         Graph graph = new Graph(getOptions());
  67         graph.add(new TestNode("a"));
  68         assertTrue(graph.hasNode(TestNode.TYPE));
  69         assertEquals("a", toString(graph.getNodes(TestNode.TYPE)));
  70     }
  71 
  72     static OptionValues getOptions() {
  73         return Graal.getRequiredCapability(OptionValues.class);
  74     }
  75 
  76     @Test
  77     public void deletingNodeTest() {
  78         TestNode testNode = new TestNode("a");
  79         Graph graph = new Graph(getOptions());
  80         graph.add(testNode);
  81         testNode.safeDelete();
  82         assertEquals("", toString(graph.getNodes(TestNode.TYPE)));
  83     }
  84 
  85     @Test
  86     public void deleteAndAddTest() {
  87         TestNode testNode = new TestNode("b");
  88         Graph graph = new Graph(getOptions());
  89         graph.add(new TestNode("a"));
  90         graph.add(testNode);
  91         testNode.safeDelete();
  92         assertEquals("a", toString(graph.getNodes(TestNode.TYPE)));
  93         graph.add(new TestNode("c"));
  94         assertEquals("ac", toString(graph.getNodes(TestNode.TYPE)));
  95     }
  96 
  97     @Test
  98     public void iteratorBehaviorTest() {
  99         Graph graph = new Graph(getOptions());
 100         graph.add(new TestNode("a"));
 101         Iterator<TestNode> iterator = graph.getNodes(TestNode.TYPE).iterator();
 102         assertTrue(iterator.hasNext());
 103         assertEquals("a", iterator.next().getName());
 104         assertFalse(iterator.hasNext());
 105         graph.add(new TestNode("b"));
 106         assertTrue(iterator.hasNext());
 107         assertEquals("b", iterator.next().getName());
 108         assertFalse(iterator.hasNext());
 109         TestNode c = new TestNode("c");
 110         graph.add(c);
 111         assertTrue(iterator.hasNext());
 112         c.safeDelete();
 113         assertFalse(iterator.hasNext());
 114     }
 115 
 116     @Test
 117     public void complicatedIterationTest() {
 118         Graph graph = new Graph(getOptions());
 119         graph.add(new TestNode("a"));
 120         for (TestNode tn : graph.getNodes(TestNode.TYPE)) {
 121             String name = tn.getName();
 122             for (int i = 0; i < name.length(); ++i) {
 123                 char c = name.charAt(i);
 124                 if (c == 'a') {
 125                     tn.safeDelete();
 126                     graph.add(new TestNode("b"));
 127                     graph.add(new TestNode("c"));
 128                 } else if (c == 'b') {
 129                     tn.safeDelete();
 130                 } else if (c == 'c') {
 131                     graph.add(new TestNode("d"));
 132                     graph.add(new TestNode("e"));
 133                     graph.add(new TestNode("d"));
 134                     graph.add(new TestNode("e"));
 135                     graph.add(new TestNode("e"));
 136                     graph.add(new TestNode("d"));
 137                     graph.add(new TestNode("e"));
 138                     graph.add(new TestNode("d"));
 139                 } else if (c == 'd') {
 140                     for (TestNode tn2 : graph.getNodes(TestNode.TYPE)) {
 141                         if (tn2.getName().equals("e")) {
 142                             tn2.safeDelete();
 143                         } else if (tn2.getName().equals("c")) {
 144                             tn2.safeDelete();
 145                         }
 146                     }
 147                 } else if (c == 'e') {
 148                     fail("All e nodes must have been deleted by visiting the d node");
 149                 }
 150             }
 151         }
 152         assertEquals("dddd", toString(graph.getNodes(TestNode.TYPE)));
 153     }
 154 
 155     @Test
 156     public void addingNodeDuringIterationTest() {
 157         Graph graph = new Graph(getOptions());
 158         graph.add(new TestNode("a"));
 159         StringBuilder sb = new StringBuilder();
 160         int z = 0;
 161         for (TestNode tn : graph.getNodes(TestNode.TYPE)) {
 162             if (z == 0) {
 163                 graph.add(new TestNode("b"));
 164             }
 165             sb.append(tn.getName());
 166             z++;
 167         }
 168         assertEquals(2, z);
 169         assertEquals("ab", sb.toString());
 170         z = 0;
 171         for (TestNode tn : graph.getNodes(TestNode.TYPE)) {
 172             if (z == 0) {
 173                 graph.add(new TestNode("c"));
 174             }
 175             assertNotNull(tn);
 176             z++;
 177         }
 178         assertEquals(3, z);
 179     }
 180 
 181     public static String toString(Iterable<? extends TestNodeInterface> nodes) {
 182         StringBuilder sb = new StringBuilder();
 183         for (TestNodeInterface tn : nodes) {
 184             sb.append(tn.getName());
 185         }
 186         return sb.toString();
 187     }
 188 }