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