| // Copyright (c) 2023, 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. |
| |
| /// Wrapper around a [StringSink] for writing tree structures. |
| class TreeStringSink { |
| final StringSink _sink; |
| String _indent = ''; |
| |
| TreeStringSink({ |
| required StringSink sink, |
| required String indent, |
| }) : _sink = sink, |
| _indent = indent; |
| |
| void withIndent(void Function() f) { |
| var indent = _indent; |
| _indent = '$indent '; |
| f(); |
| _indent = indent; |
| } |
| |
| void write(Object object) { |
| _sink.write(object); |
| } |
| |
| void writeElements<T extends Object>( |
| String name, |
| List<T> elements, |
| void Function(T) f, |
| ) { |
| if (elements.isNotEmpty) { |
| writelnWithIndent(name); |
| withIndent(() { |
| for (var element in elements) { |
| f(element); |
| } |
| }); |
| } |
| } |
| |
| Future<void> writeFlags(Map<String, bool> flags) async { |
| if (flags.values.any((flag) => flag)) { |
| writeIndentedLine(() { |
| write('flags:'); |
| for (var entry in flags.entries) { |
| if (entry.value) { |
| write(' ${entry.key}'); |
| } |
| } |
| }); |
| } |
| } |
| |
| void writeIf(bool flag, Object object) { |
| if (flag) { |
| write(object); |
| } |
| } |
| |
| void writeIndent() { |
| _sink.write(_indent); |
| } |
| |
| void writeIndentedLine(void Function() f) { |
| writeIndent(); |
| f(); |
| writeln(); |
| } |
| |
| void writeln([Object? object = '']) { |
| _sink.writeln(object); |
| } |
| |
| void writelnWithIndent(Object object) { |
| _sink.write(_indent); |
| _sink.writeln(object); |
| } |
| |
| void writeWithIndent(Object object) { |
| _sink.write(_indent); |
| _sink.write(object); |
| } |
| } |