-
Notifications
You must be signed in to change notification settings - Fork 0
/
DebugReflectWriter.swift
119 lines (100 loc) · 2.97 KB
/
DebugReflectWriter.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//
// DebugReflectWriter.swift
// DebugReflectable
//
// Created by omochimetaru on 2017/09/08.
//
import Foundation
public class DebugReflectWriter {
public init() {}
public func write(_ x: DebugReflectable) {
if let obj = castIfClass(x) {
if visited.contains(obj) {
if isPrintingSummary(x) {
writer.write(debugSummary(of: x) + " ")
}
writer.write(" { recursive }")
return
}
visited.add(obj)
}
switch x.debugReflect() {
case let .string(t):
if isPrintingSummary(x) {
writer.write(debugSummary(of: x) + "(")
}
writer.write(t)
if isPrintingSummary(x) {
writer.write(")")
}
case let .array(xs):
if isPrintingSummary(x) {
writer.write(debugSummary(of: x) + " ")
}
write(array: xs)
case let .dictionary(xs):
if isPrintingSummary(x) {
writer.write(debugSummary(of: x) + " ")
}
write(dictionary: xs)
}
}
public func output() -> String {
return writer.output()
}
private func isPrintingSummary(_ x: DebugReflectable) -> Bool {
return type(of: x).debugTypePrinting
}
private func write(any: Any) {
guard let dr = any as? DebugReflectable else {
writer.write(String(describing: any))
return
}
write(dr)
}
private func write(array: Array<Any>) {
if array.count == 0 {
writer.write("[]")
} else {
writer.write("[")
writer.writeNewline()
writer.pushIndent()
for x in array {
write(any: x)
writer.writeNewline()
}
writer.popIndent()
writer.write("]")
}
}
private func write(dictionary: Array<(String, Any)>) {
if dictionary.count == 0 {
writer.write("{}")
} else {
writer.write("{")
writer.writeNewline()
writer.pushIndent()
for (k, v) in dictionary {
writer.write(k)
writer.write(" => ")
write(any: v)
writer.writeNewline()
}
writer.popIndent()
writer.write("}")
}
}
private struct VisitedObjects {
var objects = Array<AnyObject>()
var addrs = Set<Int>()
func contains(_ x: AnyObject) -> Bool {
return addrs.contains(address(of: x))
}
mutating func add(_ x: AnyObject) {
objects.append(x)
addrs.insert(address(of: x))
}
}
private var visited = VisitedObjects()
private var writer = IndentTextWriter()
}