@@ -59,15 +59,16 @@ public class NodeImpl
5959 private final NodeImpl parent ;
6060 private final NodeImpl root ;
6161 private final int size ;
62- private final boolean isIterable ;
62+ private boolean isIterable ;
6363 private final Integer index ;
6464 private final Object key ;
6565 private final ElementKind kind ;
6666
6767 //type-specific attributes
6868 private final Class <?>[] parameterTypes ;
6969 private final Integer parameterIndex ;
70- private final Object value ;
70+ private Object value ;
71+ private boolean valueSet ;
7172 private final Class <?> containerClass ;
7273 private final Integer typeArgumentIndex ;
7374
@@ -76,7 +77,7 @@ public class NodeImpl
7677
7778 private NodeImpl (
7879 String name , NodeImpl parent , boolean isIterable , Integer index , Object key , ElementKind kind , Class <?>[] parameterTypes ,
79- Integer parameterIndex , Object value , Class <?> containerClass , Integer typeArgumentIndex
80+ Integer parameterIndex , Object value , boolean valueSet , Class <?> containerClass , Integer typeArgumentIndex
8081 ) {
8182 this .name = name ;
8283 this .parent = parent ;
@@ -85,6 +86,7 @@ private NodeImpl(
8586 this .index = index ;
8687 this .key = key ;
8788 this .value = value ;
89+ this .valueSet = valueSet ;
8890 this .isIterable = isIterable ;
8991 this .kind = kind ;
9092 this .parameterTypes = parameterTypes ;
@@ -105,6 +107,7 @@ public static NodeImpl createPropertyNode(String name, NodeImpl parent) {
105107 EMPTY_CLASS_ARRAY ,
106108 null ,
107109 null ,
110+ false ,
108111 null ,
109112 null
110113 );
@@ -121,6 +124,7 @@ public static NodeImpl createContainerElementNode(String name, NodeImpl parent)
121124 EMPTY_CLASS_ARRAY ,
122125 null ,
123126 null ,
127+ false ,
124128 null ,
125129 null
126130 );
@@ -137,6 +141,7 @@ public static NodeImpl createParameterNode(String name, NodeImpl parent, int par
137141 EMPTY_CLASS_ARRAY ,
138142 parameterIndex ,
139143 null ,
144+ false ,
140145 null ,
141146 null
142147 );
@@ -153,17 +158,18 @@ public static NodeImpl createCrossParameterNode(NodeImpl parent) {
153158 EMPTY_CLASS_ARRAY ,
154159 null ,
155160 null ,
161+ false ,
156162 null ,
157163 null
158164 );
159165 }
160166
161167 public static NodeImpl createMethodNode (String name , NodeImpl parent , Class <?>[] parameterTypes ) {
162- return new NodeImpl ( name , parent , false , null , null , ElementKind .METHOD , parameterTypes , null , null , null , null );
168+ return new NodeImpl ( name , parent , false , null , null , ElementKind .METHOD , parameterTypes , null , null , false , null , null );
163169 }
164170
165171 public static NodeImpl createConstructorNode (String name , NodeImpl parent , Class <?>[] parameterTypes ) {
166- return new NodeImpl ( name , parent , false , null , null , ElementKind .CONSTRUCTOR , parameterTypes , null , null , null , null );
172+ return new NodeImpl ( name , parent , false , null , null , ElementKind .CONSTRUCTOR , parameterTypes , null , null , false , null , null );
167173 }
168174
169175 public static NodeImpl createBeanNode (NodeImpl parent ) {
@@ -177,6 +183,7 @@ public static NodeImpl createBeanNode(NodeImpl parent) {
177183 EMPTY_CLASS_ARRAY ,
178184 null ,
179185 null ,
186+ false ,
180187 null ,
181188 null
182189 );
@@ -193,6 +200,7 @@ public static NodeImpl createReturnValue(NodeImpl parent) {
193200 EMPTY_CLASS_ARRAY ,
194201 null ,
195202 null ,
203+ false ,
196204 null ,
197205 null
198206 );
@@ -209,6 +217,7 @@ public static NodeImpl makeIterable(NodeImpl node) {
209217 node .parameterTypes ,
210218 node .parameterIndex ,
211219 node .value ,
220+ node .valueSet ,
212221 node .containerClass ,
213222 node .typeArgumentIndex
214223 );
@@ -225,6 +234,7 @@ public static NodeImpl makeIterableAndSetIndex(NodeImpl node, Integer index) {
225234 node .parameterTypes ,
226235 node .parameterIndex ,
227236 node .value ,
237+ node .valueSet ,
228238 node .containerClass ,
229239 node .typeArgumentIndex
230240 );
@@ -241,25 +251,32 @@ public static NodeImpl makeIterableAndSetMapKey(NodeImpl node, Object key) {
241251 node .parameterTypes ,
242252 node .parameterIndex ,
243253 node .value ,
254+ node .valueSet ,
244255 node .containerClass ,
245256 node .typeArgumentIndex
246257 );
247258 }
248259
249260 public static NodeImpl setPropertyValue (NodeImpl node , Object value ) {
250- return new NodeImpl (
251- node .name ,
252- node .parent ,
253- node .isIterable ,
254- node .index ,
255- node .key ,
256- node .kind ,
257- node .parameterTypes ,
258- node .parameterIndex ,
259- value ,
260- node .containerClass ,
261- node .typeArgumentIndex
262- );
261+ if ( node .valueSet && node .value != value ) {
262+ return new NodeImpl (
263+ node .name ,
264+ node .parent ,
265+ node .isIterable ,
266+ node .index ,
267+ node .key ,
268+ node .kind ,
269+ node .parameterTypes ,
270+ node .parameterIndex ,
271+ value ,
272+ true ,
273+ node .containerClass ,
274+ node .typeArgumentIndex
275+ );
276+ }
277+ node .value = value ;
278+ node .valueSet = true ;
279+ return node ;
263280 }
264281
265282 public static NodeImpl setTypeParameter (NodeImpl node , Class <?> containerClass , Integer typeArgumentIndex ) {
@@ -273,6 +290,7 @@ public static NodeImpl setTypeParameter(NodeImpl node, Class<?> containerClass,
273290 node .parameterTypes ,
274291 node .parameterIndex ,
275292 node .value ,
293+ node .valueSet ,
276294 containerClass ,
277295 typeArgumentIndex
278296 );
@@ -370,7 +388,7 @@ public int getParameterIndex() {
370388 kind == ElementKind .PARAMETER ,
371389 "getParameterIndex() may only be invoked for nodes of type ElementKind.PARAMETER."
372390 );
373- return parameterIndex . intValue () ;
391+ return parameterIndex ;
374392 }
375393
376394 @ Override
@@ -541,6 +559,7 @@ boolean isRootPath() {
541559
542560 @ Override
543561 public Iterator <Path .Node > iterator () {
562+ // TODO: keep the initialized list so next iterator calls can reuse it?
544563 if ( parent == null ) {
545564 return List .of ( (Path .Node ) this ).iterator ();
546565 }
0 commit comments