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