Skip to content

Commit 886de78

Browse files
johnniwintherCommit Queue
authored andcommitted
[model] Add StackTraceMap and StackTraceSet
This adds debug helpers that collect stack traces for updates to Map and Set. Change-Id: I79ca28055fe1fa5fa073776f21c6e380af4af9f6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429400 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent e7ef1b3 commit 886de78

File tree

1 file changed

+136
-1
lines changed

1 file changed

+136
-1
lines changed

pkg/_fe_analyzer_shared/lib/src/debug_helpers/stack_trace.dart

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class StackTraceValue<T> {
6464
///
6565
class StackTraceList<T> with ListMixin<T> implements List<T> {
6666
List<T> _list;
67-
List<(String, Object?, StackTrace)> _stackTraces = [];
67+
final List<(String, Object?, StackTrace)> _stackTraces = [];
6868

6969
StackTraceList(this._list) {
7070
_stackTraces.add(('init', _list, StackTrace.current));
@@ -119,3 +119,138 @@ class StackTraceList<T> with ListMixin<T> implements List<T> {
119119
return _list.remove(element);
120120
}
121121
}
122+
123+
/// Debug helper that tracks updates to a set.
124+
///
125+
/// Use this in debugging to record stack traces for when a set is updated.
126+
/// For instance to track the list `bars` change
127+
///
128+
/// class Foo {
129+
/// Set<Bar> bars;
130+
/// Foo(this.bars);
131+
/// }
132+
///
133+
/// to
134+
///
135+
/// class Foo {
136+
/// StackTraceSet<Bar> _bars;
137+
/// Foo(Set<Bar> bars) : _bars = StackTraceList(bars);
138+
/// Set<Bar> get bars => _bars;
139+
/// void set bars(Set<Bar> value) {
140+
/// _bars.value = value;
141+
/// }
142+
/// }
143+
///
144+
class StackTraceSet<T> with SetMixin<T> implements Set<T> {
145+
Set<T> _set;
146+
final List<(String, Object?, StackTrace)> _stackTraces = [];
147+
148+
StackTraceSet(this._set) {
149+
_stackTraces.add(('init', _set, StackTrace.current));
150+
}
151+
152+
Set<T> get value => _set;
153+
154+
void set value(Set<T> v) {
155+
_stackTraces.add(('value', v, StackTrace.current));
156+
_set = v;
157+
}
158+
159+
@override
160+
bool add(T element) {
161+
_stackTraces.add(('add', element, StackTrace.current));
162+
return _set.add(element);
163+
}
164+
165+
@override
166+
void addAll(Iterable<T> iterable) {
167+
_stackTraces.add(('addAll', iterable.toList(), StackTrace.current));
168+
_set.addAll(iterable);
169+
}
170+
171+
@override
172+
int get length => _set.length;
173+
174+
@override
175+
void clear() {
176+
_stackTraces.add(('clear', null, StackTrace.current));
177+
_set.clear();
178+
}
179+
180+
@override
181+
bool remove(Object? element) {
182+
_stackTraces.add(('remove', element, StackTrace.current));
183+
return _set.remove(element);
184+
}
185+
186+
@override
187+
bool contains(Object? element) => _set.contains(element);
188+
189+
@override
190+
Iterator<T> get iterator => _set.iterator;
191+
192+
@override
193+
T? lookup(Object? element) => _set.lookup(element);
194+
195+
@override
196+
Set<T> toSet() => _set.toSet();
197+
}
198+
199+
/// Debug helper that tracks updates to a map.
200+
///
201+
/// Use this in debugging to record stack traces for when a map is updated.
202+
/// For instance to track the map `bars` change
203+
///
204+
/// class Foo {
205+
/// Map<Bar, Baz> bars;
206+
/// Foo(this.bars);
207+
/// }
208+
///
209+
/// to
210+
///
211+
/// class Foo {
212+
/// StackTrace<Bar, Baz> _bars;
213+
/// Foo(Map<Bar, Baz> bars) : _bars = StackTraceMap(bars);
214+
/// Map<Bar, Baz> get bars => _bars;
215+
/// void set bars(Map<Bar, Baz> value) {
216+
/// _bars.value = value;
217+
/// }
218+
/// }
219+
///
220+
class StackTraceMap<K, V> with MapBase<K, V> implements Map<K, V> {
221+
Map<K, V> _map;
222+
List<(String, Object?, StackTrace)> _stackTraces = [];
223+
224+
StackTraceMap(this._map);
225+
226+
Map<K, V> get value => _map;
227+
228+
void set value(Map<K, V> v) {
229+
_stackTraces.add(('value', v, StackTrace.current));
230+
_map = value;
231+
}
232+
233+
@override
234+
V? operator [](Object? key) => _map[key];
235+
236+
@override
237+
void operator []=(K key, V value) {
238+
_stackTraces.add(('[]=', (key, value), StackTrace.current));
239+
_map[key] = value;
240+
}
241+
242+
@override
243+
void clear() {
244+
_stackTraces.add(('clear', null, StackTrace.current));
245+
_map.clear();
246+
}
247+
248+
@override
249+
Iterable<K> get keys => _map.keys;
250+
251+
@override
252+
V? remove(Object? key) {
253+
_stackTraces.add(('remove', key, StackTrace.current));
254+
return _map.remove(key);
255+
}
256+
}

0 commit comments

Comments
 (0)