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.joni;
  21 
  22 public final class NodeOptInfo {
  23     final MinMaxLen length = new  MinMaxLen();
  24     final OptAnchorInfo anchor = new OptAnchorInfo();
  25     final OptExactInfo exb = new OptExactInfo();            /* boundary */
  26     final OptExactInfo exm = new OptExactInfo();            /* middle */
  27     final OptExactInfo expr = new OptExactInfo();           /* prec read (?=...) */
  28     final OptMapInfo map = new OptMapInfo();                /* boundary */
  29 
  30     public void setBoundNode(MinMaxLen mmd) {
  31         exb.mmd.copy(mmd);
  32         expr.mmd.copy(mmd);
  33         map.mmd.copy(mmd);
  34     }
  35 
  36     public void clear() {
  37         length.clear();
  38         anchor.clear();
  39         exb.clear();
  40         exm.clear();
  41         expr.clear();
  42         map.clear();
  43     }
  44 
  45     public void copy(NodeOptInfo other) {
  46         length.copy(other.length);
  47         anchor.copy(other.anchor);
  48         exb.copy(other.exb);
  49         exm.copy(other.exm);
  50         expr.copy(other.expr);
  51         map.copy(other.map);
  52     }
  53 
  54     public void concatLeftNode(NodeOptInfo other) {
  55         OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
  56         tanchor.concat(anchor, other.anchor, length.max, other.length.max);
  57         anchor.copy(tanchor);
  58 
  59         if (other.exb.length > 0 && length.max == 0) {
  60             tanchor.concat(anchor, other.exb.anchor, length.max, other.length.max);
  61             other.exb.anchor.copy(tanchor);
  62         }
  63 
  64         if (other.map.value > 0 && length.max == 0) {
  65             if (other.map.mmd.max == 0) {
  66                 other.map.anchor.leftAnchor |= anchor.leftAnchor;
  67             }
  68         }
  69 
  70         boolean exbReach = exb.reachEnd;
  71         boolean exmReach = exm.reachEnd;
  72 
  73         if (other.length.max != 0) {
  74             exb.reachEnd = exm.reachEnd = false;
  75         }
  76 
  77         if (other.exb.length > 0) {
  78             if (exbReach) {
  79                 exb.concat(other.exb);
  80                 other.exb.clear();
  81             } else if (exmReach) {
  82                 exm.concat(other.exb);
  83                 other.exb.clear();
  84             }
  85         }
  86 
  87         exm.select(other.exb);
  88         exm.select(other.exm);
  89 
  90         if (expr.length > 0) {
  91             if (other.length.max > 0) {
  92                 // TODO: make sure it is not an Oniguruma bug (casting unsigned int to int for arithmetic comparison)
  93                 int otherLengthMax = other.length.max;
  94                 if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) otherLengthMax = -1;
  95                 if (expr.length > otherLengthMax) expr.length = otherLengthMax;
  96                 if (expr.mmd.max == 0) {
  97                     exb.select(expr);
  98                 } else {
  99                     exm.select(expr);
 100                 }
 101             }
 102         } else if (other.expr.length > 0) {
 103             expr.copy(other.expr);
 104         }
 105 
 106         map.select(other.map);
 107         length.add(other.length);
 108     }
 109 
 110     public void altMerge(NodeOptInfo other, OptEnvironment env) {
 111         anchor.altMerge(other.anchor);
 112         exb.altMerge(other.exb, env);
 113         exm.altMerge(other.exm, env);
 114         expr.altMerge(other.expr, env);
 115         map.altMerge(other.map);
 116         length.altMerge(other.length);
 117     }
 118 
 119     public void setBound(MinMaxLen mmd) {
 120         exb.mmd.copy(mmd);
 121         expr.mmd.copy(mmd);
 122         map.mmd.copy(mmd);
 123     }
 124 
 125 }