Skip to content

Commit

Permalink
împlement sticky support
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri committed Feb 14, 2022
1 parent d6907c6 commit 376e744
Show file tree
Hide file tree
Showing 4 changed files with 407 additions and 54 deletions.
81 changes: 62 additions & 19 deletions src/org/mozilla/javascript/regexp/NativeRegExp.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class NativeRegExp extends IdScriptableObject {
public static final int JSREG_GLOB = 0x1; // 'g' flag: global
public static final int JSREG_FOLD = 0x2; // 'i' flag: fold
public static final int JSREG_MULTILINE = 0x4; // 'm' flag: multiline
public static final int JSREG_STICKY = 0x8; // 'y' flag: sticky

// type of match to perform
public static final int TEST = 0;
Expand Down Expand Up @@ -187,10 +188,15 @@ public String toString() {
buf.append("(?:)");
}
buf.append('/');
appendFlags(buf);
return buf.toString();
}

private void appendFlags(StringBuilder buf) {
if ((re.flags & JSREG_GLOB) != 0) buf.append('g');
if ((re.flags & JSREG_FOLD) != 0) buf.append('i');
if ((re.flags & JSREG_MULTILINE) != 0) buf.append('m');
return buf.toString();
if ((re.flags & JSREG_STICKY) != 0) buf.append('y');
}

NativeRegExp() {}
Expand Down Expand Up @@ -234,24 +240,25 @@ Object execSub(Context cx, Scriptable scopeObj, Object[] args, int matchType) {
} else {
str = ScriptRuntime.toString(args[0]);
}

boolean globalOrSticky = (re.flags & JSREG_GLOB) != 0 || (re.flags & JSREG_STICKY) != 0;
double d = 0;
if ((re.flags & JSREG_GLOB) != 0) {
if (globalOrSticky) {
d = ScriptRuntime.toInteger(lastIndex);

if (d < 0 || str.length() < d) {
setLastIndex(ScriptRuntime.zeroObj);
return null;
}
}

Object rval;
if (d < 0 || str.length() < d) {
setLastIndex(ScriptRuntime.zeroObj);
rval = null;
} else {
int indexp[] = {(int) d};
rval = executeRegExp(cx, scopeObj, reImpl, str, indexp, matchType);
if ((re.flags & JSREG_GLOB) != 0) {
if (rval == null || rval == Undefined.instance) {
setLastIndex(ScriptRuntime.zeroObj);
} else {
setLastIndex(Double.valueOf(indexp[0]));
}
int indexp[] = {(int) d};
Object rval = executeRegExp(cx, scopeObj, reImpl, str, indexp, matchType);
if (globalOrSticky) {
if (rval == null || rval == Undefined.instance) {
setLastIndex(ScriptRuntime.zeroObj);
} else {
setLastIndex(Double.valueOf(indexp[0]));
}
}
return rval;
Expand All @@ -271,6 +278,8 @@ static RECompiled compileRE(Context cx, String str, String global, boolean flat)
f = JSREG_FOLD;
} else if (c == 'm') {
f = JSREG_MULTILINE;
} else if (c == 'y') {
f = JSREG_STICKY;
} else {
reportError("msg.invalid.re.flag", String.valueOf(c));
}
Expand Down Expand Up @@ -2334,6 +2343,11 @@ private static boolean matchRegExp(
&& upcase(matchCh) == upcase((char) anchorCh))) {
break;
}

if ((gData.regexp.flags & JSREG_STICKY) != 0) {
return false;
}

++i;
}
}
Expand All @@ -2353,6 +2367,11 @@ && upcase(matchCh) == upcase((char) anchorCh))) {
gData.skipped = end;
return false;
}

if ((gData.regexp.flags & JSREG_STICKY) != 0) {
return false;
}

i = start + gData.skipped;
}
return false;
Expand Down Expand Up @@ -2495,10 +2514,12 @@ private static void reportError(String messageId, String arg) {

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

@Override
protected int getMaxInstanceId() {
Expand All @@ -2515,6 +2536,9 @@ protected int findInstanceIdInfo(String s) {
case "source":
id = Id_source;
break;
case "flags":
id = Id_flags;
break;
case "global":
id = Id_global;
break;
Expand All @@ -2524,6 +2548,9 @@ protected int findInstanceIdInfo(String s) {
case "multiline":
id = Id_multiline;
break;
case "sticky":
id = Id_sticky;
break;
default:
id = 0;
break;
Expand All @@ -2537,9 +2564,11 @@ 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 @@ -2555,12 +2584,16 @@ 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 @@ -2572,12 +2605,20 @@ 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 @@ -2596,9 +2637,11 @@ 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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
*/
package org.mozilla.javascript.tests;

import static org.junit.Assert.*;

import java.math.BigInteger;
import junit.framework.TestCase;
import org.junit.Test;
Expand Down
Loading

0 comments on commit 376e744

Please sign in to comment.