removed unused private methods.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / InternalASTRewrite.java
1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.core.dom;
12
13 import java.util.Hashtable;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.eclipse.text.edits.MultiTextEdit;
18 import org.eclipse.text.edits.TextEdit;
19
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.TextUtilities;
22
23 import net.sourceforge.phpdt.core.dom.SimplePropertyDescriptor;
24 import net.sourceforge.phpdt.core.dom.StructuralPropertyDescriptor;
25 import net.sourceforge.phpdt.core.dom.rewrite.TargetSourceRangeComputer;
26 import net.sourceforge.phpdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
27 import net.sourceforge.phpdt.internal.core.dom.rewrite.LineInformation;
28 import net.sourceforge.phpdt.internal.core.dom.rewrite.ListRewriteEvent;
29 import net.sourceforge.phpdt.internal.core.dom.rewrite.NodeInfoStore;
30 import net.sourceforge.phpdt.internal.core.dom.rewrite.NodeRewriteEvent;
31 import net.sourceforge.phpdt.internal.core.dom.rewrite.RewriteEventStore;
32 import net.sourceforge.phpdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
33 import net.sourceforge.phpdt.internal.core.dom.rewrite.RewriteEventStore.PropertyLocation;
34
35 /**
36  * Internal class: not intended to be used by client.
37  * When AST modifications recording is enabled, all changes are recorded by this class.
38  */
39 class InternalASTRewrite extends NodeEventHandler {
40         
41         /** root node for the rewrite: Only nodes under this root are accepted */
42         private CompilationUnit root;
43
44         protected final RewriteEventStore eventStore;
45         protected final NodeInfoStore nodeStore;
46         protected final Hashtable clonedNodes;
47         
48         int cloneDepth = 0;
49         
50         /**
51          * Constructor
52          * @param root root node of the recorded ast.
53          */
54         public InternalASTRewrite(CompilationUnit root) {
55                 this.root = root;
56                 this.eventStore = new RewriteEventStore();
57                 this.nodeStore = new NodeInfoStore(root.getAST());
58                 this.clonedNodes = new Hashtable();
59         }
60
61         /**
62          * Performs the rewrite: The rewrite events are translated to the corresponding in text changes.
63          * @param document Document which describes the code of the AST that is passed in in the
64          * constructor. This document is accessed read-only.
65          * @param options options
66          * @throws IllegalArgumentException if the rewrite fails
67          * @return Returns the edit describing the text changes.
68          */
69         public TextEdit rewriteAST(IDocument document, Map options) {
70                 TextEdit result = new MultiTextEdit();
71                 
72                 final CompilationUnit rootNode = getRootNode();
73                 if (rootNode != null) {
74                         TargetSourceRangeComputer xsrComputer = new TargetSourceRangeComputer() {
75                                 /** 
76                                  * This implementation of
77                                  * {@link TargetSourceRangeComputer#computeSourceRange(ASTNode)}
78                                  * is specialized to work in the case of internal AST rewriting, where the
79                                  * original AST has been modified from its original form. This means that
80                                  * one cannot trust that the root of the given node is the compilation unit.
81                                  */
82                                 public SourceRange computeSourceRange(ASTNode node) {
83                                         int extendedStartPosition = rootNode.getExtendedStartPosition(node);
84                                         int extendedLength = rootNode.getExtendedLength(node);
85                                         return new SourceRange(extendedStartPosition, extendedLength);
86                                 }
87                         };
88                         char[] content= document.get().toCharArray();
89                         LineInformation lineInfo= LineInformation.create(document);
90                         String lineDelim= TextUtilities.getDefaultLineDelimiter(document);
91                         List comments= rootNode.getCommentList();
92                         
93                         ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(content, lineInfo, lineDelim, result, this.eventStore, this.nodeStore, comments, options, xsrComputer);
94                         rootNode.accept(visitor);
95                 }
96                 return result;
97         }
98         
99         private  void markAsMoveOrCopyTarget(ASTNode node, ASTNode newChild) {
100                 ASTNode source = (ASTNode)this.clonedNodes.get(newChild);
101                 if(source != null) {
102                         if(this.cloneDepth == 0) {
103                                 PropertyLocation propertyLocation = this.eventStore.getPropertyLocation(source, RewriteEventStore.ORIGINAL);
104                                 CopySourceInfo sourceInfo =
105                                         this.eventStore.markAsCopySource(
106                                                 propertyLocation.getParent(),
107                                                 propertyLocation.getProperty(),
108                                                 source,
109                                                 false);
110                                 this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
111                         }
112                 } else if((newChild.getFlags() & ASTNode.ORIGINAL) != 0) {
113                         PropertyLocation propertyLocation = this.eventStore.getPropertyLocation(newChild, RewriteEventStore.ORIGINAL);
114                         CopySourceInfo sourceInfo =
115                                 this.eventStore.markAsCopySource(
116                                         propertyLocation.getParent(),
117                                         propertyLocation.getProperty(),
118                                         newChild,
119                                         true);
120                         this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
121                 }
122         }
123
124         private CompilationUnit getRootNode() {
125                 return this.root;
126         }
127
128         public String toString() {
129                 StringBuffer buf = new StringBuffer();
130                 buf.append("Events:\n"); //$NON-NLS-1$
131                 buf.append(this.eventStore.toString());
132                 return buf.toString();
133         }
134         
135         void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
136                 // force event creation
137                 this.getNodeEvent(node, property);
138         }
139         
140         void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
141                 NodeRewriteEvent event = this.getNodeEvent(node, property);
142                 event.setNewValue(node.getStructuralProperty(property));
143         }
144         
145         void preAddChildEvent(ASTNode node, ASTNode child,      StructuralPropertyDescriptor property) {
146                 if(property.isChildProperty()) {
147                         NodeRewriteEvent event = this.getNodeEvent(node, property);
148                         event.setNewValue(child);
149                         if(child != null) {
150                                 this.markAsMoveOrCopyTarget(node, child);
151                         }
152                 } else if(property.isChildListProperty()) {
153                         // force event creation
154                         this.getListEvent(node, property);
155                 }
156         }
157         
158         void postAddChildEvent(ASTNode node, ASTNode child,     StructuralPropertyDescriptor property) {
159                 if(property.isChildListProperty()) {
160
161                         ListRewriteEvent event = this.getListEvent(node, property);
162                         List list = (List)node.getStructuralProperty(property);
163                         int i = list.indexOf(child);
164                         int s = list.size();
165                         int index;
166                         if(i + 1 < s) {
167                                 ASTNode nextNode = (ASTNode)list.get(i + 1);
168                                 index = event.getIndex(nextNode, ListRewriteEvent.NEW);
169                         } else {
170                                 index = -1;
171                         }
172                         event.insert(child, index);
173                         if(child != null) {
174                                 this.markAsMoveOrCopyTarget(node, child);
175                         }
176                 }
177         }
178         
179         void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
180                 if(property.isChildProperty()) {
181                         NodeRewriteEvent event = getNodeEvent(node, property);
182                         event.setNewValue(null);
183                 } else if(property.isChildListProperty()) {
184                         ListRewriteEvent event = this.getListEvent(node, property);
185                         int i = event.getIndex(child, ListRewriteEvent.NEW);
186                         NodeRewriteEvent nodeEvent = (NodeRewriteEvent)event.getChildren()[i];
187                         if(nodeEvent.getOriginalValue() == null) {
188                                 event.revertChange(nodeEvent);
189                         } else {
190                                 nodeEvent.setNewValue(null);
191                         }
192                 }
193         }
194         
195         void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
196                 if(property.isChildProperty()) {
197                         NodeRewriteEvent event = getNodeEvent(node, property);
198                         event.setNewValue(newChild);
199                         if(newChild != null) {
200                                 this.markAsMoveOrCopyTarget(node, newChild);
201                         }
202                 } else if(property.isChildListProperty()) {
203                         ListRewriteEvent event = this.getListEvent(node, property);
204                         int i = event.getIndex(child, ListRewriteEvent.NEW);
205                         NodeRewriteEvent nodeEvent = (NodeRewriteEvent)event.getChildren()[i];
206                         nodeEvent.setNewValue(newChild);
207                         if(newChild != null) {
208                                 this.markAsMoveOrCopyTarget(node, newChild);
209                         }
210                 }
211         }
212         
213         
214         void preCloneNodeEvent(ASTNode node) {
215                 this.cloneDepth++;
216         }
217         
218         
219         void postCloneNodeEvent(ASTNode node, ASTNode clone) {
220                 if(node.ast == root.ast && clone.ast == root.ast) {
221                         if((node.getFlags() & ASTNode.ORIGINAL) != 0) {
222                                 this.clonedNodes.put(clone, node);
223                         } else {
224                                 // node can be a cloned node
225                                 Object original = this.clonedNodes.get(node);
226                                 if(original != null) {
227                                         this.clonedNodes.put(clone, original);
228                                 }
229                         }
230                 }
231                 this.cloneDepth--;
232         }
233         
234         private NodeRewriteEvent getNodeEvent(ASTNode node, StructuralPropertyDescriptor property) {
235                 return this.eventStore.getNodeEvent(node, property, true);
236         }
237         
238         private ListRewriteEvent getListEvent(ASTNode node, StructuralPropertyDescriptor property) {
239                 return this.eventStore.getListEvent(node, property, true);
240         }
241 }