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