284fcc78690531f7ce883ac23a0bc22a1e923feb
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / DocumentElementParser.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler;
12
13 /*
14  * A document element parser extracts structural information
15  * from a piece of source, providing detailed source positions info.
16  *
17  * also see @IDocumentElementRequestor
18  *
19  * The structural investigation includes:
20  * - the package statement
21  * - import statements
22  * - top-level types: package member, member types (member types of member types...)
23  * - fields
24  * - methods
25  *
26  * Any (parsing) problem encountered is also provided.
27  */
28 import net.sourceforge.phpdt.core.compiler.IProblem;
29 import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariableDeclaration;
30 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
31 import net.sourceforge.phpdt.internal.compiler.ast.ArrayQualifiedTypeReference;
32 import net.sourceforge.phpdt.internal.compiler.ast.ArrayTypeReference;
33 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
34 import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
35 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
36 import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
37 import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
38 import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration;
39 import net.sourceforge.phpdt.internal.compiler.ast.LocalTypeDeclaration;
40 import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration;
41 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
42 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
43 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
44 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
45 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
46 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
47 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
48 import net.sourceforge.phpdt.internal.compiler.parser.Parser;
49 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
50 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
51 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
52
53 public class DocumentElementParser extends Parser {
54         IDocumentElementRequestor requestor;
55         private int localIntPtr;
56         private int lastFieldEndPosition;
57         private int lastFieldBodyEndPosition;   
58         private int typeStartPosition;
59         private long selectorSourcePositions;
60         private int typeDims;
61         private int extendsDim;
62         private int declarationSourceStart;
63
64         /* int[] stack for storing javadoc positions */
65         int[][] intArrayStack;
66         int intArrayPtr;
67         
68         CompilerOptions options;
69         
70 public DocumentElementParser(
71         final IDocumentElementRequestor requestor, 
72         IProblemFactory problemFactory,
73         CompilerOptions options) {
74         super(new ProblemReporter(
75                 DefaultErrorHandlingPolicies.exitAfterAllProblems(), 
76                 options, 
77                 problemFactory) {
78                 public void record(IProblem problem, CompilationResult unitResult) {
79                         requestor.acceptProblem(problem);
80                 }
81         },
82         false,
83         options.assertMode);
84         this.requestor = requestor;
85         intArrayStack = new int[30][];
86         this.options = options;
87 }
88
89 /**
90  *
91  * INTERNAL USE-ONLY
92  */
93 protected void adjustInterfaceModifiers() {
94         intStack[intPtr - 2] |= AccInterface;
95 }
96 /*
97  * Will clear the comment stack when looking
98  * for a potential JavaDoc which might contain @deprecated.
99  *
100  * Additionally, before investigating for @deprecated, retrieve the positions
101  * of the JavaDoc comments so as to notify requestor with them.
102  */
103 public void checkAnnotation() {
104
105         /* persisting javadoc positions */
106         pushOnIntArrayStack(this.getJavaDocPositions());
107         boolean deprecated = false;
108         int lastAnnotationIndex = -1;
109
110         //since jdk1.2 look only in the last java doc comment...
111         found : {
112                 if ((lastAnnotationIndex = scanner.commentPtr) >= 0) { //look for @deprecated
113                         scanner.commentPtr = -1;
114                         // reset the comment stack, since not necessary after having checked
115                         int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
116                         // javadoc only (non javadoc comment have negative end positions.)
117                         int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1;
118                         //stop is one over
119                         char[] comment = scanner.source;
120
121                         for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
122                                 if ((comment[i] == '@')
123                                         && (comment[i + 1] == 'd')
124                                         && (comment[i + 2] == 'e')
125                                         && (comment[i + 3] == 'p')
126                                         && (comment[i + 4] == 'r')
127                                         && (comment[i + 5] == 'e')
128                                         && (comment[i + 6] == 'c')
129                                         && (comment[i + 7] == 'a')
130                                         && (comment[i + 8] == 't')
131                                         && (comment[i + 9] == 'e')
132                                         && (comment[i + 10] == 'd')) {
133                                         // ensure the tag is properly ended: either followed by a space, line end or asterisk.
134                                         int nextPos = i + 11;
135                                         deprecated = 
136                                                 (comment[nextPos] == ' ')
137                                                         || (comment[nextPos] == '\n')
138                                                         || (comment[nextPos] == '\r')
139                                                         || (comment[nextPos] == '*'); 
140                                         break found;
141                                 }
142                         }
143                 }
144         }
145         if (deprecated) {
146                 checkAndSetModifiers(AccDeprecated);
147         }
148         // modify the modifier source start to point at the first comment
149         if (lastAnnotationIndex >= 0) {
150                 declarationSourceStart = scanner.commentStarts[0];
151         }
152 }
153 /**
154  *
155  * INTERNAL USE-ONLY
156  */
157 protected void consumeClassBodyDeclaration() {
158         // ClassBodyDeclaration ::= Diet Block
159         //push an Initializer
160         //optimize the push/pop
161
162         super.consumeClassBodyDeclaration();
163         Initializer initializer = (Initializer) astStack[astPtr];
164         requestor.acceptInitializer(
165                 initializer.declarationSourceStart,
166                 initializer.declarationSourceEnd,
167                 intArrayStack[intArrayPtr--], 
168                 0,
169                 modifiersSourceStart, 
170                 initializer.block.sourceStart,
171                 initializer.block.sourceEnd);
172 }
173 /**
174  *
175  * INTERNAL USE-ONLY
176  */
177 protected void consumeClassDeclaration() {
178         super.consumeClassDeclaration();
179         // we know that we have a TypeDeclaration on the top of the astStack
180         if (isLocalDeclaration()) {
181                 // we ignore the local variable declarations
182                 return;
183         }
184         requestor.exitClass(endStatementPosition, // '}' is the end of the body 
185          ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd);
186 }
187 /**
188  *
189  * INTERNAL USE-ONLY
190  */
191 protected void consumeClassHeader() {
192         //ClassHeader ::= $empty
193         super.consumeClassHeader();
194         if (isLocalDeclaration()) {
195                 // we ignore the local variable declarations
196                 intArrayPtr--;
197                 return;
198         }
199         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
200         TypeReference[] superInterfaces = typeDecl.superInterfaces;
201         char[][] interfaceNames = null;
202         int[] interfaceNameStarts = null;
203         int[] interfaceNameEnds = null;
204         if (superInterfaces != null) {
205                 int superInterfacesLength = superInterfaces.length;
206                 interfaceNames = new char[superInterfacesLength][];
207                 interfaceNameStarts = new int[superInterfacesLength];
208                 interfaceNameEnds = new int[superInterfacesLength];
209                 for (int i = 0; i < superInterfacesLength; i++) {
210                         TypeReference superInterface = superInterfaces[i];
211                         interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.'); 
212                         interfaceNameStarts[i] = superInterface.sourceStart;
213                         interfaceNameEnds[i] = superInterface.sourceEnd;
214                 }
215         }
216         // flush the comments related to the class header
217         scanner.commentPtr = -1;
218         TypeReference superclass = typeDecl.superclass;
219         if (superclass == null) {
220                 requestor.enterClass(
221                         typeDecl.declarationSourceStart, 
222                         intArrayStack[intArrayPtr--], 
223                         typeDecl.modifiers, 
224                         typeDecl.modifiersSourceStart, 
225                         typeStartPosition, 
226                         typeDecl.name, 
227                         typeDecl.sourceStart, 
228                         typeDecl.sourceEnd, 
229                         null, 
230                         -1, 
231                         -1, 
232                         interfaceNames, 
233                         interfaceNameStarts, 
234                         interfaceNameEnds, 
235                         scanner.currentPosition - 1); 
236         } else {
237                 requestor.enterClass(
238                         typeDecl.declarationSourceStart, 
239                         intArrayStack[intArrayPtr--], 
240                         typeDecl.modifiers, 
241                         typeDecl.modifiersSourceStart, 
242                         typeStartPosition, 
243                         typeDecl.name, 
244                         typeDecl.sourceStart, 
245                         typeDecl.sourceEnd, 
246                         CharOperation.concatWith(superclass.getTypeName(), '.'), 
247                         superclass.sourceStart, 
248                         superclass.sourceEnd, 
249                         interfaceNames, 
250                         interfaceNameStarts, 
251                         interfaceNameEnds, 
252                         scanner.currentPosition - 1); 
253
254         }
255 }
256 protected void consumeClassHeaderName() {
257         // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
258         TypeDeclaration typeDecl;
259         if (nestedMethod[nestedType] == 0) {
260                 if (nestedType != 0) {
261                         typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
262                 } else {
263                         typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
264                 }
265         } else {
266                 // Record that the block has a declaration for local types
267                 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
268                 markCurrentMethodWithLocalType();
269                 blockReal();
270         }
271
272         //highlight the name of the type
273         long pos = identifierPositionStack[identifierPtr];
274         typeDecl.sourceEnd = (int) pos;
275         typeDecl.sourceStart = (int) (pos >>> 32);
276         typeDecl.name = identifierStack[identifierPtr--];
277         identifierLengthPtr--;
278
279         //compute the declaration source too
280         // 'class' and 'interface' push an int position
281         typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--];
282         intPtr--;
283         int declarationSourceStart = intStack[intPtr--];
284         typeDecl.modifiersSourceStart = intStack[intPtr--];
285         typeDecl.modifiers = intStack[intPtr--];
286         if (typeDecl.declarationSourceStart > declarationSourceStart) {
287                 typeDecl.declarationSourceStart = declarationSourceStart;
288         }
289         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
290         pushOnAstStack(typeDecl);
291 }
292 /**
293  *
294  * INTERNAL USE-ONLY
295  */
296 protected void consumeCompilationUnit() {
297         // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
298         requestor.exitCompilationUnit(scanner.source.length - 1);
299 }
300 /**
301  *
302  * INTERNAL USE-ONLY
303  */
304 protected void consumeConstructorDeclaration() {
305         // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
306         super.consumeConstructorDeclaration();
307         if (isLocalDeclaration()) {
308                 // we ignore the local variable declarations
309                 return;
310         }
311         ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
312         requestor.exitConstructor(endStatementPosition, cd.declarationSourceEnd);
313 }
314 /**
315  *
316  * INTERNAL USE-ONLY
317  */
318 protected void consumeConstructorHeader() {
319         // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
320         super.consumeConstructorHeader();
321         if (isLocalDeclaration()) {
322                 // we ignore the local variable declarations
323                 intArrayPtr--;
324                 return;
325         }
326         ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
327         Argument[] arguments = cd.arguments;
328         char[][] argumentTypes = null;
329         char[][] argumentNames = null;
330         int[] argumentTypeStarts = null;
331         int[] argumentTypeEnds = null;
332         int[] argumentNameStarts = null;
333         int[] argumentNameEnds = null;
334         if (arguments != null) {
335                 int argumentLength = arguments.length;
336                 argumentTypes = new char[argumentLength][];
337                 argumentNames = new char[argumentLength][];
338                 argumentNameStarts = new int[argumentLength];
339                 argumentNameEnds = new int[argumentLength];
340                 argumentTypeStarts = new int[argumentLength];
341                 argumentTypeEnds = new int[argumentLength];
342                 for (int i = 0; i < argumentLength; i++) {
343                         Argument argument = arguments[i];
344                         TypeReference argumentType = argument.type;
345                         argumentTypes[i] = returnTypeName(argumentType);
346                         argumentNames[i] = argument.name;
347                         argumentNameStarts[i] = argument.sourceStart;
348                         argumentNameEnds[i] = argument.sourceEnd;
349                         argumentTypeStarts[i] = argumentType.sourceStart;
350                         argumentTypeEnds[i] = argumentType.sourceEnd;
351                 }
352         }
353         TypeReference[] thrownExceptions = cd.thrownExceptions;
354         char[][] exceptionTypes = null;
355         int[] exceptionTypeStarts = null;
356         int[] exceptionTypeEnds = null;
357         if (thrownExceptions != null) {
358                 int thrownExceptionLength = thrownExceptions.length;
359                 exceptionTypes = new char[thrownExceptionLength][];
360                 exceptionTypeStarts = new int[thrownExceptionLength];
361                 exceptionTypeEnds = new int[thrownExceptionLength];
362                 for (int i = 0; i < thrownExceptionLength; i++) {
363                         TypeReference exception = thrownExceptions[i];
364                         exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
365                         exceptionTypeStarts[i] = exception.sourceStart;
366                         exceptionTypeEnds[i] = exception.sourceEnd;
367                 }
368         }
369         requestor
370                 .enterConstructor(
371                         cd.declarationSourceStart, 
372                         intArrayStack[intArrayPtr--], 
373                         cd.modifiers,
374                         cd.modifiersSourceStart, 
375                         cd.selector, 
376                         cd.sourceStart, 
377                         (int) (selectorSourcePositions & 0xFFFFFFFFL), 
378                         // retrieve the source end of the name
379                         argumentTypes, 
380                         argumentTypeStarts, 
381                         argumentTypeEnds, 
382                         argumentNames, 
383                         argumentNameStarts, 
384                         argumentNameEnds, 
385                         rParenPos, 
386                         // right parenthesis
387                         exceptionTypes, 
388                         exceptionTypeStarts, 
389                         exceptionTypeEnds, 
390                         scanner.currentPosition - 1); 
391 }
392 protected void consumeConstructorHeaderName() {
393         // ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
394         ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
395
396         //name -- this is not really revelant but we do .....
397         cd.selector = identifierStack[identifierPtr];
398         selectorSourcePositions = identifierPositionStack[identifierPtr--];
399         identifierLengthPtr--;
400
401         //modifiers
402         cd.declarationSourceStart = intStack[intPtr--];
403         cd.modifiersSourceStart = intStack[intPtr--];
404         cd.modifiers = intStack[intPtr--];
405
406         //highlight starts at the selector starts
407         cd.sourceStart = (int) (selectorSourcePositions >>> 32);
408         pushOnAstStack(cd);
409
410         cd.sourceEnd = lParenPos;
411         cd.bodyStart = lParenPos + 1;
412 }
413 protected void consumeDefaultModifiers() {
414         checkAnnotation(); // might update modifiers with AccDeprecated
415         pushOnIntStack(modifiers); // modifiers
416         pushOnIntStack(-1);
417         pushOnIntStack(
418                 declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition); 
419         resetModifiers();
420 }
421 protected void consumeDiet() {
422         // Diet ::= $empty
423         super.consumeDiet();
424         /* persisting javadoc positions
425          * Will be consume in consumeClassBodyDeclaration
426          */
427         pushOnIntArrayStack(this.getJavaDocPositions());        
428 }
429 /**
430  *
431  * INTERNAL USE-ONLY
432  */
433 protected void consumeEnterCompilationUnit() {
434         // EnterCompilationUnit ::= $empty
435         requestor.enterCompilationUnit();
436 }
437 /**
438  *
439  * INTERNAL USE-ONLY
440  */
441 protected void consumeEnterVariable() {
442         // EnterVariable ::= $empty
443         boolean isLocalDeclaration = isLocalDeclaration();
444         if (!isLocalDeclaration && (variablesCounter[nestedType] != 0)) {
445                 requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition);
446         }
447         char[] name = identifierStack[identifierPtr];
448         long namePosition = identifierPositionStack[identifierPtr--];
449         int extendedTypeDimension = intStack[intPtr--];
450
451         AbstractVariableDeclaration declaration;
452         if (nestedMethod[nestedType] != 0) {
453                 // create the local variable declarations
454                 declaration = 
455                         new LocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); 
456         } else {
457                 // create the field declaration
458                 declaration = 
459                         new FieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); 
460         }
461         identifierLengthPtr--;
462         TypeReference type;
463         int variableIndex = variablesCounter[nestedType];
464         int typeDim = 0;
465         if (variableIndex == 0) {
466                 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
467                 if (nestedMethod[nestedType] != 0) {
468                         // local declaration
469                         declaration.declarationSourceStart = intStack[intPtr--];
470                         declaration.modifiersSourceStart = intStack[intPtr--];
471                         declaration.modifiers = intStack[intPtr--];
472                         type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
473                         pushOnAstStack(type);
474                 } else {
475                         // field declaration
476                         type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
477                         pushOnAstStack(type);
478                         declaration.declarationSourceStart = intStack[intPtr--];
479                         declaration.modifiersSourceStart = intStack[intPtr--];
480                         declaration.modifiers = intStack[intPtr--];
481                 }
482         } else {
483                 type = (TypeReference) astStack[astPtr - variableIndex];
484                 typeDim = type.dimensions();
485                 AbstractVariableDeclaration previousVariable = 
486                         (AbstractVariableDeclaration) astStack[astPtr]; 
487                 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
488                 declaration.modifiers = previousVariable.modifiers;
489                 declaration.modifiersSourceStart = previousVariable.modifiersSourceStart;
490         }
491
492         localIntPtr = intPtr;
493
494         if (extendedTypeDimension == 0) {
495                 declaration.type = type;
496         } else {
497                 int dimension = typeDim + extendedTypeDimension;
498                 //on the identifierLengthStack there is the information about the type....
499                 int baseType;
500                 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
501                         //it was a baseType
502                         declaration.type = TypeReference.baseTypeReference(-baseType, dimension);
503                         declaration.type.sourceStart = type.sourceStart;
504                         declaration.type.sourceEnd = type.sourceEnd;
505                 } else {
506                         declaration.type = this.copyDims(type, dimension);
507                 }
508         }
509         variablesCounter[nestedType]++;
510         nestedMethod[nestedType]++;
511         pushOnAstStack(declaration);
512
513         int[] javadocPositions = intArrayStack[intArrayPtr];
514         if (!isLocalDeclaration) {
515                 requestor
516                         .enterField(
517                                 declaration.declarationSourceStart, 
518                                 javadocPositions, 
519                                 declaration.modifiers, 
520                                 declaration.modifiersSourceStart, 
521                                 returnTypeName(declaration.type), 
522                                 type.sourceStart, 
523                                 type.sourceEnd, 
524                                 typeDims, 
525                                 name, 
526                                 (int) (namePosition >>> 32), 
527                                 (int) namePosition, 
528                                 extendedTypeDimension, 
529                                 extendedTypeDimension == 0 ? -1 : endPosition); 
530         }
531 }
532 /**
533  *
534  * INTERNAL USE-ONLY
535  */
536 protected void consumeExitVariableWithInitialization() {
537         // ExitVariableWithInitialization ::= $empty
538         // the scanner is located after the comma or the semi-colon.
539         // we want to include the comma or the semi-colon
540         super.consumeExitVariableWithInitialization();
541         nestedMethod[nestedType]--;     
542         lastFieldEndPosition = scanner.currentPosition - 1;
543         lastFieldBodyEndPosition =      ((AbstractVariableDeclaration) astStack[astPtr]).initialization.sourceEnd;
544 }
545 protected void consumeExitVariableWithoutInitialization() {
546         // ExitVariableWithoutInitialization ::= $empty
547         // do nothing by default
548         super.consumeExitVariableWithoutInitialization();
549         nestedMethod[nestedType]--;     
550         lastFieldEndPosition = scanner.currentPosition - 1;
551         lastFieldBodyEndPosition = scanner.startPosition - 1;
552 }
553 /**
554  *
555  * INTERNAL USE-ONLY
556  */
557 protected void consumeFieldDeclaration() {
558         // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
559         // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
560         // the super.consumeFieldDeclaration will reinitialize the variableCounter[nestedType]  
561         int variableIndex = variablesCounter[nestedType];
562         super.consumeFieldDeclaration();
563         intArrayPtr--;
564         if (isLocalDeclaration())
565                 return;
566         if (variableIndex != 0) {
567                 requestor.exitField(lastFieldBodyEndPosition, lastFieldEndPosition);
568         }
569 }
570 protected void consumeFormalParameter() {
571         // FormalParameter ::= Type VariableDeclaratorId ==> false
572         // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
573         /*
574         astStack : 
575         identifierStack : type identifier
576         intStack : dim dim
577          ==>
578         astStack : Argument
579         identifierStack :  
580         intStack :  
581         */
582
583         identifierLengthPtr--;
584         char[] name = identifierStack[identifierPtr];
585         long namePositions = identifierPositionStack[identifierPtr--];
586         TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
587         intPtr -= 3;
588         Argument arg = 
589                 new Argument(
590                         name, 
591                         namePositions, 
592                         type, 
593                         intStack[intPtr + 1]); // modifiers
594         pushOnAstStack(arg);
595         intArrayPtr--;
596 }
597 /**
598  *
599  * INTERNAL USE-ONLY
600  */
601 protected void consumeInterfaceDeclaration() {
602         super.consumeInterfaceDeclaration();
603         // we know that we have a TypeDeclaration on the top of the astStack
604         if (isLocalDeclaration()) {
605                 // we ignore the local variable declarations
606                 return;
607         }
608         requestor.exitInterface(endStatementPosition, // the '}' is the end of the body
609          ((TypeDeclaration) astStack[astPtr]).declarationSourceEnd);
610 }
611 /**
612  *
613  * INTERNAL USE-ONLY
614  */
615 protected void consumeInterfaceHeader() {
616         //InterfaceHeader ::= $empty
617         super.consumeInterfaceHeader();
618         if (isLocalDeclaration()) {
619                 // we ignore the local variable declarations
620                 intArrayPtr--;
621                 return;
622         }
623         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
624         TypeReference[] superInterfaces = typeDecl.superInterfaces;
625         char[][] interfaceNames = null;
626         int[] interfaceNameStarts = null;
627         int[] interfacenameEnds = null;
628         int superInterfacesLength = 0;
629         if (superInterfaces != null) {
630                 superInterfacesLength = superInterfaces.length;
631                 interfaceNames = new char[superInterfacesLength][];
632                 interfaceNameStarts = new int[superInterfacesLength];
633                 interfacenameEnds = new int[superInterfacesLength];
634         }
635         if (superInterfaces != null) {
636                 for (int i = 0; i < superInterfacesLength; i++) {
637                         TypeReference superInterface = superInterfaces[i];
638                         interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.'); 
639                         interfaceNameStarts[i] = superInterface.sourceStart;
640                         interfacenameEnds[i] = superInterface.sourceEnd;
641                 }
642         }
643         // flush the comments related to the interface header
644         scanner.commentPtr = -1;
645         requestor.enterInterface(
646                 typeDecl.declarationSourceStart, 
647                 intArrayStack[intArrayPtr--], 
648                 typeDecl.modifiers, 
649                 typeDecl.modifiersSourceStart, 
650                 typeStartPosition, 
651                 typeDecl.name, 
652                 typeDecl.sourceStart, 
653                 typeDecl.sourceEnd, 
654                 interfaceNames, 
655                 interfaceNameStarts, 
656                 interfacenameEnds, 
657                 scanner.currentPosition - 1); 
658 }
659 protected void consumeInterfaceHeaderName() {
660         // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
661         TypeDeclaration typeDecl;
662         if (nestedMethod[nestedType] == 0) {
663                 if (nestedType != 0) {
664                         typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
665                 } else {
666                         typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
667                 }
668         } else {
669                 // Record that the block has a declaration for local types
670                 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
671                 markCurrentMethodWithLocalType();
672                 blockReal();
673         }
674
675         //highlight the name of the type
676         long pos = identifierPositionStack[identifierPtr];
677         typeDecl.sourceEnd = (int) pos;
678         typeDecl.sourceStart = (int) (pos >>> 32);
679         typeDecl.name = identifierStack[identifierPtr--];
680         identifierLengthPtr--;
681
682         //compute the declaration source too
683         // 'class' and 'interface' push an int position
684         typeStartPosition = typeDecl.declarationSourceStart = intStack[intPtr--];
685         intPtr--;
686         int declarationSourceStart = intStack[intPtr--];
687         typeDecl.modifiersSourceStart = intStack[intPtr--];
688         typeDecl.modifiers = intStack[intPtr--];
689         if (typeDecl.declarationSourceStart > declarationSourceStart) {
690                 typeDecl.declarationSourceStart = declarationSourceStart;
691         }
692         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
693         pushOnAstStack(typeDecl);
694 }
695 /**
696  *
697  * INTERNAL USE-ONLY
698  */
699 protected void consumeLocalVariableDeclaration() {
700         // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
701         // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
702
703         super.consumeLocalVariableDeclaration();
704         intArrayPtr--;
705 }
706 /**
707  *
708  * INTERNAL USE-ONLY
709  */
710 protected void consumeMethodDeclaration(boolean isNotAbstract) {
711         // MethodDeclaration ::= MethodHeader MethodBody
712         // AbstractMethodDeclaration ::= MethodHeader ';'
713         super.consumeMethodDeclaration(isNotAbstract);
714         if (isLocalDeclaration()) {
715                 // we ignore the local variable declarations
716                 return;
717         }
718         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
719         requestor.exitMethod(endStatementPosition, md.declarationSourceEnd);
720 }
721 /**
722  *
723  * INTERNAL USE-ONLY
724  */
725 protected void consumeMethodHeader() {
726         // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
727         super.consumeMethodHeader();
728         if (isLocalDeclaration()) {
729                 // we ignore the local variable declarations
730                 intArrayPtr--;
731                 return;
732         }
733         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
734
735         TypeReference returnType = md.returnType;
736         char[] returnTypeName = returnTypeName(returnType);
737         Argument[] arguments = md.arguments;
738         char[][] argumentTypes = null;
739         char[][] argumentNames = null;
740         int[] argumentTypeStarts = null;
741         int[] argumentTypeEnds = null;
742         int[] argumentNameStarts = null;
743         int[] argumentNameEnds = null;
744         if (arguments != null) {
745                 int argumentLength = arguments.length;
746                 argumentTypes = new char[argumentLength][];
747                 argumentNames = new char[argumentLength][];
748                 argumentNameStarts = new int[argumentLength];
749                 argumentNameEnds = new int[argumentLength];
750                 argumentTypeStarts = new int[argumentLength];
751                 argumentTypeEnds = new int[argumentLength];
752                 for (int i = 0; i < argumentLength; i++) {
753                         Argument argument = arguments[i];
754                         TypeReference argumentType = argument.type;
755                         argumentTypes[i] = returnTypeName(argumentType);
756                         argumentNames[i] = argument.name;
757                         argumentNameStarts[i] = argument.sourceStart;
758                         argumentNameEnds[i] = argument.sourceEnd;
759                         argumentTypeStarts[i] = argumentType.sourceStart;
760                         argumentTypeEnds[i] = argumentType.sourceEnd;
761                 }
762         }
763         TypeReference[] thrownExceptions = md.thrownExceptions;
764         char[][] exceptionTypes = null;
765         int[] exceptionTypeStarts = null;
766         int[] exceptionTypeEnds = null;
767         if (thrownExceptions != null) {
768                 int thrownExceptionLength = thrownExceptions.length;
769                 exceptionTypeStarts = new int[thrownExceptionLength];
770                 exceptionTypeEnds = new int[thrownExceptionLength];
771                 exceptionTypes = new char[thrownExceptionLength][];
772                 for (int i = 0; i < thrownExceptionLength; i++) {
773                         TypeReference exception = thrownExceptions[i];
774                         exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
775                         exceptionTypeStarts[i] = exception.sourceStart;
776                         exceptionTypeEnds[i] = exception.sourceEnd;
777                 }
778         }
779         requestor
780                 .enterMethod(
781                         md.declarationSourceStart, 
782                         intArrayStack[intArrayPtr--], 
783                         md.modifiers, 
784                         md.modifiersSourceStart, 
785                         returnTypeName, 
786                         returnType.sourceStart, 
787                         returnType.sourceEnd, 
788                         typeDims, 
789                         md.selector, 
790                         md.sourceStart, 
791                         (int) (selectorSourcePositions & 0xFFFFFFFFL), 
792                         argumentTypes, 
793                         argumentTypeStarts, 
794                         argumentTypeEnds, 
795                         argumentNames, 
796                         argumentNameStarts, 
797                         argumentNameEnds, 
798                         rParenPos, 
799                         extendsDim, 
800                         extendsDim == 0 ? -1 : endPosition, 
801                         exceptionTypes, 
802                         exceptionTypeStarts, 
803                         exceptionTypeEnds, 
804                         scanner.currentPosition - 1); 
805 }
806 protected void consumeMethodHeaderExtendedDims() {
807         // MethodHeaderExtendedDims ::= Dimsopt
808         // now we update the returnType of the method
809         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
810         int extendedDims = intStack[intPtr--];
811         extendsDim = extendedDims;
812         if (extendedDims != 0) {
813                 TypeReference returnType = md.returnType;
814                 md.sourceEnd = endPosition;
815                 int dims = returnType.dimensions() + extendedDims;
816                 int baseType;
817                 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
818                         //it was a baseType
819                         int sourceStart = returnType.sourceStart;
820                         int sourceEnd = returnType.sourceEnd;
821                         returnType = TypeReference.baseTypeReference(-baseType, dims);
822                         returnType.sourceStart = sourceStart;
823                         returnType.sourceEnd = sourceEnd;
824                         md.returnType = returnType;
825                 } else {
826                         md.returnType = this.copyDims(md.returnType, dims);
827                 }
828                 if (currentToken == TokenNameLBRACE) {
829                         md.bodyStart = endPosition + 1;
830                 }
831         }
832 }
833 protected void consumeMethodHeaderName() {
834         // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
835         MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
836
837         //name
838         md.selector = identifierStack[identifierPtr];
839         selectorSourcePositions = identifierPositionStack[identifierPtr--];
840         identifierLengthPtr--;
841         //type
842         md.returnType = getTypeReference(typeDims = intStack[intPtr--]);
843         //modifiers
844         md.declarationSourceStart = intStack[intPtr--];
845         md.modifiersSourceStart = intStack[intPtr--];
846         md.modifiers = intStack[intPtr--];
847
848         //highlight starts at selector start
849         md.sourceStart = (int) (selectorSourcePositions >>> 32);
850         pushOnAstStack(md);
851         md.bodyStart = scanner.currentPosition-1;
852 }
853 protected void consumeModifiers() {
854         checkAnnotation(); // might update modifiers with AccDeprecated
855         pushOnIntStack(modifiers); // modifiers
856         pushOnIntStack(modifiersSourceStart);
857         pushOnIntStack(
858                 declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); 
859         resetModifiers();
860 }
861 /**
862  *
863  * INTERNAL USE-ONLY
864  */
865 protected void consumePackageDeclarationName() {
866         /* persisting javadoc positions */
867         pushOnIntArrayStack(this.getJavaDocPositions());
868
869         super.consumePackageDeclarationName();
870         ImportReference importReference = compilationUnit.currentPackage;
871
872         requestor.acceptPackage(
873                 importReference.declarationSourceStart, 
874                 importReference.declarationSourceEnd, 
875                 intArrayStack[intArrayPtr--], 
876                 CharOperation.concatWith(importReference.getImportName(), '.'),
877                 importReference.sourceStart);
878 }
879 protected void consumePushModifiers() {
880         checkAnnotation(); // might update modifiers with AccDeprecated
881         pushOnIntStack(modifiers); // modifiers
882         if (modifiersSourceStart < 0) {
883                 pushOnIntStack(-1);
884                 pushOnIntStack(
885                         declarationSourceStart >= 0 ? declarationSourceStart : scanner.startPosition); 
886         } else {
887                 pushOnIntStack(modifiersSourceStart);
888                 pushOnIntStack(
889                         declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); 
890         }
891         resetModifiers();
892 }
893 /**
894  *
895  * INTERNAL USE-ONLY
896  */
897 protected void consumeSingleTypeImportDeclarationName() {
898         // SingleTypeImportDeclarationName ::= 'import' Name
899
900         /* persisting javadoc positions */
901         pushOnIntArrayStack(this.getJavaDocPositions());
902
903         super.consumeSingleTypeImportDeclarationName();
904         ImportReference importReference = (ImportReference) astStack[astPtr];
905         requestor.acceptImport(
906                 importReference.declarationSourceStart, 
907                 importReference.declarationSourceEnd,
908                 intArrayStack[intArrayPtr--],
909                 CharOperation.concatWith(importReference.getImportName(), '.'),
910                 importReference.sourceStart,
911                 false);
912 }
913 /**
914  *
915  * INTERNAL USE-ONLY
916  */
917 protected void consumeStaticInitializer() {
918         // StaticInitializer ::=  StaticOnly Block
919         //push an Initializer
920         //optimize the push/pop
921         super.consumeStaticInitializer();
922         Initializer initializer = (Initializer) astStack[astPtr];
923         requestor.acceptInitializer(
924                 initializer.declarationSourceStart,
925                 initializer.declarationSourceEnd,
926                 intArrayStack[intArrayPtr--],
927                 AccStatic, 
928                 intStack[intPtr--], 
929                 initializer.block.sourceStart,
930                 initializer.declarationSourceEnd);
931 }
932 protected void consumeStaticOnly() {
933         // StaticOnly ::= 'static'
934         checkAnnotation(); // might update declaration source start
935         pushOnIntStack(modifiersSourceStart);
936         pushOnIntStack(
937                 declarationSourceStart >= 0 ? declarationSourceStart : modifiersSourceStart); 
938         jumpOverMethodBody();
939         nestedMethod[nestedType]++;
940         resetModifiers();
941 }
942 /**
943  *
944  * INTERNAL USE-ONLY
945  */
946 protected void consumeTypeImportOnDemandDeclarationName() {
947         // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
948
949         /* persisting javadoc positions */
950         pushOnIntArrayStack(this.getJavaDocPositions());
951
952         super.consumeTypeImportOnDemandDeclarationName();
953         ImportReference importReference = (ImportReference) astStack[astPtr];
954         requestor.acceptImport(
955                 importReference.declarationSourceStart, 
956                 importReference.declarationSourceEnd,
957                 intArrayStack[intArrayPtr--],
958                 CharOperation.concatWith(importReference.getImportName(), '.'), 
959                 importReference.sourceStart,
960                 true);
961 }
962 public CompilationUnitDeclaration endParse(int act) {
963         if (scanner.recordLineSeparator) {
964                 requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
965         }
966         return super.endParse(act);
967 }
968 /*
969  * Flush annotations defined prior to a given positions.
970  *
971  * Note: annotations are stacked in syntactical order
972  *
973  * Either answer given <position>, or the end position of a comment line 
974  * immediately following the <position> (same line)
975  *
976  * e.g.
977  * void foo(){
978  * } // end of method foo
979  */
980  
981 public int flushAnnotationsDefinedPriorTo(int position) {
982
983         return lastFieldEndPosition = super.flushAnnotationsDefinedPriorTo(position);
984 }
985 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
986 This variable is a type reference and dim will be its dimensions*/
987
988         int length;
989         TypeReference ref;
990         if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
991                 // single variable reference
992                 if (dim == 0) {
993                         ref = 
994                                 new SingleTypeReference(
995                                         identifierStack[identifierPtr], 
996                                         identifierPositionStack[identifierPtr--]); 
997                 } else {
998                         ref = 
999                                 new ArrayTypeReference(
1000                                         identifierStack[identifierPtr], 
1001                                         dim, 
1002                                         identifierPositionStack[identifierPtr--]); 
1003                         ref.sourceEnd = endPosition;
1004                 }
1005         } else {
1006                 if (length < 0) { //flag for precompiled type reference on base types
1007                         ref = TypeReference.baseTypeReference(-length, dim);
1008                         ref.sourceStart = intStack[intPtr--];
1009                         if (dim == 0) {
1010                                 ref.sourceEnd = intStack[intPtr--];
1011                         } else {
1012                                 intPtr--;
1013                                 ref.sourceEnd = endPosition;
1014                         }
1015                 } else { //Qualified variable reference
1016                         char[][] tokens = new char[length][];
1017                         identifierPtr -= length;
1018                         long[] positions = new long[length];
1019                         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
1020                         System.arraycopy(
1021                                 identifierPositionStack, 
1022                                 identifierPtr + 1, 
1023                                 positions, 
1024                                 0, 
1025                                 length); 
1026                         if (dim == 0) {
1027                                 ref = new QualifiedTypeReference(tokens, positions);
1028                         } else {
1029                                 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
1030                                 ref.sourceEnd = endPosition;
1031                         }
1032                 }
1033         };
1034         return ref;
1035 }
1036 public void initialize() {
1037         //positionning the parser for a new compilation unit
1038         //avoiding stack reallocation and all that....
1039         super.initialize();
1040         intArrayPtr = -1;
1041 }
1042 /**
1043  *
1044  * INTERNAL USE-ONLY
1045  */
1046 private boolean isLocalDeclaration() {
1047         int nestedDepth = nestedType;
1048         while (nestedDepth >= 0) {
1049                 if (nestedMethod[nestedDepth] != 0) {
1050                         return true;
1051                 }
1052                 nestedDepth--;
1053         }
1054         return false;
1055 }
1056 /*
1057  * Investigate one entire unit.
1058  */
1059 public void parseCompilationUnit(ICompilationUnit unit) {
1060         char[] regionSource = unit.getContents();
1061         try {
1062                 initialize();
1063                 goForCompilationUnit();
1064                 referenceContext =
1065                         compilationUnit = 
1066                                 compilationUnit = 
1067                                         new CompilationUnitDeclaration(
1068                                                 problemReporter(), 
1069                                                 new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit), 
1070                                                 regionSource.length); 
1071                 scanner.resetTo(0, regionSource.length);
1072                 scanner.setSource(regionSource);
1073                 parse();
1074         } catch (AbortCompilation ex) {
1075         }
1076 }
1077 /*
1078  * Investigate one constructor declaration.
1079  */
1080 public void parseConstructor(char[] regionSource) {
1081         try {
1082                 initialize();
1083                 goForClassBodyDeclarations();
1084                 referenceContext = 
1085                         compilationUnit = 
1086                                 compilationUnit = 
1087                                         new CompilationUnitDeclaration(
1088                                                 problemReporter(), 
1089                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1090                                                 regionSource.length); 
1091                 scanner.resetTo(0, regionSource.length);
1092                 scanner.setSource(regionSource);
1093                 parse();
1094         } catch (AbortCompilation ex) {
1095         }
1096 }
1097 /*
1098  * Investigate one field declaration statement (might have multiple declarations in it).
1099  */
1100 public void parseField(char[] regionSource) {
1101         try {
1102                 initialize();
1103                 goForFieldDeclaration();
1104                 referenceContext = 
1105                         compilationUnit = 
1106                                 compilationUnit = 
1107                                         new CompilationUnitDeclaration(
1108                                                 problemReporter(), 
1109                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1110                                                 regionSource.length); 
1111                 scanner.resetTo(0, regionSource.length);
1112                 scanner.setSource(regionSource);
1113                 parse();
1114         } catch (AbortCompilation ex) {
1115         }
1116
1117 }
1118 /*
1119  * Investigate one import statement declaration.
1120  */
1121 public void parseImport(char[] regionSource) {
1122         try {
1123                 initialize();
1124                 goForImportDeclaration();
1125                 referenceContext = 
1126                         compilationUnit = 
1127                                 compilationUnit = 
1128                                         new CompilationUnitDeclaration(
1129                                                 problemReporter(), 
1130                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1131                                                 regionSource.length); 
1132                 scanner.resetTo(0, regionSource.length);
1133                 scanner.setSource(regionSource);
1134                 parse();
1135         } catch (AbortCompilation ex) {
1136         }
1137
1138 }
1139 /*
1140  * Investigate one initializer declaration.
1141  * regionSource need to content exactly an initializer declaration.
1142  * e.g: static { i = 4; }
1143  * { name = "test"; }
1144  */
1145 public void parseInitializer(char[] regionSource) {
1146         try {
1147                 initialize();
1148                 goForInitializer();
1149                 referenceContext = 
1150                         compilationUnit = 
1151                                 compilationUnit = 
1152                                         new CompilationUnitDeclaration(
1153                                                 problemReporter(), 
1154                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1155                                                 regionSource.length); 
1156                 scanner.resetTo(0, regionSource.length);
1157                 scanner.setSource(regionSource);
1158                 parse();
1159         } catch (AbortCompilation ex) {
1160         }
1161
1162 }
1163 /*
1164  * Investigate one method declaration.
1165  */
1166 public void parseMethod(char[] regionSource) {
1167         try {
1168                 initialize();
1169                 goForGenericMethodDeclaration();
1170                 referenceContext = 
1171                         compilationUnit = 
1172                                 compilationUnit = 
1173                                         new CompilationUnitDeclaration(
1174                                                 problemReporter(), 
1175                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1176                                                 regionSource.length); 
1177                 scanner.resetTo(0, regionSource.length);
1178                 scanner.setSource(regionSource);
1179                 parse();
1180         } catch (AbortCompilation ex) {
1181         }
1182
1183 }
1184 /*
1185  * Investigate one package statement declaration.
1186  */
1187 public void parsePackage(char[] regionSource) {
1188         try {
1189                 initialize();
1190                 goForPackageDeclaration();
1191                 referenceContext = 
1192                         compilationUnit = 
1193                                 compilationUnit = 
1194                                         new CompilationUnitDeclaration(
1195                                                 problemReporter(), 
1196                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1197                                                 regionSource.length); 
1198                 scanner.resetTo(0, regionSource.length);
1199                 scanner.setSource(regionSource);
1200                 parse();
1201         } catch (AbortCompilation ex) {
1202         }
1203
1204 }
1205 /*
1206  * Investigate one type declaration, its fields, methods and member types.
1207  */
1208 public void parseType(char[] regionSource) {
1209         try {
1210                 initialize();
1211                 goForTypeDeclaration();
1212                 referenceContext = 
1213                         compilationUnit = 
1214                                 compilationUnit = 
1215                                         new CompilationUnitDeclaration(
1216                                                 problemReporter(), 
1217                                                 new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit), 
1218                                                 regionSource.length); 
1219                 scanner.resetTo(0, regionSource.length);
1220                 scanner.setSource(regionSource);
1221                 parse();
1222         } catch (AbortCompilation ex) {
1223         }
1224
1225 }
1226 /**
1227  * Returns this parser's problem reporter initialized with its reference context.
1228  * Also it is assumed that a problem is going to be reported, so initializes
1229  * the compilation result's line positions.
1230  */
1231 public ProblemReporter problemReporter() {
1232         problemReporter.referenceContext = referenceContext;
1233         return problemReporter;
1234 }
1235 protected void pushOnIntArrayStack(int[] positions) {
1236
1237         try {
1238                 intArrayStack[++intArrayPtr] = positions;
1239         } catch (IndexOutOfBoundsException e) {
1240                 //intPtr is correct 
1241                 int oldStackLength = intArrayStack.length;
1242                 int oldStack[][] = intArrayStack;
1243                 intArrayStack = new int[oldStackLength + StackIncrement][];
1244                 System.arraycopy(oldStack, 0, intArrayStack, 0, oldStackLength);
1245                 intArrayStack[intArrayPtr] = positions;
1246         }
1247 }
1248 protected void resetModifiers() {
1249         super.resetModifiers();
1250         declarationSourceStart = -1;
1251 }
1252 /*
1253  * Syntax error was detected. Will attempt to perform some recovery action in order
1254  * to resume to the regular parse loop.
1255  */
1256 protected boolean resumeOnSyntaxError() {
1257         return false;
1258 }
1259 /*
1260  * Answer a char array representation of the type name formatted like:
1261  * - type name + dimensions
1262  * Example:
1263  * "A[][]".toCharArray()
1264  * "java.lang.String".toCharArray()
1265  */
1266 private char[] returnTypeName(TypeReference type) {
1267         int dimension = type.dimensions();
1268         if (dimension != 0) {
1269                 char[] dimensionsArray = new char[dimension * 2];
1270                 for (int i = 0; i < dimension; i++) {
1271                         dimensionsArray[i*2] = '[';
1272                         dimensionsArray[(i*2) + 1] = ']';
1273                 }
1274                 return CharOperation.concat(
1275                         CharOperation.concatWith(type.getTypeName(), '.'), 
1276                         dimensionsArray); 
1277         }
1278         return CharOperation.concatWith(type.getTypeName(), '.');
1279 }
1280 public String toString() {
1281         StringBuffer buffer = new StringBuffer();
1282         buffer.append("intArrayPtr = " + intArrayPtr + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1283         buffer.append(super.toString());
1284         return buffer.toString();
1285 }
1286 /**
1287  * INTERNAL USE ONLY
1288  */
1289 protected TypeReference typeReference(
1290         int dim,
1291         int localIdentifierPtr, 
1292         int localIdentifierLengthPtr) {
1293         /* build a Reference on a variable that may be qualified or not
1294          * This variable is a type reference and dim will be its dimensions.
1295          * We don't have any side effect on the stacks' pointers.
1296          */
1297
1298         int length;
1299         TypeReference ref;
1300         if ((length = identifierLengthStack[localIdentifierLengthPtr]) == 1) {
1301                 // single variable reference
1302                 if (dim == 0) {
1303                         ref = 
1304                                 new SingleTypeReference(
1305                                         identifierStack[localIdentifierPtr], 
1306                                         identifierPositionStack[localIdentifierPtr--]); 
1307                 } else {
1308                         ref = 
1309                                 new ArrayTypeReference(
1310                                         identifierStack[localIdentifierPtr], 
1311                                         dim, 
1312                                         identifierPositionStack[localIdentifierPtr--]); 
1313                         ref.sourceEnd = endPosition;                            
1314                 }
1315         } else {
1316                 if (length < 0) { //flag for precompiled type reference on base types
1317                         ref = TypeReference.baseTypeReference(-length, dim);
1318                         ref.sourceStart = intStack[localIntPtr--];
1319                         if (dim == 0) {
1320                                 ref.sourceEnd = intStack[localIntPtr--];
1321                         } else {
1322                                 localIntPtr--;
1323                                 ref.sourceEnd = endPosition;
1324                         }
1325                 } else { //Qualified variable reference
1326                         char[][] tokens = new char[length][];
1327                         localIdentifierPtr -= length;
1328                         long[] positions = new long[length];
1329                         System.arraycopy(identifierStack, localIdentifierPtr + 1, tokens, 0, length);
1330                         System.arraycopy(
1331                                 identifierPositionStack, 
1332                                 localIdentifierPtr + 1, 
1333                                 positions, 
1334                                 0, 
1335                                 length); 
1336                         if (dim == 0)
1337                                 ref = new QualifiedTypeReference(tokens, positions);
1338                         else
1339                                 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
1340                 }
1341         };
1342         return ref;
1343 }
1344 }