A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / AbstractDOMBuilder.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.jdom;
12
13 import java.util.Stack;
14
15 import net.sourceforge.phpdt.core.compiler.IProblem;
16 import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit;
17 import net.sourceforge.phpdt.core.jdom.IDOMFactory;
18 import net.sourceforge.phpdt.core.jdom.IDOMNode;
19 import net.sourceforge.phpdt.internal.compiler.IDocumentElementRequestor;
20 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
21 import net.sourceforge.phpdt.internal.core.util.ReferenceInfoAdapter;
22
23 /**
24  * An abstract DOM builder that contains shared functionality of DOMBuilder and
25  * SimpleDOMBuilder.
26  */
27 public class AbstractDOMBuilder extends ReferenceInfoAdapter implements
28                 ILineStartFinder {
29         /**
30          * Set to true when an error is encounterd while fuzzy parsing
31          */
32         protected boolean fAbort;
33
34         /**
35          * True when a compilation unit is being constructed. False when any other
36          * type of document fragment is being constructed.
37          */
38         protected boolean fBuildingCU = false;
39
40         /**
41          * True when a compilation unit or type is being constructed. False when any
42          * other type of document fragment is being constructed.
43          */
44         protected boolean fBuildingType = false;
45
46         /**
47          * The String on which the JDOM is being created.
48          */
49         protected char[] fDocument = null;
50
51         /**
52          * The source positions of all of the line separators in the document.
53          */
54         protected int[] fLineStartPositions = new int[] { 0 };
55
56         /**
57          * A stack of enclosing scopes used when constructing a compilation unit or
58          * type. The top of the stack is the document fragment that children are
59          * added to.
60          */
61         protected Stack fStack = null;
62
63         /**
64          * The number of fields constructed in the current document. This is used
65          * when building a single field document fragment, since the DOMBuilder only
66          * accepts documents with one field declaration.
67          */
68         protected int fFieldCount;
69
70         /**
71          * The current node being constructed.
72          */
73         protected DOMNode fNode;
74
75         /**
76          * AbstractDOMBuilder constructor.
77          */
78         public AbstractDOMBuilder() {
79                 super();
80         }
81
82         /**
83          * Accepts the line separator table and converts it into a line start table.
84          * 
85          * <p>
86          * A line separator might corresponds to several characters in the source.
87          * 
88          * @see IDocumentElementRequestor#acceptLineSeparatorPositions(int[])
89          */
90         public void acceptLineSeparatorPositions(int[] positions) {
91                 if (positions != null) {
92                         int length = positions.length;
93                         if (length > 0) {
94                                 fLineStartPositions = new int[length + 1];
95                                 fLineStartPositions[0] = 0;
96                                 int documentLength = fDocument.length;
97                                 for (int i = 0; i < length; i++) {
98                                         int iPlusOne = i + 1;
99                                         int positionPlusOne = positions[i] + 1;
100                                         if (positionPlusOne < documentLength) {
101                                                 if (iPlusOne < length) {
102                                                         // more separators
103                                                         fLineStartPositions[iPlusOne] = positionPlusOne;
104                                                 } else {
105                                                         // no more separators
106                                                         if (fDocument[positionPlusOne] == '\n') {
107                                                                 fLineStartPositions[iPlusOne] = positionPlusOne + 1;
108                                                         } else {
109                                                                 fLineStartPositions[iPlusOne] = positionPlusOne;
110                                                         }
111                                                 }
112                                         } else {
113                                                 fLineStartPositions[iPlusOne] = positionPlusOne;
114                                         }
115                                 }
116                         }
117                 }
118         }
119
120         /**
121          * Does nothing.
122          */
123         public void acceptProblem(IProblem problem) {
124         } // TODO: (olivier) unused?
125
126         /**
127          * Adds the given node to the current enclosing scope, building the JDOM
128          * tree. Nodes are only added to an enclosing scope when a compilation unit
129          * or type is being built (since those are the only nodes that have
130          * children).
131          * 
132          * <p>
133          * NOTE: nodes are added to the JDOM via the method #basicAddChild such that
134          * the nodes in the newly created JDOM are not fragmented.
135          */
136         protected void addChild(IDOMNode child) {
137                 if (fStack.size() > 0) {
138                         DOMNode parent = (DOMNode) fStack.peek();
139                         if (fBuildingCU || fBuildingType) {
140                                 parent.basicAddChild(child);
141                         }
142                 }
143         }
144
145         /**
146          * @see IDOMFactory#createCompilationUnit(String, String)
147          */
148         public IDOMCompilationUnit createCompilationUnit(char[] contents,
149                         char[] name) {
150                 return createCompilationUnit(new CompilationUnit(contents, name));
151         }
152
153         /**
154          * @see IDOMFactory#createCompilationUnit(String, String)
155          */
156         public IDOMCompilationUnit createCompilationUnit(
157                         ICompilationUnit compilationUnit) {
158                 if (fAbort) {
159                         return null;
160                 }
161                 fNode.normalize(this);
162                 return (IDOMCompilationUnit) fNode;
163         }
164
165         /**
166          * @see IDocumentElementRequestor#enterClass(int, int[], int, int, int,
167          *      char[], int, int, char[], int, int, char[][], int[], int[], int)
168          */
169         public void enterCompilationUnit() {
170                 if (fBuildingCU) {
171                         IDOMCompilationUnit cu = new DOMCompilationUnit(fDocument,
172                                         new int[] { 0, fDocument.length - 1 });
173                         fStack.push(cu);
174                 }
175         }
176
177         /**
178          * Finishes the configuration of the compilation unit DOM object which was
179          * created by a previous enterCompilationUnit call.
180          * 
181          * @see IDocumentElementRequestor#exitCompilationUnit(int)
182          */
183         public void exitCompilationUnit(int declarationEnd) {
184                 DOMCompilationUnit cu = (DOMCompilationUnit) fStack.pop();
185                 cu.setSourceRangeEnd(declarationEnd);
186                 fNode = cu;
187         }
188
189         /**
190          * Finishes the configuration of the class and interface DOM objects.
191          * 
192          * @param bodyEnd -
193          *            a source position corresponding to the closing bracket of the
194          *            class
195          * @param declarationEnd -
196          *            a source position corresponding to the end of the class
197          *            declaration. This can include whitespace and comments
198          *            following the closing bracket.
199          */
200         protected void exitType(int bodyEnd, int declarationEnd) {
201                 DOMType type = (DOMType) fStack.pop();
202                 type.setSourceRangeEnd(declarationEnd);
203                 type.setCloseBodyRangeStart(bodyEnd);
204                 type.setCloseBodyRangeEnd(bodyEnd);
205                 fNode = type;
206         }
207
208         /**
209          * @see ILineStartFinder#getLineStart(int)
210          */
211         public int getLineStart(int position) {
212                 int lineSeparatorCount = fLineStartPositions.length;
213                 // reverse traversal intentional.
214                 for (int i = lineSeparatorCount - 1; i >= 0; i--) {
215                         if (fLineStartPositions[i] <= position)
216                                 return fLineStartPositions[i];
217                 }
218                 return 0;
219         }
220
221         /**
222          * Initializes the builder to create a document fragment.
223          * 
224          * @param sourceCode -
225          *            the document containing the source code to be analyzed
226          * @param buildingCompilationUnit -
227          *            true if a the document is being analyzed to create a
228          *            compilation unit, otherwise false
229          * @param buildingType -
230          *            true if the document is being analyzed to create a type or
231          *            compilation unit
232          */
233         protected void initializeBuild(char[] sourceCode,
234                         boolean buildingCompilationUnit, boolean buildingType) {
235                 fBuildingCU = buildingCompilationUnit;
236                 fBuildingType = buildingType;
237                 fStack = new Stack();
238                 fDocument = sourceCode;
239                 fFieldCount = 0;
240                 fAbort = false;
241         }
242 }