KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > SourceElementParser


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15
16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17 import org.eclipse.jdt.internal.compiler.env.*;
18 import org.eclipse.jdt.internal.compiler.impl.*;
19 import org.eclipse.jdt.core.compiler.*;
20 import org.eclipse.jdt.internal.compiler.ast.*;
21 import org.eclipse.jdt.internal.compiler.lookup.*;
22 import org.eclipse.jdt.internal.compiler.parser.*;
23 import org.eclipse.jdt.internal.compiler.problem.*;
24 import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
25 import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
26
27 /**
28  * A source element parser extracts structural and reference information
29  * from a piece of source.
30  *
31  * also see @ISourceElementRequestor
32  *
33  * The structural investigation includes:
34  * - the package statement
35  * - import statements
36  * - top-level types: package member, member types (member types of member types...)
37  * - fields
38  * - methods
39  *
40  * If reference information is requested, then all source constructs are
41  * investigated and type, field & method references are provided as well.
42  *
43  * Any (parsing) problem encountered is also provided.
44  */

45 public class SourceElementParser extends CommentRecorderParser {
46     
47     public ISourceElementRequestor requestor;
48     ISourceType sourceType;
49     boolean reportReferenceInfo;
50     char[][] typeNames;
51     char[][] superTypeNames;
52     int nestedTypeIndex;
53     LocalDeclarationVisitor localDeclarationVisitor = null;
54     CompilerOptions options;
55     HashtableOfObjectToInt sourceEnds = new HashtableOfObjectToInt();
56     HashMap JavaDoc nodesToCategories = new HashMap JavaDoc(); // a map from ASTNode to char[][]
57
boolean useSourceJavadocParser = true;
58     
59 /**
60  * An ast visitor that visits local type declarations.
61  */

62 public class LocalDeclarationVisitor extends ASTVisitor {
63     ArrayList JavaDoc declaringTypes;
64     public void pushDeclaringType(TypeDeclaration declaringType) {
65         if (this.declaringTypes == null) {
66             this.declaringTypes = new ArrayList JavaDoc();
67         }
68         this.declaringTypes.add(declaringType);
69     }
70     public void popDeclaringType() {
71         this.declaringTypes.remove(this.declaringTypes.size()-1);
72     }
73     public TypeDeclaration peekDeclaringType() {
74         if (this.declaringTypes == null) return null;
75         int size = this.declaringTypes.size();
76         if (size == 0) return null;
77         return (TypeDeclaration) this.declaringTypes.get(size-1);
78     }
79     public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
80         notifySourceElementRequestor(typeDeclaration, sourceType == null, peekDeclaringType());
81         return false; // don't visit members as this was done during notifySourceElementRequestor(...)
82
}
83     public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
84         notifySourceElementRequestor(typeDeclaration, sourceType == null, peekDeclaringType());
85         return false; // don't visit members as this was done during notifySourceElementRequestor(...)
86
}
87 }
88
89 public SourceElementParser(
90         final ISourceElementRequestor requestor,
91         IProblemFactory problemFactory,
92         CompilerOptions options,
93         boolean reportLocalDeclarations,
94         boolean optimizeStringLiterals) {
95     this(requestor, problemFactory, options, reportLocalDeclarations, optimizeStringLiterals, true/* use SourceJavadocParser */);
96 }
97
98 public SourceElementParser(
99         ISourceElementRequestor requestor,
100         IProblemFactory problemFactory,
101         CompilerOptions options,
102         boolean reportLocalDeclarations,
103         boolean optimizeStringLiterals,
104         boolean useSourceJavadocParser) {
105     
106     super(
107         new ProblemReporter(
108             DefaultErrorHandlingPolicies.exitAfterAllProblems(),
109             options,
110             problemFactory),
111         optimizeStringLiterals);
112     
113     // we want to notify all syntax error with the acceptProblem API
114
// To do so, we define the record method of the ProblemReporter
115
this.problemReporter = new ProblemReporter(
116         DefaultErrorHandlingPolicies.exitAfterAllProblems(),
117         options,
118         problemFactory) {
119         public void record(CategorizedProblem problem, CompilationResult unitResult, ReferenceContext context) {
120             unitResult.record(problem, context); // TODO (jerome) clients are trapping problems either through factory or requestor... is result storing needed?
121
SourceElementParser.this.requestor.acceptProblem(problem);
122         }
123     };
124     this.requestor = requestor;
125     typeNames = new char[4][];
126     superTypeNames = new char[4][];
127     nestedTypeIndex = 0;
128     this.options = options;
129     if (reportLocalDeclarations) {
130         this.localDeclarationVisitor = new LocalDeclarationVisitor();
131     }
132     // set specific javadoc parser
133
this.useSourceJavadocParser = useSourceJavadocParser;
134     if (useSourceJavadocParser) {
135         this.javadocParser = new SourceJavadocParser(this);
136     }
137 }
138 private void acceptJavadocTypeReference(Expression expression) {
139     if (expression instanceof JavadocSingleTypeReference) {
140         JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) expression;
141         this.requestor.acceptTypeReference(singleRef.token, singleRef.sourceStart);
142     } else if (expression instanceof JavadocQualifiedTypeReference) {
143         JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) expression;
144         this.requestor.acceptTypeReference(qualifiedRef.tokens, qualifiedRef.sourceStart, qualifiedRef.sourceEnd);
145     }
146 }
147 public void addUnknownRef(NameReference nameRef) {
148     // Note that:
149
// - the only requestor interested in references is the SourceIndexerRequestor
150
// - a name reference can become a type reference only during the cast case, it is then tagged later with the Binding.TYPE bit
151
// However since the indexer doesn't make the distinction between name reference and type reference, there is no need
152
// to report a type reference in the SourceElementParser.
153
// This gained 3.7% in the indexing performance test.
154
if (nameRef instanceof SingleNameReference) {
155         requestor.acceptUnknownReference(((SingleNameReference) nameRef).token, nameRef.sourceStart);
156     } else {
157         //QualifiedNameReference
158
requestor.acceptUnknownReference(((QualifiedNameReference) nameRef).tokens, nameRef.sourceStart, nameRef.sourceEnd);
159     }
160 }
161 public void checkComment() {
162     // discard obsolete comments while inside methods or fields initializer (see bug 74369)
163
if (!(this.diet && this.dietInt==0) && this.scanner.commentPtr >= 0) {
164         flushCommentsDefinedPriorTo(this.endStatementPosition);
165     }
166     
167     int lastComment = this.scanner.commentPtr;
168     
169     if (this.modifiersSourceStart >= 0) {
170         // eliminate comments located after modifierSourceStart if positionned
171
while (lastComment >= 0 && Math.abs(this.scanner.commentStarts[lastComment]) > this.modifiersSourceStart) lastComment--;
172     }
173     if (lastComment >= 0) {
174         // consider all remaining leading comments to be part of current declaration
175
this.modifiersSourceStart = Math.abs(this.scanner.commentStarts[0]);
176     
177         // check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)
178
while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
179
if (lastComment >= 0 && this.javadocParser != null) {
180             int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over,
181
// do not report problem before last parsed comment while recovering code...
182
this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
183             if (this.javadocParser.checkDeprecation(lastComment)) {
184                 checkAndSetModifiers(ClassFileConstants.AccDeprecated);
185             }
186             this.javadoc = this.javadocParser.docComment; // null if check javadoc is not activated
187
if (currentElement == null) this.lastJavadocEnd = commentEnd;
188         }
189     }
190
191     if (this.reportReferenceInfo && this.javadocParser.checkDocComment && this.javadoc != null) {
192         // Report reference info in javadoc comment @throws/@exception tags
193
TypeReference[] thrownExceptions = this.javadoc.exceptionReferences;
194         if (thrownExceptions != null) {
195             for (int i = 0, max=thrownExceptions.length; i < max; i++) {
196                 TypeReference typeRef = thrownExceptions[i];
197                 if (typeRef instanceof JavadocSingleTypeReference) {
198                     JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
199                     this.requestor.acceptTypeReference(singleRef.token, singleRef.sourceStart);
200                 } else if (typeRef instanceof JavadocQualifiedTypeReference) {
201                     JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) typeRef;
202                     this.requestor.acceptTypeReference(qualifiedRef.tokens, qualifiedRef.sourceStart, qualifiedRef.sourceEnd);
203                 }
204             }
205         }
206
207         // Report reference info in javadoc comment @see tags
208
Expression[] references = this.javadoc.seeReferences;
209         if (references != null) {
210             for (int i = 0, max=references.length; i < max; i++) {
211                 Expression reference = references[i];
212                 acceptJavadocTypeReference(reference);
213                 if (reference instanceof JavadocFieldReference) {
214                     JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
215                     this.requestor.acceptFieldReference(fieldRef.token, fieldRef.sourceStart);
216                     if (fieldRef.receiver != null && !fieldRef.receiver.isThis()) {
217                         acceptJavadocTypeReference(fieldRef.receiver);
218                     }
219                 } else if (reference instanceof JavadocMessageSend) {
220                     JavadocMessageSend messageSend = (JavadocMessageSend) reference;
221                     int argCount = messageSend.arguments == null ? 0 : messageSend.arguments.length;
222                     this.requestor.acceptMethodReference(messageSend.selector, argCount, messageSend.sourceStart);
223                     this.requestor.acceptConstructorReference(messageSend.selector, argCount, messageSend.sourceStart);
224                     if (messageSend.receiver != null && !messageSend.receiver.isThis()) {
225                         acceptJavadocTypeReference(messageSend.receiver);
226                     }
227                 } else if (reference instanceof JavadocAllocationExpression) {
228                     JavadocAllocationExpression constructor = (JavadocAllocationExpression) reference;
229                     int argCount = constructor.arguments == null ? 0 : constructor.arguments.length;
230                     if (constructor.type != null) {
231                         char[][] compoundName = constructor.type.getParameterizedTypeName();
232                         this.requestor.acceptConstructorReference(compoundName[compoundName.length-1], argCount, constructor.sourceStart);
233                         if (!constructor.type.isThis()) {
234                             acceptJavadocTypeReference(constructor.type);
235                         }
236                     }
237                 }
238             }
239         }
240     }
241 }
242 protected void classInstanceCreation(boolean alwaysQualified) {
243
244     boolean previousFlag = reportReferenceInfo;
245     reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
246
super.classInstanceCreation(alwaysQualified);
247     reportReferenceInfo = previousFlag;
248     if (reportReferenceInfo){
249         AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
250         TypeReference typeRef = alloc.type;
251         requestor.acceptConstructorReference(
252             typeRef instanceof SingleTypeReference
253                 ? ((SingleTypeReference) typeRef).token
254                 : CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
255             alloc.arguments == null ? 0 : alloc.arguments.length,
256             alloc.sourceStart);
257     }
258 }
259 private long[] collectAnnotationPositions(Annotation[] annotations) {
260     if (annotations == null) return null;
261     int length = annotations.length;
262     long[] result = new long[length];
263     for (int i = 0; i < length; i++) {
264         Annotation annotation = annotations[i];
265         result[i] = (((long) annotation.sourceStart) << 32) + annotation.declarationSourceEnd;
266     }
267     return result;
268 }
269 protected void consumeAnnotationAsModifier() {
270     super.consumeAnnotationAsModifier();
271     Annotation annotation = (Annotation)expressionStack[expressionPtr];
272     if (reportReferenceInfo) { // accept annotation type reference
273
this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
274     }
275 }
276 protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
277     boolean previousFlag = reportReferenceInfo;
278     reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
279
super.consumeClassInstanceCreationExpressionQualifiedWithTypeArguments();
280     reportReferenceInfo = previousFlag;
281     if (reportReferenceInfo){
282         AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
283         TypeReference typeRef = alloc.type;
284         requestor.acceptConstructorReference(
285             typeRef instanceof SingleTypeReference
286                 ? ((SingleTypeReference) typeRef).token
287                 : CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
288             alloc.arguments == null ? 0 : alloc.arguments.length,
289             alloc.sourceStart);
290     }
291 }
292 protected void consumeAnnotationTypeDeclarationHeaderName() {
293     int currentAstPtr = this.astPtr;
294     super.consumeAnnotationTypeDeclarationHeaderName();
295     if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
296
rememberCategories();
297 }
298 protected void consumeClassHeaderName1() {
299     int currentAstPtr = this.astPtr;
300     super.consumeClassHeaderName1();
301     if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
302
rememberCategories();
303 }
304 protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
305     boolean previousFlag = reportReferenceInfo;
306     reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
307
super.consumeClassInstanceCreationExpressionWithTypeArguments();
308     reportReferenceInfo = previousFlag;
309     if (reportReferenceInfo){
310         AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
311         TypeReference typeRef = alloc.type;
312         requestor.acceptConstructorReference(
313             typeRef instanceof SingleTypeReference
314                 ? ((SingleTypeReference) typeRef).token
315                 : CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
316             alloc.arguments == null ? 0 : alloc.arguments.length,
317             alloc.sourceStart);
318     }
319 }
320 protected void consumeConstructorHeaderName() {
321     long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
322     int selectorSourceEnd = (int) selectorSourcePositions;
323     int currentAstPtr = this.astPtr;
324     super.consumeConstructorHeaderName();
325     if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
326
this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
327         rememberCategories();
328     }
329 }
330 protected void consumeConstructorHeaderNameWithTypeParameters() {
331     long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
332     int selectorSourceEnd = (int) selectorSourcePositions;
333     int currentAstPtr = this.astPtr;
334     super.consumeConstructorHeaderNameWithTypeParameters();
335     if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
336
this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
337         rememberCategories();
338     }
339 }
340 protected void consumeEnumConstantWithClassBody() {
341     super.consumeEnumConstantWithClassBody();
342     if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
343             && astStack[astPtr] instanceof FieldDeclaration) {
344         this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
345         rememberCategories();
346     }
347 }
348 protected void consumeEnumConstantNoClassBody() {
349     super.consumeEnumConstantNoClassBody();
350     if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
351             && this.astStack[this.astPtr] instanceof FieldDeclaration) {
352         this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
353         rememberCategories();
354     }
355 }
356 protected void consumeEnumHeaderName() {
357     int currentAstPtr = this.astPtr;
358     super.consumeEnumHeaderName();
359     if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
360
rememberCategories();
361 }
362 protected void consumeExitVariableWithInitialization() {
363     // ExitVariableWithInitialization ::= $empty
364
// the scanner is located after the comma or the semi-colon.
365
// we want to include the comma or the semi-colon
366
super.consumeExitVariableWithInitialization();
367     if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
368             && this.astStack[this.astPtr] instanceof FieldDeclaration) {
369         this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
370         rememberCategories();
371     }
372 }
373 protected void consumeExitVariableWithoutInitialization() {
374     // ExitVariableWithoutInitialization ::= $empty
375
// do nothing by default
376
super.consumeExitVariableWithoutInitialization();
377     if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
378             && astStack[astPtr] instanceof FieldDeclaration) {
379         this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
380         rememberCategories();
381     }
382 }
383 /*
384  *
385  * INTERNAL USE-ONLY
386  */

387 protected void consumeFieldAccess(boolean isSuperAccess) {
388     // FieldAccess ::= Primary '.' 'Identifier'
389
// FieldAccess ::= 'super' '.' 'Identifier'
390
super.consumeFieldAccess(isSuperAccess);
391     FieldReference fr = (FieldReference) expressionStack[expressionPtr];
392     if (reportReferenceInfo) {
393         requestor.acceptFieldReference(fr.token, fr.sourceStart);
394     }
395 }
396 protected void consumeFormalParameter(boolean isVarArgs) {
397     super.consumeFormalParameter(isVarArgs);
398     
399     // Flush comments prior to this formal parameter so the declarationSourceStart of the following parameter
400
// is correctly set (see bug 80904)
401
// Note that this could be done in the Parser itself, but this would slow down all parsers, when they don't need
402
// the declarationSourceStart to be set
403
flushCommentsDefinedPriorTo(this.scanner.currentPosition);
404 }
405 protected void consumeInterfaceHeaderName1() {
406     int currentAstPtr = this.astPtr;
407     super.consumeInterfaceHeaderName1();
408     if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
409
rememberCategories();
410 }
411 protected void consumeMemberValuePair() {
412     super.consumeMemberValuePair();
413     MemberValuePair memberValuepair = (MemberValuePair) this.astStack[this.astPtr];
414     if (reportReferenceInfo) {
415         requestor.acceptMethodReference(memberValuepair.name, 0, memberValuepair.sourceStart);
416     }
417 }
418 protected void consumeMarkerAnnotation() {
419     super.consumeMarkerAnnotation();
420     Annotation annotation = (Annotation)expressionStack[expressionPtr];
421     if (reportReferenceInfo) { // accept annotation type reference
422
this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
423     }
424 }
425 protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
426     long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
427     int selectorSourceEnd = (int) selectorSourcePositions;
428     int currentAstPtr = this.astPtr;
429     super.consumeMethodHeaderName(isAnnotationMethod);
430     if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
431
this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
432         rememberCategories();
433     }
434 }
435
436 protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) {
437     long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
438     int selectorSourceEnd = (int) selectorSourcePositions;
439     int currentAstPtr = this.astPtr;
440     super.consumeMethodHeaderNameWithTypeParameters(isAnnotationMethod);
441     if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
442
this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
443         rememberCategories();
444 }
445 /*
446  *
447  * INTERNAL USE-ONLY
448  */

449 protected void consumeMethodInvocationName() {
450     // MethodInvocation ::= Name '(' ArgumentListopt ')'
451
super.consumeMethodInvocationName();
452
453     // when the name is only an identifier...we have a message send to "this" (implicit)
454
MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
455     Expression[] args = messageSend.arguments;
456     if (reportReferenceInfo) {
457         requestor.acceptMethodReference(
458             messageSend.selector,
459             args == null ? 0 : args.length,
460             (int)(messageSend.nameSourcePosition >>> 32));
461     }
462 }
463 protected void consumeMethodInvocationNameWithTypeArguments() {
464     // MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
465
super.consumeMethodInvocationNameWithTypeArguments();
466
467     // when the name is only an identifier...we have a message send to "this" (implicit)
468
MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
469     Expression[] args = messageSend.arguments;
470     if (reportReferenceInfo) {
471         requestor.acceptMethodReference(
472             messageSend.selector,
473             args == null ? 0 : args.length,
474             (int)(messageSend.nameSourcePosition >>> 32));
475     }
476 }
477 /*
478  *
479  * INTERNAL USE-ONLY
480  */

481 protected void consumeMethodInvocationPrimary() {
482     super.consumeMethodInvocationPrimary();
483     MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
484     Expression[] args = messageSend.arguments;
485     if (reportReferenceInfo) {
486         requestor.acceptMethodReference(
487             messageSend.selector,
488             args == null ? 0 : args.length,
489             (int)(messageSend.nameSourcePosition >>> 32));
490     }
491 }
492 /*
493  *
494  * INTERNAL USE-ONLY
495  */

496 protected void consumeMethodInvocationPrimaryWithTypeArguments() {
497     super.consumeMethodInvocationPrimaryWithTypeArguments();
498     MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
499     Expression[] args = messageSend.arguments;
500     if (reportReferenceInfo) {
501         requestor.acceptMethodReference(
502             messageSend.selector,
503             args == null ? 0 : args.length,
504             (int)(messageSend.nameSourcePosition >>> 32));
505     }
506 }
507 /*
508  *
509  * INTERNAL USE-ONLY
510  */

511 protected void consumeMethodInvocationSuper() {
512     // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
513
super.consumeMethodInvocationSuper();
514     MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
515     Expression[] args = messageSend.arguments;
516     if (reportReferenceInfo) {
517         requestor.acceptMethodReference(
518             messageSend.selector,
519             args == null ? 0 : args.length,
520             (int)(messageSend.nameSourcePosition >>> 32));
521     }
522 }
523 protected void consumeMethodInvocationSuperWithTypeArguments() {
524     // MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
525
super.consumeMethodInvocationSuperWithTypeArguments();
526     MessageSend messageSend = (MessageSend) expressionStack[expressionPtr];
527     Expression[] args = messageSend.arguments;
528     if (reportReferenceInfo) {
529         requestor.acceptMethodReference(
530             messageSend.selector,
531             args == null ? 0 : args.length,
532             (int)(messageSend.nameSourcePosition >>> 32));
533     }
534 }
535 protected void consumeNormalAnnotation() {
536     super.consumeNormalAnnotation();
537     Annotation annotation = (Annotation)expressionStack[expressionPtr];
538     if (reportReferenceInfo) { // accept annotation type reference
539
this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
540     }
541 }
542 protected void consumeSingleMemberAnnotation() {
543     super.consumeSingleMemberAnnotation();
544     SingleMemberAnnotation member = (SingleMemberAnnotation) expressionStack[expressionPtr];
545     if (reportReferenceInfo) {
546         requestor.acceptMethodReference(TypeConstants.VALUE, 0, member.sourceStart);
547     }
548 }
549 protected void consumeSingleStaticImportDeclarationName() {
550     // SingleTypeImportDeclarationName ::= 'import' 'static' Name
551
ImportReference impt;
552     int length;
553     char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
554     this.identifierPtr -= length;
555     long[] positions = new long[length];
556     System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
557     System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
558     pushOnAstStack(impt = newImportReference(tokens, positions, false, ClassFileConstants.AccStatic));
559     
560     this.modifiers = ClassFileConstants.AccDefault;
561     this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
562

563     if (this.currentToken == TokenNameSEMICOLON){
564         impt.declarationSourceEnd = this.scanner.currentPosition - 1;
565     } else {
566         impt.declarationSourceEnd = impt.sourceEnd;
567     }
568     impt.declarationEnd = impt.declarationSourceEnd;
569     //this.endPosition is just before the ;
570
impt.declarationSourceStart = this.intStack[this.intPtr--];
571     
572     if(!this.statementRecoveryActivated &&
573             this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
574             this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
575         impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
576
this.problemReporter().invalidUsageOfStaticImports(impt);
577     }
578     
579     // recovery
580
if (this.currentElement != null){
581         this.lastCheckPoint = impt.declarationSourceEnd+1;
582         this.currentElement = this.currentElement.add(impt, 0);
583         this.lastIgnoredToken = -1;
584         this.restartRecovery = true; // used to avoid branching back into the regular automaton
585
}
586     if (reportReferenceInfo) {
587         // Name for static import is TypeName '.' Identifier
588
// => accept unknown ref on identifier
589
int tokensLength = impt.tokens.length-1;
590         int start = (int) (impt.sourcePositions[tokensLength] >>> 32);
591         char[] last = impt.tokens[tokensLength];
592         // accept all possible kind for last name, index users will have to select the right one...
593
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=86901
594
requestor.acceptFieldReference(last, start);
595         requestor.acceptMethodReference(last, 0,start);
596         requestor.acceptTypeReference(last, start);
597         // accept type name
598
if (tokensLength > 0) {
599             char[][] compoundName = new char[tokensLength][];
600             System.arraycopy(impt.tokens, 0, compoundName, 0, tokensLength);
601             int end = (int) impt.sourcePositions[tokensLength-1];
602             requestor.acceptTypeReference(compoundName, impt.sourceStart, end);
603         }
604     }
605 }
606
607 protected void consumeSingleTypeImportDeclarationName() {
608     // SingleTypeImportDeclarationName ::= 'import' Name
609
/* push an ImportRef build from the last name
610     stored in the identifier stack. */

611
612     ImportReference impt;
613     int length;
614     char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
615     this.identifierPtr -= length;
616     long[] positions = new long[length];
617     System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
618     System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
619     pushOnAstStack(impt = newImportReference(tokens, positions, false, ClassFileConstants.AccDefault));
620     
621     if (this.currentToken == TokenNameSEMICOLON){
622         impt.declarationSourceEnd = this.scanner.currentPosition - 1;
623     } else {
624         impt.declarationSourceEnd = impt.sourceEnd;
625     }
626     impt.declarationEnd = impt.declarationSourceEnd;
627     //this.endPosition is just before the ;
628
impt.declarationSourceStart = this.intStack[this.intPtr--];
629     
630     // recovery
631
if (this.currentElement != null){
632         this.lastCheckPoint = impt.declarationSourceEnd+1;
633         this.currentElement = this.currentElement.add(impt, 0);
634         this.lastIgnoredToken = -1;
635         this.restartRecovery = true; // used to avoid branching back into the regular automaton
636
}
637     if (reportReferenceInfo) {
638         requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
639     }
640 }
641 protected void consumeStaticImportOnDemandDeclarationName() {
642     // TypeImportOnDemandDeclarationName ::= 'import' 'static' Name '.' '*'
643
/* push an ImportRef build from the last name
644     stored in the identifier stack. */

645
646     ImportReference impt;
647     int length;
648     char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
649     this.identifierPtr -= length;
650     long[] positions = new long[length];
651     System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
652     System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
653     pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccStatic));
654     
655     this.modifiers = ClassFileConstants.AccDefault;
656     this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
657

658     if (this.currentToken == TokenNameSEMICOLON){
659         impt.declarationSourceEnd = this.scanner.currentPosition - 1;
660     } else {
661         impt.declarationSourceEnd = impt.sourceEnd;
662     }
663     impt.declarationEnd = impt.declarationSourceEnd;
664     //this.endPosition is just before the ;
665
impt.declarationSourceStart = this.intStack[this.intPtr--];
666     
667     if(!this.statementRecoveryActivated &&
668             options.sourceLevel < ClassFileConstants.JDK1_5 &&
669             this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
670         impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
671
this.problemReporter().invalidUsageOfStaticImports(impt);
672     }
673     
674     // recovery
675
if (this.currentElement != null){
676         this.lastCheckPoint = impt.declarationSourceEnd+1;
677         this.currentElement = this.currentElement.add(impt, 0);
678         this.lastIgnoredToken = -1;
679         this.restartRecovery = true; // used to avoid branching back into the regular automaton
680
}
681     if (reportReferenceInfo) {
682         requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
683     }
684 }
685 protected void consumeTypeImportOnDemandDeclarationName() {
686     // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
687
/* push an ImportRef build from the last name
688     stored in the identifier stack. */

689
690     ImportReference impt;
691     int length;
692     char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
693     this.identifierPtr -= length;
694     long[] positions = new long[length];
695     System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
696     System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
697     pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccDefault));
698     
699     if (this.currentToken == TokenNameSEMICOLON){
700         impt.declarationSourceEnd = this.scanner.currentPosition - 1;
701     } else {
702         impt.declarationSourceEnd = impt.sourceEnd;
703     }
704     impt.declarationEnd = impt.declarationSourceEnd;
705     //this.endPosition is just before the ;
706
impt.declarationSourceStart = this.intStack[this.intPtr--];
707     
708     // recovery
709
if (this.currentElement != null){
710         this.lastCheckPoint = impt.declarationSourceEnd+1;
711         this.currentElement = this.currentElement.add(impt, 0);
712         this.lastIgnoredToken = -1;
713         this.restartRecovery = true; // used to avoid branching back into the regular automaton
714
}
715     if (reportReferenceInfo) {
716         requestor.acceptUnknownReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
717     }
718 }
719 public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
720     MethodDeclaration methodDeclaration = super.convertToMethodDeclaration(c, compilationResult);
721     int selectorSourceEnd = this.sourceEnds.removeKey(c);
722     if (selectorSourceEnd != -1)
723         this.sourceEnds.put(methodDeclaration, selectorSourceEnd);
724     char[][] categories = (char[][]) this.nodesToCategories.remove(c);
725     if (categories != null)
726         this.nodesToCategories.put(methodDeclaration, categories);
727     
728     return methodDeclaration;
729 }
730 protected CompilationUnitDeclaration endParse(int act) {
731     if (sourceType != null) {
732         switch (TypeDeclaration.kind(sourceType.getModifiers())) {
733             case TypeDeclaration.CLASS_DECL :
734                 consumeClassDeclaration();
735                 break;
736             case TypeDeclaration.INTERFACE_DECL :
737                 consumeInterfaceDeclaration();
738                 break;
739             case TypeDeclaration.ENUM_DECL :
740                 consumeEnumDeclaration();
741                 break;
742             case TypeDeclaration.ANNOTATION_TYPE_DECL :
743                 consumeAnnotationTypeDeclaration();
744                 break;
745         }
746     }
747     if (compilationUnit != null) {
748         CompilationUnitDeclaration result = super.endParse(act);
749         return result;
750     } else {
751         return null;
752     }
753 }
754 private ISourceElementRequestor.TypeParameterInfo[] getTypeParameterInfos(TypeParameter[] typeParameters) {
755     if (typeParameters == null) return null;
756     int typeParametersLength = typeParameters.length;
757     ISourceElementRequestor.TypeParameterInfo[] result = new ISourceElementRequestor.TypeParameterInfo[typeParametersLength];
758     for (int i = 0; i < typeParametersLength; i++) {
759         TypeParameter typeParameter = typeParameters[i];
760         TypeReference firstBound = typeParameter.type;
761         TypeReference[] otherBounds = typeParameter.bounds;
762         char[][] typeParameterBounds = null;
763         if (firstBound != null) {
764             if (otherBounds != null) {
765                 int otherBoundsLength = otherBounds.length;
766                 char[][] boundNames = new char[otherBoundsLength+1][];
767                 boundNames[0] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.');
768                 for (int j = 0; j < otherBoundsLength; j++) {
769                     boundNames[j+1] =
770                         CharOperation.concatWith(otherBounds[j].getParameterizedTypeName(), '.');
771                 }
772                 typeParameterBounds = boundNames;
773             } else {
774                 typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')};
775             }
776         } else {
777             typeParameterBounds = CharOperation.NO_CHAR_CHAR;
778         }
779         ISourceElementRequestor.TypeParameterInfo typeParameterInfo = new ISourceElementRequestor.TypeParameterInfo();
780         typeParameterInfo.declarationStart = typeParameter.declarationSourceStart;
781         typeParameterInfo.declarationEnd = typeParameter.declarationSourceEnd;
782         typeParameterInfo.name = typeParameter.name;
783         typeParameterInfo.nameSourceStart = typeParameter.sourceStart;
784         typeParameterInfo.nameSourceEnd = typeParameter.sourceEnd;
785         typeParameterInfo.bounds = typeParameterBounds;
786         result[i] = typeParameterInfo;
787     }
788     return result;
789 }
790 public TypeReference getTypeReference(int dim) {
791     /* build a Reference on a variable that may be qualified or not
792      * This variable is a type reference and dim will be its dimensions
793      */

794     int length = identifierLengthStack[identifierLengthPtr--];
795     if (length < 0) { //flag for precompiled type reference on base types
796
TypeReference ref = TypeReference.baseTypeReference(-length, dim);
797         ref.sourceStart = intStack[intPtr--];
798         if (dim == 0) {
799             ref.sourceEnd = intStack[intPtr--];
800         } else {
801             intPtr--; // no need to use this position as it is an array
802
ref.sourceEnd = endPosition;
803         }
804         if (reportReferenceInfo){
805                 requestor.acceptTypeReference(ref.getParameterizedTypeName(), ref.sourceStart, ref.sourceEnd);
806         }
807         return ref;
808     } else {
809         int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--];
810         if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
811             // generic type
812
TypeReference ref = getTypeReferenceForGenericType(dim, length, numberOfIdentifiers);
813             if (reportReferenceInfo) {
814                 if (length == 1 && numberOfIdentifiers == 1) {
815                     ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) ref;
816                     requestor.acceptTypeReference(parameterizedSingleTypeReference.token, parameterizedSingleTypeReference.sourceStart);
817                 } else {
818                     ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) ref;
819                     requestor.acceptTypeReference(parameterizedQualifiedTypeReference.tokens, parameterizedQualifiedTypeReference.sourceStart, parameterizedQualifiedTypeReference.sourceEnd);
820                 }
821             }
822             return ref;
823         } else if (length == 1) {
824             // single variable reference
825
this.genericsLengthPtr--; // pop the 0
826
if (dim == 0) {
827                 SingleTypeReference ref =
828                     new SingleTypeReference(
829                         identifierStack[identifierPtr],
830                         identifierPositionStack[identifierPtr--]);
831                 if (reportReferenceInfo) {
832                     requestor.acceptTypeReference(ref.token, ref.sourceStart);
833                 }
834                 return ref;
835             } else {
836                 ArrayTypeReference ref =
837                     new ArrayTypeReference(
838                         identifierStack[identifierPtr],
839                         dim,
840                         identifierPositionStack[identifierPtr--]);
841                 ref.sourceEnd = endPosition;
842                 if (reportReferenceInfo) {
843                     requestor.acceptTypeReference(ref.token, ref.sourceStart);
844                 }
845                 return ref;
846             }
847         } else {//Qualified variable reference
848
this.genericsLengthPtr--;
849             char[][] tokens = new char[length][];
850             identifierPtr -= length;
851             long[] positions = new long[length];
852             System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
853             System.arraycopy(
854                 identifierPositionStack,
855                 identifierPtr + 1,
856                 positions,
857                 0,
858                 length);
859             if (dim == 0) {
860                 QualifiedTypeReference ref = new QualifiedTypeReference(tokens, positions);
861                 if (reportReferenceInfo) {
862                     requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
863                 }
864                 return ref;
865             } else {
866                 ArrayQualifiedTypeReference ref =
867                     new ArrayQualifiedTypeReference(tokens, dim, positions);
868                 ref.sourceEnd = endPosition;
869                 if (reportReferenceInfo) {
870                     requestor.acceptTypeReference(ref.tokens, ref.sourceStart, ref.sourceEnd);
871                 }
872                 return ref;
873             }
874         }
875     }
876 }
877 public NameReference getUnspecifiedReference() {
878     /* build a (unspecified) NameReference which may be qualified*/
879
880     int length;
881     if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
882         // single variable reference
883
SingleNameReference ref =
884             newSingleNameReference(
885                 identifierStack[identifierPtr],
886                 identifierPositionStack[identifierPtr--]);
887         if (reportReferenceInfo) {
888             this.addUnknownRef(ref);
889         }
890         return ref;
891     } else {
892         //Qualified variable reference
893
char[][] tokens = new char[length][];
894         identifierPtr -= length;
895         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
896         long[] positions = new long[length];
897         System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
898         QualifiedNameReference ref =
899             newQualifiedNameReference(
900                 tokens,
901                 positions,
902                 (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
903
(int) identifierPositionStack[identifierPtr + length]); // sourceEnd
904
if (reportReferenceInfo) {
905             this.addUnknownRef(ref);
906         }
907         return ref;
908     }
909 }
910 public NameReference getUnspecifiedReferenceOptimized() {
911     /* build a (unspecified) NameReference which may be qualified
912     The optimization occurs for qualified reference while we are
913     certain in this case the last item of the qualified name is
914     a field access. This optimization is IMPORTANT while it results
915     that when a NameReference is build, the type checker should always
916     look for that it is not a type reference */

917
918     int length;
919     if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
920         // single variable reference
921
SingleNameReference ref =
922             newSingleNameReference(
923                 identifierStack[identifierPtr],
924                 identifierPositionStack[identifierPtr--]);
925         ref.bits &= ~ASTNode.RestrictiveFlagMASK;
926         ref.bits |= Binding.LOCAL | Binding.FIELD;
927         if (reportReferenceInfo) {
928             this.addUnknownRef(ref);
929         }
930         return ref;
931     }
932
933     //Qualified-variable-reference
934
//In fact it is variable-reference DOT field-ref , but it would result in a type
935
//conflict tha can be only reduce by making a superclass (or inetrface ) between
936
//nameReference and FiledReference or putting FieldReference under NameReference
937
//or else..........This optimisation is not really relevant so just leave as it is
938

939     char[][] tokens = new char[length][];
940     identifierPtr -= length;
941     System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
942     long[] positions = new long[length];
943     System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
944     QualifiedNameReference ref =
945         newQualifiedNameReference(
946             tokens,
947             positions,
948             (int) (identifierPositionStack[identifierPtr + 1] >> 32),
949     // sourceStart
950
(int) identifierPositionStack[identifierPtr + length]); // sourceEnd
951
ref.bits &= ~ASTNode.RestrictiveFlagMASK;
952     ref.bits |= Binding.LOCAL | Binding.FIELD;
953     if (reportReferenceInfo) {
954         this.addUnknownRef(ref);
955     }
956     return ref;
957 }
958
959 /*
960  * Checks whether one of the annotations is the @Deprecated annotation
961  * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807)
962  */

963 private boolean hasDeprecatedAnnotation(Annotation[] annotations) {
964     if (annotations != null) {
965         for (int i = 0, length = annotations.length; i < length; i++) {
966             Annotation annotation = annotations[i];
967             if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) {
968                 return true;
969             }
970         }
971     }
972     return false;
973 }
974
975 protected ImportReference newImportReference(char[][] tokens, long[] positions, boolean onDemand, int mod) {
976     return new ImportReference(tokens, positions, onDemand, mod);
977 }
978 protected QualifiedNameReference newQualifiedNameReference(char[][] tokens, long[] positions, int sourceStart, int sourceEnd) {
979     return new QualifiedNameReference(tokens, positions, sourceStart, sourceEnd);
980 }
981 protected SingleNameReference newSingleNameReference(char[] source, long positions) {
982     return new SingleNameReference(source, positions);
983 }
984 /*
985  * Update the bodyStart of the corresponding parse node
986  */

987 public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit) {
988     if (parsedUnit == null) {
989         // when we parse a single type member declaration the compilation unit is null, but we still
990
// want to be able to notify the requestor on the created ast node
991
if (astStack[0] instanceof AbstractMethodDeclaration) {
992             notifySourceElementRequestor((AbstractMethodDeclaration) astStack[0]);
993             return;
994         }
995         return;
996     }
997     // range check
998
boolean isInRange =
999                 scanner.initialPosition <= parsedUnit.sourceStart
1000                && scanner.eofPosition >= parsedUnit.sourceEnd;
1001    
1002    // collect the top level ast nodes
1003
int length = 0;
1004    ASTNode[] nodes = null;
1005    if (sourceType == null){
1006        if (isInRange) {
1007            requestor.enterCompilationUnit();
1008        }
1009        ImportReference currentPackage = parsedUnit.currentPackage;
1010        ImportReference[] imports = parsedUnit.imports;
1011        TypeDeclaration[] types = parsedUnit.types;
1012        length =
1013            (currentPackage == null ? 0 : 1)
1014            + (imports == null ? 0 : imports.length)
1015            + (types == null ? 0 : types.length);
1016        nodes = new ASTNode[length];
1017        int index = 0;
1018        if (currentPackage != null) {
1019            nodes[index++] = currentPackage;
1020        }
1021        if (imports != null) {
1022            for (int i = 0, max = imports.length; i < max; i++) {
1023                nodes[index++] = imports[i];
1024            }
1025        }
1026        if (types != null) {
1027            for (int i = 0, max = types.length; i < max; i++) {
1028                nodes[index++] = types[i];
1029            }
1030        }
1031    } else {
1032        TypeDeclaration[] types = parsedUnit.types;
1033        if (types != null) {
1034            length = types.length;
1035            nodes = new ASTNode[length];
1036            for (int i = 0, max = types.length; i < max; i++) {
1037                nodes[i] = types[i];
1038            }
1039        }
1040    }
1041    
1042    // notify the nodes in the syntactical order
1043
if (nodes != null && length > 0) {
1044        quickSort(nodes, 0, length-1);
1045        for (int i=0;i<length;i++) {
1046            ASTNode node = nodes[i];
1047            if (node instanceof ImportReference) {
1048                ImportReference importRef = (ImportReference)node;
1049                if (node == parsedUnit.currentPackage) {
1050                    notifySourceElementRequestor(importRef, true);
1051                } else {
1052                    notifySourceElementRequestor(importRef, false);
1053                }
1054            } else { // instanceof TypeDeclaration
1055
notifySourceElementRequestor((TypeDeclaration)node, sourceType == null, null);
1056            }
1057        }
1058    }
1059    
1060    if (sourceType == null){
1061        if (isInRange) {
1062            requestor.exitCompilationUnit(parsedUnit.sourceEnd);
1063        }
1064    }
1065}
1066
1067/*
1068 * Update the bodyStart of the corresponding parse node
1069 */

1070public void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration) {
1071
1072    // range check
1073
boolean isInRange =
1074                scanner.initialPosition <= methodDeclaration.declarationSourceStart
1075                && scanner.eofPosition >= methodDeclaration.declarationSourceEnd;
1076
1077    if (methodDeclaration.isClinit()) {
1078        this.visitIfNeeded(methodDeclaration);
1079        return;
1080    }
1081
1082    if (methodDeclaration.isDefaultConstructor()) {
1083        if (reportReferenceInfo) {
1084            ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
1085            ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
1086            if (constructorCall != null) {
1087                switch(constructorCall.accessMode) {
1088                    case ExplicitConstructorCall.This :
1089                        requestor.acceptConstructorReference(
1090                            typeNames[nestedTypeIndex-1],
1091                            constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
1092                            constructorCall.sourceStart);
1093                        break;
1094                    case ExplicitConstructorCall.Super :
1095                    case ExplicitConstructorCall.ImplicitSuper :
1096                        requestor.acceptConstructorReference(
1097                            superTypeNames[nestedTypeIndex-1],
1098                            constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
1099                            constructorCall.sourceStart);
1100                        break;
1101                }
1102            }
1103        }
1104        return;
1105    }
1106    char[][] argumentTypes = null;
1107    char[][] argumentNames = null;
1108    boolean isVarArgs = false;
1109    Argument[] arguments = methodDeclaration.arguments;
1110    if (arguments != null) {
1111        int argumentLength = arguments.length;
1112        argumentTypes = new char[argumentLength][];
1113        argumentNames = new char[argumentLength][];
1114        for (int i = 0; i < argumentLength; i++) {
1115            argumentTypes[i] = CharOperation.concatWith(arguments[i].type.getParameterizedTypeName(), '.');
1116            argumentNames[i] = arguments[i].name;
1117        }
1118        isVarArgs = arguments[argumentLength-1].isVarArgs();
1119    }
1120    char[][] thrownExceptionTypes = null;
1121    TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
1122    if (thrownExceptions != null) {
1123        int thrownExceptionLength = thrownExceptions.length;
1124        thrownExceptionTypes = new char[thrownExceptionLength][];
1125        for (int i = 0; i < thrownExceptionLength; i++) {
1126            thrownExceptionTypes[i] =
1127                CharOperation.concatWith(thrownExceptions[i].getParameterizedTypeName(), '.');
1128        }
1129    }
1130    // by default no selector end position
1131
int selectorSourceEnd = -1;
1132    if (methodDeclaration.isConstructor()) {
1133        selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
1134        if (isInRange){
1135            int currentModifiers = methodDeclaration.modifiers;
1136            if (isVarArgs)
1137                currentModifiers |= ClassFileConstants.AccVarargs;
1138            
1139            // remember deprecation so as to not lose it below
1140
boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(methodDeclaration.annotations);
1141            
1142            ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
1143            methodInfo.isConstructor = true;
1144            methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
1145            methodInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
1146            methodInfo.name = methodDeclaration.selector;
1147            methodInfo.nameSourceStart = methodDeclaration.sourceStart;
1148            methodInfo.nameSourceEnd = selectorSourceEnd;
1149            methodInfo.parameterTypes = argumentTypes;
1150            methodInfo.parameterNames = argumentNames;
1151            methodInfo.exceptionTypes = thrownExceptionTypes;
1152            methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
1153            methodInfo.annotationPositions = collectAnnotationPositions(methodDeclaration.annotations);
1154            methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration);
1155            requestor.enterConstructor(methodInfo);
1156        }
1157        if (reportReferenceInfo) {
1158            ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
1159            ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
1160            if (constructorCall != null) {
1161                switch(constructorCall.accessMode) {
1162                    case ExplicitConstructorCall.This :
1163                        requestor.acceptConstructorReference(
1164                            typeNames[nestedTypeIndex-1],
1165                            constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
1166                            constructorCall.sourceStart);
1167                        break;
1168                    case ExplicitConstructorCall.Super :
1169                    case ExplicitConstructorCall.ImplicitSuper :
1170                        requestor.acceptConstructorReference(
1171                            superTypeNames[nestedTypeIndex-1],
1172                            constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
1173                            constructorCall.sourceStart);
1174                        break;
1175                }
1176            }
1177        }
1178        this.visitIfNeeded(methodDeclaration);
1179        if (isInRange){
1180            requestor.exitConstructor(methodDeclaration.declarationSourceEnd);
1181        }
1182        return;
1183    }
1184    selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
1185    if (isInRange) {
1186        int currentModifiers = methodDeclaration.modifiers;
1187        if (isVarArgs)
1188            currentModifiers |= ClassFileConstants.AccVarargs;
1189        
1190        // remember deprecation so as to not lose it below
1191
boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(methodDeclaration.annotations);
1192            
1193        TypeReference returnType = methodDeclaration instanceof MethodDeclaration
1194            ? ((MethodDeclaration) methodDeclaration).returnType
1195            : null;
1196        ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
1197        methodInfo.isAnnotation = methodDeclaration instanceof AnnotationMethodDeclaration;
1198        methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
1199        methodInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
1200        methodInfo.returnType = returnType == null ? null : CharOperation.concatWith(returnType.getParameterizedTypeName(), '.');
1201        methodInfo.name = methodDeclaration.selector;
1202        methodInfo.nameSourceStart = methodDeclaration.sourceStart;
1203        methodInfo.nameSourceEnd = selectorSourceEnd;
1204        methodInfo.parameterTypes = argumentTypes;
1205        methodInfo.parameterNames = argumentNames;
1206        methodInfo.exceptionTypes = thrownExceptionTypes;
1207        methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
1208        methodInfo.annotationPositions = collectAnnotationPositions(methodDeclaration.annotations);
1209        methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration);
1210        requestor.enterMethod(methodInfo);
1211    }
1212        
1213    this.visitIfNeeded(methodDeclaration);
1214
1215    if (isInRange) {
1216        if (methodDeclaration instanceof AnnotationMethodDeclaration) {
1217            AnnotationMethodDeclaration annotationMethodDeclaration = (AnnotationMethodDeclaration) methodDeclaration;
1218            Expression expression = annotationMethodDeclaration.defaultValue;
1219            if (expression != null) {
1220                requestor.exitMethod(methodDeclaration.declarationSourceEnd, expression.sourceStart, expression.sourceEnd);
1221                return;
1222            }
1223        }
1224        requestor.exitMethod(methodDeclaration.declarationSourceEnd, -1, -1);
1225    }
1226}
1227
1228/*
1229* Update the bodyStart of the corresponding parse node
1230*/

1231public void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) {
1232    
1233    // range check
1234
boolean isInRange =
1235                scanner.initialPosition <= fieldDeclaration.declarationSourceStart
1236                && scanner.eofPosition >= fieldDeclaration.declarationSourceEnd;
1237
1238    switch(fieldDeclaration.getKind()) {
1239        case AbstractVariableDeclaration.ENUM_CONSTANT:
1240            // accept constructor reference for enum constant
1241
if (fieldDeclaration.initialization instanceof AllocationExpression) {
1242                AllocationExpression alloc = (AllocationExpression) fieldDeclaration.initialization;
1243                requestor.acceptConstructorReference(
1244                    declaringType.name,
1245                    alloc.arguments == null ? 0 : alloc.arguments.length,
1246                    alloc.sourceStart);
1247            }
1248            // fall through next case
1249
case AbstractVariableDeclaration.FIELD:
1250            int fieldEndPosition = this.sourceEnds.get(fieldDeclaration);
1251            if (fieldEndPosition == -1) {
1252                // use the declaration source end by default
1253
fieldEndPosition = fieldDeclaration.declarationSourceEnd;
1254            }
1255            if (isInRange) {
1256                int currentModifiers = fieldDeclaration.modifiers;
1257                
1258                // remember deprecation so as to not lose it below
1259
boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(fieldDeclaration.annotations);
1260            
1261                char[] typeName = null;
1262                if (fieldDeclaration.type == null) {
1263                    // enum constant
1264
typeName = declaringType.name;
1265                    currentModifiers |= ClassFileConstants.AccEnum;
1266                } else {
1267                    // regular field
1268
typeName = CharOperation.concatWith(fieldDeclaration.type.getParameterizedTypeName(), '.');
1269                }
1270                ISourceElementRequestor.FieldInfo fieldInfo = new ISourceElementRequestor.FieldInfo();
1271                fieldInfo.declarationStart = fieldDeclaration.declarationSourceStart;
1272                fieldInfo.name = fieldDeclaration.name;
1273                fieldInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
1274                fieldInfo.type = typeName;
1275                fieldInfo.nameSourceStart = fieldDeclaration.sourceStart;
1276                fieldInfo.nameSourceEnd = fieldDeclaration.sourceEnd;
1277                fieldInfo.annotationPositions = collectAnnotationPositions(fieldDeclaration.annotations);
1278                fieldInfo.categories = (char[][]) this.nodesToCategories.get(fieldDeclaration);
1279                requestor.enterField(fieldInfo);
1280            }
1281            this.visitIfNeeded(fieldDeclaration, declaringType);
1282            if (isInRange){
1283                requestor.exitField(
1284                    // filter out initializations that are not a constant (simple check)
1285
(fieldDeclaration.initialization == null
1286                            || fieldDeclaration.initialization instanceof ArrayInitializer
1287                            || fieldDeclaration.initialization instanceof AllocationExpression
1288                            || fieldDeclaration.initialization instanceof ArrayAllocationExpression
1289                            || fieldDeclaration.initialization instanceof Assignment
1290                            || fieldDeclaration.initialization instanceof ClassLiteralAccess
1291                            || fieldDeclaration.initialization instanceof MessageSend
1292                            || fieldDeclaration.initialization instanceof ArrayReference
1293                            || fieldDeclaration.initialization instanceof ThisReference) ?
1294                        -1 :
1295                        fieldDeclaration.initialization.sourceStart,
1296                    fieldEndPosition,
1297                    fieldDeclaration.declarationSourceEnd);
1298            }
1299            break;
1300        case AbstractVariableDeclaration.INITIALIZER:
1301            if (isInRange){
1302                requestor.enterInitializer(
1303                    fieldDeclaration.declarationSourceStart,
1304                    fieldDeclaration.modifiers);
1305            }
1306            this.visitIfNeeded((Initializer)fieldDeclaration);
1307            if (isInRange){
1308                requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
1309            }
1310            break;
1311    }
1312}
1313public void notifySourceElementRequestor(
1314    ImportReference importReference,
1315    boolean isPackage) {
1316    if (isPackage) {
1317        requestor.acceptPackage(
1318            importReference.declarationSourceStart,
1319            importReference.declarationSourceEnd,
1320            CharOperation.concatWith(importReference.getImportName(), '.'));
1321    } else {
1322        requestor.acceptImport(
1323            importReference.declarationSourceStart,
1324            importReference.declarationSourceEnd,
1325            importReference.tokens,
1326            (importReference.bits & ASTNode.OnDemand) != 0,
1327            importReference.modifiers);
1328    }
1329}
1330public void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType) {
1331    
1332    if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return;
1333
1334    // range check
1335
boolean isInRange =
1336        scanner.initialPosition <= typeDeclaration.declarationSourceStart
1337        && scanner.eofPosition >= typeDeclaration.declarationSourceEnd;
1338    
1339    FieldDeclaration[] fields = typeDeclaration.fields;
1340    AbstractMethodDeclaration[] methods = typeDeclaration.methods;
1341    TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
1342    int fieldCounter = fields == null ? 0 : fields.length;
1343    int methodCounter = methods == null ? 0 : methods.length;
1344    int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
1345    int fieldIndex = 0;
1346    int methodIndex = 0;
1347    int memberTypeIndex = 0;
1348    
1349    if (notifyTypePresence){
1350        char[][] interfaceNames = null;
1351        int superInterfacesLength = 0;
1352        TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
1353        if (superInterfaces != null) {
1354            superInterfacesLength = superInterfaces.length;
1355            interfaceNames = new char[superInterfacesLength][];
1356        } else {
1357            if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
1358                // see PR 3442
1359
QualifiedAllocationExpression alloc = typeDeclaration.allocation;
1360                if (alloc != null && alloc.type != null) {
1361                    superInterfaces = new TypeReference[] { alloc.type};
1362                    superInterfacesLength = 1;
1363                    interfaceNames = new char[1][];
1364                }
1365            }
1366        }
1367        if (superInterfaces != null) {
1368            for (int i = 0; i < superInterfacesLength; i++) {
1369                interfaceNames[i] =
1370                    CharOperation.concatWith(superInterfaces[i].getParameterizedTypeName(), '.');
1371            }
1372        }
1373        int kind = TypeDeclaration.kind(typeDeclaration.modifiers);
1374        char[] implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
1375        if (isInRange) {
1376            int currentModifiers = typeDeclaration.modifiers;
1377            
1378            // remember deprecation so as to not lose it below
1379
boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(typeDeclaration.annotations);
1380            
1381            boolean isEnumInit = typeDeclaration.allocation != null && typeDeclaration.allocation.enumConstant != null;
1382            char[] superclassName;
1383            if (isEnumInit) {
1384                currentModifiers |= ClassFileConstants.AccEnum;
1385                superclassName = declaringType.name;
1386            } else {
1387                TypeReference superclass = typeDeclaration.superclass;
1388                superclassName = superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null;
1389            }
1390            ISourceElementRequestor.TypeInfo typeInfo = new ISourceElementRequestor.TypeInfo();
1391            typeInfo.declarationStart = typeDeclaration.declarationSourceStart;
1392            typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
1393            typeInfo.name = typeDeclaration.name;
1394            typeInfo.nameSourceStart = typeDeclaration.sourceStart;
1395            typeInfo.nameSourceEnd = sourceEnd(typeDeclaration);
1396            typeInfo.superclass = superclassName;
1397            typeInfo.superinterfaces = interfaceNames;
1398            typeInfo.typeParameters = getTypeParameterInfos(typeDeclaration.typeParameters);
1399            typeInfo.annotationPositions = collectAnnotationPositions(typeDeclaration.annotations);
1400            typeInfo.categories = (char[][]) this.nodesToCategories.get(typeDeclaration);
1401            typeInfo.secondary = typeDeclaration.isSecondary();
1402            typeInfo.anonymousMember = typeDeclaration.allocation != null && typeDeclaration.allocation.enclosingInstance != null;
1403            requestor.enterType(typeInfo);
1404            switch (kind) {
1405                case TypeDeclaration.CLASS_DECL :
1406                    if (superclassName != null)
1407                        implicitSuperclassName = superclassName;
1408                    break;
1409                case TypeDeclaration.INTERFACE_DECL :
1410                    implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
1411                    break;
1412                case TypeDeclaration.ENUM_DECL :
1413                    implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ENUM;
1414                    break;
1415                case TypeDeclaration.ANNOTATION_TYPE_DECL :
1416                    implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION;
1417                    break;
1418            }
1419        }
1420        if (this.nestedTypeIndex == this.typeNames.length) {
1421            // need a resize
1422
System.arraycopy(this.typeNames, 0, (this.typeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
1423            System.arraycopy(this.superTypeNames, 0, (this.superTypeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
1424        }
1425        this.typeNames[this.nestedTypeIndex] = typeDeclaration.name;
1426        this.superTypeNames[this.nestedTypeIndex++] = implicitSuperclassName;
1427    }
1428    while ((fieldIndex < fieldCounter)
1429            || (memberTypeIndex < memberTypeCounter)
1430            || (methodIndex < methodCounter)) {
1431        FieldDeclaration nextFieldDeclaration = null;
1432        AbstractMethodDeclaration nextMethodDeclaration = null;
1433        TypeDeclaration nextMemberDeclaration = null;
1434        
1435        int position = Integer.MAX_VALUE;
1436        int nextDeclarationType = -1;
1437        if (fieldIndex < fieldCounter) {
1438            nextFieldDeclaration = fields[fieldIndex];
1439            if (nextFieldDeclaration.declarationSourceStart < position) {
1440                position = nextFieldDeclaration.declarationSourceStart;
1441                nextDeclarationType = 0; // FIELD
1442
}
1443        }
1444        if (methodIndex < methodCounter) {
1445            nextMethodDeclaration = methods[methodIndex];
1446            if (nextMethodDeclaration.declarationSourceStart < position) {
1447                position = nextMethodDeclaration.declarationSourceStart;
1448                nextDeclarationType = 1; // METHOD
1449
}
1450        }
1451        if (memberTypeIndex < memberTypeCounter) {
1452            nextMemberDeclaration = memberTypes[memberTypeIndex];
1453            if (nextMemberDeclaration.declarationSourceStart < position) {
1454                position = nextMemberDeclaration.declarationSourceStart;
1455                nextDeclarationType = 2; // MEMBER
1456
}
1457        }
1458        switch (nextDeclarationType) {
1459            case 0 :
1460                fieldIndex++;
1461                notifySourceElementRequestor(nextFieldDeclaration, typeDeclaration);
1462                break;
1463            case 1 :
1464                methodIndex++;
1465                notifySourceElementRequestor(nextMethodDeclaration);
1466                break;
1467            case 2 :
1468                memberTypeIndex++;
1469                notifySourceElementRequestor(nextMemberDeclaration, true, null);
1470        }
1471    }
1472    if (notifyTypePresence){
1473        if (isInRange){
1474            requestor.exitType(typeDeclaration.declarationSourceEnd);
1475        }
1476        nestedTypeIndex--;
1477    }
1478}
1479public void parseCompilationUnit(
1480    ICompilationUnit unit,
1481    int start,
1482    int end,
1483    boolean fullParse) {
1484
1485    this.reportReferenceInfo = fullParse;
1486    boolean old = diet;
1487    
1488    try {
1489        diet = true;
1490        CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
1491        CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, start, end);
1492        if (scanner.recordLineSeparator) {
1493            requestor.acceptLineSeparatorPositions(compilationUnitResult.getLineSeparatorPositions());
1494        }
1495        if (this.localDeclarationVisitor != null || fullParse){
1496            diet = false;
1497            this.getMethodBodies(parsedUnit);
1498        }
1499        this.scanner.resetTo(start, end);
1500        notifySourceElementRequestor(parsedUnit);
1501    } catch (AbortCompilation e) {
1502        // ignore this exception
1503
} finally {
1504        diet = old;
1505        reset();
1506    }
1507}
1508public CompilationUnitDeclaration parseCompilationUnit(
1509    ICompilationUnit unit,
1510    boolean fullParse) {
1511        
1512    boolean old = diet;
1513
1514    try {
1515        diet = true;
1516        this.reportReferenceInfo = fullParse;
1517        CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
1518        CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult);
1519        if (scanner.recordLineSeparator) {
1520            requestor.acceptLineSeparatorPositions(compilationUnitResult.getLineSeparatorPositions());
1521        }
1522        int initialStart = this.scanner.initialPosition;
1523        int initialEnd = this.scanner.eofPosition;
1524        if (this.localDeclarationVisitor != null || fullParse){
1525            diet = false;
1526            this.getMethodBodies(parsedUnit);
1527        }
1528        this.scanner.resetTo(initialStart, initialEnd);
1529        notifySourceElementRequestor(parsedUnit);
1530        return parsedUnit;
1531    } catch (AbortCompilation e) {
1532        // ignore this exception
1533
} finally {
1534        diet = old;
1535        reset();
1536    }
1537    return null;
1538}
1539public void parseTypeMemberDeclarations(
1540    ISourceType type,
1541    ICompilationUnit sourceUnit,
1542    int start,
1543    int end,
1544    boolean needReferenceInfo) {
1545    boolean old = diet;
1546    
1547    CompilationResult compilationUnitResult =
1548        new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit);
1549    try {
1550        diet = !needReferenceInfo;
1551        reportReferenceInfo = needReferenceInfo;
1552        CompilationUnitDeclaration unit =
1553            SourceTypeConverter.buildCompilationUnit(
1554                new ISourceType[]{type},
1555                // no need for field and methods
1556
// no need for member types
1557
// no need for field initialization
1558
SourceTypeConverter.NONE,
1559                problemReporter(),
1560                compilationUnitResult);
1561        if ((unit == null) || (unit.types == null) || (unit.types.length != 1))
1562            return;
1563        this.sourceType = type;
1564        try {
1565            /* automaton initialization */
1566            initialize();
1567            goForClassBodyDeclarations();
1568            /* scanner initialization */
1569            scanner.setSource(sourceUnit.getContents());
1570            scanner.resetTo(start, end);
1571            /* unit creation */
1572            referenceContext = compilationUnit = unit;
1573            /* initialize the astStacl */
1574            // the compilationUnitDeclaration should contain exactly one type
1575
pushOnAstStack(unit.types[0]);
1576            /* run automaton */
1577            parse();
1578            notifySourceElementRequestor(unit);
1579        } finally {
1580            unit = compilationUnit;
1581            compilationUnit = null; // reset parser
1582
}
1583    } catch (AbortCompilation e) {
1584        // ignore this exception
1585
} finally {
1586        if (scanner.recordLineSeparator) {
1587            requestor.acceptLineSeparatorPositions(compilationUnitResult.getLineSeparatorPositions());
1588        }
1589        diet = old;
1590        reset();
1591    }
1592}
1593
1594public void parseTypeMemberDeclarations(
1595    char[] contents,
1596    int start,
1597    int end) {
1598
1599    boolean old = diet;
1600    
1601    try {
1602        diet = true;
1603
1604        /* automaton initialization */
1605        initialize();
1606        goForClassBodyDeclarations();
1607        /* scanner initialization */
1608        scanner.setSource(contents);
1609        scanner.recordLineSeparator = false;
1610        scanner.taskTags = null;
1611        scanner.taskPriorities = null;
1612        scanner.resetTo(start, end);
1613
1614        /* unit creation */
1615        referenceContext = null;
1616
1617        /* initialize the astStacl */
1618        // the compilationUnitDeclaration should contain exactly one type
1619
/* run automaton */
1620        parse();
1621        notifySourceElementRequestor((CompilationUnitDeclaration)null);
1622    } catch (AbortCompilation e) {
1623        // ignore this exception
1624
} finally {
1625        diet = old;
1626        reset();
1627    }
1628}
1629/*
1630 * Sort the given ast nodes by their positions.
1631 */

1632private static void quickSort(ASTNode[] sortedCollection, int left, int right) {
1633    int original_left = left;
1634    int original_right = right;
1635    ASTNode mid = sortedCollection[left + (right - left) / 2];
1636    do {
1637        while (sortedCollection[left].sourceStart < mid.sourceStart) {
1638            left++;
1639        }
1640        while (mid.sourceStart < sortedCollection[right].sourceStart) {
1641            right--;
1642        }
1643        if (left <= right) {
1644            ASTNode tmp = sortedCollection[left];
1645            sortedCollection[left] = sortedCollection[right];
1646            sortedCollection[right] = tmp;
1647            left++;
1648            right--;
1649        }
1650    } while (left <= right);
1651    if (original_left < right) {
1652        quickSort(sortedCollection, original_left, right);
1653    }
1654    if (left < original_right) {
1655        quickSort(sortedCollection, left, original_right);
1656    }
1657}
1658private void rememberCategories() {
1659    if (this.useSourceJavadocParser) {
1660        SourceJavadocParser sourceJavadocParser = (SourceJavadocParser) this.javadocParser;
1661        char[][] categories = sourceJavadocParser.categories;
1662        if (categories.length > 0) {
1663            this.nodesToCategories.put(this.astStack[this.astPtr], categories);
1664            sourceJavadocParser.categories = CharOperation.NO_CHAR_CHAR;
1665        }
1666    }
1667}
1668private void reset() {
1669    this.sourceEnds = new HashtableOfObjectToInt();
1670    this.nodesToCategories = new HashMap JavaDoc();
1671    typeNames = new char[4][];
1672    superTypeNames = new char[4][];
1673    nestedTypeIndex = 0;
1674}
1675private int sourceEnd(TypeDeclaration typeDeclaration) {
1676    if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
1677        QualifiedAllocationExpression allocation = typeDeclaration.allocation;
1678        if (allocation.type == null) // case of enum constant body
1679
return typeDeclaration.sourceEnd;
1680        return allocation.type.sourceEnd;
1681    } else {
1682        return typeDeclaration.sourceEnd;
1683    }
1684}
1685private void visitIfNeeded(AbstractMethodDeclaration method) {
1686    if (this.localDeclarationVisitor != null
1687        && (method.bits & ASTNode.HasLocalType) != 0) {
1688            if (method instanceof ConstructorDeclaration) {
1689                ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method;
1690                if (constructorDeclaration.constructorCall != null) {
1691                    constructorDeclaration.constructorCall.traverse(this.localDeclarationVisitor, method.scope);
1692                }
1693            }
1694            if (method.statements != null) {
1695                int statementsLength = method.statements.length;
1696                for (int i = 0; i < statementsLength; i++)
1697                    method.statements[i].traverse(this.localDeclarationVisitor, method.scope);
1698            }
1699    }
1700}
1701
1702private void visitIfNeeded(FieldDeclaration field, TypeDeclaration declaringType) {
1703    if (this.localDeclarationVisitor != null
1704        && (field.bits & ASTNode.HasLocalType) != 0) {
1705            if (field.initialization != null) {
1706                try {
1707                    this.localDeclarationVisitor.pushDeclaringType(declaringType);
1708                    field.initialization.traverse(this.localDeclarationVisitor, (MethodScope) null);
1709                } finally {
1710                    this.localDeclarationVisitor.popDeclaringType();
1711                }
1712            }
1713    }
1714}
1715
1716private void visitIfNeeded(Initializer initializer) {
1717    if (this.localDeclarationVisitor != null
1718        && (initializer.bits & ASTNode.HasLocalType) != 0) {
1719            if (initializer.block != null) {
1720                initializer.block.traverse(this.localDeclarationVisitor, null);
1721            }
1722    }
1723}
1724}
1725
Popular Tags