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 SimpleDOMBuilder.
26 public class AbstractDOMBuilder extends ReferenceInfoAdapter implements ILineStartFinder {
28 * Set to true when an error is encounterd while
31 protected boolean fAbort;
34 * True when a compilation unit is being constructed.
35 * False when any other type of document fragment is
38 protected boolean fBuildingCU = false;
41 * True when a compilation unit or type is being
42 * constructed. False when any other type of document
43 * fragment is being constructed.
45 protected boolean fBuildingType= false;
48 * The String on which the JDOM is being created.
50 protected char[] fDocument= null;
53 * The source positions of all of the line separators in the document.
55 protected int[] fLineStartPositions = new int[] { 0 };
58 * A stack of enclosing scopes used when constructing
59 * a compilation unit or type. The top of the stack
60 * is the document fragment that children are added to.
62 protected Stack fStack = null;
65 * The number of fields constructed in the current
66 * document. This is used when building a single
67 * field document fragment, since the DOMBuilder only
68 * accepts documents with one field declaration.
70 protected int fFieldCount;
73 * The current node being constructed.
75 protected DOMNode fNode;
77 * AbstractDOMBuilder constructor.
79 public AbstractDOMBuilder() {
83 * Accepts the line separator table and converts it into a line start table.
85 * <p>A line separator might corresponds to several characters in the source.
87 * @see IDocumentElementRequestor#acceptLineSeparatorPositions(int[])
89 public void acceptLineSeparatorPositions(int[] positions) {
90 if (positions != null) {
91 int length = positions.length;
93 fLineStartPositions = new int[length + 1];
94 fLineStartPositions[0] = 0;
95 int documentLength = fDocument.length;
96 for (int i = 0; i < length; i++) {
98 int positionPlusOne = positions[i] + 1;
99 if (positionPlusOne < documentLength) {
100 if (iPlusOne < length) {
102 fLineStartPositions[iPlusOne] = positionPlusOne;
104 // no more separators
105 if (fDocument[positionPlusOne] == '\n') {
106 fLineStartPositions[iPlusOne] = positionPlusOne + 1;
108 fLineStartPositions[iPlusOne] = positionPlusOne;
112 fLineStartPositions[iPlusOne] = positionPlusOne;
121 public void acceptProblem(IProblem problem) {} //TODO: (olivier) unused?
123 * Adds the given node to the current enclosing scope, building the JDOM
124 * tree. Nodes are only added to an enclosing scope when a compilation unit or type
125 * is being built (since those are the only nodes that have children).
127 * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
128 * the nodes in the newly created JDOM are not fragmented.
130 protected void addChild(IDOMNode child) {
131 if (fStack.size() > 0) {
132 DOMNode parent = (DOMNode) fStack.peek();
133 if (fBuildingCU || fBuildingType) {
134 parent.basicAddChild(child);
139 * @see IDOMFactory#createCompilationUnit(String, String)
141 public IDOMCompilationUnit createCompilationUnit(char[] contents, char[] name) {
142 return createCompilationUnit(new CompilationUnit(contents, name));
145 * @see IDOMFactory#createCompilationUnit(String, String)
147 public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
151 fNode.normalize(this);
152 return (IDOMCompilationUnit)fNode;
155 * @see IDocumentElementRequestor#enterClass(int, int[], int, int, int, char[], int, int, char[], int, int, char[][], int[], int[], int)
157 public void enterCompilationUnit() {
159 IDOMCompilationUnit cu= new DOMCompilationUnit(fDocument, new int[] {0, fDocument.length - 1});
164 * Finishes the configuration of the compilation unit DOM object which
165 * was created by a previous enterCompilationUnit call.
167 * @see IDocumentElementRequestor#exitCompilationUnit(int)
169 public void exitCompilationUnit(int declarationEnd) {
170 DOMCompilationUnit cu = (DOMCompilationUnit) fStack.pop();
171 cu.setSourceRangeEnd(declarationEnd);
175 * Finishes the configuration of the class and interface DOM objects.
177 * @param bodyEnd - a source position corresponding to the closing bracket of the class
178 * @param declarationEnd - a source position corresponding to the end of the class
179 * declaration. This can include whitespace and comments following the closing bracket.
181 protected void exitType(int bodyEnd, int declarationEnd) {
182 DOMType type = (DOMType)fStack.pop();
183 type.setSourceRangeEnd(declarationEnd);
184 type.setCloseBodyRangeStart(bodyEnd);
185 type.setCloseBodyRangeEnd(bodyEnd);
189 * @see ILineStartFinder#getLineStart(int)
191 public int getLineStart(int position) {
192 int lineSeparatorCount = fLineStartPositions.length;
193 // reverse traversal intentional.
194 for(int i = lineSeparatorCount - 1; i >= 0; i--) {
195 if (fLineStartPositions[i] <= position)
196 return fLineStartPositions[i];
201 * Initializes the builder to create a document fragment.
203 * @param sourceCode - the document containing the source code to be analyzed
204 * @param buildingCompilationUnit - true if a the document is being analyzed to
205 * create a compilation unit, otherwise false
206 * @param buildingType - true if the document is being analyzed to create a
207 * type or compilation unit
209 protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType) {
210 fBuildingCU = buildingCompilationUnit;
211 fBuildingType = buildingType;
212 fStack = new Stack();
213 fDocument = sourceCode;