mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:20:36 +00:00
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:
parent
312a19af39
commit
8b8b4844fa
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -130,7 +130,7 @@ class Uri {
|
|||
'([^?#]+)?' + // path
|
||||
'(?:\\?([^#]*))?' + // query
|
||||
'(?:#(.*))?' + // fragment
|
||||
'\$', '');
|
||||
'\$');
|
||||
}
|
||||
return _splitReLazy;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue