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