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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.jdom;
13 import java.util.Stack;
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;
24 * An abstract DOM builder that contains shared functionality of DOMBuilder and
27 public class AbstractDOMBuilder extends ReferenceInfoAdapter implements
30 * Set to true when an error is encounterd while fuzzy parsing
32 protected boolean fAbort;
35 * True when a compilation unit is being constructed. False when any other
36 * type of document fragment is being constructed.
38 protected boolean fBuildingCU = false;
41 * True when a compilation unit or type is being constructed. False when any
42 * other type of document fragment is being constructed.
44 protected boolean fBuildingType = false;
47 * The String on which the JDOM is being created.
49 protected char[] fDocument = null;
52 * The source positions of all of the line separators in the document.
54 protected int[] fLineStartPositions = new int[] { 0 };
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
61 protected Stack fStack = null;
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.
68 protected int fFieldCount;
71 * The current node being constructed.
73 protected DOMNode fNode;
76 * AbstractDOMBuilder constructor.
78 public AbstractDOMBuilder() {
83 * Accepts the line separator table and converts it into a line start table.
86 * A line separator might corresponds to several characters in the source.
88 * @see IDocumentElementRequestor#acceptLineSeparatorPositions(int[])
90 public void acceptLineSeparatorPositions(int[] positions) {
91 if (positions != null) {
92 int length = positions.length;
94 fLineStartPositions = new int[length + 1];
95 fLineStartPositions[0] = 0;
96 int documentLength = fDocument.length;
97 for (int i = 0; i < length; i++) {
99 int positionPlusOne = positions[i] + 1;
100 if (positionPlusOne < documentLength) {
101 if (iPlusOne < length) {
103 fLineStartPositions[iPlusOne] = positionPlusOne;
105 // no more separators
106 if (fDocument[positionPlusOne] == '\n') {
107 fLineStartPositions[iPlusOne] = positionPlusOne + 1;
109 fLineStartPositions[iPlusOne] = positionPlusOne;
113 fLineStartPositions[iPlusOne] = positionPlusOne;
123 public void acceptProblem(IProblem problem) {
124 } // TODO: (olivier) unused?
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
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.
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);
146 * @see IDOMFactory#createCompilationUnit(String, String)
148 public IDOMCompilationUnit createCompilationUnit(char[] contents,
150 return createCompilationUnit(new CompilationUnit(contents, name));
154 * @see IDOMFactory#createCompilationUnit(String, String)
156 public IDOMCompilationUnit createCompilationUnit(
157 ICompilationUnit compilationUnit) {
161 fNode.normalize(this);
162 return (IDOMCompilationUnit) fNode;
166 * @see IDocumentElementRequestor#enterClass(int, int[], int, int, int,
167 * char[], int, int, char[], int, int, char[][], int[], int[], int)
169 public void enterCompilationUnit() {
171 IDOMCompilationUnit cu = new DOMCompilationUnit(fDocument,
172 new int[] { 0, fDocument.length - 1 });
178 * Finishes the configuration of the compilation unit DOM object which was
179 * created by a previous enterCompilationUnit call.
181 * @see IDocumentElementRequestor#exitCompilationUnit(int)
183 public void exitCompilationUnit(int declarationEnd) {
184 DOMCompilationUnit cu = (DOMCompilationUnit) fStack.pop();
185 cu.setSourceRangeEnd(declarationEnd);
190 * Finishes the configuration of the class and interface DOM objects.
193 * a source position corresponding to the closing bracket of the
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.
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);
209 * @see ILineStartFinder#getLineStart(int)
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];
222 * Initializes the builder to create a document fragment.
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
233 protected void initializeBuild(char[] sourceCode,
234 boolean buildingCompilationUnit, boolean buildingType) {
235 fBuildingCU = buildingCompilationUnit;
236 fBuildingType = buildingType;
237 fStack = new Stack();
238 fDocument = sourceCode;