3b8e7c0d2350372238bafd4fac33ecb4368b55bf
[org.ibex.core.git] / src / org / mozilla / javascript / regexp / NativeRegExpCtor.java
1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
2  *\r
3  * The contents of this file are subject to the Netscape Public\r
4  * License Version 1.1 (the "License"); you may not use this file\r
5  * except in compliance with the License. You may obtain a copy of\r
6  * the License at http://www.mozilla.org/NPL/\r
7  *\r
8  * Software distributed under the License is distributed on an "AS\r
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
10  * implied. See the License for the specific language governing\r
11  * rights and limitations under the License.\r
12  *\r
13  * The Original Code is Rhino code, released\r
14  * May 6, 1998.\r
15  *\r
16  * The Initial Developer of the Original Code is Netscape\r
17  * Communications Corporation.  Portions created by Netscape are\r
18  * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
19  * Rights Reserved.\r
20  *\r
21  * Contributor(s): \r
22  *\r
23  * Alternatively, the contents of this file may be used under the\r
24  * terms of the GNU Public License (the "GPL"), in which case the\r
25  * provisions of the GPL are applicable instead of those above.\r
26  * If you wish to allow use of your version of this file only\r
27  * under the terms of the GPL and not to allow others to use your\r
28  * version of this file under the NPL, indicate your decision by\r
29  * deleting the provisions above and replace them with the notice\r
30  * and other provisions required by the GPL.  If you do not delete\r
31  * the provisions above, a recipient may use your version of this\r
32  * file under either the NPL or the GPL.\r
33  */\r
34 \r
35 package org.mozilla.javascript.regexp;\r
36 \r
37 import org.mozilla.javascript.*;\r
38 import java.lang.reflect.Method;\r
39 \r
40 /**\r
41  * This class implements the RegExp constructor native object.\r
42  *\r
43  * Revision History:\r
44  * Implementation in C by Brendan Eich\r
45  * Initial port to Java by Norris Boyd from jsregexp.c version 1.36\r
46  * Merged up to version 1.38, which included Unicode support.\r
47  * Merged bug fixes in version 1.39.\r
48  * Merged JSFUN13_BRANCH changes up to 1.32.2.11\r
49  *\r
50  * @author Brendan Eich\r
51  * @author Norris Boyd\r
52  */\r
53 public class NativeRegExpCtor extends NativeFunction {\r
54 \r
55     public NativeRegExpCtor() {\r
56         functionName = "RegExp";\r
57     }\r
58     \r
59     public String getClassName() {\r
60         return "Function";\r
61     }\r
62 \r
63     public Object call(Context cx, Scriptable scope, Scriptable thisObj,\r
64                        Object[] args)\r
65     {\r
66         if (args.length > 0 && args[0] instanceof NativeRegExp &&\r
67             (args.length == 1 || args[1] == Undefined.instance))\r
68           {\r
69             return args[0];\r
70         }\r
71         return construct(cx, parent, args);\r
72     }\r
73 \r
74     public Scriptable construct(Context cx, Scriptable scope, Object[] args) {\r
75         NativeRegExp re = new NativeRegExp();\r
76         re.compile(cx, scope, args);\r
77         re.setPrototype(getClassPrototype(scope, "RegExp"));\r
78         re.setParentScope(getParentScope());\r
79         return re;\r
80     }\r
81 \r
82     static RegExpImpl getImpl() {\r
83         Context cx = Context.getCurrentContext();\r
84         return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);\r
85     }\r
86 \r
87     protected int getIdDefaultAttributes(int id) {\r
88         int shifted = id - idBase;\r
89         if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
90             switch (shifted) {\r
91                 case Id_multiline:\r
92                 case Id_STAR:\r
93                 case Id_input:\r
94                 case Id_UNDERSCORE:\r
95                     return PERMANENT;\r
96             }\r
97             return PERMANENT | READONLY;\r
98         }\r
99         return super.getIdDefaultAttributes(id);\r
100     }\r
101     \r
102     private static String stringResult(Object obj) {\r
103         return (obj == null) ? "" : obj.toString();\r
104     }\r
105 \r
106     protected Object getIdValue(int id) {\r
107         int shifted = id - idBase;\r
108         if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
109             RegExpImpl impl = getImpl();\r
110             switch (shifted) {\r
111                 case Id_multiline:\r
112                 case Id_STAR:\r
113                     return wrap_boolean(impl.multiline);\r
114 \r
115                 case Id_input:\r
116                 case Id_UNDERSCORE: \r
117                     return stringResult(impl.input);\r
118 \r
119                 case Id_lastMatch:\r
120                 case Id_AMPERSAND:\r
121                     return stringResult(impl.lastMatch);\r
122 \r
123                 case Id_lastParen:\r
124                 case Id_PLUS:\r
125                     return stringResult(impl.lastParen);\r
126 \r
127                 case Id_leftContext:\r
128                 case Id_BACK_QUOTE:\r
129                     return stringResult(impl.leftContext);\r
130 \r
131                 case Id_rightContext:\r
132                 case Id_QUOTE:\r
133                     return stringResult(impl.rightContext);\r
134             }\r
135             // Must be one of $1..$9, convert to 0..8\r
136             int substring_number = shifted - DOLLAR_ID_BASE - 1;\r
137             return impl.getParenSubString(substring_number).toString();\r
138         }\r
139         return super.getIdValue(id);\r
140     }\r
141     \r
142     protected void setIdValue(int id, Object value) {\r
143         switch (id - idBase) {\r
144             case Id_multiline:\r
145             case Id_STAR:\r
146                 getImpl().multiline = ScriptRuntime.toBoolean(value);\r
147                 return;\r
148 \r
149             case Id_input:\r
150             case Id_UNDERSCORE: \r
151                 getImpl().input = ScriptRuntime.toString(value); \r
152                 return;\r
153         }\r
154         super.setIdValue(id, value);\r
155     }\r
156 \r
157     protected String getIdName(int id) {\r
158         int shifted = id - idBase;\r
159         if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
160             switch (shifted) {\r
161                 case Id_multiline:    return "multiline";\r
162                 case Id_STAR:         return "$*";\r
163 \r
164                 case Id_input:        return "input";\r
165                 case Id_UNDERSCORE:   return "$_";\r
166 \r
167                 case Id_lastMatch:    return "lastMatch";\r
168                 case Id_AMPERSAND:    return "$&";\r
169 \r
170                 case Id_lastParen:    return "lastParen";\r
171                 case Id_PLUS:         return "$+";\r
172 \r
173                 case Id_leftContext:  return "leftContext";\r
174                 case Id_BACK_QUOTE:   return "$`";\r
175 \r
176                 case Id_rightContext: return "rightContext";\r
177                 case Id_QUOTE:        return "$'";\r
178             }\r
179             // Must be one of $1..$9, convert to 0..8\r
180             int substring_number = shifted - DOLLAR_ID_BASE - 1;\r
181             char[] buf = { '$', (char)('1' + substring_number) };\r
182             return new String(buf);\r
183         }\r
184         return super.getIdName(id);\r
185     }\r
186 \r
187     protected int maxInstanceId() {\r
188         // Note: check for idBase == 0 can not be done in constructor, \r
189         // because IdScriptable calls maxInstanceId in its constructor\r
190         // before NativeRegExpCtor constructor gets chance to run any code\r
191         if (idBase == 0) { idBase = super.maxInstanceId(); }\r
192         return idBase + MAX_INSTANCE_ID; \r
193     }\r
194 \r
195 // #string_id_map#\r
196 \r
197     private static final int\r
198         Id_multiline     = 1,\r
199         Id_STAR          = 2,  // #string=$*#\r
200 \r
201         Id_input         = 3,\r
202         Id_UNDERSCORE    = 4,  // #string=$_#\r
203 \r
204         Id_lastMatch     = 5,\r
205         Id_AMPERSAND     = 6,  // #string=$&#\r
206 \r
207         Id_lastParen     = 7,\r
208         Id_PLUS          = 8,  // #string=$+#\r
209 \r
210         Id_leftContext   = 9,\r
211         Id_BACK_QUOTE    = 10, // #string=$`#\r
212 \r
213         Id_rightContext  = 11,\r
214         Id_QUOTE         = 12, // #string=$'#\r
215         \r
216         DOLLAR_ID_BASE   = 12;\r
217         \r
218     private static final int\r
219         Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1#\r
220         Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2#\r
221         Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3#\r
222         Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4#\r
223         Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5#\r
224         Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6#\r
225         Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7#\r
226         Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8#\r
227         Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9#\r
228 \r
229         MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;\r
230 \r
231     protected int mapNameToId(String s) {\r
232         int id;\r
233 // #generated# Last update: 2001-05-24 16:09:31 GMT+02:00\r
234         L0: { id = 0; String X = null; int c;\r
235             L: switch (s.length()) {\r
236             case 2: switch (s.charAt(1)) {\r
237                 case '&': if (s.charAt(0)=='$') {id=Id_AMPERSAND; break L0;} break L;\r
238                 case '\'': if (s.charAt(0)=='$') {id=Id_QUOTE; break L0;} break L;\r
239                 case '*': if (s.charAt(0)=='$') {id=Id_STAR; break L0;} break L;\r
240                 case '+': if (s.charAt(0)=='$') {id=Id_PLUS; break L0;} break L;\r
241                 case '1': if (s.charAt(0)=='$') {id=Id_DOLLAR_1; break L0;} break L;\r
242                 case '2': if (s.charAt(0)=='$') {id=Id_DOLLAR_2; break L0;} break L;\r
243                 case '3': if (s.charAt(0)=='$') {id=Id_DOLLAR_3; break L0;} break L;\r
244                 case '4': if (s.charAt(0)=='$') {id=Id_DOLLAR_4; break L0;} break L;\r
245                 case '5': if (s.charAt(0)=='$') {id=Id_DOLLAR_5; break L0;} break L;\r
246                 case '6': if (s.charAt(0)=='$') {id=Id_DOLLAR_6; break L0;} break L;\r
247                 case '7': if (s.charAt(0)=='$') {id=Id_DOLLAR_7; break L0;} break L;\r
248                 case '8': if (s.charAt(0)=='$') {id=Id_DOLLAR_8; break L0;} break L;\r
249                 case '9': if (s.charAt(0)=='$') {id=Id_DOLLAR_9; break L0;} break L;\r
250                 case '_': if (s.charAt(0)=='$') {id=Id_UNDERSCORE; break L0;} break L;\r
251                 case '`': if (s.charAt(0)=='$') {id=Id_BACK_QUOTE; break L0;} break L;\r
252                 } break L;\r
253             case 5: X="input";id=Id_input; break L;\r
254             case 9: c=s.charAt(4);\r
255                 if (c=='M') { X="lastMatch";id=Id_lastMatch; }\r
256                 else if (c=='P') { X="lastParen";id=Id_lastParen; }\r
257                 else if (c=='i') { X="multiline";id=Id_multiline; }\r
258                 break L;\r
259             case 11: X="leftContext";id=Id_leftContext; break L;\r
260             case 12: X="rightContext";id=Id_rightContext; break L;\r
261             }\r
262             if (X!=null && X!=s && !X.equals(s)) id = 0;\r
263         }\r
264 // #/generated#\r
265 // #/string_id_map#\r
266 \r
267         return (id != 0) ? idBase + id : super.mapNameToId(s); \r
268     }\r
269     \r
270     private static int idBase;\r
271 }\r