@@ -30,145 +30,178 @@ import { each } from './util/util';
30
30
* to reflect the write added.
31
31
*/
32
32
export class CompoundWrite {
33
- constructor ( private writeTree_ : ImmutableTree < Node > ) { }
33
+ constructor ( public writeTree_ : ImmutableTree < Node > ) { }
34
34
35
35
static empty ( ) : CompoundWrite {
36
36
return new CompoundWrite ( new ImmutableTree ( null ) ) ;
37
37
}
38
+ }
38
39
39
- addWrite ( path : Path , node : Node ) : CompoundWrite {
40
- if ( path . isEmpty ( ) ) {
41
- return new CompoundWrite ( new ImmutableTree ( node ) ) ;
40
+ export function compoundWriteAddWrite (
41
+ compoundWrite : CompoundWrite ,
42
+ path : Path ,
43
+ node : Node
44
+ ) : CompoundWrite {
45
+ if ( path . isEmpty ( ) ) {
46
+ return new CompoundWrite ( new ImmutableTree ( node ) ) ;
47
+ } else {
48
+ const rootmost = compoundWrite . writeTree_ . findRootMostValueAndPath ( path ) ;
49
+ if ( rootmost != null ) {
50
+ const rootMostPath = rootmost . path ;
51
+ let value = rootmost . value ;
52
+ const relativePath = Path . relativePath ( rootMostPath , path ) ;
53
+ value = value . updateChild ( relativePath , node ) ;
54
+ return new CompoundWrite (
55
+ compoundWrite . writeTree_ . set ( rootMostPath , value )
56
+ ) ;
42
57
} else {
43
- const rootmost = this . writeTree_ . findRootMostValueAndPath ( path ) ;
44
- if ( rootmost != null ) {
45
- const rootMostPath = rootmost . path ;
46
- let value = rootmost . value ;
47
- const relativePath = Path . relativePath ( rootMostPath , path ) ;
48
- value = value . updateChild ( relativePath , node ) ;
49
- return new CompoundWrite ( this . writeTree_ . set ( rootMostPath , value ) ) ;
50
- } else {
51
- const subtree = new ImmutableTree ( node ) ;
52
- const newWriteTree = this . writeTree_ . setTree ( path , subtree ) ;
53
- return new CompoundWrite ( newWriteTree ) ;
54
- }
58
+ const subtree = new ImmutableTree ( node ) ;
59
+ const newWriteTree = compoundWrite . writeTree_ . setTree ( path , subtree ) ;
60
+ return new CompoundWrite ( newWriteTree ) ;
55
61
}
56
62
}
63
+ }
57
64
58
- addWrites ( path : Path , updates : { [ name : string ] : Node } ) : CompoundWrite {
59
- let newWrite = this as CompoundWrite ;
60
- each ( updates , ( childKey : string , node : Node ) => {
61
- newWrite = newWrite . addWrite ( path . child ( childKey ) , node ) ;
62
- } ) ;
63
- return newWrite ;
64
- }
65
+ export function compoundWriteAddWrites (
66
+ compoundWrite : CompoundWrite ,
67
+ path : Path ,
68
+ updates : { [ name : string ] : Node }
69
+ ) : CompoundWrite {
70
+ let newWrite = compoundWrite ;
71
+ each ( updates , ( childKey : string , node : Node ) => {
72
+ newWrite = compoundWriteAddWrite ( newWrite , path . child ( childKey ) , node ) ;
73
+ } ) ;
74
+ return newWrite ;
75
+ }
65
76
66
- /**
67
- * Will remove a write at the given path and deeper paths. This will <em>not</em> modify a write at a higher
68
- * location, which must be removed by calling this method with that path.
69
- *
70
- * @param path The path at which a write and all deeper writes should be removed
71
- * @return The new CompoundWrite with the removed path
72
- */
73
- removeWrite ( path : Path ) : CompoundWrite {
74
- if ( path . isEmpty ( ) ) {
75
- return CompoundWrite . empty ( ) ;
76
- } else {
77
- const newWriteTree = this . writeTree_ . setTree (
78
- path ,
79
- new ImmutableTree < Node > ( null )
80
- ) ;
81
- return new CompoundWrite ( newWriteTree ) ;
82
- }
77
+ /**
78
+ * Will remove a write at the given path and deeper paths. This will <em>not</em> modify a write at a higher
79
+ * location, which must be removed by calling this method with that path.
80
+ *
81
+ * @param compoundWrite The CompoundWrite to remove.
82
+ * @param path The path at which a write and all deeper writes should be removed
83
+ * @return The new CompoundWrite with the removed path
84
+ */
85
+ export function compoundWriteRemoveWrite (
86
+ compoundWrite : CompoundWrite ,
87
+ path : Path
88
+ ) : CompoundWrite {
89
+ if ( path . isEmpty ( ) ) {
90
+ return CompoundWrite . empty ( ) ;
91
+ } else {
92
+ const newWriteTree = compoundWrite . writeTree_ . setTree (
93
+ path ,
94
+ new ImmutableTree < Node > ( null )
95
+ ) ;
96
+ return new CompoundWrite ( newWriteTree ) ;
83
97
}
98
+ }
84
99
85
- /**
86
- * Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be
87
- * considered "complete".
88
- *
89
- * @param path The path to check for
90
- * @return Whether there is a complete write at that path
91
- */
92
- hasCompleteWrite ( path : Path ) : boolean {
93
- return this . getCompleteNode ( path ) != null ;
94
- }
100
+ /**
101
+ * Returns whether this CompoundWrite will fully overwrite a node at a given location and can therefore be
102
+ * considered "complete".
103
+ *
104
+ * @param compoundWrite The CompoundWrite to check.
105
+ * @param path The path to check for
106
+ * @return Whether there is a complete write at that path
107
+ */
108
+ export function compoundWriteHasCompleteWrite (
109
+ compoundWrite : CompoundWrite ,
110
+ path : Path
111
+ ) : boolean {
112
+ return compoundWriteGetCompleteNode ( compoundWrite , path ) != null ;
113
+ }
95
114
96
- /**
97
- * Returns a node for a path if and only if the node is a "complete" overwrite at that path. This will not aggregate
98
- * writes from deeper paths, but will return child nodes from a more shallow path.
99
- *
100
- * @param path The path to get a complete write
101
- * @return The node if complete at that path, or null otherwise.
102
- */
103
- getCompleteNode ( path : Path ) : Node | null {
104
- const rootmost = this . writeTree_ . findRootMostValueAndPath ( path ) ;
105
- if ( rootmost != null ) {
106
- return this . writeTree_
107
- . get ( rootmost . path )
108
- . getChild ( Path . relativePath ( rootmost . path , path ) ) ;
109
- } else {
110
- return null ;
111
- }
115
+ /**
116
+ * Returns a node for a path if and only if the node is a "complete" overwrite at that path. This will not aggregate
117
+ * writes from deeper paths, but will return child nodes from a more shallow path.
118
+ *
119
+ * @param compoundWrite The CompoundWrite to get the node from.
120
+ * @param path The path to get a complete write
121
+ * @return The node if complete at that path, or null otherwise.
122
+ */
123
+ export function compoundWriteGetCompleteNode (
124
+ compoundWrite : CompoundWrite ,
125
+ path : Path
126
+ ) : Node | null {
127
+ const rootmost = compoundWrite . writeTree_ . findRootMostValueAndPath ( path ) ;
128
+ if ( rootmost != null ) {
129
+ return compoundWrite . writeTree_
130
+ . get ( rootmost . path )
131
+ . getChild ( Path . relativePath ( rootmost . path , path ) ) ;
132
+ } else {
133
+ return null ;
112
134
}
135
+ }
113
136
114
- /**
115
- * Returns all children that are guaranteed to be a complete overwrite.
116
- *
117
- * @return A list of all complete children.
118
- */
119
- getCompleteChildren ( ) : NamedNode [ ] {
120
- const children : NamedNode [ ] = [ ] ;
121
- const node = this . writeTree_ . value ;
122
- if ( node != null ) {
123
- // If it's a leaf node, it has no children; so nothing to do.
124
- if ( ! node . isLeafNode ( ) ) {
125
- ( node as ChildrenNode ) . forEachChild (
126
- PRIORITY_INDEX ,
127
- ( childName , childNode ) => {
128
- children . push ( new NamedNode ( childName , childNode ) ) ;
129
- }
130
- ) ;
131
- }
132
- } else {
133
- this . writeTree_ . children . inorderTraversal ( ( childName , childTree ) => {
137
+ /**
138
+ * Returns all children that are guaranteed to be a complete overwrite.
139
+ *
140
+ * @param compoundWrite The CompoundWrite to get children from.
141
+ * @return A list of all complete children.
142
+ */
143
+ export function compoundWriteGetCompleteChildren (
144
+ compoundWrite : CompoundWrite
145
+ ) : NamedNode [ ] {
146
+ const children : NamedNode [ ] = [ ] ;
147
+ const node = compoundWrite . writeTree_ . value ;
148
+ if ( node != null ) {
149
+ // If it's a leaf node, it has no children; so nothing to do.
150
+ if ( ! node . isLeafNode ( ) ) {
151
+ ( node as ChildrenNode ) . forEachChild (
152
+ PRIORITY_INDEX ,
153
+ ( childName , childNode ) => {
154
+ children . push ( new NamedNode ( childName , childNode ) ) ;
155
+ }
156
+ ) ;
157
+ }
158
+ } else {
159
+ compoundWrite . writeTree_ . children . inorderTraversal (
160
+ ( childName , childTree ) => {
134
161
if ( childTree . value != null ) {
135
162
children . push ( new NamedNode ( childName , childTree . value ) ) ;
136
163
}
137
- } ) ;
138
- }
139
- return children ;
164
+ }
165
+ ) ;
140
166
}
167
+ return children ;
168
+ }
141
169
142
- childCompoundWrite ( path : Path ) : CompoundWrite {
143
- if ( path . isEmpty ( ) ) {
144
- return this ;
170
+ export function compoundWriteChildCompoundWrite (
171
+ compoundWrite : CompoundWrite ,
172
+ path : Path
173
+ ) : CompoundWrite {
174
+ if ( path . isEmpty ( ) ) {
175
+ return compoundWrite ;
176
+ } else {
177
+ const shadowingNode = compoundWriteGetCompleteNode ( compoundWrite , path ) ;
178
+ if ( shadowingNode != null ) {
179
+ return new CompoundWrite ( new ImmutableTree ( shadowingNode ) ) ;
145
180
} else {
146
- const shadowingNode = this . getCompleteNode ( path ) ;
147
- if ( shadowingNode != null ) {
148
- return new CompoundWrite ( new ImmutableTree ( shadowingNode ) ) ;
149
- } else {
150
- return new CompoundWrite ( this . writeTree_ . subtree ( path ) ) ;
151
- }
181
+ return new CompoundWrite ( compoundWrite . writeTree_ . subtree ( path ) ) ;
152
182
}
153
183
}
184
+ }
154
185
155
- /**
156
- * Returns true if this CompoundWrite is empty and therefore does not modify any nodes.
157
- * @return Whether this CompoundWrite is empty
158
- */
159
- isEmpty ( ) : boolean {
160
- return this . writeTree_ . isEmpty ( ) ;
161
- }
186
+ /**
187
+ * Returns true if this CompoundWrite is empty and therefore does not modify any nodes.
188
+ * @return Whether this CompoundWrite is empty
189
+ */
190
+ export function compoundWriteIsEmpty ( compoundWrite : CompoundWrite ) : boolean {
191
+ return compoundWrite . writeTree_ . isEmpty ( ) ;
192
+ }
162
193
163
- /**
164
- * Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the
165
- * node
166
- * @param node The node to apply this CompoundWrite to
167
- * @return The node with all writes applied
168
- */
169
- apply ( node : Node ) : Node {
170
- return applySubtreeWrite ( Path . Empty , this . writeTree_ , node ) ;
171
- }
194
+ /**
195
+ * Applies this CompoundWrite to a node. The node is returned with all writes from this CompoundWrite applied to the
196
+ * node
197
+ * @param node The node to apply this CompoundWrite to
198
+ * @return The node with all writes applied
199
+ */
200
+ export function compoundWriteApply (
201
+ compoundWrite : CompoundWrite ,
202
+ node : Node
203
+ ) : Node {
204
+ return applySubtreeWrite ( Path . Empty , compoundWrite . writeTree_ , node ) ;
172
205
}
173
206
174
207
function applySubtreeWrite (
0 commit comments