Node.java revision 953:221a84ef44c0
1177595Sweongyo/* 2177595Sweongyo * Permission is hereby granted, free of charge, to any person obtaining a copy of 3177595Sweongyo * this software and associated documentation files (the "Software"), to deal in 4177595Sweongyo * the Software without restriction, including without limitation the rights to 5177595Sweongyo * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 6177595Sweongyo * of the Software, and to permit persons to whom the Software is furnished to do 7177595Sweongyo * so, subject to the following conditions: 8177595Sweongyo * 9177595Sweongyo * The above copyright notice and this permission notice shall be included in all 10177595Sweongyo * copies or substantial portions of the Software. 11177595Sweongyo * 12177595Sweongyo * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13177595Sweongyo * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14177595Sweongyo * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15177595Sweongyo * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16177595Sweongyo * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17177595Sweongyo * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18177595Sweongyo * SOFTWARE. 19177595Sweongyo */ 20177595Sweongyopackage jdk.nashorn.internal.runtime.regexp.joni.ast; 21177595Sweongyo 22177595Sweongyoimport java.util.Set; 23177595Sweongyoimport jdk.nashorn.internal.runtime.regexp.joni.Config; 24177595Sweongyoimport jdk.nashorn.internal.runtime.regexp.joni.WarnCallback; 25177595Sweongyoimport jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; 26177595Sweongyo 27177595Sweongyopublic abstract class Node implements NodeType { 28177595Sweongyo public Node parent; 29177595Sweongyo 30177595Sweongyo public abstract int getType(); 31177595Sweongyo 32177595Sweongyo public final int getType2Bit() { 33177595Sweongyo return 1 << getType(); 34177595Sweongyo } 35177595Sweongyo 36177595Sweongyo protected void setChild(final Node tgt){} // default definition 37177595Sweongyo protected Node getChild(){return null;} // default definition 38177595Sweongyo 39177595Sweongyo public void swap(final Node with) { 40177595Sweongyo Node tmp; 41177595Sweongyo 42177595Sweongyo //if (getChild() != null) getChild().parent = with; 43177595Sweongyo //if (with.getChild() != null) with.getChild().parent = this; 44177595Sweongyo 45177595Sweongyo //tmp = getChild(); 46177595Sweongyo //setChild(with.getChild()); 47177595Sweongyo //with.setChild(tmp); 48177595Sweongyo 49177595Sweongyo if (parent != null) parent.setChild(with); 50177595Sweongyo 51177595Sweongyo if (with.parent != null) with.parent.setChild(this); 52177595Sweongyo 53177595Sweongyo tmp = parent; 54177595Sweongyo parent = with.parent; 55177595Sweongyo with.parent = tmp; 56177595Sweongyo } 57177595Sweongyo 58177595Sweongyo // overridden by ConsAltNode and CallNode 59177595Sweongyo public void verifyTree(final Set<Node> set, final WarnCallback warnings) { 60177595Sweongyo if (!set.contains(this) && getChild() != null) { 61177595Sweongyo set.add(this); 62177595Sweongyo if (getChild().parent != this) { 63177595Sweongyo warnings.warn("broken link to child: " + this.getAddressName() + " -> " + getChild().getAddressName()); 64177595Sweongyo } 65177595Sweongyo getChild().verifyTree(set, warnings); 66177595Sweongyo } 67177595Sweongyo } 68177595Sweongyo 69177595Sweongyo public abstract String getName(); 70177595Sweongyo protected abstract String toString(int level); 71177595Sweongyo 72177595Sweongyo public String getAddressName() { 73177595Sweongyo return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this)); 74177595Sweongyo } 75177595Sweongyo 76177595Sweongyo @Override 77177595Sweongyo public final String toString() { 78177595Sweongyo final StringBuilder s = new StringBuilder(); 79177595Sweongyo s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>"); 80177595Sweongyo return s + toString(0); 81177595Sweongyo } 82177595Sweongyo 83177595Sweongyo protected static String pad(final Object value, final int level) { 84177595Sweongyo if (value == null) return "NULL"; 85177595Sweongyo 86177595Sweongyo final StringBuilder pad = new StringBuilder(" "); 87177595Sweongyo for (int i=0; i<level; i++) pad.append(pad); 88177595Sweongyo 89177595Sweongyo return value.toString().replace("\n", "\n" + pad); 90177595Sweongyo } 91177595Sweongyo 92177595Sweongyo public final boolean isInvalidQuantifier() { 93177595Sweongyo if (!Config.VANILLA) return false; 94177595Sweongyo 95177595Sweongyo ConsAltNode node; 96177595Sweongyo 97177595Sweongyo switch(getType()) { 98177595Sweongyo 99177595Sweongyo case ANCHOR: 100177595Sweongyo return true; 101177595Sweongyo 102177595Sweongyo case ENCLOSE: 103177595Sweongyo /* allow enclosed elements */ 104177595Sweongyo /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */ 105177595Sweongyo break; 106177595Sweongyo 107177595Sweongyo case LIST: 108177595Sweongyo node = (ConsAltNode)this; 109177595Sweongyo do { 110177595Sweongyo if (!node.car.isInvalidQuantifier()) return false; 111177595Sweongyo } while ((node = node.cdr) != null); 112177595Sweongyo return false; 113177595Sweongyo 114177595Sweongyo case ALT: 115177595Sweongyo node = (ConsAltNode)this; 116177595Sweongyo do { 117177595Sweongyo if (node.car.isInvalidQuantifier()) return true; 118177595Sweongyo } while ((node = node.cdr) != null); 119177595Sweongyo break; 120177595Sweongyo 121177595Sweongyo default: 122177595Sweongyo break; 123177595Sweongyo } 124177595Sweongyo 125177595Sweongyo return false; 126177595Sweongyo } 127177595Sweongyo 128177595Sweongyo public final boolean isAllowedInLookBehind() { 129177595Sweongyo return (getType2Bit() & ALLOWED_IN_LB) != 0; 130177595Sweongyo } 131177595Sweongyo 132177595Sweongyo public final boolean isSimple() { 133177595Sweongyo return (getType2Bit() & SIMPLE) != 0; 134177595Sweongyo } 135177595Sweongyo} 136177595Sweongyo