@@ -11,12 +11,11 @@ import Foundation
11
11
12
12
public final class RuntimeTreeInspector {
13
13
14
- private let rootNode : TreeNode
14
+ public let rootNode : TreeNode
15
15
16
- init ? ( rootContainer: DependencyContainer ,
17
- dependencyGraph: DependencyGraph ) {
18
- guard let treeNode = TreeNode ( rootContainer: rootContainer, dependencyGraph: dependencyGraph) else { return nil }
19
- self . rootNode = treeNode
16
+ init ( rootContainer: DependencyContainer ,
17
+ dependencyGraph: DependencyGraph ) {
18
+ self . rootNode = TreeNode ( rootContainer: rootContainer, dependencyGraph: dependencyGraph)
20
19
}
21
20
22
21
public func validate( ) throws {
@@ -97,8 +96,9 @@ private extension RuntimeTreeInspector {
97
96
98
97
// dependencyChain
99
98
var stepCount = 1
100
- for parentContainer in node. dependencyChain. reversed ( ) {
101
- if let earlyReturn = resolveStep ( stepCount, parentContainer) {
99
+ var _parent = node. parent
100
+ while let parent = _parent {
101
+ if let earlyReturn = resolveStep ( stepCount, parent. inspectingContainer) {
102
102
switch earlyReturn {
103
103
case . empty:
104
104
return nil
@@ -107,49 +107,52 @@ private extension RuntimeTreeInspector {
107
107
}
108
108
}
109
109
110
+ _parent = parent. parent
110
111
stepCount += 1
111
112
}
112
113
113
- if let rootContainer = node. dependencyChain. first {
114
- history. append ( . dependencyNotFound( dependency, in: rootContainer) )
115
- }
114
+ history. append ( . dependencyNotFound( dependency, in: rootNode. inspectingContainer) )
116
115
117
116
return history
118
117
}
119
118
}
120
119
121
120
// MARK: - Full Tree Iterator
122
121
123
- final class TreeNode : Sequence , IteratorProtocol {
122
+ public final class TreeNode : Sequence , IteratorProtocol {
124
123
125
124
let inspectingContainer : DependencyContainer
126
125
127
- let dependencyChain : [ DependencyContainer ]
126
+ private ( set ) var children : [ TreeNode ] = [ ]
128
127
129
- let dependencyGraph : DependencyGraph
128
+ weak var parent : TreeNode ?
130
129
131
- let dependencyPointer : Dependency
130
+ // do not encode
131
+ private( set) var dependencyPointer : Dependency ?
132
132
133
- convenience init ? ( rootContainer: DependencyContainer ,
134
- dependencyGraph: DependencyGraph ) {
135
- guard let firstDependency = rootContainer. dependencies. orderedValues. first else {
136
- return nil
137
- }
133
+ private( set) var previousDependencyPointer : Dependency ?
134
+
135
+ let dependencyGraph : DependencyGraph
138
136
137
+ convenience init ( rootContainer: DependencyContainer ,
138
+ dependencyGraph: DependencyGraph ) {
139
139
self . init ( inspectingContainer: rootContainer,
140
- dependencyChain: [ ] ,
141
140
dependencyGraph: dependencyGraph,
142
- dependencyPointer: firstDependency)
141
+ dependencyPointer: rootContainer. dependencies. orderedValues. first,
142
+ previousDependencyPointer: nil ,
143
+ parent: nil )
143
144
}
144
145
145
146
private init ( inspectingContainer: DependencyContainer ,
146
- dependencyChain: [ DependencyContainer ] ,
147
- dependencyGraph: DependencyGraph ,
148
- dependencyPointer: Dependency ) {
147
+ dependencyGraph: DependencyGraph ,
148
+ dependencyPointer: Dependency ? ,
149
+ previousDependencyPointer: Dependency ? ,
150
+ parent: TreeNode ? ) {
149
151
self . inspectingContainer = inspectingContainer
150
- self . dependencyChain = dependencyChain
151
152
self . dependencyGraph = dependencyGraph
152
153
self . dependencyPointer = dependencyPointer
154
+ self . previousDependencyPointer = previousDependencyPointer
155
+ self . parent = parent
153
156
}
154
157
155
158
/*
@@ -160,18 +163,26 @@ final class TreeNode: Sequence, IteratorProtocol {
160
163
- If none, then move to the next sibling dependency in the current node
161
164
- If none, then pop up to the parent node
162
165
*/
163
- func next( ) -> TreeNode ? {
166
+ public func next( ) -> TreeNode ? {
167
+
168
+ guard let dependencyPointer = dependencyPointer else {
169
+ return nextByPopping ( )
170
+ }
164
171
165
172
guard dependencyPointer. kind. isRegistration,
166
- let nextContainer = try ? dependencyGraph. dependencyContainer ( for: dependencyPointer) ,
167
- let firstNestedDependency = nextContainer. dependencies. orderedValues. first else {
168
- return nextByIterating ( after: dependencyPointer)
173
+ let nextContainer = try ? dependencyGraph. dependencyContainer ( for: dependencyPointer) else {
174
+ return nextByIterating ( after: dependencyPointer)
169
175
}
170
176
171
- return TreeNode ( inspectingContainer: nextContainer,
172
- dependencyChain: dependencyChain + [ inspectingContainer] ,
173
- dependencyGraph: dependencyGraph,
174
- dependencyPointer: firstNestedDependency)
177
+ let node = TreeNode ( inspectingContainer: nextContainer,
178
+ dependencyGraph: dependencyGraph,
179
+ dependencyPointer: nextContainer. dependencies. orderedValues. first,
180
+ previousDependencyPointer: dependencyPointer,
181
+ parent: self )
182
+
183
+ children. append ( node)
184
+
185
+ return node
175
186
}
176
187
177
188
private func nextByIterating( after dependency: Dependency ) -> TreeNode ? {
@@ -183,34 +194,17 @@ final class TreeNode: Sequence, IteratorProtocol {
183
194
}
184
195
185
196
let nextIndex = values. index ( after: firstIndex)
186
- guard nextIndex < values. count else {
187
- return nextByPopping ( )
188
- }
189
-
190
- let nextDependency : Dependency = values [ nextIndex]
191
- return TreeNode ( inspectingContainer: inspectingContainer,
192
- dependencyChain: dependencyChain,
193
- dependencyGraph: dependencyGraph,
194
- dependencyPointer: nextDependency) . next ( )
197
+ dependencyPointer = nextIndex < values. count ? values [ nextIndex] : nil
198
+ return next ( )
195
199
}
196
200
197
201
private func nextByPopping( ) -> TreeNode ? {
198
- guard let parentContainer: DependencyContainer = dependencyChain. last else {
199
- return nil
200
- }
201
-
202
- guard let dependencyNames = parentContainer. dependencyNamesByConcreteType [ inspectingContainer. type] else {
203
- return nil
204
- }
205
202
206
- guard let dependencyName = dependencyNames . first ( where : { parentContainer . dependencies [ $0 ] != nil } ) ,
207
- let parentDependency = parentContainer . dependencies [ dependencyName ] else {
203
+ guard let parent = parent ,
204
+ let parentDependency = parent . inspectingContainer . dependencies. orderedValues . first ( where : { $0 === previousDependencyPointer } ) else {
208
205
return nil
209
206
}
210
207
211
- return TreeNode ( inspectingContainer: parentContainer,
212
- dependencyChain: dependencyChain. dropLast ( ) ,
213
- dependencyGraph: dependencyGraph,
214
- dependencyPointer: parentDependency) . nextByIterating ( after: parentDependency)
208
+ return parent. nextByIterating ( after: parentDependency)
215
209
}
216
210
}
0 commit comments