NodeOptInfo.java revision 953:221a84ef44c0
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
22public 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(final 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(final 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(final NodeOptInfo other) {
55        final 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        final boolean exbReach = exb.reachEnd;
71        final 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(final NodeOptInfo other, final 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(final MinMaxLen mmd) {
120        exb.mmd.copy(mmd);
121        expr.mmd.copy(mmd);
122        map.mmd.copy(mmd);
123    }
124
125}
126