15
15
*/
16
16
package com .diffplug .common .swt ;
17
17
18
+ import java .lang .reflect .Field ;
19
+ import java .lang .reflect .Modifier ;
18
20
import java .util .Arrays ;
19
21
import java .util .Collection ;
22
+ import java .util .Map ;
23
+ import java .util .Objects ;
24
+ import java .util .function .Predicate ;
20
25
import java .util .stream .Collectors ;
21
26
import java .util .stream .Stream ;
22
27
28
+ import javax .annotation .Nullable ;
29
+
23
30
import org .eclipse .swt .SWT ;
24
31
import org .eclipse .swt .widgets .Event ;
25
32
import org .eclipse .swt .widgets .Widget ;
26
33
34
+ import com .diffplug .common .base .Predicates ;
27
35
import com .diffplug .common .base .StringPrinter ;
36
+ import com .diffplug .common .base .Throwing ;
28
37
import com .diffplug .common .collect .ImmutableMap ;
29
- import com .diffplug .common .debug . FieldsAndGetters ;
38
+ import com .diffplug .common .collect . Maps ;
30
39
import com .diffplug .common .rx .Rx ;
31
40
32
41
/**
@@ -43,7 +52,7 @@ public static void dumpEvent(String name, Event e, StringPrinter to) {
43
52
// print the name
44
53
to .println (name + ": " + eventType (e ));
45
54
// print the non-null / non-zero fields
46
- FieldsAndGetters . fields (e ).filter (entry -> {
55
+ fields (e ).filter (entry -> {
47
56
Object value = entry .getValue ();
48
57
if (value == null ) {
49
58
return false ;
@@ -58,12 +67,12 @@ public static void dumpEvent(String name, Event e, StringPrinter to) {
58
67
to .println ("\t " + entry .getKey ().getName () + " = " + entry .getValue ());
59
68
});
60
69
// print the nulls
61
- to .println ("\t null = " + FieldsAndGetters . fields (e )
70
+ to .println ("\t null = " + fields (e )
62
71
.filter (entry -> entry .getValue () == null )
63
72
.map (entry -> entry .getKey ().getName ())
64
73
.collect (Collectors .joining (", " )));
65
74
// print the zeroes
66
- to .println ("\t 0 = " + FieldsAndGetters . fields (e )
75
+ to .println ("\t 0 = " + fields (e )
67
76
.filter (entry -> {
68
77
if (entry .getValue () instanceof Number ) {
69
78
return ((Number ) entry .getValue ()).intValue () == 0 ;
@@ -184,4 +193,64 @@ public static ImmutableMap<Integer, String> allEvents() {
184
193
builder .put (wakeup , "PostExternalEventDispatch" ); // 53
185
194
events = builder .build ();
186
195
}
196
+
197
+ ////////////////////////////////////////////////
198
+ // Copied from DurianDebug's FieldsAndGetters //
199
+ ////////////////////////////////////////////////
200
+ /**
201
+ * Returns a {@code Stream} of all public fields which match {@code predicate} and their values for the given object.
202
+ * <p>
203
+ * This method uses reflection to find all of the public instance fields of the given object,
204
+ * and if they pass the given predicate, it includes them in a stream of {@code Map.Entry<Field, Object>}
205
+ * where the entry's value is the value of the field for this object.
206
+ */
207
+ private static Stream <Map .Entry <Field , Object >> fields (@ Nullable Object obj , Predicate <Field > predicate ) {
208
+ Objects .requireNonNull (predicate );
209
+ return Arrays .asList (getClassNullable (obj ).getFields ()).stream ()
210
+ // gotta be public
211
+ .filter (field -> Modifier .isPublic (field .getModifiers ()))
212
+ // gotta be an instance field
213
+ .filter (field -> !Modifier .isStatic (field .getModifiers ()))
214
+ // gotta pass the predicate
215
+ .filter (predicate )
216
+ // then create the field
217
+ .map (field -> Maps .immutableEntry (field , tryCall (field .getName (), () -> field .get (obj ))));
218
+ }
219
+
220
+ private static Object tryCall (String methodName , Throwing .Supplier <Object > supplier ) {
221
+ try {
222
+ return supplier .get ();
223
+ } catch (Throwable error ) {
224
+ return new CallException (methodName , error );
225
+ }
226
+ }
227
+
228
+ /** Exception which wraps up a thrown exception - ensures that users don't think an exception was returned. */
229
+ private static class CallException extends Exception {
230
+ private static final long serialVersionUID = 1206955156719866328L ;
231
+
232
+ private final String methodName ;
233
+
234
+ private CallException (String methodName , Throwable cause ) {
235
+ super (cause );
236
+ this .methodName = methodName ;
237
+ }
238
+
239
+ @ Override
240
+ public String toString () {
241
+ return "When calling " + methodName + ": " + getCause ().getMessage ();
242
+ }
243
+ }
244
+
245
+ private static Stream <Map .Entry <Field , Object >> fields (@ Nullable Object obj ) {
246
+ return fields (obj , Predicates .alwaysTrue ());
247
+ }
248
+
249
+ private static Class <?> getClassNullable (@ Nullable Object obj ) {
250
+ return obj == null ? ObjectIsNull .class : obj .getClass ();
251
+ }
252
+
253
+ /** Sentinel class for null objects. */
254
+ public static class ObjectIsNull {}
255
+
187
256
}
0 commit comments