@@ -30,145 +30,178 @@ import { each } from './util/util';
3030 * to reflect the write added.
3131 */
3232export class CompoundWrite {
33- constructor ( private writeTree_ : ImmutableTree < Node > ) { }
33+ constructor ( public writeTree_ : ImmutableTree < Node > ) { }
3434
3535 static empty ( ) : CompoundWrite {
3636 return new CompoundWrite ( new ImmutableTree ( null ) ) ;
3737 }
38+ }
3839
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+ ) ;
4257 } 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 ) ;
5561 }
5662 }
63+ }
5764
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+ }
6576
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 ) ;
8397 }
98+ }
8499
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+ }
95114
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 ;
112134 }
135+ }
113136
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 ) => {
134161 if ( childTree . value != null ) {
135162 children . push ( new NamedNode ( childName , childTree . value ) ) ;
136163 }
137- } ) ;
138- }
139- return children ;
164+ }
165+ ) ;
140166 }
167+ return children ;
168+ }
141169
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 ) ) ;
145180 } 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 ) ) ;
152182 }
153183 }
184+ }
154185
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+ }
162193
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 ) ;
172205}
173206
174207function applySubtreeWrite (
0 commit comments