1 package net.sourceforge.phpdt.internal.compiler.parser;
4 import net.sourceforge.phpdt.core.IJavaModelMarker;
5 import net.sourceforge.phpdt.core.compiler.IProblem;
6 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
7 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
8 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
9 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
10 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
11 import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
12 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
13 import net.sourceforge.phpeclipse.internal.compiler.ast.Initializer;
14 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
15 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
17 import org.eclipse.core.resources.IMarker;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.runtime.CoreException;
25 public class UnitParser extends Parser {
27 public UnitParser(ProblemReporter problemReporter) { //, boolean optimizeStringLiterals, boolean assertMode) {
28 super(problemReporter);
29 nestedMethod = new int[30];
31 // this.optimizeStringLiterals = optimizeStringLiterals;
32 // this.assertMode = assertMode;
33 // this.initializeScanner();
34 astLengthStack = new int[50];
35 // expressionLengthStack = new int[30];
36 // intStack = new int[50];
37 // identifierStack = new char[30][];
38 // identifierLengthStack = new int[30];
39 // nestedMethod = new int[30];
40 // realBlockStack = new int[30];
41 // identifierPositionStack = new long[30];
42 // variablesCounter = new int[30];
45 public void goForConstructorBody() {
46 //tells the scanner to go for compilation unit parsing
48 firstToken = TokenNameEQUAL_EQUAL;
49 scanner.recordLineSeparator = false;
51 public void goForExpression() {
52 //tells the scanner to go for an expression parsing
54 firstToken = TokenNameREMAINDER;
55 scanner.recordLineSeparator = false;
57 public void goForCompilationUnit() {
58 //tells the scanner to go for compilation unit parsing
60 firstToken = TokenNamePLUS_PLUS;
62 scanner.foundTaskCount = 0;
63 scanner.recordLineSeparator = true;
64 // scanner.currentLine= null;
66 public void goForInitializer() {
67 //tells the scanner to go for initializer parsing
69 firstToken = TokenNameRIGHT_SHIFT;
70 scanner.recordLineSeparator = false;
72 public void goForMethodBody() {
73 //tells the scanner to go for method body parsing
75 firstToken = TokenNameMINUS_MINUS;
76 scanner.recordLineSeparator = false;
78 public void initialize(boolean phpMode) {
79 super.initialize(phpMode);
80 //positionning the parser for a new compilation unit
81 //avoiding stack reallocation and all that....
84 // expressionPtr = -1;
85 // expressionLengthPtr = -1;
86 // identifierPtr = -1;
87 // identifierLengthPtr = -1;
89 // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
90 // variablesCounter[nestedType] = 0;
93 // endStatementPosition = 0;
95 //remove objects from stack too, while the same parser/compiler couple is
96 //re-used between two compilations ....
98 // int astLength = astStack.length;
99 // if (noAstNodes.length < astLength){
100 // noAstNodes = new ASTNode[astLength];
101 // //System.out.println("Resized AST stacks : "+ astLength);
104 // System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
106 // int expressionLength = expressionStack.length;
107 // if (noExpressions.length < expressionLength){
108 // noExpressions = new Expression[expressionLength];
109 // //System.out.println("Resized EXPR stacks : "+ expressionLength);
111 // System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
113 // reset scanner state
114 scanner.commentPtr = -1;
115 scanner.foundTaskCount = 0;
116 scanner.eofPosition = Integer.MAX_VALUE;
121 // lastCheckPoint = -1;
122 // currentElement = null;
123 // restartRecovery = false;
124 // hasReportedError = false;
125 // recoveredStaticInitializerStart = 0;
126 // lastIgnoredToken = -1;
127 // lastErrorEndPosition = -1;
133 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
134 // parses a compilation unit and manages error handling (even bugs....)
136 CompilationUnitDeclaration unit;
138 /* automaton initialization */
140 goForCompilationUnit();
142 /* scanner initialization */
143 scanner.setSource(sourceUnit, sourceUnit.getContents());
147 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
148 // TODO TypeDeclaration test
149 // TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
150 // typeDecl.sourceStart = 0;
151 // typeDecl.sourceEnd = 10;
152 // typeDecl.name = new char[]{'t', 'e','s','t'};
153 // this.compilationUnit.types = new ArrayList();
154 // this.compilationUnit.types.add(typeDecl);
157 // // TODO jsurfer start
158 // if (sourceUnit instanceof BasicCompilationUnit) {
159 // storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(), compilationResult.getAllProblems());
164 unit = compilationUnit;
165 compilationUnit = null; // reset parser
170 * Creates a marker from each problem and adds it to the resource.
171 * The marker is as follows:
172 * - its type is T_PROBLEM
173 * - its plugin ID is the JavaBuilder's plugin ID
174 * - its message is the problem's message
175 * - its priority reflects the severity of the problem
176 * - its range is the problem's range
177 * - it has an extra attribute "ID" which holds the problem's id
179 protected void storeProblemsFor(IResource resource, IProblem[] problems) throws CoreException {
180 if (resource == null || problems == null || problems.length == 0)
183 for (int i = 0, l = problems.length; i < l; i++) {
184 IProblem problem = problems[i];
185 int id = problem.getID();
186 if (id != IProblem.Task) {
187 IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
188 marker.setAttributes(
196 IJavaModelMarker.ARGUMENTS },
198 problem.getMessage(),
199 new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING),
201 new Integer(problem.getSourceStart()),
202 new Integer(problem.getSourceEnd() + 1),
203 new Integer(problem.getSourceLineNumber()),
204 net.sourceforge.phpdt.internal.core.util.Util.getProblemArgumentsForMarker(problem.getArguments())});
213 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
214 //only parse the method body of cd
215 //fill out its statements
217 //convert bugs into parse error
220 goForConstructorBody();
221 nestedMethod[nestedType]++;
223 referenceContext = cd;
224 compilationUnit = unit;
226 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
229 } catch (AbortCompilation ex) {
230 lastAct = ERROR_ACTION;
233 nestedMethod[nestedType]--;
236 if (lastAct == ERROR_ACTION) {
242 // cd.explicitDeclarations = realBlockStack[realBlockPtr--];
244 // if ((length = astLengthStack[astLengthPtr--]) != 0) {
246 // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
247 // //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
252 // cd.statements = new Statement[length - 1],
255 // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
256 // } else { //need to add explicitly the super();
260 // cd.statements = new Statement[length],
263 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
266 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
269 // if (cd.constructorCall.sourceEnd == 0) {
270 // cd.constructorCall.sourceEnd = cd.sourceEnd;
271 // cd.constructorCall.sourceStart = cd.sourceStart;
276 public void parse(FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) {
277 //only parse the initializationSource of the given field
279 //convert bugs into parse error
283 nestedMethod[nestedType]++;
285 referenceContext = type;
286 compilationUnit = unit;
288 scanner.setSource(initializationSource);
289 scanner.resetTo(0, initializationSource.length - 1);
292 } catch (AbortCompilation ex) {
293 lastAct = ERROR_ACTION;
295 nestedMethod[nestedType]--;
298 // if (lastAct == ERROR_ACTION) {
302 // field.initialization = expressionStack[expressionPtr];
304 // // mark field with local type if one was found during parsing
305 // if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
306 // field.bits |= ASTNode.HasLocalTypeMASK;
311 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
312 //only parse the method body of md
313 //fill out method statements
315 //convert bugs into parse error
319 nestedMethod[nestedType]++;
321 referenceContext = type;
322 compilationUnit = unit;
324 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
327 } catch (AbortCompilation ex) {
328 lastAct = ERROR_ACTION;
330 nestedMethod[nestedType]--;
333 // if (lastAct == ERROR_ACTION) {
337 // ini.block = ((Initializer) astStack[astPtr]).block;
339 // // mark initializer with local type if one was found during parsing
340 // if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
341 // ini.bits |= ASTNode.HasLocalTypeMASK;
346 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
347 // TODO jsurfer - make the parse process work on methods ?
350 // //only parse the method body of md
351 // //fill out method statements
353 // //convert bugs into parse error
355 // if (md.isAbstract())
357 // // if (md.isNative())
359 // // if ((md.modifiers & AccSemicolonBody) != 0)
362 // initialize(false);
363 // goForMethodBody();
364 // nestedMethod[nestedType]++;
366 // referenceContext = md;
367 // compilationUnit = unit;
369 // scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
371 // // reset the scanner to parser from { down to }
374 // } catch (AbortCompilation ex) {
375 // lastAct = ERROR_ACTION;
377 // nestedMethod[nestedType]--;
380 // // if (lastAct == ERROR_ACTION) {
384 // // //refill statements
385 // // md.explicitDeclarations = realBlockStack[realBlockPtr--];
387 // // if ((length = astLengthStack[astLengthPtr--]) != 0)
388 // // System.arraycopy(
390 // // (astPtr -= length) + 1,
391 // // md.statements = new Statement[length],
398 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
399 // parses a compilation unit and manages error handling (even bugs....)
401 CompilationUnitDeclaration unit;
403 /* automaton initialization */
405 goForCompilationUnit();
407 /* scanner initialization */
408 scanner.setSource(sourceUnit, sourceUnit.getContents());
409 scanner.resetTo(start, end);
412 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
415 } catch (SyntaxError syntaxError) {
418 unit = compilationUnit;
419 compilationUnit = null; // reset parser
424 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
425 return dietParse(sourceUnit, compilationResult, false);
427 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, boolean phpMode) {
429 CompilationUnitDeclaration parsedUnit;
433 parsedUnit = parse(sourceUnit, compilationResult, phpMode);