1 11 package org.eclipse.jdt.core.dom.rewrite; 12 13 import java.util.Iterator ; 14 import java.util.Map ; 15 16 import org.eclipse.text.edits.MultiTextEdit; 17 import org.eclipse.text.edits.TextEdit; 18 import org.eclipse.text.edits.TextEditGroup; 19 20 import org.eclipse.jface.text.IDocument; 21 22 import org.eclipse.jdt.core.JavaCore; 23 24 import org.eclipse.jdt.core.dom.AST; 25 import org.eclipse.jdt.core.dom.ASTNode; 26 import org.eclipse.jdt.core.dom.Block; 27 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; 28 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 29 30 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer; 31 import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore; 32 import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent; 33 import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore; 34 import org.eclipse.jdt.internal.core.dom.rewrite.TrackedNodePosition; 35 import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo; 36 37 78 public class ASTRewrite { 79 80 81 private final AST ast; 82 83 private final RewriteEventStore eventStore; 84 private final NodeInfoStore nodeStore; 85 86 91 private TargetSourceRangeComputer targetSourceRangeComputer = null; 92 93 100 public static ASTRewrite create(AST ast) { 101 return new ASTRewrite(ast); 102 } 103 104 110 protected ASTRewrite(AST ast) { 111 this.ast= ast; 112 this.eventStore= new RewriteEventStore(); 113 this.nodeStore= new NodeInfoStore(ast); 114 } 115 116 121 public final AST getAST() { 122 return this.ast; 123 } 124 125 130 protected final RewriteEventStore getRewriteEventStore() { 131 return this.eventStore; 132 } 133 134 139 protected final NodeInfoStore getNodeStore() { 140 return this.nodeStore; 141 } 142 143 171 public TextEdit rewriteAST(IDocument document, Map options) throws IllegalArgumentException { 172 if (document == null) { 173 throw new IllegalArgumentException (); 174 } 175 TextEdit result= new MultiTextEdit(); 176 177 ASTNode rootNode= getRootNode(); 178 if (rootNode != null) { 179 181 TargetSourceRangeComputer sourceRangeComputer= getExtendedSourceRangeComputer(); 182 183 this.eventStore.prepareMovedNodes(sourceRangeComputer); 184 185 ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, result, this.eventStore, this.nodeStore, options, sourceRangeComputer); 186 rootNode.accept(visitor); 188 this.eventStore.revertMovedNodes(); 189 } 190 return result; 191 } 192 193 private ASTNode getRootNode() { 194 ASTNode node= null; 195 int start= -1; 196 int end= -1; 197 198 for (Iterator iter= getRewriteEventStore().getChangeRootIterator(); iter.hasNext();) { 199 ASTNode curr= (ASTNode) iter.next(); 200 if (!RewriteEventStore.isNewNode(curr)) { 201 int currStart= curr.getStartPosition(); 202 int currEnd= currStart + curr.getLength(); 203 if (node == null || currStart < start && currEnd > end) { 204 start= currStart; 205 end= currEnd; 206 node= curr; 207 } else if (currStart < start) { 208 start= currStart; 209 } else if (currEnd > end) { 210 end= currEnd; 211 } 212 } 213 } 214 if (node != null) { 215 int currStart= node.getStartPosition(); 216 int currEnd= currStart + node.getLength(); 217 while (start < currStart || end > currEnd) { node= node.getParent(); 219 currStart= node.getStartPosition(); 220 currEnd= currStart + node.getLength(); 221 } 222 ASTNode parent= node.getParent(); while (parent != null && parent.getStartPosition() == node.getStartPosition() && parent.getLength() == node.getLength()) { 224 node= parent; 225 parent= node.getParent(); 226 } 227 } 228 return node; 229 } 230 231 244 245 257 public final void remove(ASTNode node, TextEditGroup editGroup) { 258 if (node == null) { 259 throw new IllegalArgumentException (); 260 } 261 StructuralPropertyDescriptor property= node.getLocationInParent(); 262 if (property.isChildListProperty()) { 263 getListRewrite(node.getParent(), (ChildListPropertyDescriptor) property).remove(node, editGroup); 264 } else { 265 set(node.getParent(), property, null, editGroup); 266 } 267 } 268 269 286 public final void replace(ASTNode node, ASTNode replacement, TextEditGroup editGroup) { 287 if (node == null) { 288 throw new IllegalArgumentException (); 289 } 290 StructuralPropertyDescriptor property= node.getLocationInParent(); 291 if (property.isChildListProperty()) { 292 getListRewrite(node.getParent(), (ChildListPropertyDescriptor) property).replace(node, replacement, editGroup); 293 } else { 294 set(node.getParent(), property, replacement, editGroup); 295 } 296 } 297 298 319 public final void set(ASTNode node, StructuralPropertyDescriptor property, Object value, TextEditGroup editGroup) { 320 if (node == null || property == null) { 321 throw new IllegalArgumentException (); 322 } 323 validateIsInsideAST(node); 324 validatePropertyType(property, value); 325 326 NodeRewriteEvent nodeEvent= this.eventStore.getNodeEvent(node, property, true); 327 nodeEvent.setNewValue(value); 328 if (editGroup != null) { 329 this.eventStore.setEventEditGroup(nodeEvent, editGroup); 330 } 331 } 332 333 344 public final ListRewrite getListRewrite(ASTNode node, ChildListPropertyDescriptor property) { 345 if (node == null || property == null) { 346 throw new IllegalArgumentException (); 347 } 348 validateIsListProperty(property); 349 350 return new ListRewrite(this, node, property); 351 } 352 353 366 public final ITrackedNodePosition track(ASTNode node) { 367 if (node == null) { 368 throw new IllegalArgumentException (); 369 } 370 TextEditGroup group= this.eventStore.getTrackedNodeData(node); 371 if (group == null) { 372 group= new TextEditGroup("internal"); this.eventStore.setTrackedNodeData(node, group); 374 } 375 return new TrackedNodePosition(group, node); 376 } 377 378 private void validateIsInsideAST(ASTNode node) { 379 if (node.getStartPosition() == -1) { 380 throw new IllegalArgumentException ("Node is not an existing node"); } 382 383 if (node.getAST() != getAST()) { 384 throw new IllegalArgumentException ("Node is not inside the AST"); } 386 } 387 388 private void validateIsListProperty(StructuralPropertyDescriptor property) { 389 if (!property.isChildListProperty()) { 390 String message= property.getId() + " is not a list property"; throw new IllegalArgumentException (message); 392 } 393 } 394 395 private void validatePropertyType(StructuralPropertyDescriptor prop, Object node) { 396 if (prop.isChildListProperty()) { 397 String message= "Can not modify a list property, use a list rewriter"; throw new IllegalArgumentException (message); 399 } 400 } 412 413 426 public final ASTNode createStringPlaceholder(String code, int nodeType) { 427 if (code == null) { 428 throw new IllegalArgumentException (); 429 } 430 ASTNode placeholder= getNodeStore().newPlaceholderNode(nodeType); 431 if (placeholder == null) { 432 throw new IllegalArgumentException ("String placeholder is not supported for type" + nodeType); } 434 435 getNodeStore().markAsStringPlaceholder(placeholder, code); 436 return placeholder; 437 } 438 439 455 public final ASTNode createGroupNode(ASTNode[] targetNodes) { 456 if (targetNodes == null || targetNodes.length == 0) { 457 throw new IllegalArgumentException (); 458 } 459 Block res= getNodeStore().createCollapsePlaceholder(); 460 ListRewrite listRewrite= getListRewrite(res, Block.STATEMENTS_PROPERTY); 461 for (int i= 0; i < targetNodes.length; i++) { 462 listRewrite.insertLast(targetNodes[i], null); 463 } 464 return res; 465 } 466 467 468 private ASTNode createTargetNode(ASTNode node, boolean isMove) { 469 if (node == null) { 470 throw new IllegalArgumentException (); 471 } 472 validateIsInsideAST(node); 473 CopySourceInfo info= getRewriteEventStore().markAsCopySource(node.getParent(), node.getLocationInParent(), node, isMove); 474 475 ASTNode placeholder= getNodeStore().newPlaceholderNode(node.getNodeType()); 476 if (placeholder == null) { 477 throw new IllegalArgumentException ("Creating a target node is not supported for nodes of type" + node.getClass().getName()); } 479 getNodeStore().markAsCopyTarget(placeholder, info); 480 481 return placeholder; 482 } 483 484 496 public final ASTNode createCopyTarget(ASTNode node) { 497 return createTargetNode(node, false); 498 } 499 500 513 public final ASTNode createMoveTarget(ASTNode node) { 514 return createTargetNode(node, true); 515 } 516 517 524 public final TargetSourceRangeComputer getExtendedSourceRangeComputer() { 525 if (this.targetSourceRangeComputer == null) { 526 this.targetSourceRangeComputer = new TargetSourceRangeComputer(); 528 } 529 return this.targetSourceRangeComputer; 530 } 531 532 541 public final void setTargetSourceRangeComputer(TargetSourceRangeComputer computer) { 542 this.targetSourceRangeComputer = computer; 544 } 545 546 551 public String toString() { 552 StringBuffer buf= new StringBuffer (); 553 buf.append("Events:\n"); if (this.eventStore != null) { 556 buf.append(this.eventStore.toString()); 557 } 558 return buf.toString(); 559 } 560 } 561 | Popular Tags |