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 
setBoundNode(final MinMaxLen mmd)31     public void setBoundNode(final MinMaxLen mmd) {
32         exb.mmd.copy(mmd);
33         expr.mmd.copy(mmd);
34         map.mmd.copy(mmd);
35     }
36 
clear()37     public void clear() {
38         length.clear();
39         anchor.clear();
40         exb.clear();
41         exm.clear();
42         expr.clear();
43         map.clear();
44     }
45 
copy(final NodeOptInfo other)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 
concatLeftNode(final NodeOptInfo other)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 
altMerge(final NodeOptInfo other, final OptEnvironment env)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 
setBound(final MinMaxLen mmd)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 }
131