| // 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. | |
| /// Provides [EnumSet] which works when compiled to JS. | |
| library; | |
| import 'package:analyzer/src/binary/binary_reader.dart'; | |
| import 'package:analyzer/src/binary/binary_writer.dart'; | |
| /// The set of [Enum] values, up to `60` constants. | |
| extension type EnumSet<T extends Enum>((int, int) _bits) { | |
| EnumSet.empty() : this((0, 0)); | |
| factory EnumSet.read(BinaryReader reader) { | |
| return EnumSet((reader.readInt64(), reader.readInt64())); | |
| } | |
| /// Whether [constant] is present. | |
| bool operator [](T constant) { | |
| var index = constant.index; | |
| _checkIndex(index); | |
| // In JavaScript bitwise operations are performed on 32-bit integers. | |
| if (index <= 30) { | |
| var mask = 1 << index; | |
| return (_bits.$1 & mask) != 0; | |
| } else { | |
| var mask = 1 << (index - 30); | |
| return (_bits.$2 & mask) != 0; | |
| } | |
| } | |
| /// Returns a new set, with presence of [constant] updated. | |
| EnumSet<T> updated(T constant, bool value) { | |
| var index = constant.index; | |
| _checkIndex(index); | |
| if (index <= 30) { | |
| var mask = 1 << index; | |
| var field = _bits.$1; | |
| var newField = value ? field | mask : field & ~mask; | |
| return EnumSet<T>((newField, _bits.$2)); | |
| } else { | |
| var mask = 1 << (index - 30); | |
| var field = _bits.$2; | |
| var newField = value ? field | mask : field & ~mask; | |
| return EnumSet<T>((_bits.$1, newField)); | |
| } | |
| } | |
| void write(BinaryWriter writer) { | |
| writer.writeInt64(_bits.$1); | |
| writer.writeInt64(_bits.$2); | |
| } | |
| /// Throws an exception if the [index] does not fit the storage. | |
| static void _checkIndex(int index) { | |
| if (index < 0 || index > 60) { | |
| throw RangeError("Index not between 0 and 60: $index"); | |
| } | |
| } | |
| } |