1 11 package org.eclipse.jdt.internal.core.dom.rewrite; 12 13 import java.util.*; 14 15 import org.eclipse.jdt.core.Signature; 16 import org.eclipse.jdt.core.dom.*; 17 import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer; 18 import org.eclipse.text.edits.TextEditGroup; 19 20 21 25 public final class RewriteEventStore { 26 27 28 public static final class PropertyLocation { 29 private final ASTNode parent; 30 private final StructuralPropertyDescriptor property; 31 32 public PropertyLocation(ASTNode parent, StructuralPropertyDescriptor property) { 33 this.parent= parent; 34 this.property= property; 35 } 36 37 public ASTNode getParent() { 38 return this.parent; 39 } 40 41 public StructuralPropertyDescriptor getProperty() { 42 return this.property; 43 } 44 45 public boolean equals(Object obj) { 46 if (obj != null && obj.getClass().equals(this.getClass())) { 47 PropertyLocation other= (PropertyLocation) obj; 48 return other.getParent().equals(getParent()) && other.getProperty().equals(getProperty()); 49 } 50 return false; 51 } 52 53 public int hashCode() { 54 return getParent().hashCode() + getProperty().hashCode(); 55 } 56 57 } 58 59 64 public static interface INodePropertyMapper { 65 71 Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor childProperty); 72 } 73 74 77 private static class EventHolder { 78 public final ASTNode parent; 79 public final StructuralPropertyDescriptor childProperty; 80 public final RewriteEvent event; 81 82 public EventHolder(ASTNode parent, StructuralPropertyDescriptor childProperty, RewriteEvent change) { 83 this.parent= parent; 84 this.childProperty= childProperty; 85 this.event= change; 86 } 87 88 public String toString() { 89 StringBuffer buf= new StringBuffer (); 90 buf.append(this.parent).append(" - "); buf.append(this.childProperty.getId()).append(": "); buf.append(this.event).append('\n'); 93 return buf.toString(); 94 } 95 } 96 97 public static class CopySourceInfo implements Comparable { 98 public final PropertyLocation location; private final ASTNode node; 100 public final boolean isMove; 101 102 public CopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) { 103 this.location= location; 104 this.node= node; 105 this.isMove= isMove; 106 } 107 108 public ASTNode getNode() { 109 return this.node; 110 } 111 112 public int compareTo(Object o2) { 113 CopySourceInfo r2= (CopySourceInfo) o2; 114 115 int startDiff= this.getNode().getStartPosition() - r2.getNode().getStartPosition(); 116 if (startDiff != 0) { 117 return startDiff; } 119 120 if (r2.isMove != this.isMove) { 121 return this.isMove ? -1 : 1; } 123 return 0; 124 } 125 126 public String toString() { 127 StringBuffer buf= new StringBuffer (); 128 if (this.isMove) { 129 buf.append("move source: "); } else { 131 buf.append("copy source: "); } 133 buf.append(this.node); 134 return buf.toString(); 135 } 136 } 137 138 private static class NodeRangeInfo implements Comparable { 139 private final ASTNode first; 140 private final ASTNode last; 141 public final CopySourceInfo copyInfo; public final ASTNode replacingNode; 143 public final TextEditGroup editGroup; 144 145 public NodeRangeInfo(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, CopySourceInfo copyInfo, ASTNode replacingNode, TextEditGroup editGroup) { 146 this.first= first; 147 this.last= last; 148 this.copyInfo= copyInfo; 149 this.replacingNode= replacingNode; 150 this.editGroup= editGroup; 151 } 152 153 public ASTNode getStartNode() { 154 return this.first; 155 } 156 157 public ASTNode getEndNode() { 158 return this.last; 159 } 160 161 public boolean isMove() { 162 return this.copyInfo.isMove; 163 } 164 165 public Block getInternalPlaceholder() { 166 return (Block) this.copyInfo.getNode(); 167 } 168 169 public int compareTo(Object o2) { 170 NodeRangeInfo r2= (NodeRangeInfo) o2; 171 172 int startDiff= this.getStartNode().getStartPosition() - r2.getStartNode().getStartPosition(); 173 if (startDiff != 0) { 174 return startDiff; } 176 int endDiff= this.getEndNode().getStartPosition() - r2.getEndNode().getStartPosition(); 177 if (endDiff != 0) { 178 return -endDiff; } 180 if (r2.isMove() != this.isMove()) { 181 return this.isMove() ? -1 : 1; } 183 return 0; 184 } 185 186 public void updatePlaceholderSourceRanges(TargetSourceRangeComputer sourceRangeComputer) { 187 TargetSourceRangeComputer.SourceRange startRange= sourceRangeComputer.computeSourceRange(getStartNode()); 188 TargetSourceRangeComputer.SourceRange endRange= sourceRangeComputer.computeSourceRange(getEndNode()); 189 int startPos= startRange.getStartPosition(); 190 int endPos= endRange.getStartPosition() + endRange.getLength(); 191 192 Block internalPlaceholder= getInternalPlaceholder(); 193 internalPlaceholder.setSourceRange(startPos, endPos - startPos); 194 } 195 196 public String toString() { 197 StringBuffer buf= new StringBuffer (); 198 if (this.first != this.last) { 199 buf.append("range "); } 201 if (isMove()) { 202 buf.append("move source: "); } else { 204 buf.append("copy source: "); } 206 buf.append(this.first); 207 buf.append(" - "); buf.append(this.last); 209 return buf.toString(); 210 } 211 212 213 } 214 215 218 private class ParentIterator implements Iterator { 219 220 private Iterator eventIter; 221 private Iterator sourceNodeIter; 222 private Iterator rangeNodeIter; 223 private Iterator trackedNodeIter; 224 225 public ParentIterator() { 226 this.eventIter= RewriteEventStore.this.events.iterator(); 227 if (RewriteEventStore.this.nodeCopySources != null) { 228 this.sourceNodeIter= RewriteEventStore.this.nodeCopySources.iterator(); 229 } else { 230 this.sourceNodeIter= Collections.EMPTY_LIST.iterator(); 231 } 232 if (RewriteEventStore.this.nodeRangeInfos != null) { 233 this.rangeNodeIter= RewriteEventStore.this.nodeRangeInfos.keySet().iterator(); 234 } else { 235 this.rangeNodeIter= Collections.EMPTY_LIST.iterator(); 236 } 237 if (RewriteEventStore.this.trackedNodes != null) { 238 this.trackedNodeIter= RewriteEventStore.this.trackedNodes.keySet().iterator(); 239 } else { 240 this.trackedNodeIter= Collections.EMPTY_LIST.iterator(); 241 } 242 } 243 244 247 public boolean hasNext() { 248 return this.eventIter.hasNext() || this.sourceNodeIter.hasNext() || this.rangeNodeIter.hasNext() || this.trackedNodeIter.hasNext(); 249 } 250 251 254 public Object next() { 255 if (this.eventIter.hasNext()) { 256 return ((EventHolder) this.eventIter.next()).parent; 257 } 258 if (this.sourceNodeIter.hasNext()) { 259 return ((CopySourceInfo) this.sourceNodeIter.next()).getNode(); 260 } 261 if (this.rangeNodeIter.hasNext()) { 262 return ((PropertyLocation) this.rangeNodeIter.next()).getParent(); 263 } 264 return this.trackedNodeIter.next(); 265 } 266 267 270 public void remove() { 271 throw new UnsupportedOperationException (); 272 } 273 } 274 275 public final static int NEW= 1; 276 public final static int ORIGINAL= 2; 277 public final static int BOTH= NEW | ORIGINAL; 278 279 280 281 final List events; 282 283 284 private EventHolder lastEvent; 285 286 287 private Map editGroups; 288 289 290 List nodeCopySources; 291 292 293 Map nodeRangeInfos; 294 295 296 Map trackedNodes; 297 298 300 private Set insertBoundToPrevious; 301 302 303 private INodePropertyMapper nodePropertyMapper; 304 305 private static final String INTERNAL_PLACEHOLDER_PROPERTY= "rewrite_internal_placeholder"; 307 public RewriteEventStore() { 308 this.events= new ArrayList(); 309 this.lastEvent= null; 310 311 this.editGroups= null; 313 this.trackedNodes= null; 314 this.insertBoundToPrevious= null; 315 316 this.nodePropertyMapper= null; 317 this.nodeCopySources= null; 318 this.nodeRangeInfos= null; 319 } 320 321 326 public void setNodePropertyMapper(INodePropertyMapper nodePropertyMapper) { 327 this.nodePropertyMapper= nodePropertyMapper; 328 } 329 330 public void clear() { 331 this.events.clear(); 332 this.lastEvent= null; 333 this.trackedNodes= null; 334 335 this.editGroups= null; this.insertBoundToPrevious= null; 337 this.nodeCopySources= null; 338 } 339 340 public void addEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, RewriteEvent event) { 341 validateHasChildProperty(parent, childProperty); 342 343 if (event.isListRewrite()) { 344 validateIsListProperty(childProperty); 345 } 346 347 EventHolder holder= new EventHolder(parent, childProperty, event); 348 349 for (int i= 0; i < this.events.size(); i++) { 351 EventHolder curr= (EventHolder) this.events.get(i); 352 if (curr.parent == parent && curr.childProperty == childProperty) { 353 this.events.set(i, holder); 354 this.lastEvent= null; 355 return; 356 } 357 } 358 this.events.add(holder); 359 } 360 361 public RewriteEvent getEvent(ASTNode parent, StructuralPropertyDescriptor property) { 362 validateHasChildProperty(parent, property); 363 364 if (this.lastEvent != null && this.lastEvent.parent == parent && this.lastEvent.childProperty == property) { 365 return this.lastEvent.event; 366 } 367 368 for (int i= 0; i < this.events.size(); i++) { 369 EventHolder holder= (EventHolder) this.events.get(i); 370 if (holder.parent == parent && holder.childProperty == property) { 371 this.lastEvent= holder; 372 return holder.event; 373 } 374 } 375 return null; 376 } 377 378 public NodeRewriteEvent getNodeEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, boolean forceCreation) { 379 validateIsNodeProperty(childProperty); 380 NodeRewriteEvent event= (NodeRewriteEvent) getEvent(parent, childProperty); 381 if (event == null && forceCreation) { 382 Object originalValue= accessOriginalValue(parent, childProperty); 383 event= new NodeRewriteEvent(originalValue, originalValue); 384 addEvent(parent, childProperty, event); 385 } 386 return event; 387 } 388 389 public ListRewriteEvent getListEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, boolean forceCreation) { 390 validateIsListProperty(childProperty); 391 ListRewriteEvent event= (ListRewriteEvent) getEvent(parent, childProperty); 392 if (event == null && forceCreation) { 393 List originalValue= (List) accessOriginalValue(parent, childProperty); 394 event= new ListRewriteEvent(originalValue); 395 addEvent(parent, childProperty, event); 396 } 397 return event; 398 } 399 400 public Iterator getChangeRootIterator() { 401 return new ParentIterator(); 402 } 403 404 405 public boolean hasChangedProperties(ASTNode parent) { 406 for (int i= 0; i < this.events.size(); i++) { 407 EventHolder holder= (EventHolder) this.events.get(i); 408 if (holder.parent == parent) { 409 if (holder.event.getChangeKind() != RewriteEvent.UNCHANGED) { 410 return true; 411 } 412 } 413 } 414 return false; 415 } 416 417 public PropertyLocation getPropertyLocation(Object value, int kind) { 418 for (int i= 0; i < this.events.size(); i++) { 419 EventHolder holder= (EventHolder) this.events.get(i); 420 RewriteEvent event= holder.event; 421 if (isNodeInEvent(event, value, kind)) { 422 return new PropertyLocation(holder.parent, holder.childProperty); 423 } 424 if (event.isListRewrite()) { 425 RewriteEvent[] children= event.getChildren(); 426 for (int k= 0; k < children.length; k++) { 427 if (isNodeInEvent(children[k], value, kind)) { 428 return new PropertyLocation(holder.parent, holder.childProperty); 429 } 430 } 431 } 432 } 433 if (value instanceof ASTNode) { 434 ASTNode node= (ASTNode) value; 435 return new PropertyLocation(node.getParent(), node.getLocationInParent()); 436 } 437 return null; 438 } 439 440 441 447 public RewriteEvent findEvent(Object value, int kind) { 448 for (int i= 0; i < this.events.size(); i++) { 449 RewriteEvent event= ((EventHolder) this.events.get(i)).event; 450 if (isNodeInEvent(event, value, kind)) { 451 return event; 452 } 453 if (event.isListRewrite()) { 454 RewriteEvent[] children= event.getChildren(); 455 for (int k= 0; k < children.length; k++) { 456 if (isNodeInEvent(children[k], value, kind)) { 457 return children[k]; 458 } 459 } 460 } 461 } 462 return null; 463 } 464 465 private boolean isNodeInEvent(RewriteEvent event, Object value, int kind) { 466 if (((kind & NEW) != 0) && event.getNewValue() == value) { 467 return true; 468 } 469 if (((kind & ORIGINAL) != 0) && event.getOriginalValue() == value) { 470 return true; 471 } 472 return false; 473 } 474 475 476 public Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor property) { 477 RewriteEvent event= getEvent(parent, property); 478 if (event != null) { 479 return event.getOriginalValue(); 480 } 481 return accessOriginalValue(parent, property); 482 } 483 484 public Object getNewValue(ASTNode parent, StructuralPropertyDescriptor property) { 485 RewriteEvent event= getEvent(parent, property); 486 if (event != null) { 487 return event.getNewValue(); 488 } 489 return accessOriginalValue(parent, property); 490 } 491 492 public int getChangeKind(ASTNode node) { 493 RewriteEvent event= findEvent(node, ORIGINAL); 494 if (event != null) { 495 return event.getChangeKind(); 496 } 497 return RewriteEvent.UNCHANGED; 498 } 499 500 504 private Object accessOriginalValue(ASTNode parent, StructuralPropertyDescriptor childProperty) { 505 if (this.nodePropertyMapper != null) { 506 return this.nodePropertyMapper.getOriginalValue(parent, childProperty); 507 } 508 509 return parent.getStructuralProperty(childProperty); 510 } 511 512 public TextEditGroup getEventEditGroup(RewriteEvent event) { 513 if (this.editGroups == null) { 514 return null; 515 } 516 return (TextEditGroup) this.editGroups.get(event); 517 } 518 519 public void setEventEditGroup(RewriteEvent event, TextEditGroup editGroup) { 520 if (this.editGroups == null) { 521 this.editGroups= new IdentityHashMap(5); 522 } 523 this.editGroups.put(event, editGroup); 524 } 525 526 527 public final TextEditGroup getTrackedNodeData(ASTNode node) { 528 if (this.trackedNodes != null) { 529 return (TextEditGroup) this.trackedNodes.get(node); 530 } 531 return null; 532 } 533 534 public void setTrackedNodeData(ASTNode node, TextEditGroup editGroup) { 535 if (this.trackedNodes == null) { 536 this.trackedNodes= new IdentityHashMap(); 537 } 538 this.trackedNodes.put(node, editGroup); 539 } 540 541 547 public final void markAsTracked(ASTNode node, TextEditGroup editGroup) { 548 if (getTrackedNodeData(node) != null) { 549 throw new IllegalArgumentException ("Node is already marked as tracked"); } 551 setTrackedNodeData(node, editGroup); 552 } 553 554 private final CopySourceInfo createCopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) { 555 CopySourceInfo copySource= new CopySourceInfo(location, node, isMove); 556 557 if (this.nodeCopySources == null) { 558 this.nodeCopySources= new ArrayList(); 559 } 560 this.nodeCopySources.add(copySource); 561 return copySource; 562 } 563 564 public final CopySourceInfo markAsCopySource(ASTNode parent, StructuralPropertyDescriptor property, ASTNode node, boolean isMove) { 565 return createCopySourceInfo(new PropertyLocation(parent, property), node, isMove); 566 } 567 568 public final boolean isRangeCopyPlaceholder(ASTNode node) { 569 return node.getProperty(INTERNAL_PLACEHOLDER_PROPERTY) != null; 570 } 571 572 public final CopySourceInfo createRangeCopy(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, boolean isMove, ASTNode internalPlaceholder, ASTNode replacingNode, TextEditGroup editGroup) { 573 CopySourceInfo copyInfo= createCopySourceInfo(null, internalPlaceholder, isMove); 574 internalPlaceholder.setProperty(INTERNAL_PLACEHOLDER_PROPERTY, internalPlaceholder); 575 576 NodeRangeInfo copyRangeInfo= new NodeRangeInfo(parent, childProperty, first, last, copyInfo, replacingNode, editGroup); 577 578 ListRewriteEvent listEvent= getListEvent(parent, childProperty, true); 579 580 int indexFirst= listEvent.getIndex(first, ListRewriteEvent.OLD); 581 if (indexFirst == -1) { 582 throw new IllegalArgumentException ("Start node is not a original child of the given list"); } 584 int indexLast= listEvent.getIndex(last, ListRewriteEvent.OLD); 585 if (indexLast == -1) { 586 throw new IllegalArgumentException ("End node is not a original child of the given list"); } 588 589 if (indexFirst > indexLast) { 590 throw new IllegalArgumentException ("Start node must be before end node"); } 592 593 if (this.nodeRangeInfos == null) { 594 this.nodeRangeInfos= new HashMap(); 595 } 596 PropertyLocation loc= new PropertyLocation(parent, childProperty); 597 List innerList= (List) this.nodeRangeInfos.get(loc); 598 if (innerList == null) { 599 innerList= new ArrayList(2); 600 this.nodeRangeInfos.put(loc, innerList); 601 } else { 602 assertNoOverlap(listEvent, indexFirst, indexLast, innerList); 603 } 604 innerList.add(copyRangeInfo); 605 606 607 return copyInfo; 608 } 609 610 public CopySourceInfo[] getNodeCopySources(ASTNode node) { 611 if (this.nodeCopySources == null) { 612 return null; 613 } 614 return internalGetCopySources(this.nodeCopySources, node); 615 } 616 617 618 public CopySourceInfo[] internalGetCopySources(List copySources, ASTNode node) { 619 ArrayList res= new ArrayList(3); 620 for (int i= 0; i < copySources.size(); i++) { 621 CopySourceInfo curr= (CopySourceInfo) copySources.get(i); 622 if (curr.getNode() == node) { 623 res.add(curr); 624 } 625 } 626 if (res.isEmpty()) { 627 return null; 628 } 629 630 CopySourceInfo[] arr= (CopySourceInfo[]) res.toArray(new CopySourceInfo[res.size()]); 631 Arrays.sort(arr); 632 return arr; 633 } 634 635 636 private void assertNoOverlap(ListRewriteEvent listEvent, int indexFirst, int indexLast, List innerList) { 637 for (Iterator iter= innerList.iterator(); iter.hasNext();) { 638 NodeRangeInfo curr= (NodeRangeInfo) iter.next(); 639 int currStart= listEvent.getIndex(curr.getStartNode(), ListRewriteEvent.BOTH); 640 int currEnd= listEvent.getIndex(curr.getEndNode(), ListRewriteEvent.BOTH); 641 if (currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst 642 || currStart > indexFirst && currStart <= currEnd && currEnd > indexLast) { 643 throw new IllegalArgumentException ("Range overlapps with an existing copy or move range"); } 645 } 646 } 647 648 public void prepareMovedNodes(TargetSourceRangeComputer sourceRangeComputer) { 649 if (this.nodeCopySources != null) { 650 prepareSingleNodeCopies(); 651 } 652 653 if (this.nodeRangeInfos != null) { 654 prepareNodeRangeCopies(sourceRangeComputer); 655 } 656 } 657 658 public void revertMovedNodes() { 659 if (this.nodeRangeInfos != null) { 660 removeMoveRangePlaceholders(); 661 } 662 } 663 664 private void removeMoveRangePlaceholders() { 665 for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) { 666 Map.Entry entry= (Map.Entry) iter.next(); 667 Set placeholders= new HashSet(); List rangeInfos= (List) entry.getValue(); for (int i= 0; i < rangeInfos.size(); i++) { 670 placeholders.add(((NodeRangeInfo) rangeInfos.get(i)).getInternalPlaceholder()); 671 } 672 673 PropertyLocation loc= (PropertyLocation) entry.getKey(); 674 675 RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren(); 676 List revertedChildren= new ArrayList(); 677 revertListWithRanges(children, placeholders, revertedChildren); 678 RewriteEvent[] revertedChildrenArr= (RewriteEvent[]) revertedChildren.toArray(new RewriteEvent[revertedChildren.size()]); 679 addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(revertedChildrenArr)); } 681 } 682 683 private void revertListWithRanges(RewriteEvent[] childEvents, Set placeholders, List revertedChildren) { 684 for (int i= 0; i < childEvents.length; i++) { 685 RewriteEvent event= childEvents[i]; 686 ASTNode node= (ASTNode) event.getOriginalValue(); 687 if (placeholders.contains(node)) { 688 RewriteEvent[] placeholderChildren= getListEvent(node, Block.STATEMENTS_PROPERTY, false).getChildren(); 689 revertListWithRanges(placeholderChildren, placeholders, revertedChildren); 690 } else { 691 revertedChildren.add(event); 692 } 693 } 694 } 695 696 private void prepareNodeRangeCopies(TargetSourceRangeComputer sourceRangeComputer) { 697 for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) { 698 Map.Entry entry= (Map.Entry) iter.next(); 699 List rangeInfos= (List) entry.getValue(); Collections.sort(rangeInfos); 702 PropertyLocation loc= (PropertyLocation) entry.getKey(); 703 RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren(); 704 705 RewriteEvent[] newChildren= processListWithRanges(rangeInfos, children, sourceRangeComputer); 706 addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(newChildren)); } 708 } 709 710 private RewriteEvent[] processListWithRanges(List rangeInfos, RewriteEvent[] childEvents, TargetSourceRangeComputer sourceRangeComputer) { 711 List newChildEvents= new ArrayList(childEvents.length); 712 NodeRangeInfo topInfo= null; 713 Stack newChildrenStack= new Stack(); 714 Stack topInfoStack= new Stack(); 715 716 Iterator rangeInfoIterator= rangeInfos.iterator(); 717 NodeRangeInfo nextInfo= (NodeRangeInfo) rangeInfoIterator.next(); 718 719 for (int k= 0; k < childEvents.length; k++) { 720 RewriteEvent event= childEvents[k]; 721 ASTNode node= (ASTNode) event.getOriginalValue(); 722 while (nextInfo != null && node == nextInfo.getStartNode()) { nextInfo.updatePlaceholderSourceRanges(sourceRangeComputer); 725 726 Block internalPlaceholder= nextInfo.getInternalPlaceholder(); 727 RewriteEvent newEvent; 728 if (nextInfo.isMove()) { 729 newEvent= new NodeRewriteEvent(internalPlaceholder, nextInfo.replacingNode); } else { 731 newEvent= new NodeRewriteEvent(internalPlaceholder, internalPlaceholder); } 733 newChildEvents.add(newEvent); 734 if (nextInfo.editGroup != null) { 735 setEventEditGroup(newEvent, nextInfo.editGroup); 736 } 737 738 newChildrenStack.push(newChildEvents); 739 topInfoStack.push(topInfo); 740 741 newChildEvents= new ArrayList(childEvents.length); 742 topInfo= nextInfo; 743 744 nextInfo= rangeInfoIterator.hasNext() ? (NodeRangeInfo) rangeInfoIterator.next() : null; 745 } 746 747 newChildEvents.add(event); 748 749 while (topInfo != null && node == topInfo.getEndNode()) { 750 RewriteEvent[] placeholderChildEvents= (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]); 751 Block internalPlaceholder= topInfo.getInternalPlaceholder(); 752 addEvent(internalPlaceholder, Block.STATEMENTS_PROPERTY, new ListRewriteEvent(placeholderChildEvents)); 753 754 newChildEvents= (List) newChildrenStack.pop(); 755 topInfo= (NodeRangeInfo) topInfoStack.pop(); 756 } 757 } 758 return (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]); 759 } 760 761 764 private void prepareSingleNodeCopies() { 765 for (int i= 0; i < this.nodeCopySources.size(); i++) { 766 CopySourceInfo curr= (CopySourceInfo) this.nodeCopySources.get(i); 767 if (curr.isMove && curr.location != null) { 768 doMarkMovedAsRemoved(curr, curr.location.getParent(), curr.location.getProperty()); 769 } 770 } 771 772 } 773 774 private void doMarkMovedAsRemoved(CopySourceInfo curr, ASTNode parent, StructuralPropertyDescriptor childProperty) { 775 if (childProperty.isChildListProperty()) { 776 ListRewriteEvent event= getListEvent(parent, childProperty, true); 777 int index= event.getIndex(curr.getNode(), ListRewriteEvent.OLD); 778 if (index != -1 && event.getChangeKind(index) == RewriteEvent.UNCHANGED) { 779 event.setNewValue(null, index); 780 } 781 } else { 782 NodeRewriteEvent event= getNodeEvent(parent, childProperty, true); 783 if (event.getChangeKind() == RewriteEvent.UNCHANGED) { 784 event.setNewValue(null); 785 } 786 } 787 } 788 789 public boolean isInsertBoundToPrevious(ASTNode node) { 790 if (this.insertBoundToPrevious != null) { 791 return this.insertBoundToPrevious.contains(node); 792 } 793 return false; 794 } 795 796 public void setInsertBoundToPrevious(ASTNode node) { 797 if (this.insertBoundToPrevious == null) { 798 this.insertBoundToPrevious= new HashSet(); 799 } 800 this.insertBoundToPrevious.add(node); 801 } 802 803 private void validateIsListProperty(StructuralPropertyDescriptor property) { 804 if (!property.isChildListProperty()) { 805 String message= property.getId() + " is not a list property"; throw new IllegalArgumentException (message); 807 } 808 } 809 810 private void validateHasChildProperty(ASTNode parent, StructuralPropertyDescriptor property) { 811 if (!parent.structuralPropertiesForType().contains(property)) { 812 String message= Signature.getSimpleName(parent.getClass().getName()) + " has no property " + property.getId(); throw new IllegalArgumentException (message); 814 } 815 } 816 817 private void validateIsNodeProperty(StructuralPropertyDescriptor property) { 818 if (property.isChildListProperty()) { 819 String message= property.getId() + " is not a node property"; throw new IllegalArgumentException (message); 821 } 822 } 823 824 public String toString() { 825 StringBuffer buf= new StringBuffer (); 826 for (int i= 0; i < this.events.size(); i++) { 827 buf.append(this.events.get(i).toString()).append('\n'); 828 } 829 return buf.toString(); 830 } 831 832 public static boolean isNewNode(ASTNode node) { 833 return (node.getFlags() & ASTNode.ORIGINAL) == 0; 834 } 835 836 837 } 838 | Popular Tags |