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 */
20package jdk.nashorn.internal.runtime.regexp.joni;
21
22@SuppressWarnings("javadoc")
23public 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}
131