95b1b8d756
(Part of https://github.com/dart-lang/sdk/issues/63288) This change migrates the front_end package to use the new constructor declaration syntax, described in https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md#abbreviations-of-in-body-constructor-declarations. This change was performed in an automated fashion, by (a) enabling the lints `unnecessary_type_name_in_constructor` and `unnecessary_const_in_enum_constructor`, (b) fixing the resulting lint failures using `dart fix`, and then (c) reformatting the affected files. To ease code review, I've reverted unrelated formatting changes. Change-Id: I6b48c0f1c762c3fa132fbd79382496ca6a6a6964 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508368 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
112 lines
3.7 KiB
Dart
112 lines
3.7 KiB
Dart
// Copyright (c) 2024, 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.
|
|
|
|
import 'dart:typed_data';
|
|
|
|
// Based on (as in mostly a copy from) the _IntervalListBuilder in
|
|
// package:kernel/class_hierarchy.dart.
|
|
class IntervalListBuilder {
|
|
bool _finished = false;
|
|
final List<int> _events = <int>[];
|
|
|
|
IntervalListBuilder clone() {
|
|
if (_finished) throw "Can't clone an already finished builder.";
|
|
IntervalListBuilder clone = new IntervalListBuilder();
|
|
clone._events.addAll(_events);
|
|
return clone;
|
|
}
|
|
|
|
void addIntervalIncludingEnd(int start, int end) {
|
|
// Add an event point for each interval end point, using the low bit to
|
|
// distinguish opening from closing end points. Closing end points should
|
|
// have the high bit to ensure they occur after an opening end point.
|
|
_events.add(start << 1);
|
|
// Add 1 to include the end.
|
|
_events.add(((end + 1) << 1) + 1);
|
|
}
|
|
|
|
void addIntervalExcludingEnd(int start, int end) {
|
|
// Add an event point for each interval end point, using the low bit to
|
|
// distinguish opening from closing end points. Closing end points should
|
|
// have the high bit to ensure they occur after an opening end point.
|
|
_events.add(start << 1);
|
|
_events.add((end << 1) + 1);
|
|
}
|
|
|
|
void addSingleton(int x) {
|
|
addIntervalExcludingEnd(x, x + 1);
|
|
}
|
|
|
|
IntervalList buildIntervalList() {
|
|
if (_finished) throw "Can't build an already finished builder.";
|
|
// Sort the event points and sweep left to right while tracking how many
|
|
// intervals we are currently inside. Record an interval end point when the
|
|
// number of intervals drop to zero or increase from zero to one.
|
|
// Event points are encoded so that an opening end point occur before a
|
|
// closing end point at the same value.
|
|
_events.sort();
|
|
int insideCount = 0; // The number of intervals we are currently inside.
|
|
int storeIndex = 0;
|
|
for (int i = 0; i < _events.length; ++i) {
|
|
int event = _events[i];
|
|
if (event & 1 == 0) {
|
|
// Start point
|
|
++insideCount;
|
|
if (insideCount == 1) {
|
|
// Store the results temporarily back in the event array.
|
|
_events[storeIndex++] = event >> 1;
|
|
}
|
|
} else {
|
|
// End point
|
|
--insideCount;
|
|
if (insideCount == 0) {
|
|
_events[storeIndex++] = event >> 1;
|
|
}
|
|
}
|
|
}
|
|
// Copy the results over to a typed array of the correct length.
|
|
Uint32List result = new Uint32List(storeIndex);
|
|
for (int i = 0; i < storeIndex; ++i) {
|
|
result[i] = _events[i];
|
|
}
|
|
|
|
_finished = true;
|
|
return new IntervalList._(result);
|
|
}
|
|
}
|
|
|
|
class IntervalList {
|
|
final Uint32List _intervalList;
|
|
new _(this._intervalList);
|
|
|
|
bool get isEmpty => _intervalList.isEmpty;
|
|
|
|
bool contains(int x) {
|
|
int low = 0, high = _intervalList.length - 1;
|
|
if (high == -1 || x < _intervalList[0] || _intervalList[high] <= x) {
|
|
return false;
|
|
}
|
|
// Find the lower bound of x in the list.
|
|
// If the lower bound is at an even index, the lower bound is an opening
|
|
// point of an interval that contains x, otherwise it is a closing point of
|
|
// an interval below x and there is no interval containing x.
|
|
while (low < high) {
|
|
int mid = high - ((high - low) >> 1); // Get middle, rounding up.
|
|
int pivot = _intervalList[mid];
|
|
if (pivot <= x) {
|
|
low = mid;
|
|
} else {
|
|
high = mid - 1;
|
|
}
|
|
}
|
|
return low == high && (low & 1) == 0;
|
|
}
|
|
|
|
void forEach(void action(int open, int close)) {
|
|
for (int i = 0; i < _intervalList.length; i += 2) {
|
|
action(_intervalList[i], _intervalList[i + 1]);
|
|
}
|
|
}
|
|
}
|