| Index: runtime/lib/string_patch.dart
|
| diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
|
| index 4612571698742625156e02be247ccb164c825241..80b369cb10003122b2307fe367cc762914e68254 100644
|
| --- a/runtime/lib/string_patch.dart
|
| +++ b/runtime/lib/string_patch.dart
|
| @@ -113,11 +113,8 @@ class _StringBase {
|
|
|
| bool _substringMatches(int start, String other) {
|
| if (other.isEmpty) return true;
|
| - if ((start < 0) || (start >= this.length)) {
|
| - return false;
|
| - }
|
| final int len = other.length;
|
| - if ((start + len) > this.length) {
|
| + if ((start < 0) || (start + len > this.length)) {
|
| return false;
|
| }
|
| for (int i = 0; i < len; i++) {
|
| @@ -132,38 +129,57 @@ class _StringBase {
|
| return _substringMatches(this.length - other.length, other);
|
| }
|
|
|
| - bool startsWith(String other) {
|
| - return _substringMatches(0, other);
|
| + bool startsWith(Pattern pattern) {
|
| + if (pattern is String) {
|
| + return _substringMatches(0, pattern);
|
| + }
|
| + return pattern.matchAsPrefix(this, 0) != null;
|
| }
|
|
|
| - int indexOf(String other, [int start = 0]) {
|
| - if (other.isEmpty) {
|
| - return start < this.length ? start : this.length;
|
| + int indexOf(Pattern pattern, [int start = 0]) {
|
| + if (start < 0 || start > this.length) {
|
| + throw new RangeError.range(start, 0, this.length);
|
| }
|
| - if ((start < 0) || (start >= this.length)) {
|
| + if (pattern is String) {
|
| + String other = pattern;
|
| + int maxIndex = this.length - other.length;
|
| + // TODO: Use an efficient string search (e.g. BMH).
|
| + for (int index = start; index <= maxIndex; index++) {
|
| + if (_substringMatches(index, other)) {
|
| + return index;
|
| + }
|
| + }
|
| return -1;
|
| }
|
| - int len = this.length - other.length + 1;
|
| - for (int index = start; index < len; index++) {
|
| - if (_substringMatches(index, other)) {
|
| - return index;
|
| - }
|
| + for (int i = start; i <= this.length; i++) {
|
| + // TODO(11276); This has quadratic behavior because matchAsPrefix tries
|
| + // to find a later match too. Optimize matchAsPrefix to avoid this.
|
| + if (pattern.matchAsPrefix(this, i) != null) return i;
|
| }
|
| return -1;
|
| }
|
|
|
| - int lastIndexOf(String other, [int start = null]) {
|
| - if (start == null) start = length - 1;
|
| - if (other.isEmpty) {
|
| - return min(this.length, start);
|
| - }
|
| - if (start >= this.length) {
|
| - start = this.length - 1;
|
| + int lastIndexOf(Pattern pattern, [int start = null]) {
|
| + if (start == null) {
|
| + start = this.length;
|
| + } else if (start < 0 || start > this.length) {
|
| + throw new RangeError.range(start, 0, this.length);
|
| }
|
| - for (int index = start; index >= 0; index--) {
|
| - if (_substringMatches(index, other)) {
|
| - return index;
|
| + if (pattern is String) {
|
| + String other = pattern;
|
| + int maxIndex = this.length - other.length;
|
| + if (maxIndex < start) start = maxIndex;
|
| + for (int index = start; index >= 0; index--) {
|
| + if (_substringMatches(index, other)) {
|
| + return index;
|
| + }
|
| }
|
| + return -1;
|
| + }
|
| + for (int i = start; i >= 0; i--) {
|
| + // TODO(11276); This has quadratic behavior because matchAsPrefix tries
|
| + // to find a later match too. Optimize matchAsPrefix to avoid this.
|
| + if (pattern.matchAsPrefix(this, i) != null) return i;
|
| }
|
| return -1;
|
| }
|
|
|