Add default arguments for regexp flags.

Review URL: https://chromereviews.googleplex.com/3558016

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@213 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ngeoffray@google.com 2011-10-07 12:47:56 +00:00
parent 312a19af39
commit 8b8b4844fa
13 changed files with 83 additions and 69 deletions

View file

@ -12,17 +12,17 @@ class Device {
/**
* The regular expression for detecting an iPhone or iPod.
*/
static final _IPHONE_REGEX = const RegExp('iPhone|iPod', '');
static final _IPHONE_REGEX = const RegExp('iPhone|iPod');
/**
* The regular expression for detecting an iPhone or iPod or iPad.
*/
static final _MOBILE_SAFARI_REGEX = const RegExp('iPhone|iPod|iPad', '');
static final _MOBILE_SAFARI_REGEX = const RegExp('iPhone|iPod|iPad');
/**
* The regular expression for detecting an iPhone or iPod or iPad simulator.
*/
static final _APPLE_SIM_REGEX = const RegExp('iP.*Simulator', '');
static final _APPLE_SIM_REGEX = const RegExp('iP.*Simulator');
/**
* Gets the browser's user agent. Using this function allows tests to inject

View file

@ -70,7 +70,7 @@ class BenchUtil {
StringBuffer sb = new StringBuffer();
int pos = 0;
for (Match match in new RegExp(pattern, '').allMatches(s)) {
for (Match match in new RegExp(pattern).allMatches(s)) {
sb.add(s.substring(pos, match.start()));
sb.add(replacement(match));
pos = match.end();

View file

@ -130,7 +130,7 @@ class Uri {
'([^?#]+)?' + // path
'(?:\\?([^#]*))?' + // query
'(?:#(.*))?' + // fragment
'\$', '');
'\$');
}
return _splitReLazy;
}

View file

@ -3,11 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
class JSSyntaxRegExp implements RegExp {
const JSSyntaxRegExp(String pattern, String flags)
: this.pattern = pattern, this.flags = flags;
const JSSyntaxRegExp(
String this.pattern,
[bool this.multiLine = false,
bool this.ignoreCase = false]);
final String pattern;
final String flags;
final bool multiLine;
final bool ignoreCase;
Iterable<Match> allMatches(String str) {
return new _LazyAllMatches(this, str);
@ -20,8 +23,11 @@ class JSSyntaxRegExp implements RegExp {
static String _pattern(JSSyntaxRegExp regexp) native {
return regexp.pattern;
}
static String _flags(JSSyntaxRegExp regexp) native {
return regexp.flags;
static bool _multiLine(JSSyntaxRegExp regexp) native {
return regexp.multiLine;
}
static bool _ignoreCase(JSSyntaxRegExp regexp) native {
return regexp.ignoreCase;
}
}

View file

@ -60,6 +60,8 @@ function native__LazyAllMatchesIterator__computeNextMatch(regExp, str) {
}
function $DartRegExpToJSRegExp(exp) {
return new RegExp(native_JSSyntaxRegExp__pattern(exp),
native_JSSyntaxRegExp__flags(exp) + 'g');
var flags = "g";
if (native_JSSyntaxRegExp__multiLine(exp)) flags += "m";
if (native_JSSyntaxRegExp__ignoreCase(exp)) flags += "i";
return new RegExp(native_JSSyntaxRegExp__pattern(exp), flags);
}

View file

@ -11,7 +11,7 @@
* and iterates through the returned iterable of [Match] objects.
*
* [:
* RegExp exp = const RegExp(@"(\w+)", "");
* RegExp exp = const RegExp(@"(\w+)");
* String str = "Parse my string";
* Iterable<Match> matches = exp.allMatches(str, exp);
* for (Match m in matches) {
@ -84,7 +84,7 @@ interface Match {
* a string.
*
* [:
* RegExp exp = const RegExp(@"(\w+)", "");
* RegExp exp = const RegExp(@"(\w+)");
* String str = "Parse my string";
* Iterable<Match> matches = exp.allMatches(str, exp);
* :]
@ -92,9 +92,10 @@ interface Match {
interface RegExp extends Pattern factory JSSyntaxRegExp {
/**
* Constructs a regular expression.
* Constructs a regular expression. The default implementation of a
* [RegExp] sets [multiLine] and [ignoreCase] to false.
*/
const RegExp(String pattern, String flags);
const RegExp(String pattern, [bool multiLine, bool ignoreCase]);
/**
* Searches for the first match of the regular expression
@ -125,7 +126,12 @@ interface RegExp extends Pattern factory JSSyntaxRegExp {
final String pattern;
/**
* The flags for this regular expression.
* Whether this regular expression matches multiple lines.
*/
final String flags;
final bool multiLine;
/**
* Whether this regular expression is case insensitive.
*/
final bool ignoreCase;
}

View file

@ -13,11 +13,16 @@
namespace dart {
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_factory, 3) {
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_factory, 4) {
ASSERT(TypeArguments::CheckedHandle(arguments->At(0)).IsNull());
const String& pattern = String::CheckedHandle(arguments->At(1));
const String& flags = String::CheckedHandle(arguments->At(2));
const JSRegExp& new_regex = JSRegExp::Handle(Jscre::Compile(pattern, flags));
const Instance& handle_multi_line = Instance::CheckedHandle(arguments->At(2));
const Instance& handle_ignore_case =
Instance::CheckedHandle(arguments->At(3));
bool ignore_case = handle_ignore_case.raw() == Bool::True();
bool multi_line = handle_multi_line.raw() == Bool::True();
const JSRegExp& new_regex = JSRegExp::Handle(
Jscre::Compile(pattern, multi_line, ignore_case));
arguments->SetReturn(new_regex);
}
@ -29,9 +34,16 @@ DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_getPattern, 1) {
}
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_getFlags, 1) {
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_multiLine, 1) {
const JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->At(0));
const String& result = String::Handle(String::New(regexp.Flags()));
const Bool& result = Bool::Handle(Bool::Get(regexp.is_multi_line()));
arguments->SetReturn(result);
}
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_ignoreCase, 1) {
const JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->At(0));
const Bool& result = Bool::Handle(Bool::Get(regexp.is_ignore_case()));
arguments->SetReturn(result);
}

View file

@ -50,8 +50,10 @@ class JSRegExpMatch implements Match {
class JSSyntaxRegExp implements RegExp {
const factory JSSyntaxRegExp(String pattern, String flags)
native "JSSyntaxRegExp_factory";
const factory JSSyntaxRegExp(
String pattern,
[bool multiLine = false,
bool ignoreCase = false]) native "JSSyntaxRegExp_factory";
Match firstMatch(String str) {
List match = _ExecuteMatch(str, 0);
@ -92,7 +94,9 @@ class JSSyntaxRegExp implements RegExp {
String get pattern() native "JSSyntaxRegExp_getPattern";
String get flags() native "JSSyntaxRegExp_getFlags";
bool get multiLine() native "JSSyntaxRegExp_multiLine";
bool get ignoreCase() native "JSSyntaxRegExp_ignoreCase";
int get _groupCount() native "JSSyntaxRegExp_getGroupCount";

View file

@ -53,40 +53,28 @@ static void ThrowExceptionOnError(const String& pattern,
}
RawJSRegExp* Jscre::Compile(const String& pattern, const String& flags) {
RawJSRegExp* Jscre::Compile(const String& pattern,
bool multi_line,
bool ignore_case) {
// First convert the pattern to UTF16 format as the jscre library expects
// strings to be in UTF16 encoding.
uint16_t* two_byte_pattern = GetTwoByteData(pattern);
// Parse the flags.
jscre::JSRegExpIgnoreCaseOption ignore_case = jscre::JSRegExpDoNotIgnoreCase;
// A Dart regexp is always global.
bool is_global = true;
jscre::JSRegExpMultilineOption multi_line = jscre::JSRegExpSingleLine;
for (int i = 0; i < flags.Length(); i++) {
switch (flags.CharAt(i)) {
case 'i':
ignore_case = jscre::JSRegExpIgnoreCase;
break;
case 'm':
multi_line = jscre::JSRegExpMultiline;
break;
default:
// Unrecognized flag, throw an exception.
ThrowExceptionOnError(pattern,
"Unknown flag specified for regular expression");
UNREACHABLE();
return JSRegExp::null();
}
}
// Parse the flags.
jscre::JSRegExpIgnoreCaseOption jscre_ignore_case = ignore_case ?
jscre::JSRegExpIgnoreCase : jscre::JSRegExpDoNotIgnoreCase;
jscre::JSRegExpMultilineOption jscre_multi_line = multi_line ?
jscre::JSRegExpMultiline : jscre::JSRegExpSingleLine;
// Compile the regex by calling into the jscre library.
uint32_t num_bracket_expressions = 0;
const char* error_msg = NULL;
jscre::JSRegExp* jscregexp = jscre::jsRegExpCompile(two_byte_pattern,
pattern.Length(),
ignore_case,
multi_line,
jscre_ignore_case,
jscre_multi_line,
&num_bracket_expressions,
&error_msg,
&JSREMalloc,
@ -102,10 +90,10 @@ RawJSRegExp* Jscre::Compile(const String& pattern, const String& flags) {
JSRegExp& regexp =
JSRegExp::Handle(JSRegExp::FromDataStartAddress(jscregexp));
regexp.set_pattern(pattern);
if (multi_line == jscre::JSRegExpMultiline) {
if (jscre_multi_line == jscre::JSRegExpMultiline) {
regexp.set_is_multi_line();
}
if (ignore_case == jscre::JSRegExpIgnoreCase) {
if (jscre_ignore_case == jscre::JSRegExpIgnoreCase) {
regexp.set_is_ignore_case();
}
if (is_global) {

View file

@ -12,7 +12,9 @@ namespace dart {
class Jscre : public AllStatic {
public:
static RawJSRegExp* Compile(const String& pattern, const String& flags);
static RawJSRegExp* Compile(const String& pattern,
bool multi_line,
bool ignore_case);
static RawArray* Execute(const JSRegExp& regex,
const String& str,
intptr_t index);

View file

@ -55,9 +55,10 @@ namespace dart {
V(Double_truncate, 1) \
V(Double_toInt, 1) \
V(Double_pow, 2) \
V(JSSyntaxRegExp_factory, 3) \
V(JSSyntaxRegExp_factory, 4) \
V(JSSyntaxRegExp_getPattern, 1) \
V(JSSyntaxRegExp_getFlags, 1) \
V(JSSyntaxRegExp_multiLine, 1) \
V(JSSyntaxRegExp_ignoreCase, 1) \
V(JSSyntaxRegExp_getGroupCount, 1) \
V(JSSyntaxRegExp_ExecuteMatch, 3) \
V(ObjectArray_allocate, 2) \

View file

@ -187,22 +187,13 @@ LangGuideTest/08_Expressions/08_2_Assignment_Operator/Variable_Or_Parameter_Assi
LangGuideTest/08_Expressions/A01/t02: Fail,Okay
# end of main argument list.
# RegExp flags do not contain "g" anymore.
LibTest/core/RegExp/RegExp/RegExp/A01/t01: Fail
# Following tests use the old syntax for default argument values.
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A01/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.15_NonEmptyClassRanges/RegExp/firstMatch/NonEmptyClassRanges/A01/t03: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A05/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A02/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A04/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A03/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.12_CharacterClassEscape/RegExp/firstMatch/CharacterClassEscape/A05/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.12_CharacterClassEscape/RegExp/firstMatch/CharacterClassEscape/A01/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.12_CharacterClassEscape/RegExp/firstMatch/CharacterClassEscape/A06/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.12_CharacterClassEscape/RegExp/firstMatch/CharacterClassEscape/A02/t01: Fail
LibTest/core/RegExp/hasMatch/Pattern_semantics/15.10.2.11_DecimalEscape/RegExp/hasMatch/DecimalEscape/A01/t04: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.11_DecimalEscape/RegExp/firstMatch/DecimalEscape/A01/t04: Fail
# Following tests use the old syntax for default argument values.
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.06_Assertion/RegExp/firstMatch/Assertion/A01/t01: Fail
LibTest/core/RegExp/firstMatch/Pattern_semantics/15.10.2.15_NonEmptyClassRanges/RegExp/firstMatch/NonEmptyClassRanges/A01/t03: Fail
# Rationals are not part of the language anymore so the test below which
# uses Rationals is incorrect. Marking as Fail,Okay

View file

@ -5,20 +5,22 @@
class RegExp1Test {
static testMain() {
RegExp exp1 = const RegExp("bar|foo", "");
RegExp exp1 = const RegExp("bar|foo");
Expect.equals(true, exp1.hasMatch("foo"));
Expect.equals(true, exp1.hasMatch("bar"));
Expect.equals(false, exp1.hasMatch("gim"));
Expect.equals(true, exp1.hasMatch("just foo"));
Expect.equals("bar|foo", exp1.pattern);
Expect.equals("", exp1.flags);
Expect.equals(false, exp1.multiLine);
Expect.equals(false, exp1.ignoreCase);
RegExp exp2 = const RegExp("o+", "i");
RegExp exp2 = const RegExp("o+", ignoreCase: true);
Expect.equals(true, exp2.hasMatch("this looks good"));
Expect.equals(true, exp2.hasMatch("fOO"));
Expect.equals(false, exp2.hasMatch("bar"));
Expect.equals("o+", exp2.pattern);
Expect.equals("i", exp2.flags);
Expect.equals(true, exp2.ignoreCase);
Expect.equals(false, exp2.multiLine);
}
}