improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / SimpleDOMBuilder.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.HashMap;
14 import java.util.Map;
15
16 import net.sourceforge.phpdt.core.JavaCore;
17 import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit;
18 import net.sourceforge.phpdt.core.jdom.IDOMFactory;
19 import net.sourceforge.phpdt.internal.compiler.ISourceElementRequestor;
20 import net.sourceforge.phpdt.internal.compiler.SourceElementParser;
21 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
22 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
23 import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
24 import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
25
26 /**
27  * A DOM builder that uses the SourceElementParser
28  */
29 public class SimpleDOMBuilder extends AbstractDOMBuilder implements ISourceElementRequestor {
30
31   public void acceptImport(int declarationStart, int declarationEnd, char[] name, boolean onDemand) {
32     int[] sourceRange = { declarationStart, declarationEnd };
33     String importName = new String(name);
34     /** name is set to contain the '*' */
35     if (onDemand) {
36       importName += ".*"; //$NON-NLS-1$
37     }
38     fNode = new DOMImport(fDocument, sourceRange, importName, onDemand);
39     addChild(fNode);
40   }
41
42   public void acceptPackage(int declarationStart, int declarationEnd, char[] name) {
43     int[] sourceRange = new int[] { declarationStart, declarationEnd };
44     fNode = new DOMPackage(fDocument, sourceRange, CharArrayOps.charToString(name));
45     addChild(fNode);
46   }
47
48   /**
49    * @see IDOMFactory#createCompilationUnit(String, String)
50    */
51   public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name) {
52     return createCompilationUnit(sourceCode.toCharArray(), name.toCharArray());
53   }
54
55   /**
56    * @see IDOMFactory#createCompilationUnit(String, String)
57    */
58   public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
59     initializeBuild(compilationUnit.getContents(), true, true);
60     getParser(JavaCore.getOptions()).parseCompilationUnit(compilationUnit, false);
61     return super.createCompilationUnit(compilationUnit);
62   }
63
64   /**
65    * Creates a new DOMMethod and inizializes.
66    * 
67    * @param declarationStart -
68    *          a source position corresponding to the first character of this constructor declaration
69    * @param modifiers -
70    *          the modifiers for this constructor converted to a flag
71    * @param returnType -
72    *          the name of the return type
73    * @param name -
74    *          the name of this constructor
75    * @param nameStart -
76    *          a source position corresponding to the first character of the name
77    * @param nameEnd -
78    *          a source position corresponding to the last character of the name
79    * @param parameterTypes -
80    *          a list of parameter type names
81    * @param parameterNames -
82    *          a list of the names of the parameters
83    * @param exceptionTypes -
84    *          a list of the exception types
85    */
86   protected void enterAbstractMethod(int declarationStart, int modifiers, char[] returnType, char[] name, int nameStart,
87       int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes, boolean isConstructor) {
88
89     int[] sourceRange = { declarationStart, -1 }; // will be fixed up on exit
90     int[] nameRange = { nameStart, nameEnd };
91     fNode = new DOMMethod(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, modifiers, isConstructor,
92         CharArrayOps.charToString(returnType), CharArrayOps.charcharToString(parameterTypes), CharArrayOps
93             .charcharToString(parameterNames), CharArrayOps.charcharToString(exceptionTypes));
94     addChild(fNode);
95     fStack.push(fNode);
96   }
97
98   /**
99    */
100   public void enterClass(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[] superclass,
101       char[][] superinterfaces) {
102     enterType(declarationStart, modifiers, name, nameStart, nameEnd, superclass, superinterfaces, true);
103   }
104
105   /**
106    */
107   public void enterConstructor(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd,
108       char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) {
109     /* see 1FVIIQZ */
110     String nameString = new String(fDocument, nameStart, nameEnd - nameStart);
111     int openParenPosition = nameString.indexOf('(');
112     if (openParenPosition > -1)
113       nameEnd = nameStart + openParenPosition - 1;
114
115     enterAbstractMethod(declarationStart, modifiers, null, name, nameStart, nameEnd, parameterTypes, parameterNames,
116         exceptionTypes, true);
117   }
118
119   /**
120    */
121   public void enterField(int declarationStart, int modifiers, char[] type, char[] name, int nameStart, int nameEnd) {
122
123     int[] sourceRange = { declarationStart, -1 };
124     int[] nameRange = { nameStart, nameEnd };
125     boolean isSecondary = false;
126     if (fNode instanceof DOMField) {
127       isSecondary = declarationStart == fNode.fSourceRange[0];
128     }
129     fNode = new DOMField(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, modifiers, CharArrayOps
130         .charToString(type), isSecondary);
131     addChild(fNode);
132     fStack.push(fNode);
133   }
134
135   /**
136    *  
137    */
138   public void enterInitializer(int declarationSourceStart, int modifiers) {
139     int[] sourceRange = { declarationSourceStart, -1 };
140     fNode = new DOMInitializer(fDocument, sourceRange, modifiers);
141     addChild(fNode);
142     fStack.push(fNode);
143   }
144
145   /**
146    */
147   public void enterInterface(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] superinterfaces) {
148     enterType(declarationStart, modifiers, name, nameStart, nameEnd, null, superinterfaces, false);
149   }
150
151   /**
152    */
153   public void enterMethod(int declarationStart, int modifiers, char[] returnType, char[] name, int nameStart, int nameEnd,
154       char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) {
155     enterAbstractMethod(declarationStart, modifiers, returnType, name, nameStart, nameEnd, parameterTypes, parameterNames,
156         exceptionTypes, false);
157   }
158
159   /**
160    */
161   protected void enterType(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[] superclass,
162       char[][] superinterfaces, boolean isClass) {
163     if (fBuildingType) {
164       int[] sourceRange = { declarationStart, -1 }; // will be fixed in the exit
165       int[] nameRange = new int[] { nameStart, nameEnd };
166       fNode = new DOMType(fDocument, sourceRange, new String(name), nameRange, modifiers, CharArrayOps
167           .charcharToString(superinterfaces), isClass);
168       addChild(fNode);
169       fStack.push(fNode);
170     }
171   }
172
173   /**
174    * Finishes the configuration of the class DOM object which was created by a previous enterClass call.
175    * 
176    * @see ISourceElementRequestor#exitClass(int)
177    */
178   public void exitClass(int declarationEnd) {
179     exitType(declarationEnd);
180   }
181
182   /**
183    * Finishes the configuration of the method DOM object which was created by a previous enterConstructor call.
184    * 
185    * @see ISourceElementRequestor#exitConstructor(int)
186    */
187   public void exitConstructor(int declarationEnd) {
188     exitMember(declarationEnd);
189   }
190
191   /**
192    */
193   public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
194     exitMember(declarationEnd);
195   }
196
197   /**
198    */
199   public void exitInitializer(int declarationEnd) {
200     exitMember(declarationEnd);
201   }
202
203   /**
204    */
205   public void exitInterface(int declarationEnd) {
206     exitType(declarationEnd);
207   }
208
209   /**
210    * Finishes the configuration of the member.
211    * 
212    * @param declarationEnd -
213    *          a source position corresponding to the end of the method declaration. This can include whitespace and comments
214    *          following the closing bracket.
215    */
216   protected void exitMember(int declarationEnd) {
217     DOMMember m = (DOMMember) fStack.pop();
218     m.setSourceRangeEnd(declarationEnd);
219     fNode = m;
220   }
221
222   /**
223    */
224   public void exitMethod(int declarationEnd) {
225     exitMember(declarationEnd);
226   }
227
228   /**
229    * @see AbstractDOMBuilder#exitType
230    * 
231    * @param declarationEnd -
232    *          a source position corresponding to the end of the class declaration. This can include whitespace and comments
233    *          following the closing bracket.
234    */
235   protected void exitType(int declarationEnd) {
236     exitType(declarationEnd, declarationEnd);
237   }
238
239   /**
240    * Creates a new parser.
241    */
242   protected SourceElementParser getParser(Map settings) {
243     return new SourceElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings));
244   }
245 }