avoid ClassCastException
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / SourceElementParser.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.compiler;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
16
17 import net.sourceforge.phpdt.core.compiler.CharOperation;
18 import net.sourceforge.phpdt.core.compiler.IProblem;
19 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
20 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
21 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
22 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
23 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
24 import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
25 import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
26 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
27 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
28 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
29 import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration;
30 import net.sourceforge.phpeclipse.internal.compiler.ast.Argument;
31 import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
32 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
33 import net.sourceforge.phpeclipse.internal.compiler.ast.ConstructorDeclaration;
34 import net.sourceforge.phpeclipse.internal.compiler.ast.ExplicitConstructorCall;
35 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
36 import net.sourceforge.phpeclipse.internal.compiler.ast.LocalTypeDeclaration;
37 import net.sourceforge.phpeclipse.internal.compiler.ast.MemberTypeDeclaration;
38 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
39 import net.sourceforge.phpeclipse.internal.compiler.ast.NameReference;
40 import net.sourceforge.phpeclipse.internal.compiler.ast.QualifiedAllocationExpression;
41 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
42 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference;
43
44
45
46 /**
47  * A source element parser extracts structural and reference information
48  * from a piece of source.
49  *
50  * also see @ISourceElementRequestor
51  *
52  * The structural investigation includes:
53  * - the package statement
54  * - import statements
55  * - top-level types: package member, member types (member types of member types...)
56  * - fields
57  * - methods
58  *
59  * If reference information is requested, then all source constructs are
60  * investigated and type, field & method references are provided as well.
61  *
62  * Any (parsing) problem encountered is also provided.
63  */
64
65 public class SourceElementParser extends UnitParser {
66         
67         ISourceElementRequestor requestor;
68         int fieldCount;
69         int localIntPtr;
70         int lastFieldEndPosition;
71         ISourceType sourceType;
72         boolean reportReferenceInfo;
73         char[][] typeNames;
74         char[][] superTypeNames;
75         int nestedTypeIndex;
76         static final char[] JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$
77         NameReference[] unknownRefs;
78         int unknownRefsCounter;
79         LocalDeclarationVisitor localDeclarationVisitor = null;
80 //      CompilerOptions options;
81         
82 /**
83  * An ast visitor that visits local type declarations.
84  */
85 public class LocalDeclarationVisitor extends AbstractSyntaxTreeVisitorAdapter {
86 //      public boolean visit(
87 //                      AnonymousLocalTypeDeclaration anonymousTypeDeclaration,
88 //                      BlockScope scope) {
89 //              notifySourceElementRequestor(anonymousTypeDeclaration, sourceType == null);
90 //              return false; // don't visit members as this was done during notifySourceElementRequestor(...)
91 //      }
92         public boolean visit(LocalTypeDeclaration typeDeclaration, BlockScope scope) {
93                 notifySourceElementRequestor(typeDeclaration, sourceType == null);
94                 return false; // don't visit members as this was done during notifySourceElementRequestor(...)
95         }
96         public boolean visit(MemberTypeDeclaration typeDeclaration, ClassScope scope) {
97                 notifySourceElementRequestor(typeDeclaration, sourceType == null);
98                 return false; // don't visit members as this was done during notifySourceElementRequestor(...)
99         }
100         
101 }
102
103 public SourceElementParser(
104         final ISourceElementRequestor requestor, 
105         IProblemFactory problemFactory,
106         CompilerOptions options) {
107         // we want to notify all syntax error with the acceptProblem API
108         // To do so, we define the record method of the ProblemReporter
109         super(
110         new ProblemReporter(
111                 DefaultErrorHandlingPolicies.exitAfterAllProblems(),
112                 options, 
113                 problemFactory) {
114                 public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
115                         unitResult.record(problem, referenceContext);
116                         requestor.acceptProblem(problem);
117                 }
118         });
119 //      true);
120 //      options.sourceLevel >= CompilerOptions.JDK1_4);
121         this.requestor = requestor;
122         typeNames = new char[4][];
123         superTypeNames = new char[4][];
124         nestedTypeIndex = 0;
125         this.options = options;
126 }
127
128 /** @deprecated use SourceElementParser(ISourceElementRequestor, IProblemFactory, CompilerOptions) */
129 //public SourceElementParser(
130 //      final ISourceElementRequestor requestor, 
131 //      IProblemFactory problemFactory) {
132 //              this(requestor, problemFactory, new CompilerOptions());
133 //}
134
135 //public SourceElementParser(
136 //      final ISourceElementRequestor requestor, 
137 //      IProblemFactory problemFactory,
138 //      CompilerOptions options,
139 //      boolean reportLocalDeclarations) {
140 //              this(requestor, problemFactory, options);
141 //              if (reportLocalDeclarations) {
142 //                      this.localDeclarationVisitor = new LocalDeclarationVisitor();
143 //              }
144 //}
145
146 //public void checkAnnotation() {
147 //      int firstCommentIndex = scanner.commentPtr;
148 //
149 //      super.checkAnnotation();
150 //
151 //      // modify the modifier source start to point at the first comment
152 //      if (firstCommentIndex >= 0) {
153 //              modifiersSourceStart = scanner.commentStarts[0]; 
154 //      }
155 //}
156
157 //protected void classInstanceCreation(boolean alwaysQualified) {
158 //
159 //      boolean previousFlag = reportReferenceInfo;
160 //      reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
161 //      super.classInstanceCreation(alwaysQualified);
162 //      reportReferenceInfo = previousFlag;
163 //      if (reportReferenceInfo){
164 //              AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
165 //              TypeReference typeRef = alloc.type;
166 //              requestor.acceptConstructorReference(
167 //                      typeRef instanceof SingleTypeReference 
168 //                              ? ((SingleTypeReference) typeRef).token
169 //                              : CharOperation.concatWith(alloc.type.getTypeName(), '.'),
170 //                      alloc.arguments == null ? 0 : alloc.arguments.length, 
171 //                      alloc.sourceStart);
172 //      }
173 //}
174 //protected void consumeConstructorHeaderName() {
175 //      // ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
176 //
177 //      /* recovering - might be an empty message send */
178 //      if (currentElement != null){
179 //              if (lastIgnoredToken == TokenNamenew){ // was an allocation expression
180 //                      lastCheckPoint = scanner.startPosition; // force to restart at this exact position                              
181 //                      restartRecovery = true;
182 //                      return;
183 //              }
184 //      }
185 //      SourceConstructorDeclaration cd = new SourceConstructorDeclaration(this.compilationUnit.compilationResult);
186 //
187 //      //name -- this is not really revelant but we do .....
188 //      cd.selector = identifierStack[identifierPtr];
189 //      long selectorSourcePositions = identifierPositionStack[identifierPtr--];
190 //      identifierLengthPtr--;
191 //
192 //      //modifiers
193 //      cd.declarationSourceStart = intStack[intPtr--];
194 //      cd.modifiers = intStack[intPtr--];
195 //
196 //      //highlight starts at the selector starts
197 //      cd.sourceStart = (int) (selectorSourcePositions >>> 32);
198 //      cd.selectorSourceEnd = (int) selectorSourcePositions;
199 //      pushOnAstStack(cd);
200 //
201 //      cd.sourceEnd = lParenPos;
202 //      cd.bodyStart = lParenPos+1;
203 //      listLength = 0; // initialize listLength before reading parameters/throws
204 //
205 //      // recovery
206 //      if (currentElement != null){
207 //              lastCheckPoint = cd.bodyStart;
208 //              if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT)
209 //                      || cd.modifiers != 0){
210 //                      currentElement = currentElement.add(cd, 0);
211 //                      lastIgnoredToken = -1;
212 //              }
213 //      }       
214 //}
215 ///**
216 // *
217 // * INTERNAL USE-ONLY
218 // */
219 //protected void consumeExitVariableWithInitialization() {
220 //      // ExitVariableWithInitialization ::= $empty
221 //      // the scanner is located after the comma or the semi-colon.
222 //      // we want to include the comma or the semi-colon
223 //      super.consumeExitVariableWithInitialization();
224 //      if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON)))
225 //              return;
226 //      ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
227 //}
228 //protected void consumeExitVariableWithoutInitialization() {
229 //      // ExitVariableWithoutInitialization ::= $empty
230 //      // do nothing by default
231 //      super.consumeExitVariableWithoutInitialization();
232 //      if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON)))
233 //              return;
234 //      ((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
235 //}
236 ///**
237 // *
238 // * INTERNAL USE-ONLY
239 // */
240 //protected void consumeFieldAccess(boolean isSuperAccess) {
241 //      // FieldAccess ::= Primary '.' 'Identifier'
242 //      // FieldAccess ::= 'super' '.' 'Identifier'
243 //      super.consumeFieldAccess(isSuperAccess);
244 //      FieldReference fr = (FieldReference) expressionStack[expressionPtr];
245 //      if (reportReferenceInfo) {
246 //              requestor.acceptFieldReference(fr.token, fr.sourceStart);
247 //      }
248 //}
249 //protected void consumeMethodHeaderName() {
250 //      // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
251 //      SourceMethodDeclaration md = new SourceMethodDeclaration(this.compilationUnit.compilationResult);
252 //
253 //      //name
254 //      md.selector = identifierStack[identifierPtr];
255 //      long selectorSourcePositions = identifierPositionStack[identifierPtr--];
256 //      identifierLengthPtr--;
257 //      //type
258 //      md.returnType = getTypeReference(intStack[intPtr--]);
259 //      //modifiers
260 //      md.declarationSourceStart = intStack[intPtr--];
261 //      md.modifiers = intStack[intPtr--];
262 //
263 //      //highlight starts at selector start
264 //      md.sourceStart = (int) (selectorSourcePositions >>> 32);
265 //      md.selectorSourceEnd = (int) selectorSourcePositions;
266 //      pushOnAstStack(md);
267 //      md.sourceEnd = lParenPos;
268 //      md.bodyStart = lParenPos+1;
269 //      listLength = 0; // initialize listLength before reading parameters/throws
270 //      
271 //      // recovery
272 //      if (currentElement != null){
273 //              if (currentElement instanceof RecoveredType 
274 //                      //|| md.modifiers != 0
275 //                      || (scanner.getLineNumber(md.returnType.sourceStart)
276 //                                      == scanner.getLineNumber(md.sourceStart))){
277 //                      lastCheckPoint = md.bodyStart;
278 //                      currentElement = currentElement.add(md, 0);
279 //                      lastIgnoredToken = -1;                  
280 //              } else {
281 //                      lastCheckPoint = md.sourceStart;
282 //                      restartRecovery = true;
283 //              }
284 //      }               
285 //}
286 ///**
287 // *
288 // * INTERNAL USE-ONLY
289 // */
290 //protected void consumeMethodInvocationName() {
291 //      // MethodInvocation ::= Name '(' ArgumentListopt ')'
292 //
293 //      // when the name is only an identifier...we have a message send to "this" (implicit)
294 //      super.consumeMethodInvocationName();
295 //      MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
296 //      Expression[] args = messageSend.arguments;
297 //      if (reportReferenceInfo) {
298 //              requestor.acceptMethodReference(
299 //                      messageSend.selector, 
300 //                      args == null ? 0 : args.length, 
301 //                      (int)(messageSend.nameSourcePosition >>> 32));
302 //      }
303 //}
304 ///**
305 // *
306 // * INTERNAL USE-ONLY
307 // */
308 //protected void consumeMethodInvocationPrimary() {
309 //      super.consumeMethodInvocationPrimary();
310 //      MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
311 //      Expression[] args = messageSend.arguments;
312 //      if (reportReferenceInfo) {
313 //              requestor.acceptMethodReference(
314 //                      messageSend.selector, 
315 //                      args == null ? 0 : args.length, 
316 //                      (int)(messageSend.nameSourcePosition >>> 32));
317 //      }
318 //}
319 ///**
320 // *
321 // * INTERNAL USE-ONLY
322 // */
323 //protected void consumeMethodInvocationSuper() {
324 //      // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
325 //      super.consumeMethodInvocationSuper();
326 //      MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
327 //      Expression[] args = messageSend.arguments;
328 //      if (reportReferenceInfo) {
329 //              requestor.acceptMethodReference(
330 //                      messageSend.selector, 
331 //                      args == null ? 0 : args.length, 
332 //                      (int)(messageSend.nameSourcePosition >>> 32));
333 //      }
334 //}
335 //protected void consumeSingleTypeImportDeclarationName() {
336 //      // SingleTypeImportDeclarationName ::= 'import' Name
337 //      /* push an ImportRef build from the last name 
338 //      stored in the identifier stack. */
339 //
340 //      super.consumeSingleTypeImportDeclarationName();
341 //      ImportReference impt = (ImportReference)astStack[astPtr];
342 //      if (reportReferenceInfo) {
343 //              requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
344 //      }
345 //}
346 //protected void consumeTypeImportOnDemandDeclarationName() {
347 //      // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
348 //      /* push an ImportRef build from the last name 
349 //      stored in the identifier stack. */
350 //
351 //      super.consumeTypeImportOnDemandDeclarationName();
352 //      ImportReference impt = (ImportReference)astStack[astPtr];
353 //      if (reportReferenceInfo) {
354 //              requestor.acceptUnknownReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
355 //      }
356 //}
357 //protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
358 //      return new SourceFieldDeclaration(null, name, sourceStart, sourceEnd);
359 //}
360 //protected CompilationUnitDeclaration endParse(int act) {
361 //      if (sourceType != null) {
362 //              if (sourceType.isInterface()) {
363 //                      consumeInterfaceDeclaration();
364 //              } else {
365 //                      consumeClassDeclaration();
366 //              }
367 //      }
368 //      if (compilationUnit != null) {
369 //              CompilationUnitDeclaration result = super.endParse(act);
370 //              return result;
371 //      } else {
372 //              return null;
373 //      }               
374 //}
375 /*
376  * Flush annotations defined prior to a given positions.
377  *
378  * Note: annotations are stacked in syntactical order
379  *
380  * Either answer given <position>, or the end position of a comment line 
381  * immediately following the <position> (same line)
382  *
383  * e.g.
384  * void foo(){
385  * } // end of method foo
386  */
387 // 
388 //public int flushAnnotationsDefinedPriorTo(int position) {
389 //
390 //      return lastFieldEndPosition = super.flushAnnotationsDefinedPriorTo(position);
391 //}
392 //public TypeReference getTypeReference(int dim) {
393 //      /* build a Reference on a variable that may be qualified or not
394 //       * This variable is a type reference and dim will be its dimensions
395 //       */
396 //      int length;
397 //      if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
398 //              // single variable reference
399 //              if (dim == 0) {
400 //                      SingleTypeReference ref = 
401 //                              new SingleTypeReference(
402 //                                      identifierStack[identifierPtr], 
403 //                                      identifierPositionStack[identifierPtr--]);
404 //                      if (reportReferenceInfo) {
405 //                              requestor.acceptTypeReference(ref.token, ref.sourceStart);
406 //                      }
407 //                      return ref;
408 //              } else {
409 //                      ArrayTypeReference ref = 
410 //                              new ArrayTypeReference(
411 //                                      identifierStack[identifierPtr], 
412 //                                      dim, 
413 //                                      identifierPositionStack[identifierPtr--]); 
414 //                      ref.sourceEnd = endPosition;
415 //                      if (reportReferenceInfo) {
416 //                              requestor.acceptTypeReference(ref.token, ref.sourceStart);
417 //                      }
418 //                      return ref;
419 //              }
420 //      } else {
421 //              if (length < 0) { //flag for precompiled type reference on base types
422 //                      TypeReference ref = TypeReference.baseTypeReference(-length, dim);
423 //                      ref.sourceStart = intStack[intPtr--];
424 //                      if (dim == 0) {
425 //                              ref.sourceEnd = intStack[intPtr--];
426 //                      } else {
427 //                              intPtr--; // no need to use this position as it is an array
428 //                              ref.sourceEnd = endPosition;
429 //                      }
430 //                      if (reportReferenceInfo){
431 //                                      requestor.acceptTypeReference(ref.getTypeName(), ref.sourceStart, ref.sourceEnd);
432 //                      }
433 //                      return ref;
434 //              } else { //Qualified variable reference
435 //                      char[][] tokens = new char[length][];
436 //                      identifierPtr -= length;
437 //                      long[] positions = new long[length];
438 //                      System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
439 //                      System.arraycopy(
440 //                              identifierPositionStack, 
441 //                              identifierPtr + 1, 
442 //                              positions, 
443 //                              0, 
444 //                              length); 
445 //                      if (dim == 0) {
446 //                              QualifiedTypeReference ref = new QualifiedTypeReference(tokens, positions);
447 //                              if (reportReferenceInfo) {
448 //                                      requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
449 //                              }
450 //                              return ref;
451 //                      } else {
452 //                              ArrayQualifiedTypeReference ref = 
453 //                                      new ArrayQualifiedTypeReference(tokens, dim, positions); 
454 //                              ref.sourceEnd = endPosition;                                    
455 //                              if (reportReferenceInfo) {
456 //                                      requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
457 //                              }
458 //                              return ref;
459 //                      }
460 //              }
461 //      }
462 //}
463 //public NameReference getUnspecifiedReference() {
464 //      /* build a (unspecified) NameReference which may be qualified*/
465 //
466 //      int length;
467 //      if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
468 //              // single variable reference
469 //              SingleNameReference ref = 
470 //                      new SingleNameReference(
471 //                              identifierStack[identifierPtr], 
472 //                              identifierPositionStack[identifierPtr--]); 
473 //              if (reportReferenceInfo) {
474 //                      this.addUnknownRef(ref);
475 //              }
476 //              return ref;
477 //      } else {
478 //              //Qualified variable reference
479 //              char[][] tokens = new char[length][];
480 //              identifierPtr -= length;
481 //              System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
482 //              QualifiedNameReference ref = 
483 //                      new QualifiedNameReference(
484 //                              tokens, 
485 //                              (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
486 //                              (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
487 //              if (reportReferenceInfo) {
488 //                      this.addUnknownRef(ref);
489 //              }
490 //              return ref;
491 //      }
492 //}
493 //public NameReference getUnspecifiedReferenceOptimized() {
494 //      /* build a (unspecified) NameReference which may be qualified
495 //      The optimization occurs for qualified reference while we are
496 //      certain in this case the last item of the qualified name is
497 //      a field access. This optimization is IMPORTANT while it results
498 //      that when a NameReference is build, the type checker should always
499 //      look for that it is not a type reference */
500 //
501 //      int length;
502 //      if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
503 //              // single variable reference
504 //              SingleNameReference ref = 
505 //                      new SingleNameReference(
506 //                              identifierStack[identifierPtr], 
507 //                              identifierPositionStack[identifierPtr--]); 
508 //              ref.bits &= ~AstNode.RestrictiveFlagMASK;
509 //              ref.bits |= LOCAL | FIELD;
510 //              if (reportReferenceInfo) {
511 //                      this.addUnknownRef(ref);
512 //              }
513 //              return ref;
514 //      }
515 //
516 //      //Qualified-variable-reference
517 //      //In fact it is variable-reference DOT field-ref , but it would result in a type
518 //      //conflict tha can be only reduce by making a superclass (or inetrface ) between
519 //      //nameReference and FiledReference or putting FieldReference under NameReference
520 //      //or else..........This optimisation is not really relevant so just leave as it is
521 //
522 //      char[][] tokens = new char[length][];
523 //      identifierPtr -= length;
524 //      System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
525 //      QualifiedNameReference ref = 
526 //              new QualifiedNameReference(
527 //                      tokens, 
528 //                      (int) (identifierPositionStack[identifierPtr + 1] >> 32), 
529 //      // sourceStart
530 //       (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
531 //      ref.bits &= ~AstNode.RestrictiveFlagMASK;
532 //      ref.bits |= LOCAL | FIELD;
533 //      if (reportReferenceInfo) {
534 //              this.addUnknownRef(ref);
535 //      }
536 //      return ref;
537 //}
538 ///**
539 // *
540 // * INTERNAL USE-ONLY
541 // */
542 //private boolean isLocalDeclaration() {
543 //      int nestedDepth = nestedType;
544 //      while (nestedDepth >= 0) {
545 //              if (nestedMethod[nestedDepth] != 0) {
546 //                      return true;
547 //              }
548 //              nestedDepth--;
549 //      }
550 //      return false;
551 //}
552 /*
553  * Update the bodyStart of the corresponding parse node
554  */
555 public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit) {
556         if (parsedUnit == null) {
557                 // when we parse a single type member declaration the compilation unit is null, but we still
558                 // want to be able to notify the requestor on the created ast node
559                 if (astStack[0] instanceof AbstractMethodDeclaration) {
560                         notifySourceElementRequestor((AbstractMethodDeclaration) astStack[0]);
561                         return;
562                 }
563                 return;
564         }
565         // range check
566         boolean isInRange = 
567                                 scanner.initialPosition <= parsedUnit.sourceStart
568                                 && scanner.eofPosition >= parsedUnit.sourceEnd;
569         
570 //      if (reportReferenceInfo) {
571 //              notifyAllUnknownReferences();
572 //      }
573         // collect the top level ast nodes
574         int length = 0;
575         AstNode[] nodes = null;
576         if (sourceType == null){
577                 if (isInRange) {
578                         requestor.enterCompilationUnit();
579                 }
580 //              ImportReference currentPackage = parsedUnit.currentPackage;
581 //              ImportReference[] imports = parsedUnit.imports;
582 //              TypeDeclaration[] types = parsedUnit.types;
583                 ArrayList types = parsedUnit.types;
584                 if (types != null) {
585 //              length = 
586 //                      (currentPackage == null ? 0 : 1) 
587 //                      + (imports == null ? 0 : imports.length)
588 //                      + (types == null ? 0 : types.length);
589 //              nodes = new AstNode[length];
590                         length = types.size();
591                 nodes = new AstNode[length];
592                 int index = 0;
593 //              if (currentPackage != null) {
594 //                      nodes[index++] = currentPackage;
595 //              }
596 //              if (imports != null) {
597 //                      for (int i = 0, max = imports.length; i < max; i++) {
598 //                              nodes[index++] = imports[i];
599 //                      }
600 //              }
601
602                         for (int i = 0, max = types.size(); i < max; i++) {
603                                 nodes[index++] = (AstNode)types.get(i);
604                         }
605                 }
606         } else {
607 //              TypeDeclaration[] types = parsedUnit.types;
608     ArrayList types = parsedUnit.types;
609                 if (types != null) {
610                         length = types.size();
611                         nodes = new AstNode[length];
612                         for (int i = 0, max = types.size(); i < max; i++) {
613                                 nodes[i] = (AstNode)types.get(i);
614                         }
615                 }
616         }
617         
618         // notify the nodes in the syntactical order
619         if (nodes != null && length > 0) {
620                 quickSort(nodes, 0, length-1);
621                 for (int i=0;i<length;i++) {
622                         AstNode node = nodes[i];
623 //                      if (node instanceof ImportReference) {
624 //                              ImportReference importRef = (ImportReference)node;
625 //                              if (node == parsedUnit.currentPackage) {
626 //                                      notifySourceElementRequestor(importRef, true);
627 //                              } else {
628 //                                      notifySourceElementRequestor(importRef, false);
629 //                              }
630 //                      } else { // instanceof TypeDeclaration
631       if (node instanceof TypeDeclaration) {
632                           notifySourceElementRequestor((TypeDeclaration)node, sourceType == null);
633 //                              notifySourceElementRequestor((CompilationUnitDeclaration)node, sourceType == null);
634                         }
635                         // jsurfer - INSERT start
636                         if (node instanceof AbstractMethodDeclaration) {
637                                 notifySourceElementRequestor((AbstractMethodDeclaration)node);
638                         }
639 //              jsurfer - INSERT end
640                 }
641         }
642         
643         if (sourceType == null){
644                 if (isInRange) {
645                         requestor.exitCompilationUnit(parsedUnit.sourceEnd);
646                 }
647         }
648 }
649
650 //private void notifyAllUnknownReferences() {
651 //      for (int i = 0, max = this.unknownRefsCounter; i < max; i++) {
652 //              NameReference nameRef = this.unknownRefs[i];
653 //              if ((nameRef.bits & BindingIds.VARIABLE) != 0) {
654 //                      if ((nameRef.bits & BindingIds.TYPE) == 0) { 
655 //                              // variable but not type
656 //                              if (nameRef instanceof SingleNameReference) { 
657 //                                      // local var or field
658 //                                      requestor.acceptUnknownReference(((SingleNameReference) nameRef).token, nameRef.sourceStart);
659 //                              } else {
660 //                                      // QualifiedNameReference
661 //                                      // The last token is a field reference and the previous tokens are a type/variable references
662 //                                      char[][] tokens = ((QualifiedNameReference) nameRef).tokens;
663 //                                      int tokensLength = tokens.length;
664 //                                      requestor.acceptFieldReference(tokens[tokensLength - 1], nameRef.sourceEnd - tokens[tokensLength - 1].length + 1);
665 //                                      char[][] typeRef = new char[tokensLength - 1][];
666 //                                      System.arraycopy(tokens, 0, typeRef, 0, tokensLength - 1);
667 //                                      requestor.acceptUnknownReference(typeRef, nameRef.sourceStart, nameRef.sourceEnd - tokens[tokensLength - 1].length);
668 //                              }
669 //                      } else {
670 //                              // variable or type
671 //                              if (nameRef instanceof SingleNameReference) {
672 //                                      requestor.acceptUnknownReference(((SingleNameReference) nameRef).token, nameRef.sourceStart);
673 //                              } else {
674 //                                      //QualifiedNameReference
675 //                                      requestor.acceptUnknownReference(((QualifiedNameReference) nameRef).tokens, nameRef.sourceStart, nameRef.sourceEnd);
676 //                              }
677 //                      }
678 //              } else if ((nameRef.bits & BindingIds.TYPE) != 0) {
679 //                      if (nameRef instanceof SingleNameReference) {
680 //                              requestor.acceptTypeReference(((SingleNameReference) nameRef).token, nameRef.sourceStart);
681 //                      } else {
682 //                              // it is a QualifiedNameReference
683 //                              requestor.acceptTypeReference(((QualifiedNameReference) nameRef).tokens, nameRef.sourceStart, nameRef.sourceEnd);
684 //                      }
685 //              }
686 //      }
687 //}
688 /*
689  * Update the bodyStart of the corresponding parse node
690  */
691 public void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration) {
692
693         // range check
694         boolean isInRange = 
695                                 scanner.initialPosition <= methodDeclaration.declarationSourceStart
696                                 && scanner.eofPosition >= methodDeclaration.declarationSourceEnd;
697
698         if (methodDeclaration.isClinit()) {
699                 this.visitIfNeeded(methodDeclaration);
700                 return;
701         }
702
703         if (methodDeclaration.isDefaultConstructor()) {
704                 if (reportReferenceInfo) {
705                         ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
706                         ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
707                         if (constructorCall != null) {
708                                 switch(constructorCall.accessMode) {
709                                         case ExplicitConstructorCall.This :
710                                                 requestor.acceptConstructorReference(
711                                                         typeNames[nestedTypeIndex-1],
712                                                         constructorCall.arguments == null ? 0 : constructorCall.arguments.length, 
713                                                         constructorCall.sourceStart);
714                                                 break;
715                                         case ExplicitConstructorCall.Super :
716                                         case ExplicitConstructorCall.ImplicitSuper :                                    
717                                                 requestor.acceptConstructorReference(
718                                                         superTypeNames[nestedTypeIndex-1],
719                                                         constructorCall.arguments == null ? 0 : constructorCall.arguments.length, 
720                                                         constructorCall.sourceStart);
721                                                 break;
722                                 }
723                         }
724                 }       
725                 return; 
726         }       
727         char[][] argumentTypes = null;
728         char[][] argumentNames = null;
729         Argument[] arguments = methodDeclaration.arguments;
730         if (arguments != null) {
731                 int argumentLength = arguments.length;
732                 argumentTypes = new char[argumentLength][];
733                 argumentNames = new char[argumentLength][];
734                 for (int i = 0; i < argumentLength; i++) {
735                         argumentTypes[i] = returnTypeName(arguments[i].type);
736                         argumentNames[i] = arguments[i].name;
737                 }
738         }
739         char[][] thrownExceptionTypes = null;
740         TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
741         if (thrownExceptions != null) {
742                 int thrownExceptionLength = thrownExceptions.length;
743                 thrownExceptionTypes = new char[thrownExceptionLength][];
744                 for (int i = 0; i < thrownExceptionLength; i++) {
745                         thrownExceptionTypes[i] = 
746                                 CharOperation.concatWith(thrownExceptions[i].getTypeName(), '.'); 
747                 }
748         }
749         // by default no selector end position
750         int selectorSourceEnd = -1;
751         if (methodDeclaration.isConstructor()) {
752 //              if (methodDeclaration instanceof SourceConstructorDeclaration) {
753 //                      selectorSourceEnd = 
754 //                              ((SourceConstructorDeclaration) methodDeclaration).selectorSourceEnd; 
755 //              }
756                 if (isInRange){
757                         requestor.enterConstructor(
758                                 methodDeclaration.declarationSourceStart, 
759                                 methodDeclaration.modifiers, 
760                                 methodDeclaration.selector, 
761                                 methodDeclaration.sourceStart, 
762                                 selectorSourceEnd, 
763                                 argumentTypes, 
764                                 argumentNames, 
765                                 thrownExceptionTypes);
766                 }
767                 if (reportReferenceInfo) {
768                         ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
769                         ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
770                         if (constructorCall != null) {
771                                 switch(constructorCall.accessMode) {
772                                         case ExplicitConstructorCall.This :
773                                                 requestor.acceptConstructorReference(
774                                                         typeNames[nestedTypeIndex-1],
775                                                         constructorCall.arguments == null ? 0 : constructorCall.arguments.length, 
776                                                         constructorCall.sourceStart);
777                                                 break;
778                                         case ExplicitConstructorCall.Super :
779                                         case ExplicitConstructorCall.ImplicitSuper :
780                                                 requestor.acceptConstructorReference(
781                                                         superTypeNames[nestedTypeIndex-1],
782                                                         constructorCall.arguments == null ? 0 : constructorCall.arguments.length, 
783                                                         constructorCall.sourceStart);
784                                                 break;
785                                 }
786                         }
787                 }
788                 this.visitIfNeeded(methodDeclaration);
789                 if (isInRange){
790                         requestor.exitConstructor(methodDeclaration.declarationSourceEnd);
791                 }
792                 return;
793         }
794 //      if (methodDeclaration instanceof SourceMethodDeclaration) {
795 //              selectorSourceEnd = 
796 //                      ((SourceMethodDeclaration) methodDeclaration).selectorSourceEnd; 
797 //      }
798         if (isInRange) {
799                 int modifiers = methodDeclaration.modifiers;
800 //              boolean deprecated = (modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below
801                 requestor.enterMethod(
802                         methodDeclaration.declarationSourceStart, 
803                 modifiers, // deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, 
804                         returnTypeName(((MethodDeclaration) methodDeclaration).returnType), 
805                         methodDeclaration.selector, 
806                         methodDeclaration.sourceStart, 
807                         selectorSourceEnd, 
808                         argumentTypes, 
809                         argumentNames, 
810                         thrownExceptionTypes); 
811         }               
812         this.visitIfNeeded(methodDeclaration);
813
814         if (isInRange){ 
815                 requestor.exitMethod(methodDeclaration.declarationSourceEnd);
816         }
817 }
818 ///*
819 //* Update the bodyStart of the corresponding parse node
820 //*/
821 //public void notifySourceElementRequestor(FieldDeclaration fieldDeclaration) {
822 //      
823 //      // range check
824 //      boolean isInRange = 
825 //                              scanner.initialPosition <= fieldDeclaration.declarationSourceStart
826 //                              && scanner.eofPosition >= fieldDeclaration.declarationSourceEnd;
827 //
828 //      if (fieldDeclaration.isField()) {
829 //              int fieldEndPosition = fieldDeclaration.declarationSourceEnd;
830 //              if (fieldDeclaration instanceof SourceFieldDeclaration) {
831 //                      fieldEndPosition = ((SourceFieldDeclaration) fieldDeclaration).fieldEndPosition;
832 //                      if (fieldEndPosition == 0) {
833 //                              // use the declaration source end by default
834 //                              fieldEndPosition = fieldDeclaration.declarationSourceEnd;
835 //                      }
836 //              }
837 //              if (isInRange) {
838 //                      int modifiers = fieldDeclaration.modifiers;
839 //                      boolean deprecated = (modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below
840 //                      requestor.enterField(
841 //                              fieldDeclaration.declarationSourceStart, 
842 //                              deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, 
843 //                              returnTypeName(fieldDeclaration.type), 
844 //                              fieldDeclaration.name, 
845 //                              fieldDeclaration.sourceStart, 
846 //                              fieldDeclaration.sourceEnd); 
847 //              }
848 //              this.visitIfNeeded(fieldDeclaration);
849 //              if (isInRange){
850 //                      requestor.exitField(
851 //                              // filter out initializations that are not a constant (simple check)
852 //                              (fieldDeclaration.initialization == null 
853 //                                              || fieldDeclaration.initialization instanceof ArrayInitializer
854 //                                              || fieldDeclaration.initialization instanceof AllocationExpression
855 //                                              || fieldDeclaration.initialization instanceof ArrayAllocationExpression
856 //                                              || fieldDeclaration.initialization instanceof Assignment
857 //                                              || fieldDeclaration.initialization instanceof ClassLiteralAccess
858 //                                              || fieldDeclaration.initialization instanceof MessageSend
859 //                                              || fieldDeclaration.initialization instanceof ArrayReference
860 //                                              || fieldDeclaration.initialization instanceof ThisReference) ? 
861 //                                      -1 :  
862 //                                      fieldDeclaration.initialization.sourceStart, 
863 //                              fieldEndPosition,
864 //                              fieldDeclaration.declarationSourceEnd);
865 //              }
866 //
867 //      } else {
868 //              if (isInRange){
869 //                      requestor.enterInitializer(
870 //                              fieldDeclaration.declarationSourceStart,
871 //                              fieldDeclaration.modifiers); 
872 //              }
873 //              this.visitIfNeeded((Initializer)fieldDeclaration);
874 //              if (isInRange){
875 //                      requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
876 //              }
877 //      }
878 //}
879 //public void notifySourceElementRequestor(
880 //      ImportReference importReference, 
881 //      boolean isPackage) {
882 //      if (isPackage) {
883 //              requestor.acceptPackage(
884 //                      importReference.declarationSourceStart, 
885 //                      importReference.declarationSourceEnd, 
886 //                      CharOperation.concatWith(importReference.getImportName(), '.')); 
887 //      } else {
888 //              requestor.acceptImport(
889 //                      importReference.declarationSourceStart, 
890 //                      importReference.declarationSourceEnd, 
891 //                      CharOperation.concatWith(importReference.getImportName(), '.'), 
892 //                      importReference.onDemand); 
893 //      }
894 //}
895 public void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence) {
896 ////    public void notifySourceElementRequestor(AstNode typeDeclaration, boolean notifyTypePresence) {
897         
898         // range check
899         boolean isInRange = 
900                                 scanner.initialPosition <= typeDeclaration.declarationSourceStart
901                                 && scanner.eofPosition >= typeDeclaration.declarationSourceEnd;
902         
903         FieldDeclaration[] fields = typeDeclaration.fields;
904         AbstractMethodDeclaration[] methods = typeDeclaration.methods;
905         MemberTypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
906         int fieldCount = fields == null ? 0 : fields.length;
907         int methodCount = methods == null ? 0 : methods.length;
908         int memberTypeCount = memberTypes == null ? 0 : memberTypes.length;
909         int fieldIndex = 0;
910         int methodIndex = 0;
911         int memberTypeIndex = 0;
912         boolean isInterface = typeDeclaration.isInterface();
913
914         if (notifyTypePresence){
915                 char[][] interfaceNames = null;
916                 int superInterfacesLength = 0;
917                 TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
918                 if (superInterfaces != null) {
919                         superInterfacesLength = superInterfaces.length;
920                         interfaceNames = new char[superInterfacesLength][];
921                 } else {
922                         if (typeDeclaration instanceof AnonymousLocalTypeDeclaration) {
923                                 // see PR 3442
924                                 QualifiedAllocationExpression alloc = ((AnonymousLocalTypeDeclaration)typeDeclaration).allocation;
925                                 if (alloc != null && alloc.type != null) {
926                                         superInterfaces = new TypeReference[] { ((AnonymousLocalTypeDeclaration)typeDeclaration).allocation.type};
927                                         superInterfacesLength = 1;
928                                         interfaceNames = new char[1][];
929                                 }
930                         }
931                 }
932                 if (superInterfaces != null) {
933                         for (int i = 0; i < superInterfacesLength; i++) {
934                                 interfaceNames[i] = 
935                                         CharOperation.concatWith(superInterfaces[i].getTypeName(), '.'); 
936                         }
937                 }
938                 if (isInterface) {
939                         if (isInRange){
940                                 int modifiers = typeDeclaration.modifiers;
941                                 boolean deprecated = false; //(modifiers & AccDeprecated) != 0; // remember deprecation so as to not lose it below
942                                 requestor.enterInterface(
943                                         typeDeclaration.declarationSourceStart, 
944                                         modifiers, //deprecated ? (modifiers & AccJustFlag) | AccDeprecated : modifiers & AccJustFlag, 
945                                         typeDeclaration.name, 
946                                         typeDeclaration.sourceStart, 
947                                         typeDeclaration.sourceEnd, 
948                                         interfaceNames);
949                         }
950                         if (nestedTypeIndex == typeNames.length) {
951                                 // need a resize
952                                 System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
953                                 System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
954                         }
955                         typeNames[nestedTypeIndex] = typeDeclaration.name;
956                         superTypeNames[nestedTypeIndex++] = JAVA_LANG_OBJECT;
957                 } else {
958                         TypeReference superclass = typeDeclaration.superclass;
959                         if (superclass == null) {
960                                 if (isInRange){
961                                         requestor.enterClass(
962                                                 typeDeclaration.declarationSourceStart, 
963                                                 typeDeclaration.modifiers, 
964                                                 typeDeclaration.name, 
965                                                 typeDeclaration.sourceStart, 
966                                                 typeDeclaration.sourceEnd, 
967                                                 null, 
968                                                 interfaceNames); 
969                                 }
970                         } else {
971                                 if (isInRange){
972                                         requestor.enterClass(
973                                                 typeDeclaration.declarationSourceStart, 
974                                                 typeDeclaration.modifiers, 
975                                                 typeDeclaration.name, 
976                                                 typeDeclaration.sourceStart, 
977                                                 typeDeclaration.sourceEnd, 
978                                                 CharOperation.concatWith(superclass.getTypeName(), '.'), 
979                                                 interfaceNames); 
980                                 }
981                         }
982                         if (nestedTypeIndex == typeNames.length) {
983                                 // need a resize
984                                 System.arraycopy(typeNames, 0, (typeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
985                                 System.arraycopy(superTypeNames, 0, (superTypeNames = new char[nestedTypeIndex * 2][]), 0, nestedTypeIndex);
986                         }
987                         typeNames[nestedTypeIndex] = typeDeclaration.name;
988                         superTypeNames[nestedTypeIndex++] = superclass == null ? JAVA_LANG_OBJECT : CharOperation.concatWith(superclass.getTypeName(), '.');
989                 }
990         }
991         while ((fieldIndex < fieldCount)
992                 || (memberTypeIndex < memberTypeCount)
993                 || (methodIndex < methodCount)) {
994                 FieldDeclaration nextFieldDeclaration = null;
995                 AbstractMethodDeclaration nextMethodDeclaration = null;
996                 TypeDeclaration nextMemberDeclaration = null;
997
998                 int position = Integer.MAX_VALUE;
999                 int nextDeclarationType = -1;
1000                 if (fieldIndex < fieldCount) {
1001                         nextFieldDeclaration = fields[fieldIndex];
1002                         if (nextFieldDeclaration.declarationSourceStart < position) {
1003                                 position = nextFieldDeclaration.declarationSourceStart;
1004                                 nextDeclarationType = 0; // FIELD
1005                         }
1006                 }
1007                 if (methodIndex < methodCount) {
1008                         nextMethodDeclaration = methods[methodIndex];
1009                         if (nextMethodDeclaration.declarationSourceStart < position) {
1010                                 position = nextMethodDeclaration.declarationSourceStart;
1011                                 nextDeclarationType = 1; // METHOD
1012                         }
1013                 }
1014                 if (memberTypeIndex < memberTypeCount) {
1015                         nextMemberDeclaration = memberTypes[memberTypeIndex];
1016                         if (nextMemberDeclaration.declarationSourceStart < position) {
1017                                 position = nextMemberDeclaration.declarationSourceStart;
1018                                 nextDeclarationType = 2; // MEMBER
1019                         }
1020                 }
1021                 switch (nextDeclarationType) {
1022                         case 0 :
1023                                 fieldIndex++;
1024 //                              notifySourceElementRequestor(nextFieldDeclaration);
1025                                 break;
1026                         case 1 :
1027                                 methodIndex++;
1028                                 notifySourceElementRequestor(nextMethodDeclaration);
1029                                 break;
1030                         case 2 :
1031                                 memberTypeIndex++;
1032                                 notifySourceElementRequestor(nextMemberDeclaration, true);
1033                 }
1034         }
1035         if (notifyTypePresence){
1036                 if (isInRange){
1037                         if (isInterface) {
1038                                 requestor.exitInterface(typeDeclaration.declarationSourceEnd);
1039                         } else {
1040                                 requestor.exitClass(typeDeclaration.declarationSourceEnd);
1041                         }
1042                 }
1043                 nestedTypeIndex--;
1044         }
1045 }
1046 public void parseCompilationUnit (
1047         ICompilationUnit unit, 
1048         int start, 
1049         int end ) { 
1050 //      boolean needReferenceInfo) {
1051
1052 //      reportReferenceInfo = needReferenceInfo;
1053 //      boolean old = diet;
1054 //      if (needReferenceInfo) {
1055 //              unknownRefs = new NameReference[10];
1056 //              unknownRefsCounter = 0;
1057 //      }
1058         
1059         try {
1060 //              diet = true;
1061                 CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, 10); //this.options.maxProblemsPerUnit);
1062                 CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, start, end);
1063 //              if (scanner.recordLineSeparator) {
1064 //                      requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
1065 //              }
1066 //              if (this.localDeclarationVisitor != null || needReferenceInfo){
1067 //                      diet = false;
1068 //                      this.getMethodBodies(parsedUnit);
1069 //              }               
1070 //              this.scanner.resetTo(start, end);
1071 //              notifySourceElementRequestor(parsedUnit);
1072         } catch (AbortCompilation e) {
1073         } finally {
1074 //              diet = old;
1075         }
1076 }
1077 public CompilationUnitDeclaration parseCompilationUnit(
1078                 ICompilationUnit unit, 
1079                 boolean fullParse) {
1080                         
1081 //              boolean old = diet;
1082 //              if (fullParse) {
1083 //                      unknownRefs = new NameReference[10];
1084 //                      unknownRefsCounter = 0;
1085 //              }
1086
1087                 try {
1088 //                      diet = true;
1089                         this.reportReferenceInfo = fullParse;
1090                         CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
1091                         CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, false);
1092                         if (scanner.recordLineSeparator) {
1093                                 requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
1094                         }
1095                         int initialStart = this.scanner.initialPosition;
1096                         int initialEnd = this.scanner.eofPosition;
1097 //                      if (this.localDeclarationVisitor != null || fullParse){
1098 //                              diet = false;
1099 //                              this.getMethodBodies(parsedUnit);
1100 //                      }
1101                         this.scanner.resetTo(initialStart, initialEnd);
1102                         notifySourceElementRequestor(parsedUnit);
1103                         return parsedUnit;
1104                 } catch (AbortCompilation e) {
1105                         // ignore this exception
1106                 } finally {
1107 //                      diet = old;
1108                 }
1109                 return null;
1110         }
1111
1112 //public void parseTypeMemberDeclarations(
1113 //      ISourceType sourceType, 
1114 //      ICompilationUnit sourceUnit, 
1115 //      int start, 
1116 //      int end, 
1117 //      boolean needReferenceInfo) {
1118 //      boolean old = diet;
1119 //      if (needReferenceInfo) {
1120 //              unknownRefs = new NameReference[10];
1121 //              unknownRefsCounter = 0;
1122 //      }
1123 //      
1124 //      try {
1125 //              diet = !needReferenceInfo;
1126 //              reportReferenceInfo = needReferenceInfo;
1127 //              CompilationResult compilationUnitResult = 
1128 //                      new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit); 
1129 //              CompilationUnitDeclaration unit = 
1130 //                      SourceTypeConverter.buildCompilationUnit(
1131 //                              new ISourceType[]{sourceType}, 
1132 //                              false, // no need for field and methods
1133 //                              false, // no need for member types
1134 //                              false, // no need for field initialization
1135 //                              problemReporter(), 
1136 //                              compilationUnitResult); 
1137 //              if ((unit == null) || (unit.types == null) || (unit.types.length != 1))
1138 //                      return;
1139 //              this.sourceType = sourceType;
1140 //              try {
1141 //                      /* automaton initialization */
1142 //                      initialize();
1143 //                      goForClassBodyDeclarations();
1144 //                      /* scanner initialization */
1145 //                      scanner.setSource(sourceUnit.getContents());
1146 //                      scanner.resetTo(start, end);
1147 //                      /* unit creation */
1148 //                      referenceContext = compilationUnit = unit;
1149 //                      /* initialize the astStacl */
1150 //                      // the compilationUnitDeclaration should contain exactly one type
1151 //                      pushOnAstStack(unit.types[0]);
1152 //                      /* run automaton */
1153 //                      parse();
1154 //                      notifySourceElementRequestor(unit);
1155 //              } finally {
1156 //                      unit = compilationUnit;
1157 //                      compilationUnit = null; // reset parser
1158 //              }
1159 //      } catch (AbortCompilation e) {
1160 //      } finally {
1161 //              if (scanner.recordLineSeparator) {
1162 //                      requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
1163 //              }
1164 //              diet = old;
1165 //      }
1166 //}
1167 //
1168 //public void parseTypeMemberDeclarations(
1169 //      char[] contents, 
1170 //      int start, 
1171 //      int end) {
1172 //
1173 //      boolean old = diet;
1174 //      
1175 //      try {
1176 //              diet = true;
1177 //
1178 //              /* automaton initialization */
1179 //              initialize();
1180 //              goForClassBodyDeclarations();
1181 //              /* scanner initialization */
1182 //              scanner.setSource(contents);
1183 //              scanner.recordLineSeparator = false;
1184 //              scanner.taskTags = null;
1185 //              scanner.taskPriorities = null;
1186 //              scanner.resetTo(start, end);
1187 //
1188 //              /* unit creation */
1189 //              referenceContext = null;
1190 //
1191 //              /* initialize the astStacl */
1192 //              // the compilationUnitDeclaration should contain exactly one type
1193 //              /* run automaton */
1194 //              parse();
1195 //              notifySourceElementRequestor((CompilationUnitDeclaration)null);
1196 //      } catch (AbortCompilation e) {
1197 //      } finally {
1198 //              diet = old;
1199 //      }
1200 //}
1201 /**
1202  * Sort the given ast nodes by their positions.
1203  */
1204 private static void quickSort(AstNode[] sortedCollection, int left, int right) {
1205         int original_left = left;
1206         int original_right = right;
1207         AstNode mid = sortedCollection[ (left + right) / 2];
1208         do {
1209                 while (sortedCollection[left].sourceStart < mid.sourceStart) {
1210                         left++;
1211                 }
1212                 while (mid.sourceStart < sortedCollection[right].sourceStart) {
1213                         right--;
1214                 }
1215                 if (left <= right) {
1216                         AstNode tmp = sortedCollection[left];
1217                         sortedCollection[left] = sortedCollection[right];
1218                         sortedCollection[right] = tmp;
1219                         left++;
1220                         right--;
1221                 }
1222         } while (left <= right);
1223         if (original_left < right) {
1224                 quickSort(sortedCollection, original_left, right);
1225         }
1226         if (left < original_right) {
1227                 quickSort(sortedCollection, left, original_right);
1228         }
1229 }
1230 /*
1231  * Answer a char array representation of the type name formatted like:
1232  * - type name + dimensions
1233  * Example:
1234  * "A[][]".toCharArray()
1235  * "java.lang.String".toCharArray()
1236  */
1237 private char[] returnTypeName(TypeReference type) {
1238         if (type == null)
1239                 return null;
1240         int dimension = type.dimensions();
1241         if (dimension != 0) {
1242                 char[] dimensionsArray = new char[dimension * 2];
1243                 for (int i = 0; i < dimension; i++) {
1244                         dimensionsArray[i * 2] = '[';
1245                         dimensionsArray[(i * 2) + 1] = ']';
1246                 }
1247                 return CharOperation.concat(
1248                         CharOperation.concatWith(type.getTypeName(), '.'), 
1249                         dimensionsArray); 
1250         }
1251         return CharOperation.concatWith(type.getTypeName(), '.');
1252 }
1253
1254 public void addUnknownRef(NameReference nameRef) {
1255         if (this.unknownRefs.length == this.unknownRefsCounter) {
1256                 // resize
1257                 System.arraycopy(
1258                         this.unknownRefs,
1259                         0,
1260                         (this.unknownRefs = new NameReference[this.unknownRefsCounter * 2]),
1261                         0,
1262                         this.unknownRefsCounter);
1263         }
1264         this.unknownRefs[this.unknownRefsCounter++] = nameRef;
1265 }
1266
1267 private void visitIfNeeded(AbstractMethodDeclaration method) {
1268         if (this.localDeclarationVisitor != null 
1269                 && (method.bits & AstNode.HasLocalTypeMASK) != 0) {
1270                         if (method.statements != null) {
1271                                 int statementsLength = method.statements.length;
1272                                 for (int i = 0; i < statementsLength; i++)
1273                                         method.statements[i].traverse(this.localDeclarationVisitor, method.scope);
1274                         }
1275         }
1276 }
1277
1278 //private void visitIfNeeded(FieldDeclaration field) {
1279 //      if (this.localDeclarationVisitor != null 
1280 //              && (field.bits & AstNode.HasLocalTypeMASK) != 0) {
1281 //                      if (field.initialization != null) {
1282 //                              field.initialization.traverse(this.localDeclarationVisitor, null);
1283 //                      }
1284 //      }
1285 //}
1286 //
1287 //private void visitIfNeeded(Initializer initializer) {
1288 //      if (this.localDeclarationVisitor != null 
1289 //              && (initializer.bits & AstNode.HasLocalTypeMASK) != 0) {
1290 //                      if (initializer.block != null) {
1291 //                              initializer.block.traverse(this.localDeclarationVisitor, null);
1292 //                      }
1293 //      }
1294 //}
1295 //
1296 //protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
1297 //      if (compilationUnit == null) return;
1298 //      super.reportSyntaxError(act, currentKind,stateStackTop);
1299 //}
1300
1301 }