Skip to content

Commit f6e1f63

Browse files
scheglovCommit Queue
authored and
Commit Queue
committed
Use EnumSet instead of BooleanArray for element modifiers.
Change-Id: I5db1104cc13cc61c39e4b4565c3bc3942848c7f3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354281 Reviewed-by: Phil Quitslund <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 4bea796 commit f6e1f63

File tree

3 files changed

+52
-69
lines changed

3 files changed

+52
-69
lines changed

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,8 +1909,8 @@ abstract class ElementImpl implements Element {
19091909
/// declaration of this element.
19101910
int _nameOffset = 0;
19111911

1912-
/// A bit-encoded form of the modifiers associated with this element.
1913-
int _modifiers = 0;
1912+
/// The modifiers associated with this element.
1913+
EnumSet<Modifier> _modifiers = EnumSet.empty();
19141914

19151915
/// A list containing all of the metadata associated with this element.
19161916
List<ElementAnnotationImpl> _metadata = const [];
@@ -2444,8 +2444,7 @@ abstract class ElementImpl implements Element {
24442444
}
24452445

24462446
/// Return `true` if this element has the given [modifier] associated with it.
2447-
bool hasModifier(Modifier modifier) =>
2448-
BooleanArray.get(_modifiers, modifier.index);
2447+
bool hasModifier(Modifier modifier) => _modifiers[modifier];
24492448

24502449
@override
24512450
bool isAccessibleIn(LibraryElement library) {
@@ -2468,7 +2467,7 @@ abstract class ElementImpl implements Element {
24682467
/// Set whether the given [modifier] is associated with this element to
24692468
/// correspond to the given [value].
24702469
void setModifier(Modifier modifier, bool value) {
2471-
_modifiers = BooleanArray.set(_modifiers, modifier.index, value);
2470+
_modifiers = _modifiers.updated(modifier, value);
24722471
}
24732472

24742473
@override

pkg/analyzer/lib/src/generated/utilities_collection.dart

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,33 @@ bool listsEqual(List a, List b) {
2323
return true;
2424
}
2525

26-
/// Methods for operating on integers as if they were arrays of booleans. These
27-
/// arrays can be indexed by either integers or by enumeration constants.
28-
class BooleanArray {
29-
/// Return the value of the element of the given [array] at the given [index].
30-
static bool get(int array, int index) {
26+
/// The set of [Enum] values, backed by [int].
27+
extension type EnumSet<T extends Enum>(int _bits) {
28+
EnumSet.empty() : this(0);
29+
30+
/// Whether [constant] is present.
31+
bool operator [](T constant) {
32+
var index = constant.index;
3133
_checkIndex(index);
32-
return (array & (1 << index)) > 0;
34+
35+
var mask = 1 << index;
36+
return (_bits & mask) != 0;
3337
}
3438

35-
/// Set the value of the element of the given [array] at the given [index] to
36-
/// the given [value].
37-
static int set(int array, int index, bool value) {
39+
/// Returns a new set, with presence of [constant] updated.
40+
EnumSet<T> updated(T constant, bool value) {
41+
var index = constant.index;
3842
_checkIndex(index);
43+
44+
var mask = 1 << index;
3945
if (value) {
40-
return array | (1 << index);
46+
return EnumSet<T>(_bits | mask);
4147
} else {
42-
return array & ~(1 << index);
48+
return EnumSet<T>(_bits & ~mask);
4349
}
4450
}
4551

46-
/// Throw an exception if the index is not within the bounds allowed for an
47-
/// integer-encoded array of boolean values.
52+
/// Throws an exception if the [index] does not fit [int].
4853
static void _checkIndex(int index) {
4954
if (index < 0 || index > 60) {
5055
throw RangeError("Index not between 0 and 60: $index");

pkg/analyzer/test/generated/utilities_test.dart

Lines changed: 30 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,70 +16,47 @@ import '../util/feature_sets.dart';
1616

1717
main() {
1818
defineReflectiveSuite(() {
19-
defineReflectiveTests(BooleanArrayTest);
19+
defineReflectiveTests(EnumSetTest);
2020
defineReflectiveTests(LineInfoTest);
2121
defineReflectiveTests(NodeReplacerTest);
2222
defineReflectiveTests(SourceRangeTest);
2323
});
2424
}
2525

2626
@reflectiveTest
27-
class BooleanArrayTest {
28-
void test_get_negative() {
29-
try {
30-
BooleanArray.get(0, -1);
31-
fail("Expected ");
32-
} on RangeError {
33-
// Expected
34-
}
35-
}
27+
class EnumSetTest {
28+
void test_it() {
29+
var enumSet = EnumSet<_MyEnum>.empty();
3630

37-
void test_get_tooBig() {
38-
try {
39-
BooleanArray.get(0, 61);
40-
fail("Expected ");
41-
} on RangeError {
42-
// Expected
43-
}
44-
}
31+
// Can set `foo`.
32+
enumSet = enumSet.updated(_MyEnum.foo, true);
33+
expect(enumSet[_MyEnum.foo], true);
34+
expect(enumSet[_MyEnum.bar], false);
4535

46-
void test_get_valid() {
47-
expect(BooleanArray.get(0, 0), false);
48-
expect(BooleanArray.get(1, 0), true);
49-
expect(BooleanArray.get(0, 30), false);
50-
expect(BooleanArray.get(1 << 30, 30), true);
51-
}
36+
// Can set `bar`.
37+
enumSet = enumSet.updated(_MyEnum.bar, true);
38+
expect(enumSet[_MyEnum.foo], true);
39+
expect(enumSet[_MyEnum.bar], true);
5240

53-
void test_set_negative() {
54-
try {
55-
BooleanArray.set(0, -1, true);
56-
fail("Expected ");
57-
} on RangeError {
58-
// Expected
59-
}
60-
}
41+
// Can set `foo` again.
42+
enumSet = enumSet.updated(_MyEnum.foo, true);
43+
expect(enumSet[_MyEnum.foo], true);
44+
expect(enumSet[_MyEnum.bar], true);
6145

62-
void test_set_tooBig() {
63-
try {
64-
BooleanArray.set(0, 61, true);
65-
fail("Expected ");
66-
} on RangeError {
67-
// Expected
68-
}
69-
}
46+
// Can clear `foo`.
47+
enumSet = enumSet.updated(_MyEnum.foo, false);
48+
expect(enumSet[_MyEnum.foo], false);
49+
expect(enumSet[_MyEnum.bar], true);
7050

71-
void test_set_valueChanging() {
72-
expect(BooleanArray.set(0, 0, true), 1);
73-
expect(BooleanArray.set(1, 0, false), 0);
74-
expect(BooleanArray.set(0, 30, true), 1 << 30);
75-
expect(BooleanArray.set(1 << 30, 30, false), 0);
76-
}
51+
// Can clear `foo` again.
52+
enumSet = enumSet.updated(_MyEnum.foo, false);
53+
expect(enumSet[_MyEnum.foo], false);
54+
expect(enumSet[_MyEnum.bar], true);
7755

78-
void test_set_valuePreserving() {
79-
expect(BooleanArray.set(0, 0, false), 0);
80-
expect(BooleanArray.set(1, 0, true), 1);
81-
expect(BooleanArray.set(0, 30, false), 0);
82-
expect(BooleanArray.set(1 << 30, 30, true), 1 << 30);
56+
// Can clear `bar`.
57+
enumSet = enumSet.updated(_MyEnum.bar, false);
58+
expect(enumSet[_MyEnum.foo], false);
59+
expect(enumSet[_MyEnum.bar], false);
8360
}
8461
}
8562

@@ -2193,3 +2170,5 @@ class SourceRangeTest {
21932170
expect(r.toString(), "[offset=10, length=1]");
21942171
}
21952172
}
2173+
2174+
enum _MyEnum { foo, bar }

0 commit comments

Comments
 (0)