blob: ef73b1cd87fb02817670a2cf039886d63ff20b05 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Patch file for dart:coreimpl classes.
// Patch for String implementation.
// TODO(ager): Split out into date_patch.dart and allow #source
// in patch files?
patch class StringImplementation {
patch static String _fromCharCodes(List<int> charCodes) {
checkNull(charCodes);
if (!isJsArray(charCodes)) {
if (charCodes is !List) throw new ArgumentError(charCodes);
charCodes = new List.from(charCodes);
}
return Primitives.stringFromCharCodes(charCodes);
}
patch String join(List<String> strings, String separator) {
checkNull(strings);
checkNull(separator);
if (separator is !String) throw new ArgumentError(separator);
return stringJoinUnchecked(_toJsStringArray(strings), separator);
}
patch String concatAll(List<String> strings) {
return stringJoinUnchecked(_toJsStringArray(strings), "");
}
static List _toJsStringArray(List<String> strings) {
checkNull(strings);
var array;
final length = strings.length;
if (isJsArray(strings)) {
array = strings;
for (int i = 0; i < length; i++) {
final string = strings[i];
checkNull(string);
if (string is !String) throw new ArgumentError(string);
}
} else {
array = new List(length);
for (int i = 0; i < length; i++) {
final string = strings[i];
checkNull(string);
if (string is !String) throw new ArgumentError(string);
array[i] = string;
}
}
return array;
}
}
// Patch for List implementation.
// TODO(ager): Split out into date_patch.dart and allow #source
// in patch files?
patch class ListImplementation<E> {
patch factory List([int length]) => Primitives.newList(length);
patch static List _from(Iterable other) {
List result = new List();
for (var element in other) {
result.add(element);
}
return result;
}
}
// Patch for Stopwatch implementation.
// TODO(ager): Split out into stopwatch_patch.dart and allow #source
// in patch files?
patch class StopwatchImplementation {
patch static int _frequency() => 1000;
patch static int _now() => Primitives.dateNow();
}
// Patch for RegExp implementation.
// TODO(ager): Split out into regexp_patch.dart and allow #source in
// patch files?
patch class JSSyntaxRegExp {
final String _pattern;
final bool _multiLine;
final bool _ignoreCase;
patch const JSSyntaxRegExp(String pattern,
{bool multiLine: false,
bool ignoreCase: false})
: _pattern = pattern,
_multiLine = multiLine,
_ignoreCase = ignoreCase;
patch Match firstMatch(String str) {
List<String> m = regExpExec(this, checkString(str));
if (m == null) return null;
var matchStart = regExpMatchStart(m);
// m.lastIndex only works with flag 'g'.
var matchEnd = matchStart + m[0].length;
return new _MatchImplementation(pattern, str, matchStart, matchEnd, m);
}
patch bool hasMatch(String str) => regExpTest(this, checkString(str));
patch String stringMatch(String str) {
var match = firstMatch(str);
return match == null ? null : match.group(0);
}
patch Iterable<Match> allMatches(String str) {
checkString(str);
return new _AllMatchesIterable(this, str);
}
patch String get pattern => _pattern;
patch bool get multiLine => _multiLine;
patch bool get ignoreCase => _ignoreCase;
static JSSyntaxRegExp _globalVersionOf(JSSyntaxRegExp other) {
JSSyntaxRegExp re = new JSSyntaxRegExp(other.pattern,
multiLine: other.multiLine,
ignoreCase: other.ignoreCase);
regExpAttachGlobalNative(re);
return re;
}
_getNative() => regExpGetNative(this);
}
class _MatchImplementation implements Match {
final String pattern;
final String str;
final int start;
final int end;
final List<String> _groups;
const _MatchImplementation(
String this.pattern,
String this.str,
int this.start,
int this.end,
List<String> this._groups);
String group(int index) => _groups[index];
String operator [](int index) => group(index);
int get groupCount => _groups.length - 1;
List<String> groups(List<int> groups) {
List<String> out = [];
for (int i in groups) {
out.add(group(i));
}
return out;
}
}
class _AllMatchesIterable implements Iterable<Match> {
final JSSyntaxRegExp _re;
final String _str;
const _AllMatchesIterable(this._re, this._str);
Iterator<Match> iterator() => new _AllMatchesIterator(_re, _str);
}
class _AllMatchesIterator implements Iterator<Match> {
final RegExp _re;
final String _str;
Match _next;
bool _done;
_AllMatchesIterator(JSSyntaxRegExp re, String this._str)
: _done = false, _re = JSSyntaxRegExp._globalVersionOf(re);
Match next() {
if (!hasNext) {
throw new StateError("No more elements");
}
// _next is set by [hasNext].
var next = _next;
_next = null;
return next;
}
bool get hasNext {
if (_done) {
return false;
} else if (_next != null) {
return true;
}
// firstMatch actually acts as nextMatch because of
// hidden global flag.
_next = _re.firstMatch(_str);
if (_next == null) {
_done = true;
return false;
} else {
return true;
}
}
}