Skip to content

Commit 4c8aedc

Browse files
lrhnCommit Queue
authored andcommitted
Tweak some VM String operations.
Mainly the `contains` which had some out-dated assumptions and should just default to `indexOf` all the time. Tested: No new test, only refactoring of existing API. Change-Id: Ifcbec2bcd909a9e63f3bd14590b58518b2219d9a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413761 Reviewed-by: Daco Harkes <[email protected]> Commit-Queue: Lasse Nielsen <[email protected]>
1 parent ae5a55b commit 4c8aedc

File tree

1 file changed

+15
-23
lines changed

1 file changed

+15
-23
lines changed

sdk/lib/_internal/vm/lib/string_patch.dart

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,21 @@ abstract final class _StringBase implements String {
385385

386386
int indexOf(Pattern pattern, [int start = 0]) {
387387
if ((start < 0) || (start > this.length)) {
388-
throw new RangeError.range(start, 0, this.length, "start");
388+
throw RangeError.range(start, 0, this.length, "start");
389389
}
390390
if (pattern is String) {
391391
String other = pattern;
392-
int maxIndex = this.length - other.length;
393-
// TODO: Use an efficient string search (e.g. BMH).
392+
var otherLength = other.length;
393+
if (otherLength == 0) return start;
394+
if (otherLength == 1) {
395+
int codeUnit = other.codeUnitAt(0);
396+
for (var index = start; index < this.length; index++) {
397+
if (codeUnit == this.codeUnitAt(index)) return index;
398+
}
399+
return -1;
400+
}
401+
int maxIndex = this.length - otherLength;
402+
// TODO: Use an efficient string search (e.g., BMH).
394403
for (int index = start; index <= maxIndex; index++) {
395404
if (_substringMatches(index, other)) {
396405
return index;
@@ -399,8 +408,6 @@ abstract final class _StringBase implements String {
399408
return -1;
400409
}
401410
for (int i = start; i <= this.length; i++) {
402-
// TODO(11276); This has quadratic behavior because matchAsPrefix tries
403-
// to find a later match too. Optimize matchAsPrefix to avoid this.
404411
if (pattern.matchAsPrefix(this, i) != null) return i;
405412
}
406413
return -1;
@@ -424,8 +431,6 @@ abstract final class _StringBase implements String {
424431
return -1;
425432
}
426433
for (int i = start; i >= 0; i--) {
427-
// TODO(11276); This has quadratic behavior because matchAsPrefix tries
428-
// to find a later match too. Optimize matchAsPrefix to avoid this.
429434
if (pattern.matchAsPrefix(this, i) != null) return i;
430435
}
431436
return -1;
@@ -604,30 +609,17 @@ abstract final class _StringBase implements String {
604609
}
605610

606611
bool contains(Pattern pattern, [int startIndex = 0]) {
607-
if (pattern is String) {
608-
if (startIndex < 0 || startIndex > this.length) {
609-
throw new RangeError.range(startIndex, 0, this.length);
610-
}
612+
if (startIndex >= 0 && startIndex <= this.length) {
611613
return indexOf(pattern, startIndex) >= 0;
612614
}
613-
return pattern.allMatches(this.substring(startIndex)).isNotEmpty;
615+
throw RangeError.range(startIndex, 0, this.length, "startIndex");
614616
}
615617

616618
String replaceFirst(
617619
Pattern pattern,
618620
String replacement, [
619621
int startIndex = 0,
620622
]) {
621-
// TODO: Remove these null checks once all code is opted into strong nonnullable mode.
622-
if (pattern == null) {
623-
throw new ArgumentError.notNull("pattern");
624-
}
625-
if (replacement == null) {
626-
throw new ArgumentError.notNull("replacement");
627-
}
628-
if (startIndex == null) {
629-
throw new ArgumentError.notNull("startIndex");
630-
}
631623
RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
632624
Iterator iterator =
633625
startIndex == 0
@@ -708,7 +700,7 @@ abstract final class _StringBase implements String {
708700
if (replacementIsOneByte &&
709701
length < _maxJoinReplaceOneByteStringLength &&
710702
this._isOneByte) {
711-
// TODO(lrn): Is there a cut-off point, or is runtime always faster?
703+
// TODO: Is there a cut-off point, or is runtime always faster?
712704
return _joinReplaceAllOneByteResult(this, matches, length);
713705
}
714706
return _joinReplaceAllResult(this, matches, length, replacementIsOneByte);

0 commit comments

Comments
 (0)