1 /*
   2  * Copyright (c) 2012, 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.iterators;
  26 
  27 import org.graalvm.compiler.graph.Node;
  28 
  29 public abstract class NodePredicates {
  30 
  31     private static final TautologyPredicate TAUTOLOGY = new TautologyPredicate();
  32     private static final ContradictionPredicate CONTRADICTION = new ContradictionPredicate();
  33     private static final IsNullPredicate IS_NULL = new IsNullPredicate();
  34 
  35     public static NodePredicate alwaysTrue() {
  36         return TAUTOLOGY;
  37     }
  38 
  39     public static NodePredicate alwaysFalse() {
  40         return CONTRADICTION;
  41     }
  42 
  43     public static NodePredicate isNull() {
  44         return IS_NULL;
  45     }
  46 
  47     public static NegativeTypePredicate isNotA(Class<? extends Node> clazz) {
  48         return new NegativeTypePredicate(clazz);
  49     }
  50 
  51     public static PositiveTypePredicate isA(Class<? extends Node> clazz) {
  52         return new PositiveTypePredicate(clazz);
  53     }
  54 
  55     static final class TautologyPredicate implements NodePredicate {
  56 
  57         @Override
  58         public boolean apply(Node n) {
  59             return true;
  60         }
  61 
  62         @Override
  63         public NodePredicate and(NodePredicate np) {
  64             return np;
  65         }
  66     }
  67 
  68     static final class ContradictionPredicate implements NodePredicate {
  69 
  70         @Override
  71         public boolean apply(Node n) {
  72             return false;
  73         }
  74 
  75         @Override
  76         public NodePredicate and(NodePredicate np) {
  77             return this;
  78         }
  79     }
  80 
  81     static final class AndPredicate implements NodePredicate {
  82 
  83         private final NodePredicate a;
  84         private final NodePredicate b;
  85 
  86         AndPredicate(NodePredicate a, NodePredicate b) {
  87             this.a = a;
  88             this.b = b;
  89         }
  90 
  91         @Override
  92         public boolean apply(Node n) {
  93             return a.apply(n) && b.apply(n);
  94         }
  95     }
  96 
  97     static final class NotPredicate implements NodePredicate {
  98 
  99         private final NodePredicate a;
 100 
 101         NotPredicate(NodePredicate n) {
 102             this.a = n;
 103         }
 104 
 105         @Override
 106         public boolean apply(Node n) {
 107             return !a.apply(n);
 108         }
 109 
 110         @Override
 111         public NodePredicate negate() {
 112             return a;
 113         }
 114     }
 115 
 116     static final class IsNullPredicate implements NodePredicate {
 117 
 118         @Override
 119         public boolean apply(Node n) {
 120             return n == null;
 121         }
 122     }
 123 
 124     public static final class PositiveTypePredicate implements NodePredicate {
 125 
 126         private final Class<?> type;
 127         private PositiveTypePredicate or;
 128 
 129         PositiveTypePredicate(Class<?> type) {
 130             this.type = type;
 131         }
 132 
 133         public PositiveTypePredicate(NegativeTypePredicate a) {
 134             type = a.type;
 135             if (a.nor != null) {
 136                 or = new PositiveTypePredicate(a.nor);
 137             }
 138         }
 139 
 140         @Override
 141         public boolean apply(Node n) {
 142             return type.isInstance(n) || (or != null && or.apply(n));
 143         }
 144 
 145         public PositiveTypePredicate or(Class<? extends Node> clazz) {
 146             if (or == null) {
 147                 or = new PositiveTypePredicate(clazz);
 148             } else {
 149                 or.or(clazz);
 150             }
 151             return this;
 152         }
 153 
 154         @Override
 155         public NodePredicate negate() {
 156             return new NegativeTypePredicate(this);
 157         }
 158     }
 159 
 160     public static final class NegativeTypePredicate implements NodePredicate {
 161 
 162         private final Class<?> type;
 163         private NegativeTypePredicate nor;
 164 
 165         NegativeTypePredicate(Class<?> type) {
 166             this.type = type;
 167         }
 168 
 169         public NegativeTypePredicate(PositiveTypePredicate a) {
 170             type = a.type;
 171             if (a.or != null) {
 172                 nor = new NegativeTypePredicate(a.or);
 173             }
 174         }
 175 
 176         @Override
 177         public boolean apply(Node n) {
 178             return !type.isInstance(n) && (nor == null || nor.apply(n));
 179         }
 180 
 181         public NegativeTypePredicate nor(Class<? extends Node> clazz) {
 182             if (nor == null) {
 183                 nor = new NegativeTypePredicate(clazz);
 184             } else {
 185                 nor.nor(clazz);
 186             }
 187             return this;
 188         }
 189 
 190         @Override
 191         public NodePredicate negate() {
 192             return new PositiveTypePredicate(this);
 193         }
 194     }
 195 }