X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java new file mode 100644 index 0000000..40fe1be --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/AbstractDOMBuilder.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.core.jdom; + +import java.util.Stack; + +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit; +import net.sourceforge.phpdt.core.jdom.IDOMNode; +import net.sourceforge.phpdt.internal.core.util.ReferenceInfoAdapter; + +/** + * An abstract DOM builder that contains shared functionality of DOMBuilder and SimpleDOMBuilder. + */ +public class AbstractDOMBuilder extends ReferenceInfoAdapter implements ILineStartFinder { + /** + * Set to true when an error is encounterd while + * fuzzy parsing + */ + protected boolean fAbort; + + /** + * True when a compilation unit is being constructed. + * False when any other type of document fragment is + * being constructed. + */ + protected boolean fBuildingCU = false; + + /** + * True when a compilation unit or type is being + * constructed. False when any other type of document + * fragment is being constructed. + */ + protected boolean fBuildingType= false; + + /** + * The String on which the JDOM is being created. + */ + protected char[] fDocument= null; + + /** + * The source positions of all of the line separators in the document. + */ + protected int[] fLineStartPositions = new int[] { 0 }; + + /** + * A stack of enclosing scopes used when constructing + * a compilation unit or type. The top of the stack + * is the document fragment that children are added to. + */ + protected Stack fStack = null; + + /** + * The number of fields constructed in the current + * document. This is used when building a single + * field document fragment, since the DOMBuilder only + * accepts documents with one field declaration. + */ + protected int fFieldCount; + + /** + * The current node being constructed. + */ + protected DOMNode fNode; +/** + * AbstractDOMBuilder constructor. + */ +public AbstractDOMBuilder() { + super(); +} +/** + * Accepts the line separator table and converts it into a line start table. + * + *

A line separator might corresponds to several characters in the source. + * + * @see IDocumentElementRequestor#acceptLineSeparatorPositions(int[]) + */ +public void acceptLineSeparatorPositions(int[] positions) { + if (positions != null) { + int length = positions.length; + if (length > 0) { + fLineStartPositions = new int[length + 1]; + fLineStartPositions[0] = 0; + int documentLength = fDocument.length; + for (int i = 0; i < length; i++) { + int iPlusOne = i + 1; + int positionPlusOne = positions[i] + 1; + if (positionPlusOne < documentLength) { + if (iPlusOne < length) { + // more separators + fLineStartPositions[iPlusOne] = positionPlusOne; + } else { + // no more separators + if (fDocument[positionPlusOne] == '\n') { + fLineStartPositions[iPlusOne] = positionPlusOne + 1; + } else { + fLineStartPositions[iPlusOne] = positionPlusOne; + } + } + } else { + fLineStartPositions[iPlusOne] = positionPlusOne; + } + } + } + } +} +/** + * Does nothing. + */ +public void acceptProblem(IProblem problem) {} //TODO: (olivier) unused? +/** + * Adds the given node to the current enclosing scope, building the JDOM + * tree. Nodes are only added to an enclosing scope when a compilation unit or type + * is being built (since those are the only nodes that have children). + * + *

NOTE: nodes are added to the JDOM via the method #basicAddChild such that + * the nodes in the newly created JDOM are not fragmented. + */ +protected void addChild(IDOMNode child) { + if (fStack.size() > 0) { + DOMNode parent = (DOMNode) fStack.peek(); + if (fBuildingCU || fBuildingType) { + parent.basicAddChild(child); + } + } +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(char[] contents, char[] name) { + return createCompilationUnit(new CompilationUnit(contents, name)); +} +/** + * @see IDOMFactory#createCompilationUnit(String, String) + */ +public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) { + if (fAbort) { + return null; + } + fNode.normalize(this); + return (IDOMCompilationUnit)fNode; +} +/** + * @see IDocumentElementRequestor#enterClass(int, int[], int, int, int, char[], int, int, char[], int, int, char[][], int[], int[], int) + */ +public void enterCompilationUnit() { + if (fBuildingCU) { + IDOMCompilationUnit cu= new DOMCompilationUnit(fDocument, new int[] {0, fDocument.length - 1}); + fStack.push(cu); + } +} +/** + * Finishes the configuration of the compilation unit DOM object which + * was created by a previous enterCompilationUnit call. + * + * @see IDocumentElementRequestor#exitCompilationUnit(int) + */ +public void exitCompilationUnit(int declarationEnd) { + DOMCompilationUnit cu = (DOMCompilationUnit) fStack.pop(); + cu.setSourceRangeEnd(declarationEnd); + fNode = cu; +} +/** + * Finishes the configuration of the class and interface DOM objects. + * + * @param bodyEnd - a source position corresponding to the closing bracket of the class + * @param declarationEnd - a source position corresponding to the end of the class + * declaration. This can include whitespace and comments following the closing bracket. + */ +protected void exitType(int bodyEnd, int declarationEnd) { + DOMType type = (DOMType)fStack.pop(); + type.setSourceRangeEnd(declarationEnd); + type.setCloseBodyRangeStart(bodyEnd); + type.setCloseBodyRangeEnd(bodyEnd); + fNode = type; +} +/** + * @see ILineStartFinder#getLineStart(int) + */ +public int getLineStart(int position) { + int lineSeparatorCount = fLineStartPositions.length; + // reverse traversal intentional. + for(int i = lineSeparatorCount - 1; i >= 0; i--) { + if (fLineStartPositions[i] <= position) + return fLineStartPositions[i]; + } + return 0; +} +/** + * Initializes the builder to create a document fragment. + * + * @param sourceCode - the document containing the source code to be analyzed + * @param buildingCompilationUnit - true if a the document is being analyzed to + * create a compilation unit, otherwise false + * @param buildingType - true if the document is being analyzed to create a + * type or compilation unit + */ +protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType) { + fBuildingCU = buildingCompilationUnit; + fBuildingType = buildingType; + fStack = new Stack(); + fDocument = sourceCode; + fFieldCount = 0; + fAbort = false; +} +}