1) Fixed issue #872.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / UnitParser.java
1 package net.sourceforge.phpdt.internal.compiler.parser;
2
3 //import net.sourceforge.phpdt.core.IJavaModelMarker;
4 //import net.sourceforge.phpdt.core.compiler.IProblem;
5 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
6 //import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
7 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
8 import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
9 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
10 import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
11 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
12 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
13 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
14 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
15 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
16
17 //import org.eclipse.core.resources.IMarker;
18 //import org.eclipse.core.resources.IResource;
19 //import org.eclipse.core.runtime.CoreException;
20
21 /**
22  * 
23  * 
24  */
25 public class UnitParser extends Parser {
26
27         public UnitParser(ProblemReporter problemReporter) { // , boolean
28                                                                                                                         // optimizeStringLiterals,
29                                                                                                                         // boolean
30                                                                                                                         // assertMode) {
31                 super(problemReporter);
32                 nestedMethod = new int[30];
33
34                 // this.optimizeStringLiterals = optimizeStringLiterals;
35                 // this.assertMode = assertMode;
36                 // this.initializeScanner();
37                 astLengthStack = new int[50];
38                 // expressionLengthStack = new int[30];
39                 // intStack = new int[50];
40                 // identifierStack = new char[30][];
41                 // identifierLengthStack = new int[30];
42                 // nestedMethod = new int[30];
43                 // realBlockStack = new int[30];
44                 // identifierPositionStack = new long[30];
45                 // variablesCounter = new int[30];
46         }
47
48         public void goForConstructorBody() {
49                 // tells the scanner to go for compilation unit parsing
50
51                 firstToken = TokenName.EQUAL_EQUAL;
52                 scanner.recordLineSeparator = false;
53         }
54
55         public void goForExpression() {
56                 // tells the scanner to go for an expression parsing
57
58                 firstToken = TokenName.REMAINDER;
59                 scanner.recordLineSeparator = false;
60         }
61
62         public void goForCompilationUnit() {
63                 // tells the scanner to go for compilation unit parsing
64
65                 firstToken = TokenName.PLUS_PLUS;
66                 scanner.linePtr = -1;
67                 scanner.foundTaskCount = 0;
68                 scanner.recordLineSeparator = true;
69                 // scanner.currentLine= null;
70         }
71
72         public void goForInitializer() {
73                 // tells the scanner to go for initializer parsing
74
75                 firstToken = TokenName.RIGHT_SHIFT;
76                 scanner.recordLineSeparator = false;
77         }
78
79         public void goForMethodBody() {
80                 // tells the scanner to go for method body parsing
81
82                 firstToken = TokenName.MINUS_MINUS;
83                 scanner.recordLineSeparator = false;
84         }
85
86         public void initialize(boolean phpMode) {
87                 super.initialize(phpMode);
88                 // positionning the parser for a new compilation unit
89                 // avoiding stack reallocation and all that....
90                 // astPtr = -1;
91                 // astLengthPtr = -1;
92                 // expressionPtr = -1;
93                 // expressionLengthPtr = -1;
94                 // identifierPtr = -1;
95                 // identifierLengthPtr = -1;
96                 // intPtr = -1;
97                 // nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
98                 // variablesCounter[nestedType] = 0;
99                 // dimensions = 0 ;
100                 // realBlockPtr = -1;
101                 // endStatementPosition = 0;
102
103                 // remove objects from stack too, while the same parser/compiler couple
104                 // is
105                 // re-used between two compilations ....
106
107                 // int astLength = astStack.length;
108                 // if (noAstNodes.length < astLength){
109                 // noAstNodes = new ASTNode[astLength];
110                 // //System.out.println("Resized AST stacks : "+ astLength);
111                 //              
112                 // }
113                 // System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
114                 //
115                 // int expressionLength = expressionStack.length;
116                 // if (noExpressions.length < expressionLength){
117                 // noExpressions = new Expression[expressionLength];
118                 // //System.out.println("Resized EXPR stacks : "+ expressionLength);
119                 // }
120                 // System.arraycopy(noExpressions, 0, expressionStack, 0,
121                 // expressionLength);
122
123                 // reset scanner state
124                 scanner.commentPtr = -1;
125                 scanner.foundTaskCount = 0;
126                 scanner.eofPosition = Integer.MAX_VALUE;
127
128                 // resetModifiers();
129                 //
130                 // // recovery
131                 // lastCheckPoint = -1;
132                 // currentElement = null;
133                 // restartRecovery = false;
134                 // hasReportedError = false;
135                 // recoveredStaticInitializerStart = 0;
136                 // lastIgnoredToken = -1;
137                 // lastErrorEndPosition = -1;
138                 // listLength = 0;
139         }
140
141         // A P I
142
143         public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit,
144                         CompilationResult compilationResult, boolean phpMode) {
145                 // parses a compilation unit and manages error handling (even bugs....)
146
147                 CompilationUnitDeclaration unit;
148                 try {
149                         /* automaton initialization */
150                         initialize(phpMode);
151                         goForCompilationUnit();
152
153                         /* scanner initialization */
154                         scanner.setSource(sourceUnit, sourceUnit.getContents());
155
156                         /* unit creation */
157                         referenceContext = compilationUnit = new CompilationUnitDeclaration(
158                                         problemReporter, compilationResult, scanner.source.length);
159                         // TODO TypeDeclaration test
160                         // TypeDeclaration typeDecl = new
161                         // TypeDeclaration(this.compilationUnit.compilationResult);
162                         // typeDecl.sourceStart = 0;
163                         // typeDecl.sourceEnd = 10;
164                         // typeDecl.name = new char[]{'t', 'e','s','t'};
165                         // this.compilationUnit.types = new ArrayList();
166                         // this.compilationUnit.types.add(typeDecl);
167                         /* run automaton */
168                         super.parse();
169                         // // TODO jsurfer start
170                         // if (sourceUnit instanceof BasicCompilationUnit) {
171                         // storeProblemsFor(((BasicCompilationUnit)sourceUnit).getResource(),
172                         // compilationResult.getAllProblems());
173                         // }
174                         // // jsurfer end
175
176                 } finally {
177                         unit = compilationUnit;
178                         compilationUnit = null; // reset parser
179                 }
180                 return unit;
181         }
182
183         /**
184          * Creates a marker from each problem and adds it to the resource. The
185          * marker is as follows: - its type is T_PROBLEM - its plugin ID is the
186          * JavaBuilder's plugin ID - its message is the problem's message - its
187          * priority reflects the severity of the problem - its range is the
188          * problem's range - it has an extra attribute "ID" which holds the
189          * problem's id
190          */
191 //      protected void storeProblemsFor(IResource resource, IProblem[] problems)
192 //                      throws CoreException {
193 //              if (resource == null || problems == null || problems.length == 0)
194 //                      return;
195 //
196 //              for (int i = 0, l = problems.length; i < l; i++) {
197 //                      IProblem problem = problems[i];
198 //                      int id = problem.getID();
199 //                      if (id != IProblem.Task) {
200 //                              IMarker marker = resource
201 //                                              .createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
202 //                              marker
203 //                                              .setAttributes(
204 //                                                              new String[] { IMarker.MESSAGE,
205 //                                                                              IMarker.SEVERITY, IJavaModelMarker.ID,
206 //                                                                              IMarker.CHAR_START, IMarker.CHAR_END,
207 //                                                                              IMarker.LINE_NUMBER,
208 //                                                                              IJavaModelMarker.ARGUMENTS },
209 //                                                              new Object[] {
210 //                                                                              problem.getMessage(),
211 //                                                                              new Integer(
212 //                                                                                              problem.isError() ? IMarker.SEVERITY_ERROR
213 //                                                                                                              : IMarker.SEVERITY_WARNING),
214 //                                                                              new Integer(id),
215 //                                                                              new Integer(problem.getSourceStart()),
216 //                                                                              new Integer(problem.getSourceEnd() + 1),
217 //                                                                              new Integer(problem
218 //                                                                                              .getSourceLineNumber()),
219 //                                                                              net.sourceforge.phpdt.internal.core.util.Util
220 //                                                                                              .getProblemArgumentsForMarker(problem
221 //                                                                                                              .getArguments()) });
222 //                      }
223 //
224 //              }
225 //      }
226
227         // A P I
228
229         public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
230                 // only parse the method body of cd
231                 // fill out its statements
232
233                 // convert bugs into parse error
234
235                 initialize(false);
236                 goForConstructorBody();
237                 nestedMethod[nestedType]++;
238
239                 referenceContext = cd;
240                 compilationUnit = unit;
241
242                 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
243                 try {
244                         parse();
245                 } catch (AbortCompilation ex) {
246                         lastAct = ERROR_ACTION;
247
248                 } finally {
249                         nestedMethod[nestedType]--;
250                 }
251
252                 if (lastAct == ERROR_ACTION) {
253                         initialize(false);
254                         return;
255                 }
256
257                 // statements
258                 // cd.explicitDeclarations = realBlockStack[realBlockPtr--];
259                 // int length;
260                 // if ((length = astLengthStack[astLengthPtr--]) != 0) {
261                 // astPtr -= length;
262                 // if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
263                 // //avoid a isSomeThing that would only be used here BUT what is faster
264                 // between two alternatives ?
265                 // {
266                 // System.arraycopy(
267                 // astStack,
268                 // astPtr + 2,
269                 // cd.statements = new Statement[length - 1],
270                 // 0,
271                 // length - 1);
272                 // cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
273                 // } else { //need to add explicitly the super();
274                 // System.arraycopy(
275                 // astStack,
276                 // astPtr + 1,
277                 // cd.statements = new Statement[length],
278                 // 0,
279                 // length);
280                 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
281                 // }
282                 // } else {
283                 // cd.constructorCall = SuperReference.implicitSuperConstructorCall();
284                 // }
285                 //
286                 // if (cd.constructorCall.sourceEnd == 0) {
287                 // cd.constructorCall.sourceEnd = cd.sourceEnd;
288                 // cd.constructorCall.sourceStart = cd.sourceStart;
289                 // }
290         }
291
292         // A P I
293
294         public void parse(FieldDeclaration field, TypeDeclaration type,
295                         CompilationUnitDeclaration unit, char[] initializationSource) {
296                 // only parse the initializationSource of the given field
297
298                 // convert bugs into parse error
299
300                 initialize(false);
301                 goForExpression();
302                 nestedMethod[nestedType]++;
303
304                 referenceContext = type;
305                 compilationUnit = unit;
306
307                 scanner.setSource(initializationSource);
308                 scanner.resetTo(0, initializationSource.length - 1);
309                 try {
310                         parse();
311                 } catch (AbortCompilation ex) {
312                         lastAct = ERROR_ACTION;
313                 } finally {
314                         nestedMethod[nestedType]--;
315                 }
316
317                 // if (lastAct == ERROR_ACTION) {
318                 // return;
319                 // }
320                 //
321                 // field.initialization = expressionStack[expressionPtr];
322                 //      
323                 // // mark field with local type if one was found during parsing
324                 // if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
325                 // field.bits |= ASTNode.HasLocalTypeMASK;
326                 // }
327         }
328
329         // A P I
330
331         public void parse(Initializer ini, TypeDeclaration type,
332                         CompilationUnitDeclaration unit) {
333                 // only parse the method body of md
334                 // fill out method statements
335
336                 // convert bugs into parse error
337
338                 initialize(false);
339                 goForInitializer();
340                 nestedMethod[nestedType]++;
341
342                 referenceContext = type;
343                 compilationUnit = unit;
344
345                 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the
346                                                                                                                         // beginning {
347                 try {
348                         parse();
349                 } catch (AbortCompilation ex) {
350                         lastAct = ERROR_ACTION;
351                 } finally {
352                         nestedMethod[nestedType]--;
353                 }
354
355                 // if (lastAct == ERROR_ACTION) {
356                 // return;
357                 // }
358                 //
359                 // ini.block = ((Initializer) astStack[astPtr]).block;
360                 //      
361                 // // mark initializer with local type if one was found during parsing
362                 // if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
363                 // ini.bits |= ASTNode.HasLocalTypeMASK;
364                 // }
365         }
366
367         // A P I
368
369         public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
370                 // TODO jsurfer - make the parse process work on methods ?
371                 return;
372
373                 // //only parse the method body of md
374                 // //fill out method statements
375                 //
376                 // //convert bugs into parse error
377                 //
378                 // if (md.isAbstract())
379                 // return;
380                 // // if (md.isNative())
381                 // // return;
382                 // // if ((md.modifiers & AccSemicolonBody) != 0)
383                 // // return;
384                 //
385                 // initialize(false);
386                 // goForMethodBody();
387                 // nestedMethod[nestedType]++;
388                 //
389                 // referenceContext = md;
390                 // compilationUnit = unit;
391                 //
392                 // scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
393                 //   
394                 // // reset the scanner to parser from { down to }
395                 // try {
396                 // parse();
397                 // } catch (AbortCompilation ex) {
398                 // lastAct = ERROR_ACTION;
399                 // } finally {
400                 // nestedMethod[nestedType]--;
401                 // }
402                 //
403                 // // if (lastAct == ERROR_ACTION) {
404                 // // return;
405                 // // }
406                 // //
407                 // // //refill statements
408                 // // md.explicitDeclarations = realBlockStack[realBlockPtr--];
409                 // // int length;
410                 // // if ((length = astLengthStack[astLengthPtr--]) != 0)
411                 // // System.arraycopy(
412                 // // astStack,
413                 // // (astPtr -= length) + 1,
414                 // // md.statements = new Statement[length],
415                 // // 0,
416                 // // length);
417         }
418
419         // A P I
420
421 //      public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit,
422 //                      CompilationResult compilationResult, int start, int end) {
423 //              // parses a compilation unit and manages error handling (even bugs....)
424 //
425 //              CompilationUnitDeclaration unit;
426 //              try {
427 //                      /* automaton initialization */
428 //                      initialize(false);
429 //                      goForCompilationUnit();
430 //
431 //                      /* scanner initialization */
432 //                      scanner.setSource(sourceUnit, sourceUnit.getContents());
433 //                      scanner.resetTo(start, end);
434 //                      /* unit creation */
435 //                      referenceContext = compilationUnit = new CompilationUnitDeclaration(
436 //                                      problemReporter, compilationResult, scanner.source.length);
437 //
438 //                      /* run automaton */
439 //                      parse();
440 //              } catch (SyntaxError syntaxError) {
441 //                      // 
442 //              } finally {
443 //                      unit = compilationUnit;
444 //                      compilationUnit = null; // reset parser
445 //              }
446 //              return unit;
447 //      }
448
449         public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit,
450                         CompilationResult compilationResult) {
451                 return dietParse(sourceUnit, compilationResult, false);
452         }
453
454         public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit,
455                         CompilationResult compilationResult, boolean phpMode) {
456
457                 CompilationUnitDeclaration parsedUnit;
458                 boolean old = diet;
459                 try {
460                         diet = true;
461                         parsedUnit = parse(sourceUnit, compilationResult, phpMode);
462                 } finally {
463                         diet = old;
464                 }
465                 return parsedUnit;
466         }
467
468 //      public void getMethodBodies(CompilationUnitDeclaration unit) {
469 //              // fill the methods bodies in order for the code to be generated
470 //
471 //              if (unit == null)
472 //                      return;
473 //
474 //              if (unit.ignoreMethodBodies) {
475 //                      unit.ignoreFurtherInvestigation = true;
476 //                      return;
477 //                      // if initial diet parse did not work, no need to dig into method
478 //                      // bodies.
479 //              }
480 //
481 //              if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
482 //                      return; // work already done ...
483 //
484 //              // real parse of the method....
485 //              char[] contents = unit.compilationResult.compilationUnit.getContents();
486 //              this.scanner.setSource(contents);
487 //
488 //              // save existing values to restore them at the end of the parsing
489 //              // process
490 //              // see bug 47079 for more details
491 //              int[] oldLineEnds = this.scanner.lineEnds;
492 //              int oldLinePtr = this.scanner.linePtr;
493 //
494 //              final int[] lineSeparatorPositions = unit.compilationResult.lineSeparatorPositions;
495 //              this.scanner.lineEnds = lineSeparatorPositions;
496 //              this.scanner.linePtr = lineSeparatorPositions.length - 1;
497 //
498 //              // if (this.javadocParser != null && this.javadocParser.checkDocComment)
499 //              // {
500 //              // this.javadocParser.scanner.setSource(contents);
501 //              // }
502 //              if (unit.types != null) {
503 //                      for (int i = unit.types.size(); --i >= 0;)
504 //                              ((TypeDeclaration) unit.types.get(i)).parseMethod(this, unit);
505 //              }
506 //
507 //              // tag unit has having read bodies
508 //              unit.bits |= ASTNode.HasAllMethodBodies;
509 //
510 //              // this is done to prevent any side effects on the compilation unit
511 //              // result
512 //              // line separator positions array.
513 //              this.scanner.lineEnds = oldLineEnds;
514 //              this.scanner.linePtr = oldLinePtr;
515 //      }
516 }