Skip to content

Commit

Permalink
convert RegEx properties
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri committed Feb 15, 2022
1 parent 376e744 commit ae78dbf
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 88 deletions.
174 changes: 116 additions & 58 deletions src/org/mozilla/javascript/regexp/NativeRegExp.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ public class NativeRegExp extends IdScriptableObject {

private static final int ANCHOR_BOL = -2;

private static final SymbolKey GET_FLAGS = new SymbolKey("[Symbol.getFlags]");
private static final SymbolKey GET_GLOBAL = new SymbolKey("[Symbol.getGlobal]");
private static final SymbolKey GET_IGNORE_CASE = new SymbolKey("[Symbol.getIgnoreCase]");
private static final SymbolKey GET_MULTILINE = new SymbolKey("[Symbol.getMultiline]");
private static final SymbolKey GET_STICKY = new SymbolKey("[Symbol.getSticky]");

public static void init(Context cx, Scriptable scope, boolean sealed) {

NativeRegExp proto = NativeRegExpInstantiator.withLanguageVersion(cx.getLanguageVersion());
Expand All @@ -126,6 +132,36 @@ public static void init(Context cx, Scriptable scope, boolean sealed) {

ctor.setImmunePrototypeProperty(proto);

ScriptableObject desc = (ScriptableObject) cx.newObject(scope);
desc.put("enumerable", desc, Boolean.FALSE);
desc.put("configurable", desc, Boolean.TRUE);
desc.put("get", desc, proto.get(GET_FLAGS, proto));
proto.defineOwnProperty(cx, "flags", desc);

desc = (ScriptableObject) cx.newObject(scope);
desc.put("enumerable", desc, Boolean.FALSE);
desc.put("configurable", desc, Boolean.TRUE);
desc.put("get", desc, proto.get(GET_GLOBAL, proto));
proto.defineOwnProperty(cx, "global", desc);

desc = (ScriptableObject) cx.newObject(scope);
desc.put("enumerable", desc, Boolean.FALSE);
desc.put("configurable", desc, Boolean.TRUE);
desc.put("get", desc, proto.get(GET_IGNORE_CASE, proto));
proto.defineOwnProperty(cx, "ignoreCase", desc);

desc = (ScriptableObject) cx.newObject(scope);
desc.put("enumerable", desc, Boolean.FALSE);
desc.put("configurable", desc, Boolean.TRUE);
desc.put("get", desc, proto.get(GET_MULTILINE, proto));
proto.defineOwnProperty(cx, "multiline", desc);

desc = (ScriptableObject) cx.newObject(scope);
desc.put("enumerable", desc, Boolean.FALSE);
desc.put("configurable", desc, Boolean.TRUE);
desc.put("get", desc, proto.get(GET_STICKY, proto));
proto.defineOwnProperty(cx, "sticky", desc);

if (sealed) {
proto.sealObject();
ctor.sealObject();
Expand Down Expand Up @@ -2512,14 +2548,7 @@ private static void reportError(String messageId, String arg) {
throw ScriptRuntime.constructError("SyntaxError", msg);
}

private static final int Id_lastIndex = 1,
Id_source = 2,
Id_flags = 3,
Id_global = 4,
Id_ignoreCase = 5,
Id_multiline = 6,
Id_sticky = 7,
MAX_INSTANCE_ID = 7;
private static final int Id_lastIndex = 1, Id_source = 2, MAX_INSTANCE_ID = Id_source;

@Override
protected int getMaxInstanceId() {
Expand All @@ -2536,21 +2565,6 @@ protected int findInstanceIdInfo(String s) {
case "source":
id = Id_source;
break;
case "flags":
id = Id_flags;
break;
case "global":
id = Id_global;
break;
case "ignoreCase":
id = Id_ignoreCase;
break;
case "multiline":
id = Id_multiline;
break;
case "sticky":
id = Id_sticky;
break;
default:
id = 0;
break;
Expand All @@ -2564,11 +2578,6 @@ protected int findInstanceIdInfo(String s) {
attr = lastIndexAttr;
break;
case Id_source:
case Id_flags:
case Id_global:
case Id_ignoreCase:
case Id_multiline:
case Id_sticky:
attr = PERMANENT | READONLY | DONTENUM;
break;
default:
Expand All @@ -2584,16 +2593,6 @@ protected String getInstanceIdName(int id) {
return "lastIndex";
case Id_source:
return "source";
case Id_flags:
return "flags";
case Id_global:
return "global";
case Id_ignoreCase:
return "ignoreCase";
case Id_multiline:
return "multiline";
case Id_sticky:
return "sticky";
}
return super.getInstanceIdName(id);
}
Expand All @@ -2605,20 +2604,6 @@ protected Object getInstanceIdValue(int id) {
return lastIndex;
case Id_source:
return new String(re.source);
case Id_flags:
{
StringBuilder buf = new StringBuilder();
appendFlags(buf);
return buf.toString();
}
case Id_global:
return ScriptRuntime.wrapBoolean((re.flags & JSREG_GLOB) != 0);
case Id_ignoreCase:
return ScriptRuntime.wrapBoolean((re.flags & JSREG_FOLD) != 0);
case Id_multiline:
return ScriptRuntime.wrapBoolean((re.flags & JSREG_MULTILINE) != 0);
case Id_sticky:
return ScriptRuntime.wrapBoolean((re.flags & JSREG_STICKY) != 0);
}
return super.getInstanceIdValue(id);
}
Expand All @@ -2637,11 +2622,6 @@ protected void setInstanceIdValue(int id, Object value) {
setLastIndex(value);
return;
case Id_source:
case Id_flags:
case Id_global:
case Id_ignoreCase:
case Id_multiline:
case Id_sticky:
return;
}
super.setInstanceIdValue(id, value);
Expand All @@ -2667,6 +2647,26 @@ protected void initPrototypeId(int id) {
initPrototypeMethod(REGEXP_TAG, id, SymbolKey.SEARCH, "[Symbol.search]", 1);
return;
}
if (id == SymbolId_getFlags) {
initPrototypeMethod(REGEXP_TAG, id, GET_FLAGS, "get flags", 0);
return;
}
if (id == SymbolId_getGlobal) {
initPrototypeMethod(REGEXP_TAG, id, GET_GLOBAL, "get global", 0);
return;
}
if (id == SymbolId_getIgnoreCase) {
initPrototypeMethod(REGEXP_TAG, id, GET_IGNORE_CASE, "get ignoreCase", 0);
return;
}
if (id == SymbolId_getMultiline) {
initPrototypeMethod(REGEXP_TAG, id, GET_MULTILINE, "get multiline", 0);
return;
}
if (id == SymbolId_getSticky) {
initPrototypeMethod(REGEXP_TAG, id, GET_STICKY, "get sticky", 0);
return;
}

String s;
int arity;
Expand Down Expand Up @@ -2728,6 +2728,21 @@ public Object execIdCall(
case Id_prefix:
return realThis(thisObj, f).execSub(cx, scope, args, PREFIX);

case SymbolId_getFlags:
return realThis(thisObj, f).js_getFlags();

case SymbolId_getGlobal:
return realThis(thisObj, f).js_getGlobal();

case SymbolId_getIgnoreCase:
return realThis(thisObj, f).js_getIgnoreCase();

case SymbolId_getMultiline:
return realThis(thisObj, f).js_getMultiline();

case SymbolId_getSticky:
return realThis(thisObj, f).js_getSticky();

case SymbolId_match:
return realThis(thisObj, f).execSub(cx, scope, args, MATCH);

Expand All @@ -2751,6 +2766,22 @@ protected int findPrototypeId(Symbol k) {
if (SymbolKey.SEARCH.equals(k)) {
return SymbolId_search;
}

if (GET_FLAGS.equals(k)) {
return SymbolId_getFlags;
}
if (GET_GLOBAL.equals(k)) {
return SymbolId_getGlobal;
}
if (GET_IGNORE_CASE.equals(k)) {
return SymbolId_getIgnoreCase;
}
if (GET_MULTILINE.equals(k)) {
return SymbolId_getMultiline;
}
if (GET_STICKY.equals(k)) {
return SymbolId_getSticky;
}
return 0;
}

Expand Down Expand Up @@ -2783,6 +2814,28 @@ protected int findPrototypeId(String s) {
return id;
}

private Object js_getFlags() {
StringBuilder buf = new StringBuilder();
appendFlags(buf);
return buf.toString();
}

private Object js_getGlobal() {
return ScriptRuntime.wrapBoolean((re.flags & JSREG_GLOB) != 0);
}

private Object js_getIgnoreCase() {
return ScriptRuntime.wrapBoolean((re.flags & JSREG_FOLD) != 0);
}

private Object js_getMultiline() {
return ScriptRuntime.wrapBoolean((re.flags & JSREG_MULTILINE) != 0);
}

private Object js_getSticky() {
return ScriptRuntime.wrapBoolean((re.flags & JSREG_STICKY) != 0);
}

private static final int Id_compile = 1,
Id_toString = 2,
Id_toSource = 3,
Expand All @@ -2791,7 +2844,12 @@ protected int findPrototypeId(String s) {
Id_prefix = 6,
SymbolId_match = 7,
SymbolId_search = 8,
MAX_PROTOTYPE_ID = SymbolId_search;
SymbolId_getFlags = 9,
SymbolId_getGlobal = 10,
SymbolId_getIgnoreCase = 11,
SymbolId_getMultiline = 12,
SymbolId_getSticky = 13,
MAX_PROTOTYPE_ID = SymbolId_getSticky;

private RECompiled re;
Object lastIndex = ScriptRuntime.zeroObj; /* index after last match, for //g iterator */
Expand Down
43 changes: 38 additions & 5 deletions testsrc/org/mozilla/javascript/tests/NativeRegExpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import static org.junit.Assert.assertEquals;

import org.junit.Ignore;
import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
Expand Down Expand Up @@ -303,7 +304,8 @@ public void matchStickyAndGlobal() throws Exception {
}

/** @throws Exception if an error occurs */
// TODO @Test
@Ignore
@Test
public void matchStickyAndGlobalSymbol() throws Exception {
final String script =
"var result = /a/yg[Symbol.match]('aaba');\n"
Expand All @@ -315,17 +317,48 @@ public void matchStickyAndGlobalSymbol() throws Exception {
}

/** @throws Exception if an error occurs */
// TODO @Test
@Test
public void flagsPropery() throws Exception {
testPropery("0-function-undefined-true-false-undefined", "flags");
}

/** @throws Exception if an error occurs */
@Test
public void globalPropery() throws Exception {
testPropery("0-function-undefined-true-false-undefined", "global");
}

/** @throws Exception if an error occurs */
@Test
public void ignoreCasePropery() throws Exception {
testPropery("0-function-undefined-true-false-undefined", "ignoreCase");
}

/** @throws Exception if an error occurs */
@Test
public void multilinePropery() throws Exception {
testPropery("0-function-undefined-true-false-undefined", "multiline");
}

/** @throws Exception if an error occurs */
@Test
public void stickyPropery() throws Exception {
testPropery("0-function-undefined-true-false-undefined", "sticky");
}

private static void testPropery(String expected, String property) throws Exception {
final String script =
"var get = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');\n"
+ "var res = '';" // + get.get.length;\n"
"var get = Object.getOwnPropertyDescriptor(RegExp.prototype, '"
+ property
+ "');\n"
+ "var res = '' + get.get.length;\n"
+ "var res = res + '-' + typeof get.get;\n"
+ "res = res + '-' + get.value;\n"
+ "res = res + '-' + get.configurable;\n"
+ "res = res + '-' + get.enumerable;\n"
+ "res = res + '-' + get.writable;\n"
+ "res;";
test("0-undefined-true-false-undefined", script);
test(expected, script);
}

private static void test(final String expected, final String script) {
Expand Down
Loading

0 comments on commit ae78dbf

Please sign in to comment.