public override Scriptable Construct(Context cx, Scriptable scope, object[] args) { NativeRegExp re = new NativeRegExp(); re.Compile(cx, scope, args); ScriptRuntime.SetBuiltinProtoAndParent(re, scope, TopLevel.Builtins.RegExp); return re; }
/// <summary>Analog of C match_or_replace.</summary> /// <remarks>Analog of C match_or_replace.</remarks> private static object MatchOrReplace(Context cx, Scriptable scope, Scriptable thisObj, object[] args, RegExpImpl reImpl, GlobData data, bool forceFlat) { NativeRegExp re; string str = ScriptRuntime.ToString(thisObj); data.str = str; Scriptable topScope = ScriptableObject.GetTopLevelScope(scope); if (args.Length == 0) { RECompiled compiled = NativeRegExp.CompileRE(cx, string.Empty, string.Empty, false); re = new NativeRegExp(topScope, compiled); } else { if (args[0] is NativeRegExp) { re = (NativeRegExp)args[0]; } else { string src = ScriptRuntime.ToString(args[0]); string opt; if (data.optarg < args.Length) { args[0] = src; opt = ScriptRuntime.ToString(args[data.optarg]); } else { opt = null; } RECompiled compiled = NativeRegExp.CompileRE(cx, src, opt, forceFlat); re = new NativeRegExp(topScope, compiled); } } data.global = (re.GetFlags() & NativeRegExp.JSREG_GLOB) != 0; int[] indexp = new int[] { 0 }; object result = null; if (data.mode == RegExpProxyConstants.RA_SEARCH) { result = re.ExecuteRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result != null && result.Equals(true)) { result = Sharpen.Extensions.ValueOf(reImpl.leftContext.length); } else { result = Sharpen.Extensions.ValueOf(-1); } } else { if (data.global) { re.lastIndex = 0; for (int count = 0; indexp[0] <= str.Length; count++) { result = re.ExecuteRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result == null || !result.Equals(true)) { break; } if (data.mode == RegExpProxyConstants.RA_MATCH) { Match_glob(data, cx, scope, count, reImpl); } else { if (data.mode != RegExpProxyConstants.RA_REPLACE) { Kit.CodeBug(); } SubString lastMatch = reImpl.lastMatch; int leftIndex = data.leftIndex; int leftlen = lastMatch.index - leftIndex; data.leftIndex = lastMatch.index + lastMatch.length; Replace_glob(data, cx, scope, reImpl, leftIndex, leftlen); } if (reImpl.lastMatch.length == 0) { if (indexp[0] == str.Length) { break; } indexp[0]++; } } } else { result = re.ExecuteRegExp(cx, scope, reImpl, str, indexp, ((data.mode == RegExpProxyConstants.RA_REPLACE) ? NativeRegExp.TEST : NativeRegExp.MATCH)); } } return result; }
// 'g' flag: global // 'i' flag: fold // 'm' flag: multiline //type of match to perform // private static final byte REOP_UCFLAT = 20; /* flat Unicode string; len immediate counts chars */ // private static final byte REOP_UCFLATi = 21; /* case-independent REOP_UCFLAT */ // private static final byte REOP_DOTSTAR = 33; /* optimize .* to use a single opcode */ // private static final byte REOP_ANCHOR = 34; /* like .* but skips left context to unanchored r.e. */ // private static final byte REOP_EOLONLY = 35; /* $ not preceded by any pattern */ // private static final byte REOP_BACKREFi = 37; /* case-independent REOP_BACKREF */ // private static final byte REOP_LPARENNON = 40; /* non-capturing version of REOP_LPAREN */ // private static final byte REOP_ENDALT = 56; /* end of final alternate */ public static void Init(Context cx, Scriptable scope, bool @sealed) { Rhino.Regexp.NativeRegExp proto = new Rhino.Regexp.NativeRegExp(); proto.re = CompileRE(cx, string.Empty, null, false); proto.ActivatePrototypeMap(MAX_PROTOTYPE_ID); proto.SetParentScope(scope); proto.SetPrototype(GetObjectPrototype(scope)); NativeRegExpCtor ctor = new NativeRegExpCtor(); // Bug #324006: ECMA-262 15.10.6.1 says "The initial value of // RegExp.prototype.constructor is the builtin RegExp constructor." proto.DefineProperty("constructor", ctor, ScriptableObject.DONTENUM); ScriptRuntime.SetFunctionProtoAndParent(ctor, scope); ctor.SetImmunePrototypeProperty(proto); if (@sealed) { proto.SealObject(); ctor.SealObject(); } DefineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM); }