1 /*
   2  * Permission is hereby granted, free of charge, to any person obtaining a copy of
   3  * this software and associated documentation files (the "Software"), to deal in
   4  * the Software without restriction, including without limitation the rights to
   5  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   6  * of the Software, and to permit persons to whom the Software is furnished to do
   7  * so, subject to the following conditions:
   8  *
   9  * The above copyright notice and this permission notice shall be included in all
  10  * copies or substantial portions of the Software.
  11  *
  12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18  * SOFTWARE.
  19  */
  20 package jdk.nashorn.internal.runtime.regexp.joni;
  21 
  22 @SuppressWarnings("javadoc")
  23 public final class NodeOptInfo {
  24     final MinMaxLen length = new  MinMaxLen();
  25     final OptAnchorInfo anchor = new OptAnchorInfo();
  26     final OptExactInfo exb = new OptExactInfo();            /* boundary */
  27     final OptExactInfo exm = new OptExactInfo();            /* middle */
  28     final OptExactInfo expr = new OptExactInfo();           /* prec read (?=...) */
  29     final OptMapInfo map = new OptMapInfo();                /* boundary */
  30 
  31     public void setBoundNode(final MinMaxLen mmd) {
  32         exb.mmd.copy(mmd);
  33         expr.mmd.copy(mmd);
  34         map.mmd.copy(mmd);
  35     }
  36 
  37     public void clear() {
  38         length.clear();
  39         anchor.clear();
  40         exb.clear();
  41         exm.clear();
  42         expr.clear();
  43         map.clear();
  44     }
  45 
  46     public void copy(final NodeOptInfo other) {
  47         length.copy(other.length);
  48         anchor.copy(other.anchor);
  49         exb.copy(other.exb);
  50         exm.copy(other.exm);
  51         expr.copy(other.expr);
  52         map.copy(other.map);
  53     }
  54 
  55     public void concatLeftNode(final NodeOptInfo other) {
  56         final OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
  57         tanchor.concat(anchor, other.anchor, length.max, other.length.max);
  58         anchor.copy(tanchor);
  59 
  60         if (other.exb.length > 0 && length.max == 0) {
  61             tanchor.concat(anchor, other.exb.anchor, length.max, other.length.max);
  62             other.exb.anchor.copy(tanchor);
  63         }
  64 
  65         if (other.map.value > 0 && length.max == 0) {
  66             if (other.map.mmd.max == 0) {
  67                 other.map.anchor.leftAnchor |= anchor.leftAnchor;
  68             }
  69         }
  70 
  71         final boolean exbReach = exb.reachEnd;
  72         final boolean exmReach = exm.reachEnd;
  73 
  74         if (other.length.max != 0) {
  75             exb.reachEnd = exm.reachEnd = false;
  76         }
  77 
  78         if (other.exb.length > 0) {
  79             if (exbReach) {
  80                 exb.concat(other.exb);
  81                 other.exb.clear();
  82             } else if (exmReach) {
  83                 exm.concat(other.exb);
  84                 other.exb.clear();
  85             }
  86         }
  87 
  88         exm.select(other.exb);
  89         exm.select(other.exm);
  90 
  91         if (expr.length > 0) {
  92             if (other.length.max > 0) {
  93                 // TODO: make sure it is not an Oniguruma bug (casting unsigned int to int for arithmetic comparison)
  94                 int otherLengthMax = other.length.max;
  95                 if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) {
  96                     otherLengthMax = -1;
  97                 }
  98                 if (expr.length > otherLengthMax) {
  99                     expr.length = otherLengthMax;
 100                 }
 101                 if (expr.mmd.max == 0) {
 102                     exb.select(expr);
 103                 } else {
 104                     exm.select(expr);
 105                 }
 106             }
 107         } else if (other.expr.length > 0) {
 108             expr.copy(other.expr);
 109         }
 110 
 111         map.select(other.map);
 112         length.add(other.length);
 113     }
 114 
 115     public void altMerge(final NodeOptInfo other, final OptEnvironment env) {
 116         anchor.altMerge(other.anchor);
 117         exb.altMerge(other.exb, env);
 118         exm.altMerge(other.exm, env);
 119         expr.altMerge(other.expr, env);
 120         map.altMerge(other.map);
 121         length.altMerge(other.length);
 122     }
 123 
 124     public void setBound(final MinMaxLen mmd) {
 125         exb.mmd.copy(mmd);
 126         expr.mmd.copy(mmd);
 127         map.mmd.copy(mmd);
 128     }
 129 
 130 }