comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 11951:c0c616fe3588

Back out changeset be0a33a631fa.
author Andreas Woess <andreas.woess@jku.at>
date Thu, 10 Oct 2013 03:23:40 +0200
parents be0a33a631fa
children 57b8a41c0e18
comparison
equal deleted inserted replaced
11950:be0a33a631fa 11951:c0c616fe3588
37 37
38 private Node parent; 38 private Node parent;
39 39
40 private SourceSection sourceSection; 40 private SourceSection sourceSection;
41 41
42 private Node replacedWith;
43
44 /** 42 /**
45 * Marks array fields that are children of this node. 43 * Marks array fields that are children of this node.
46 */ 44 */
47 @Retention(RetentionPolicy.RUNTIME) 45 @Retention(RetentionPolicy.RUNTIME)
48 @Target({ElementType.FIELD}) 46 @Target({ElementType.FIELD})
170 * 168 *
171 * @param newNode the new node that is the replacement 169 * @param newNode the new node that is the replacement
172 * @param reason a description of the reason for the replacement 170 * @param reason a description of the reason for the replacement
173 * @return the new node 171 * @return the new node
174 */ 172 */
173 @SuppressWarnings({"unchecked"})
175 public final <T extends Node> T replace(T newNode, String reason) { 174 public final <T extends Node> T replace(T newNode, String reason) {
176 CompilerDirectives.transferToInterpreter();
177 if (this.getParent() == null) { 175 if (this.getParent() == null) {
178 throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); 176 throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent.");
179 } 177 }
180 if (sourceSection != null && newNode.getSourceSection() == null) { 178 if (sourceSection != null && newNode.getSourceSection() == null) {
181 // Pass on the source section to the new node. 179 // Pass on the source section to the new node.
182 newNode.assignSourceSection(sourceSection); 180 newNode.assignSourceSection(sourceSection);
183 } 181 }
184 onReplace(newNode, reason); 182 onReplace(newNode, reason);
185 if (NodeUtil.replaceChild(parent, this, newNode)) { 183 return (T) this.getParent().replaceChild(this, newNode);
186 parent.adoptChild(newNode); 184 }
187 this.replacedWith = newNode; 185
188 } else if (replacedWith != null) { 186 private <T extends Node> T replaceChild(T oldChild, T newChild) {
189 replaceFailedHelper(newNode); 187 NodeUtil.replaceChild(this, oldChild, newChild);
190 } else { 188 adoptChild(newChild);
191 throw new IllegalStateException("Child not found in parent."); 189 return newChild;
192 }
193 return newNode;
194 }
195
196 private void replaceFailedHelper(Node newNode) {
197 Node lastReplacedWith = replacedWith;
198 assert lastReplacedWith != this;
199 while (lastReplacedWith.replacedWith != null) {
200 lastReplacedWith = lastReplacedWith.replacedWith;
201 assert lastReplacedWith != this;
202 }
203 newNode.parent = parent;
204 newNode.replacedWith = lastReplacedWith;
205 for (Node child : newNode.getChildren()) {
206 if (child != null) {
207 child.parent = lastReplacedWith;
208 }
209 }
210 } 190 }
211 191
212 /** 192 /**
213 * Replaces this node with another node. If there is a source section (see 193 * Replaces this node with another node. If there is a source section (see
214 * {@link #getSourceSection()}) associated with this node, it is transferred to the new node. 194 * {@link #getSourceSection()}) associated with this node, it is transferred to the new node.