removed Makefile; lifted repo/org.ibex.tool/src/ to src/
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / Parser.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *     Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196
11  *******************************************************************************/
12 package org.eclipse.jdt.internal.compiler.parser;
13
14 import java.io.*;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Locale;
20 import java.util.MissingResourceException;
21 import java.util.ResourceBundle;
22
23 import org.eclipse.jdt.core.compiler.CharOperation;
24 import org.eclipse.jdt.core.compiler.InvalidInputException;
25 import org.eclipse.jdt.internal.compiler.CompilationResult;
26 import org.eclipse.jdt.internal.compiler.ast.*;
27 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
28 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
29 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
30 import org.eclipse.jdt.internal.compiler.lookup.BindingIds;
31 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
32 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
33 import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
34 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
35 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
36 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
37 import org.eclipse.jdt.internal.compiler.util.Util;
38
39 public class Parser implements BindingIds, ParserBasicInformation, TerminalTokens, CompilerModifiers, OperatorIds, TypeIds {
40         protected ProblemReporter problemReporter;
41         protected CompilerOptions options;
42         public int firstToken ; // handle for multiple parsing goals
43         public int lastAct ; //handle for multiple parsing goals
44         public ReferenceContext referenceContext;
45         public int currentToken;
46         private int synchronizedBlockSourceStart;
47
48         //error recovery management
49         protected int lastCheckPoint;
50         protected RecoveredElement currentElement;
51         public static boolean VERBOSE_RECOVERY = false;
52         protected boolean restartRecovery;
53         protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
54         protected boolean hasError;
55         protected boolean hasReportedError;
56         public boolean reportSyntaxErrorIsRequired = true;
57         public boolean reportOnlyOneSyntaxError = false;
58         protected int recoveredStaticInitializerStart;
59         protected int lastIgnoredToken, nextIgnoredToken;
60         protected int lastErrorEndPosition;
61         protected boolean ignoreNextOpeningBrace;
62                 
63         //internal data for the automat 
64         protected final static int StackIncrement = 255;
65         protected int stateStackTop;
66         protected int[] stack = new int[StackIncrement];
67         //scanner token 
68         public Scanner scanner;
69         //ast stack
70         final static int AstStackIncrement = 100;
71         protected int astPtr;
72         protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
73         protected int astLengthPtr;
74         protected int[] astLengthStack;
75         public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
76         ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
77         //expression stack
78         final static int ExpressionStackIncrement = 100;
79         protected int expressionPtr;
80         protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
81         protected int expressionLengthPtr;
82         protected int[] expressionLengthStack;
83         Expression [] noExpressions = new Expression[ExpressionStackIncrement];
84         //identifiers stacks 
85         protected int identifierPtr;
86         protected char[][] identifierStack;
87         protected int identifierLengthPtr;
88         protected int[] identifierLengthStack;
89         protected long[] identifierPositionStack;
90         //positions , dimensions , .... (int stacks)
91         protected int intPtr;
92         protected int[] intStack;
93         protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
94         protected int endStatementPosition;
95         protected int lParenPos,rParenPos; //accurate only when used !
96         protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
97         //modifiers dimensions nestedType etc.......
98         protected boolean optimizeStringLiterals =true;
99         protected int modifiers;
100         protected int modifiersSourceStart;
101         protected int nestedType, dimensions;
102         protected int[] nestedMethod; //the ptr is nestedType
103         protected int[] realBlockStack;
104         protected int realBlockPtr;
105         protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
106         protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
107         protected int[] variablesCounter;
108
109         // javadoc
110         public JavadocParser javadocParser;
111         public Javadoc javadoc;
112         
113         public static byte rhs[] = null;
114         public static char asb[] = null;
115         public static char asr[] = null;
116         public static char nasb[] = null;
117         public static char nasr[] = null;
118
119         public static char terminal_index[] = null;
120         public static char non_terminal_index[] = null;
121         
122         public static char term_action[] = null;
123         public static byte term_check[] = null;
124
125         private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
126         private static final String INVALID_CHARACTER = "Invalid Character" ; //$NON-NLS-1$
127         private static final String EOF_TOKEN = "$eof" ; //$NON-NLS-1$
128         private static final String ERROR_TOKEN = "$error" ; //$NON-NLS-1$
129
130         public static String name[] = null;
131         public static String readableName[] = null;
132     
133         public static short check_table[] = null;
134         public static char lhs[] =  null;
135         public static char base_action[] = lhs;
136         
137         public static char scope_prefix[] = null;
138     public static char scope_suffix[] = null;
139     public static char scope_lhs[] = null;
140     
141     public static byte scope_la[] = null;
142
143     public static char scope_state_set[] = null;
144     public static char scope_rhs[] = null;
145     public static char scope_state[] = null;
146     public static char in_symb[] = null;
147     
148         private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
149         private final static String READABLE_NAMES_FILE = "readableNames"; //$NON-NLS-1$
150         private final static String READABLE_NAMES =
151                 "org.eclipse.jdt.internal.compiler.parser." + READABLE_NAMES_FILE; //$NON-NLS-1$
152
153         static {
154                 try{
155                         initTables();
156                 } catch(java.io.IOException ex){
157                         throw new ExceptionInInitializerError(ex.getMessage());
158                 }
159         }
160
161         public static final int RoundBracket = 0;
162         public static final int SquareBracket = 1;
163         public static final int CurlyBracket = 2;
164         public static final int BracketKinds = 3;
165
166 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
167                 
168         this.problemReporter = problemReporter;
169         this.options = problemReporter.options;
170         this.optimizeStringLiterals = optimizeStringLiterals;
171         this.initializeScanner();
172         this.astLengthStack = new int[50];
173         this.expressionLengthStack = new int[30];
174         this.intStack = new int[50];
175         this.identifierStack = new char[30][];
176         this.identifierLengthStack = new int[30];
177         this.nestedMethod = new int[30];
178         this.realBlockStack = new int[30];
179         this.identifierPositionStack = new long[30];
180         this.variablesCounter = new int[30];
181         
182         // javadoc support
183         this.javadocParser = new JavadocParser(this);   
184 }
185 /**
186  *
187  * INTERNAL USE-ONLY
188  */
189 protected void adjustInterfaceModifiers() {
190         this.intStack[this.intPtr - 1] |= AccInterface;
191 }
192 public final void arrayInitializer(int length) {
193         //length is the size of the array Initializer
194         //expressionPtr points on the last elt of the arrayInitializer, 
195         // in other words, it has not been decremented yet.
196
197         ArrayInitializer ai = new ArrayInitializer();
198         if (length != 0) {
199                 this.expressionPtr -= length;
200                 System.arraycopy(this.expressionStack, this.expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
201         }
202         pushOnExpressionStack(ai);
203         //positionning
204         ai.sourceEnd = this.endStatementPosition;
205         int searchPosition = length == 0 ? this.endPosition + 1 : ai.expressions[0].sourceStart;
206         try {
207                 //does not work with comments(that contain '{') nor '{' describes as a unicode....              
208                 while (this.scanner.source[--searchPosition] != '{'){/*empty*/}
209         } catch (IndexOutOfBoundsException ex) {
210                 //should never occur (except for strange cases like whose describe above)
211                 searchPosition = (length == 0 ? this.endPosition : ai.expressions[0].sourceStart) - 1;
212         }
213         ai.sourceStart = searchPosition;
214 }
215 public static int asi(int state) {
216
217         return asb[original_state(state)]; 
218 }
219 protected void blockReal() {
220         // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
221         // increment the amount of declared variables for this block
222         this.realBlockStack[this.realBlockPtr]++;
223 }
224 private final static void buildFileOfByteFor(String filename, String tag, String[] tokens) throws java.io.IOException {
225
226         //transform the String tokens into chars before dumping then into file
227
228         int i = 0;
229         //read upto the tag
230         while (!tokens[i++].equals(tag)){/*empty*/}
231         //read upto the }
232         
233         byte[] bytes = new byte[tokens.length]; //can't be bigger
234         int ic = 0;
235         String token;
236         while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
237                 int c = Integer.parseInt(token);
238                 bytes[ic++] = (byte) c;
239         }
240
241         //resize
242         System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
243
244         buildFileForTable(filename, bytes);
245 }
246 private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) throws java.io.IOException {
247
248         //transform the String tokens into chars before dumping then into file
249
250         int i = 0;
251         //read upto the tag
252         while (!tokens[i++].equals(tag)){/*empty*/}
253         //read upto the }
254         
255         char[] chars = new char[tokens.length]; //can't be bigger
256         int ic = 0;
257         String token;
258         while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
259                 int c = Integer.parseInt(token);
260                 chars[ic++] = (char) c;
261         }
262
263         //resize
264         System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
265
266         buildFileForTable(filename, chars);
267         return chars;
268 }
269 private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) throws java.io.IOException {
270
271         //transform the String tokens into chars before dumping then into file
272
273         int i = 0;
274         //read upto the tag
275         while (!tokens[i++].equals(tag)){/*empty*/}
276         //read upto the }
277         
278         char[] chars = new char[tokens.length]; //can't be bigger
279         int ic = 0;
280         String token;
281         while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
282                 int c = Integer.parseInt(token);
283                 chars[ic++] = (char) (c + 32768);
284         }
285
286         //resize
287         System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
288
289         buildFileForTable(filename, chars);
290 }
291 private final static String[] buildFileForName(String filename, String contents) throws java.io.IOException {
292         String[] result = new String[contents.length()];
293         result[0] = null;
294         int resultCount = 1;
295         
296         StringBuffer buffer = new StringBuffer();
297         
298         int start = contents.indexOf("name[]"); //$NON-NLS-1$
299         start = contents.indexOf('\"', start); 
300         int end = contents.indexOf("};", start); //$NON-NLS-1$
301         
302         contents = contents.substring(start, end);
303         
304         boolean addLineSeparator = false;
305         int tokenStart = -1;
306         StringBuffer currentToken = new StringBuffer();
307         for (int i = 0; i < contents.length(); i++) {
308                 char c = contents.charAt(i);
309                 if(c == '\"') {
310                         if(tokenStart == -1) {
311                                 tokenStart = i + 1;     
312                         } else {
313                                 if(addLineSeparator) {
314                                         buffer.append('\n');
315                                         result[resultCount++] = currentToken.toString();
316                                         currentToken = new StringBuffer();
317                                 }
318                                 String token = contents.substring(tokenStart, i);
319                                 if(token.equals(ERROR_TOKEN)){
320                                         token = INVALID_CHARACTER;
321                                 } else if(token.equals(EOF_TOKEN)) {
322                                         token = UNEXPECTED_EOF;
323                                 }
324                                 buffer.append(token);
325                                 currentToken.append(token);
326                                 addLineSeparator = true;
327                                 tokenStart = -1;
328                         }
329                 }
330                 if(tokenStart == -1 && c == '+'){
331                         addLineSeparator = false;
332                 }
333         }
334         if(currentToken.length() > 0) {
335                 result[resultCount++] = currentToken.toString();
336         }
337         
338         buildFileForTable(filename, buffer.toString().toCharArray());
339         
340         System.arraycopy(result, 0, result = new String[resultCount], 0, resultCount);
341         return result;
342 }
343 private static void buildFileForReadableName(
344         String file,
345         char[] newLhs,
346         char[] newNonTerminalIndex,
347         String[] newName,
348         String[] tokens) throws java.io.IOException {
349
350         ArrayList entries = new ArrayList();
351         
352         boolean[] alreadyAdded = new boolean[newName.length];
353         
354         for (int i = 0; i < tokens.length; i = i + 2) {
355                 int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i])]];
356                 StringBuffer buffer = new StringBuffer();
357                 if(!alreadyAdded[index]) {
358                         alreadyAdded[index] = true;
359                         buffer.append(newName[index]);
360                         buffer.append('=');
361                         buffer.append(tokens[i+1].trim());
362                         buffer.append('\n');
363                         entries.add(String.valueOf(buffer));
364                 }
365         }
366         int i = 1;
367         while(!INVALID_CHARACTER.equals(newName[i])) i++;
368         i++;
369         for (; i < alreadyAdded.length; i++) {
370                 if(!alreadyAdded[i]) {
371                         System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
372                 }
373         }
374         Collections.sort(entries);
375         buildFile(file, entries);
376 }
377 private final static void buildFile(String filename, List listToDump) throws java.io.IOException {
378         BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
379         for (Iterator iterator = listToDump.iterator(); iterator.hasNext(); ) {
380                 writer.write(String.valueOf(iterator.next()));
381         }
382         writer.flush();
383         writer.close();
384         System.out.println(filename + " creation complete"); //$NON-NLS-1$
385 }
386 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
387
388         byte[] bytes = new byte[chars.length * 2];
389         for (int i = 0; i < chars.length; i++) {
390                 bytes[2 * i] = (byte) (chars[i] >>> 8);
391                 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
392         }
393
394         java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
395         stream.write(bytes);
396         stream.close();
397         System.out.println(filename + " creation complete"); //$NON-NLS-1$
398 }
399 private final static void buildFileForTable(String filename, byte[] bytes) throws java.io.IOException {
400         java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
401         stream.write(bytes);
402         stream.close();
403         System.out.println(filename + " creation complete"); //$NON-NLS-1$
404 }
405 public final static void buildFilesFromLPG(String dataFilename, String dataFilename2)   throws java.io.IOException {
406
407         //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
408
409         //build from the lpg javadcl.java files that represents the parser tables
410         //lhs check_table asb asr symbol_index
411
412         //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
413
414         char[] contents = new char[] {};
415         try {
416                 contents = Util.getFileCharContent(new File(dataFilename), null);
417         } catch (IOException ex) {
418                 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
419                 return;
420         }
421         java.util.StringTokenizer st = 
422                 new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;");  //$NON-NLS-1$
423         String[] tokens = new String[st.countTokens()];
424         int i = 0;
425         while (st.hasMoreTokens()) {
426                 tokens[i++] = st.nextToken();
427         }
428         final String prefix = FILEPREFIX;
429         i = 0;
430         
431         char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
432         buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
433         buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
434         buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
435         buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
436         buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
437         buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
438         char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
439         buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
440         
441         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
442         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
443         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
444         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
445         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
446         buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
447         buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
448         
449         buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
450         buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
451         buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
452         
453         String[] newName = buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$
454         
455         contents = new char[] {};
456         try {
457                 contents = Util.getFileCharContent(new File(dataFilename2), null);
458         } catch (IOException ex) {
459                 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
460                 return;
461         }
462         st = new java.util.StringTokenizer(new String(contents), "\t\n\r=");  //$NON-NLS-1$
463         tokens = new String[st.countTokens()];
464         i = 0;
465         while (st.hasMoreTokens()) {
466                 tokens[i++] = st.nextToken();
467         }
468         buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
469         
470         System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
471 }
472 /*
473  * Build initial recovery state.
474  * Recovery state is inferred from the current state of the parser (reduced node stack).
475  */
476 public RecoveredElement buildInitialRecoveryState(){
477
478         /* initialize recovery by retrieving available reduced nodes 
479          * also rebuild bracket balance 
480          */
481         this.lastCheckPoint = 0;
482
483         RecoveredElement element = null;
484         if (this.referenceContext instanceof CompilationUnitDeclaration){
485                 element = new RecoveredUnit(this.compilationUnit, 0, this);
486                 
487                 /* ignore current stack state, since restarting from the beginnning 
488                    since could not trust simple brace count */
489                 if (true){ // experimenting restart recovery from scratch
490                         this.compilationUnit.currentPackage = null;
491                         this.compilationUnit.imports = null;
492                         this.compilationUnit.types = null;
493                         this.currentToken = 0;
494                         this.listLength = 0;
495                         this.endPosition = 0;
496                         this.endStatementPosition = 0;
497                         return element;
498                 }
499                 if (this.compilationUnit.currentPackage != null){
500                         this.lastCheckPoint = this.compilationUnit.currentPackage.declarationSourceEnd+1;
501                 }
502                 if (this.compilationUnit.imports != null){
503                         this.lastCheckPoint = this.compilationUnit.imports[this.compilationUnit.imports.length -1].declarationSourceEnd+1;              
504                 }
505         } else {
506                 if (this.referenceContext instanceof AbstractMethodDeclaration){
507                         element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
508                         this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
509                 } else {
510                         /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
511                         if (this.referenceContext instanceof TypeDeclaration){
512                                 TypeDeclaration type = (TypeDeclaration) this.referenceContext;
513                                 for (int i = 0; i < type.fields.length; i++){
514                                         FieldDeclaration field = type.fields[i];                                        
515                                         if (field != null
516                                                 && !field.isField()
517                                                 && field.declarationSourceStart <= this.scanner.initialPosition
518                                                 && this.scanner.initialPosition <= field.declarationSourceEnd
519                                                 && this.scanner.eofPosition <= field.declarationSourceEnd+1){
520                                                 element = new RecoveredInitializer(field, null, 1, this);
521                                                 this.lastCheckPoint = field.declarationSourceStart;                                     
522                                                 break;
523                                         }
524                                 }
525                         } 
526                 }
527         }
528
529         if (element == null) return element;
530         
531         for(int i = 0; i <= this.astPtr; i++){
532                 ASTNode node = this.astStack[i];
533                 if (node instanceof AbstractMethodDeclaration){
534                         AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
535                         if (method.declarationSourceEnd == 0){
536                                 element = element.add(method, 0);
537                                 this.lastCheckPoint = method.bodyStart;
538                         } else {
539                                 element = element.add(method, 0);
540                                 this.lastCheckPoint = method.declarationSourceEnd + 1;
541                         }
542                         continue;
543                 }
544                 if (node instanceof Initializer){
545                         Initializer initializer = (Initializer) node;
546                         if (initializer.declarationSourceEnd == 0){
547                                 element = element.add(initializer, 1);
548                                 this.lastCheckPoint = initializer.sourceStart;                          
549                         } else {
550                                 element = element.add(initializer, 0);
551                                 this.lastCheckPoint = initializer.declarationSourceEnd + 1;
552                         }
553                         continue;
554                 }               
555                 if (node instanceof FieldDeclaration){
556                         FieldDeclaration field = (FieldDeclaration) node;
557                         if (field.declarationSourceEnd == 0){
558                                 element = element.add(field, 0);
559                                 if (field.initialization == null){
560                                         this.lastCheckPoint = field.sourceEnd + 1;
561                                 } else {
562                                         this.lastCheckPoint = field.initialization.sourceEnd + 1;
563                                 }
564                         } else {
565                                 element = element.add(field, 0);
566                                 this.lastCheckPoint = field.declarationSourceEnd + 1;
567                         }
568                         continue;
569                 }
570                 if (node instanceof TypeDeclaration){
571                         TypeDeclaration type = (TypeDeclaration) node;
572                         if (type.declarationSourceEnd == 0){
573                                 element = element.add(type, 0); 
574                                 this.lastCheckPoint = type.bodyStart;
575                         } else {
576                                 element = element.add(type, 0);                         
577                                 this.lastCheckPoint = type.declarationSourceEnd + 1;
578                         }
579                         continue;
580                 }
581                 if (node instanceof ImportReference){
582                         ImportReference importRef = (ImportReference) node;
583                         element = element.add(importRef, 0);
584                         this.lastCheckPoint = importRef.declarationSourceEnd + 1;
585                 }
586         }
587         return element;
588 }
589 public final static short base_check(int i) {
590         return check_table[i - (NUM_RULES + 1)];
591 }
592 public final void checkAndSetModifiers(int flag){
593         /*modify the current modifiers buffer.
594         When the startPosition of the modifiers is 0
595         it means that the modifier being parsed is the first
596         of a list of several modifiers. The startPosition
597         is zeroed when a copy of modifiers-buffer is push
598         onto the astStack. */
599
600         if ((this.modifiers & flag) != 0){ // duplicate modifier
601                 this.modifiers |= AccAlternateModifierProblem;
602         }
603         this.modifiers |= flag;
604                         
605         if (this.modifiersSourceStart < 0) this.modifiersSourceStart = this.scanner.startPosition;
606 }
607 public void checkComment() {
608
609         if (this.currentElement != null && this.scanner.commentPtr >= 0) {
610                 flushCommentsDefinedPriorTo(this.endStatementPosition); // discard obsolete comments during recovery
611         }
612         
613         int lastComment = this.scanner.commentPtr;
614         
615         if (this.modifiersSourceStart >= 0) {
616                 // eliminate comments located after modifierSourceStart if positionned
617                 while (lastComment >= 0 && this.scanner.commentStarts[lastComment] > this.modifiersSourceStart) lastComment--;
618         }
619         if (lastComment >= 0) {
620                 // consider all remaining leading comments to be part of current declaration
621                 this.modifiersSourceStart = this.scanner.commentStarts[0]; 
622         
623                 // check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)      
624                 while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
625                 if (lastComment >= 0 && this.javadocParser != null) {
626                         if (this.javadocParser.checkDeprecation(
627                                         this.scanner.commentStarts[lastComment],
628                                         this.scanner.commentStops[lastComment] - 1)) { //stop is one over,
629                                 checkAndSetModifiers(AccDeprecated);
630                         }
631                         this.javadoc = this.javadocParser.docComment;   // null if check javadoc is not activated 
632                 }
633         }
634 }
635 protected void checkNonExternalizedStringLiteral() {
636         if (this.scanner.wasNonExternalizedStringLiteral) {
637                 StringLiteral[] literals = this.scanner.nonNLSStrings;
638                 // could not reproduce, but this is the only NPE
639                 // added preventive null check see PR 9035
640                 if (literals != null) {
641                         for (int i = 0, max = literals.length; i < max; i++) {
642                                 problemReporter().nonExternalizedStringLiteral(literals[i]);
643                         }
644                 }
645                 this.scanner.wasNonExternalizedStringLiteral = false;
646         }
647 }
648 protected void checkNonNLSAfterBodyEnd(int declarationEnd){
649         if(this.scanner.currentPosition - 1 <= declarationEnd) {
650                 this.scanner.eofPosition = declarationEnd < Integer.MAX_VALUE ? declarationEnd + 1 : declarationEnd;
651                 try {
652                         while(this.scanner.getNextToken() != TokenNameEOF){/*empty*/}
653                         checkNonExternalizedStringLiteral();
654                 } catch (InvalidInputException e) {
655                         // Nothing to do
656                 }
657         }
658 }
659 protected char getNextCharacter(char[] comment, int[] index) {
660         char nextCharacter = comment[index[0]++];
661         switch(nextCharacter) {
662                 case '\\' :
663                         int c1, c2, c3, c4;
664                         index[0]++;
665                         while (comment[index[0]] == 'u') index[0]++;
666                         if (!(((c1 = Character.getNumericValue(comment[index[0]++])) > 15
667                                 || c1 < 0)
668                                 || ((c2 = Character.getNumericValue(comment[index[0]++])) > 15 || c2 < 0)
669                                 || ((c3 = Character.getNumericValue(comment[index[0]++])) > 15 || c3 < 0)
670                                 || ((c4 = Character.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) {
671                                         nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
672                         }
673                         break;
674         }
675         return nextCharacter;
676 }
677 protected void classInstanceCreation(boolean alwaysQualified) {
678         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
679
680         // ClassBodyopt produces a null item on the astStak if it produces NO class body
681         // An empty class body produces a 0 on the length stack.....
682
683         AllocationExpression alloc;
684         int length;
685         if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
686                 && (this.astStack[this.astPtr] == null)) {
687                 //NO ClassBody
688                 this.astPtr--;
689                 if (alwaysQualified) {
690                         alloc = new QualifiedAllocationExpression();
691                 } else {
692                         alloc = new AllocationExpression();
693                 }
694                 alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
695
696                 if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
697                         this.expressionPtr -= length;
698                         System.arraycopy(
699                                 this.expressionStack, 
700                                 this.expressionPtr + 1, 
701                                 alloc.arguments = new Expression[length], 
702                                 0, 
703                                 length); 
704                 }
705                 alloc.type = getTypeReference(0);
706                 //the default constructor with the correct number of argument
707                 //will be created and added by the TC (see createsInternalConstructorWithBinding)
708                 alloc.sourceStart = this.intStack[this.intPtr--];
709                 pushOnExpressionStack(alloc);
710         } else {
711                 dispatchDeclarationInto(length);
712                 TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
713                 anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
714                 anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
715                 if (anonymousTypeDeclaration.allocation != null) {
716                         anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
717                 }
718                 if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
719                         anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlockMASK;
720                 }
721                 this.astPtr--;
722                 this.astLengthPtr--;
723                 
724                 // mark initializers with local type mark if needed
725                 markInitializersWithLocalType(anonymousTypeDeclaration);
726         }
727 }
728 protected final void concatExpressionLists() {
729         this.expressionLengthStack[--this.expressionLengthPtr]++;
730 }
731 private final void concatNodeLists() {
732         /*
733          * This is a case where you have two sublists into the astStack that you want
734          * to merge in one list. There is no action required on the astStack. The only
735          * thing you need to do is merge the two lengths specified on the astStackLength.
736          * The top two length are for example:
737          * ... p   n
738          * and you want to result in a list like:
739          * ... n+p 
740          * This means that the p could be equals to 0 in case there is no astNode pushed
741          * on the astStack.
742          * Look at the InterfaceMemberDeclarations for an example.
743          */
744
745         this.astLengthStack[this.astLengthPtr - 1] += this.astLengthStack[this.astLengthPtr--];
746 }
747 protected void consumeAllocationHeader() {
748         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
749
750         // ClassBodyopt produces a null item on the astStak if it produces NO class body
751         // An empty class body produces a 0 on the length stack.....
752
753         if (this.currentElement == null){
754                 return; // should never occur, this consumeRule is only used in recovery mode
755         }
756         if (this.currentToken == TokenNameLBRACE){
757                 // beginning of an anonymous type
758                 TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
759                 anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
760                 anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
761                 anonymousType.sourceStart = this.intStack[this.intPtr--];
762                 anonymousType.sourceEnd = this.rParenPos; // closing parenthesis
763                 QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
764                 alloc.type = getTypeReference(0);
765                 alloc.sourceStart = anonymousType.sourceStart;
766                 alloc.sourceEnd = anonymousType.sourceEnd ;
767                 anonymousType.allocation = alloc; 
768                 this.lastCheckPoint = anonymousType.bodyStart = this.scanner.currentPosition;
769                 this.currentElement = this.currentElement.add(anonymousType, 0);
770                 this.lastIgnoredToken = -1;
771                 this.currentToken = 0; // opening brace already taken into account
772                 return;
773         }
774         this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
775         this.restartRecovery = true; // request to restart from here on
776 }
777 protected void consumeArgumentList() {
778         // ArgumentList ::= ArgumentList ',' Expression
779         concatExpressionLists();
780 }
781 protected void consumeArrayAccess(boolean unspecifiedReference) {
782         // ArrayAccess ::= Name '[' Expression ']' ==> true
783         // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
784
785
786         //optimize push/pop
787         Expression exp;
788         if (unspecifiedReference) {
789                 exp = 
790                         this.expressionStack[this.expressionPtr] = 
791                                 new ArrayReference(
792                                         getUnspecifiedReferenceOptimized(),
793                                         this.expressionStack[this.expressionPtr]);
794         } else {
795                 this.expressionPtr--;
796                 this.expressionLengthPtr--;
797                 exp = 
798                         this.expressionStack[this.expressionPtr] = 
799                                 new ArrayReference(
800                                         this.expressionStack[this.expressionPtr],
801                                         this.expressionStack[this.expressionPtr + 1]);
802         }
803         exp.sourceEnd = this.endPosition;
804 }
805 protected void consumeArrayCreationExpressionWithoutInitializer() {
806         // ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
807         // ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
808
809         int length;
810         ArrayAllocationExpression aae = new ArrayAllocationExpression();
811         aae.type = getTypeReference(0);
812         length = (this.expressionLengthStack[this.expressionLengthPtr--]);
813         this.expressionPtr -= length ;
814         System.arraycopy(
815                 this.expressionStack,
816                 this.expressionPtr+1,
817                 aae.dimensions = new Expression[length],
818                 0,
819                 length);
820         aae.sourceStart = this.intStack[this.intPtr--];
821         if (aae.initializer == null) {
822                 aae.sourceEnd = this.endPosition;
823         } else {
824                 aae.sourceEnd = aae.initializer.sourceEnd ;
825         }
826         pushOnExpressionStack(aae);
827 }
828
829 protected void consumeArrayCreationHeader() {
830         // nothing to do
831 }
832 protected void consumeArrayCreationExpressionWithInitializer() {
833         // ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer
834         // ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
835
836         int length;
837         ArrayAllocationExpression aae = new ArrayAllocationExpression();
838         this.expressionLengthPtr -- ;
839         aae.initializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
840                 
841         aae.type = getTypeReference(0);
842         length = (this.expressionLengthStack[this.expressionLengthPtr--]);
843         this.expressionPtr -= length ;
844         System.arraycopy(
845                 this.expressionStack,
846                 this.expressionPtr+1,
847                 aae.dimensions = new Expression[length],
848                 0,
849                 length);
850         aae.sourceStart = this.intStack[this.intPtr--];
851         if (aae.initializer == null) {
852                 aae.sourceEnd = this.endPosition;
853         } else {
854                 aae.sourceEnd = aae.initializer.sourceEnd ;
855         }
856         pushOnExpressionStack(aae);
857 }
858 protected void consumeArrayInitializer() {
859         // ArrayInitializer ::= '{' VariableInitializers '}'
860         // ArrayInitializer ::= '{' VariableInitializers , '}'
861
862         arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
863 }
864
865 protected void consumeAssertStatement() {
866         // AssertStatement ::= 'assert' Expression ':' Expression ';'
867         this.expressionLengthPtr-=2;
868         pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
869 }
870
871 protected void consumeAssignment() {
872         // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
873         //optimize the push/pop
874
875         int op = this.intStack[this.intPtr--] ; //<--the encoded operator
876         
877         this.expressionPtr -- ; this.expressionLengthPtr -- ;
878         this.expressionStack[this.expressionPtr] =
879                 (op != EQUAL ) ?
880                         new CompoundAssignment(
881                                 this.expressionStack[this.expressionPtr] ,
882                                 this.expressionStack[this.expressionPtr+1], 
883                                 op,
884                                 this.scanner.startPosition - 1) :
885                         new Assignment(
886                                 this.expressionStack[this.expressionPtr] ,
887                                 this.expressionStack[this.expressionPtr+1],
888                                 this.scanner.startPosition - 1);
889 }
890 protected void consumeAssignmentOperator(int pos) {
891         // AssignmentOperator ::= '='
892         // AssignmentOperator ::= '*='
893         // AssignmentOperator ::= '/='
894         // AssignmentOperator ::= '%='
895         // AssignmentOperator ::= '+='
896         // AssignmentOperator ::= '-='
897         // AssignmentOperator ::= '<<='
898         // AssignmentOperator ::= '>>='
899         // AssignmentOperator ::= '>>>='
900         // AssignmentOperator ::= '&='
901         // AssignmentOperator ::= '^='
902         // AssignmentOperator ::= '|='
903
904         pushOnIntStack(pos);
905 }
906 protected void consumeBinaryExpression(int op) {
907         // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
908         // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
909         // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
910         // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
911         // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
912         // ShiftExpression ::= ShiftExpression '<<'  AdditiveExpression
913         // ShiftExpression ::= ShiftExpression '>>'  AdditiveExpression
914         // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
915         // RelationalExpression ::= RelationalExpression '<'  ShiftExpression
916         // RelationalExpression ::= RelationalExpression '>'  ShiftExpression
917         // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
918         // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
919         // AndExpression ::= AndExpression '&' EqualityExpression
920         // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
921         // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
922         // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
923         // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
924
925         //optimize the push/pop
926
927         this.expressionPtr--;
928         this.expressionLengthPtr--;
929         Expression expr1 = this.expressionStack[this.expressionPtr];
930         Expression expr2 = this.expressionStack[this.expressionPtr + 1];
931         switch(op) {
932                 case OR_OR :
933                         this.expressionStack[this.expressionPtr] = 
934                                 new OR_OR_Expression(
935                                         expr1, 
936                                         expr2, 
937                                         op); 
938                         break;
939                 case AND_AND :
940                         this.expressionStack[this.expressionPtr] = 
941                                 new AND_AND_Expression(
942                                         expr1, 
943                                         expr2, 
944                                         op);
945                         break;
946                 case PLUS :
947                         // look for "string1" + "string2"
948                         if (this.optimizeStringLiterals) {
949                                 if (expr1 instanceof StringLiteral) {
950                                         if (expr2 instanceof CharLiteral) { // string+char
951                                                 this.expressionStack[this.expressionPtr] = 
952                                                         ((StringLiteral) expr1).extendWith((CharLiteral) expr2); 
953                                         } else if (expr2 instanceof StringLiteral) { //string+string
954                                                 this.expressionStack[this.expressionPtr] = 
955                                                         ((StringLiteral) expr1).extendWith((StringLiteral) expr2); 
956                                         } else {
957                                                 this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
958                                         }
959                                 } else {
960                                         this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
961                                 }
962                         } else if (expr1 instanceof StringLiteral) {
963                                 if (expr2 instanceof StringLiteral) {
964                                         // string + string
965                                         this.expressionStack[this.expressionPtr] = 
966                                                 ((StringLiteral) expr1).extendsWith((StringLiteral) expr2); 
967                                 } else {
968                                         this.expressionStack[this.expressionPtr] = 
969                                                 new BinaryExpression(
970                                                         expr1, 
971                                                         expr2, 
972                                                         op);
973                                 }
974                         } else {
975                                 this.expressionStack[this.expressionPtr] = 
976                                         new BinaryExpression(
977                                                 expr1, 
978                                                 expr2, 
979                                                 op);
980                         }
981                         break;
982                 default :
983                         this.expressionStack[this.expressionPtr] = 
984                                 new BinaryExpression(
985                                         expr1, 
986                                         expr2, 
987                                         op);            
988         }
989 }
990 protected void consumeBlock() {
991         // Block ::= OpenBlock '{' BlockStatementsopt '}'
992         // simpler action for empty blocks
993
994         int statementsLength = this.astLengthStack[this.astLengthPtr--];
995         Block block;
996         if (statementsLength == 0) { // empty block 
997                 block = new Block(0);
998                 block.sourceStart = this.intStack[this.intPtr--];
999                 block.sourceEnd = this.endStatementPosition;
1000                 // check whether this block at least contains some comment in it
1001                 if (!containsComment(block.sourceStart, block.sourceEnd)) {
1002                         block.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1003                 }
1004                 this.realBlockPtr--; // still need to pop the block variable counter
1005         } else {
1006                 block = new Block(this.realBlockStack[this.realBlockPtr--]);
1007                 this.astPtr -= statementsLength;
1008                 System.arraycopy(
1009                         this.astStack, 
1010                         this.astPtr + 1, 
1011                         block.statements = new Statement[statementsLength], 
1012                         0, 
1013                         statementsLength); 
1014                 block.sourceStart = this.intStack[this.intPtr--];
1015                 block.sourceEnd = this.endStatementPosition;
1016         }
1017         pushOnAstStack(block);
1018 }
1019 protected void consumeBlockStatements() {
1020         // BlockStatements ::= BlockStatements BlockStatement
1021         concatNodeLists();
1022 }
1023 protected void consumeCaseLabel() {
1024         // SwitchLabel ::= 'case' ConstantExpression ':'
1025         this.expressionLengthPtr--;
1026         Expression expression = this.expressionStack[this.expressionPtr--];
1027         pushOnAstStack(new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]));
1028 }
1029 protected void consumeCastExpression() {
1030         // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression
1031         // CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1032
1033         //this.intStack : posOfLeftParen dim posOfRightParen
1034
1035         //optimize the push/pop
1036
1037         Expression exp, cast, castType;
1038         int end = this.intStack[this.intPtr--];
1039         this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
1040         castType.sourceEnd = end - 1;
1041         castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1042         cast.sourceEnd = exp.sourceEnd;
1043 }
1044 protected void consumeCastExpressionLL1() {
1045         //CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
1046         // Expression is used in order to make the grammar LL1
1047
1048         //optimize push/pop
1049
1050         Expression cast,exp;
1051         this.expressionPtr--;
1052         this.expressionStack[this.expressionPtr] = 
1053                 cast = new CastExpression(
1054                         exp=this.expressionStack[this.expressionPtr+1] ,
1055                         getTypeReference(this.expressionStack[this.expressionPtr]));
1056         this.expressionLengthPtr -- ;
1057         updateSourcePosition(cast);
1058         cast.sourceEnd=exp.sourceEnd;
1059 }
1060 protected void consumeCatches() {
1061         // Catches ::= Catches CatchClause
1062         optimizedConcatNodeLists();
1063 }
1064 protected void consumeCatchHeader() {
1065         // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1066
1067         if (this.currentElement == null){
1068                 return; // should never occur, this consumeRule is only used in recovery mode
1069         }
1070         // current element should be a block due to the presence of the opening brace
1071         if (!(this.currentElement instanceof RecoveredBlock)){
1072                 if(!(this.currentElement instanceof RecoveredMethod)) {
1073                         return;
1074                 }
1075                 RecoveredMethod rMethod = (RecoveredMethod) this.currentElement;
1076                 if(!(rMethod.methodBody == null && rMethod.bracketBalance > 0)) {
1077                         return;
1078                 }
1079         }
1080         
1081         Argument arg = (Argument)this.astStack[this.astPtr--];
1082         // convert argument to local variable
1083         LocalDeclaration localDeclaration = new LocalDeclaration(arg.name, arg.sourceStart, arg.sourceEnd);
1084         localDeclaration.type = arg.type;
1085         localDeclaration.declarationSourceStart = arg.declarationSourceStart;
1086         localDeclaration.declarationSourceEnd = arg.declarationSourceEnd;
1087         
1088         this.currentElement = this.currentElement.add(localDeclaration, 0);
1089         this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
1090         this.restartRecovery = true; // request to restart from here on
1091         this.lastIgnoredToken = -1;
1092 }
1093 protected void consumeClassBodyDeclaration() {
1094         // ClassBodyDeclaration ::= Diet Block
1095         //push an Initializer
1096         //optimize the push/pop
1097         this.nestedMethod[this.nestedType]--;
1098         Block block = (Block) this.astStack[this.astPtr];
1099         if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlockMASK; // clear bit since was diet
1100         Initializer initializer = new Initializer(block, 0);
1101         this.intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1102         initializer.bodyStart = this.intStack[this.intPtr--];
1103         this.realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1104         int javadocCommentStart = this.intStack[this.intPtr--];
1105         if (javadocCommentStart != -1) {
1106                 initializer.declarationSourceStart = javadocCommentStart;
1107                 initializer.javadoc = this.javadoc;
1108                 this.javadoc = null;
1109         }
1110         this.astStack[this.astPtr] = initializer;
1111         initializer.bodyEnd = this.endPosition;
1112         initializer.sourceEnd = this.endStatementPosition;
1113         initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1114 }
1115 protected void consumeClassBodyDeclarations() {
1116         // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1117         concatNodeLists();
1118 }
1119 protected void consumeClassBodyDeclarationsopt() {
1120         // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1121         this.nestedType-- ;
1122 }
1123 protected void consumeClassBodyopt() {
1124         // ClassBodyopt ::= $empty
1125         pushOnAstStack(null);
1126         this.endPosition = this.scanner.startPosition - 1;
1127 }
1128 protected void consumeClassDeclaration() {
1129         // ClassDeclaration ::= ClassHeader ClassBody
1130
1131         int length;
1132         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1133                 //there are length declarations
1134                 //dispatch according to the type of the declarations
1135                 dispatchDeclarationInto(length);
1136         }
1137
1138         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1139
1140         // mark initializers with local type mark if needed
1141         markInitializersWithLocalType(typeDecl);
1142
1143         //convert constructor that do not have the type's name into methods
1144         boolean hasConstructor = typeDecl.checkConstructors(this);
1145         
1146         //add the default constructor when needed (interface don't have it)
1147         if (!hasConstructor && !typeDecl.isInterface()) {
1148                 boolean insideFieldInitializer = false;
1149                 if (this.diet) {
1150                         for (int i = this.nestedType; i > 0; i--){
1151                                 if (this.variablesCounter[i] > 0) {
1152                                         insideFieldInitializer = true;
1153                                         break;
1154                                 }
1155                         }
1156                 }
1157                 typeDecl.createsInternalConstructor(!this.diet || insideFieldInitializer, true);
1158         }
1159
1160         //always add <clinit> (will be remove at code gen time if empty)
1161         if (this.scanner.containsAssertKeyword) {
1162                 typeDecl.bits |= ASTNode.AddAssertionMASK;
1163         }
1164         typeDecl.addClinit();
1165         typeDecl.bodyEnd = this.endStatementPosition;
1166         if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
1167                 typeDecl.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1168         }
1169
1170         typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); 
1171 }
1172 protected void consumeClassHeader() {
1173         // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1174
1175         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];        
1176         if (this.currentToken == TokenNameLBRACE) { 
1177                 typeDecl.bodyStart = this.scanner.currentPosition;
1178         }
1179         if (this.currentElement != null) {
1180                 this.restartRecovery = true; // used to avoid branching back into the regular automaton         
1181         }
1182         // flush the comments related to the class header
1183         this.scanner.commentPtr = -1;
1184 }
1185 protected void consumeClassHeaderExtends() {
1186         // ClassHeaderExtends ::= 'extends' ClassType
1187         // There is a class declaration on the top of stack
1188         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1189         //superclass
1190         typeDecl.superclass = getTypeReference(0);
1191         typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1192         // recovery
1193         if (this.currentElement != null){
1194                 this.lastCheckPoint = typeDecl.bodyStart;
1195         }
1196 }
1197 protected void consumeClassHeaderImplements() {
1198         // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1199         int length = this.astLengthStack[this.astLengthPtr--];
1200         //super interfaces
1201         this.astPtr -= length;
1202         // There is a class declaration on the top of stack
1203         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1204         System.arraycopy(
1205                 this.astStack, 
1206                 this.astPtr + 1, 
1207                 typeDecl.superInterfaces = new TypeReference[length], 
1208                 0, 
1209                 length); 
1210         typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
1211         this.listLength = 0; // reset after having read super-interfaces
1212         // recovery
1213         if (this.currentElement != null) { // is recovering
1214                 this.lastCheckPoint = typeDecl.bodyStart;
1215         }
1216 }
1217 protected void consumeClassHeaderName() {
1218         // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1219         TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1220         if (this.nestedMethod[this.nestedType] == 0) {
1221                 if (this.nestedType != 0) {
1222                         typeDecl.bits |= ASTNode.IsMemberTypeMASK;
1223                 }
1224         } else {
1225                 // Record that the block has a declaration for local types
1226                 typeDecl.bits |= ASTNode.IsLocalTypeMASK;
1227                 markEnclosingMemberWithLocalType();
1228                 blockReal();
1229         }
1230
1231         //highlight the name of the type
1232         long pos = this.identifierPositionStack[this.identifierPtr];
1233         typeDecl.sourceEnd = (int) pos;
1234         typeDecl.sourceStart = (int) (pos >>> 32);
1235         typeDecl.name = this.identifierStack[this.identifierPtr--];
1236         this.identifierLengthPtr--;
1237
1238         //compute the declaration source too
1239         // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
1240         // we want to keep the beginning position but get rid of the end position
1241         // it is only used for the ClassLiteralAccess positions.
1242         typeDecl.declarationSourceStart = this.intStack[this.intPtr--]; 
1243         this.intPtr--; // remove the end position of the class token
1244
1245         typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
1246         typeDecl.modifiers = this.intStack[this.intPtr--];
1247         if (typeDecl.modifiersSourceStart >= 0) {
1248                 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
1249         }
1250         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
1251         pushOnAstStack(typeDecl);
1252
1253         this.listLength = 0; // will be updated when reading super-interfaces
1254         // recovery
1255         if (this.currentElement != null){ 
1256                 this.lastCheckPoint = typeDecl.bodyStart;
1257                 this.currentElement = this.currentElement.add(typeDecl, 0);
1258                 this.lastIgnoredToken = -1;
1259         }
1260         // javadoc
1261         typeDecl.javadoc = this.javadoc;
1262         this.javadoc = null;
1263 }
1264 protected void consumeClassInstanceCreationExpression() {
1265         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1266         classInstanceCreation(false);
1267 }
1268 protected void consumeClassInstanceCreationExpressionName() {
1269         // ClassInstanceCreationExpressionName ::= Name '.'
1270         pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1271 }
1272 protected void consumeClassInstanceCreationExpressionQualified() {
1273         // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1274         // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1275
1276         classInstanceCreation(true); //  <-- push the Qualifed....
1277
1278         this.expressionLengthPtr--;
1279         QualifiedAllocationExpression qae = 
1280                 (QualifiedAllocationExpression) this.expressionStack[this.expressionPtr--]; 
1281         qae.enclosingInstance = this.expressionStack[this.expressionPtr];
1282         this.expressionStack[this.expressionPtr] = qae;
1283         qae.sourceStart = qae.enclosingInstance.sourceStart;
1284 }
1285 protected void consumeClassTypeElt() {
1286         // ClassTypeElt ::= ClassType
1287         pushOnAstStack(getTypeReference(0));
1288         /* if incomplete thrown exception list, listLength counter will not have been reset,
1289                 indicating that some items are available on the stack */
1290         this.listLength++;      
1291 }
1292 protected void consumeClassTypeList() {
1293         // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
1294         optimizedConcatNodeLists();
1295 }
1296 protected void consumeCompilationUnit() {
1297         // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
1298         // do nothing by default
1299 }
1300 protected void consumeConditionalExpression(int op) {
1301         // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
1302         //optimize the push/pop
1303
1304         this.expressionPtr -= 2;
1305         this.expressionLengthPtr -= 2;
1306         this.expressionStack[this.expressionPtr] =
1307                 new ConditionalExpression(
1308                         this.expressionStack[this.expressionPtr],
1309                         this.expressionStack[this.expressionPtr + 1],
1310                         this.expressionStack[this.expressionPtr + 2]);
1311 }
1312 protected void consumeConstructorBlockStatements() {
1313         // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
1314         concatNodeLists(); // explictly add the first statement into the list of statements 
1315 }
1316 protected void consumeConstructorBody() {
1317         // ConstructorBody ::= NestedMethod  '{' BlockStatementsopt '}'
1318         // ConstructorBody ::= NestedMethod  '{' ExplicitConstructorInvocation '}'
1319         this.nestedMethod[this.nestedType] --;
1320 }
1321 protected void consumeConstructorDeclaration() {
1322         // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
1323
1324         /*
1325         astStack : MethodDeclaration statements
1326         identifierStack : name
1327          ==>
1328         astStack : MethodDeclaration
1329         identifierStack :
1330         */
1331
1332         //must provide a default constructor call when needed
1333
1334         int length;
1335
1336         // pop the position of the {  (body of the method) pushed in block decl
1337         this.intPtr--;
1338         this.intPtr--;
1339
1340         //statements
1341         this.realBlockPtr--;
1342         ExplicitConstructorCall constructorCall = null;
1343         Statement[] statements = null;
1344         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1345                 this.astPtr -= length;
1346                 if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) {
1347                         //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
1348                         System.arraycopy(
1349                                 this.astStack, 
1350                                 this.astPtr + 2, 
1351                                 statements = new Statement[length - 1], 
1352                                 0, 
1353                                 length - 1); 
1354                         constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
1355                 } else { //need to add explicitly the super();
1356                         System.arraycopy(
1357                                 this.astStack, 
1358                                 this.astPtr + 1, 
1359                                 statements = new Statement[length], 
1360                                 0, 
1361                                 length); 
1362                         constructorCall = SuperReference.implicitSuperConstructorCall();
1363                 }
1364         } else {
1365                 boolean insideFieldInitializer = false;
1366                 if (this.diet) {
1367                         for (int i = this.nestedType; i > 0; i--){
1368                                 if (this.variablesCounter[i] > 0) {
1369                                         insideFieldInitializer = true;
1370                                         break;
1371                                 }
1372                         }
1373                 }
1374                 
1375                 if (!this.diet || insideFieldInitializer){
1376                         // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
1377                         constructorCall = SuperReference.implicitSuperConstructorCall();
1378                 }
1379         }
1380
1381         // now we know that the top of stack is a constructorDeclaration
1382         ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
1383         cd.constructorCall = constructorCall;
1384         cd.statements = statements;
1385
1386         //highlight of the implicit call on the method name
1387         if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
1388                 cd.constructorCall.sourceEnd = cd.sourceEnd;
1389                 cd.constructorCall.sourceStart = cd.sourceStart;
1390         }
1391
1392         if (!this.diet && (statements == null && constructorCall.isImplicitSuper())) {
1393                 if (!containsComment(cd.bodyStart, this.endPosition)) {
1394                         cd.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1395                 }
1396         }
1397
1398         //watch for } that could be given as a unicode ! ( u007D is '}' )
1399         // store the endPosition (position just before the '}') in case there is
1400         // a trailing comment behind the end of the method
1401         cd.bodyEnd = this.endPosition;
1402         cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); 
1403 }
1404
1405 protected void consumeInvalidConstructorDeclaration() {
1406         // ConstructorDeclaration ::= ConstructorHeader ';'
1407         // now we know that the top of stack is a constructorDeclaration
1408         ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
1409
1410         cd.bodyEnd = this.endPosition; // position just before the trailing semi-colon
1411         cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); 
1412         // report the problem and continue the parsing - narrowing the problem onto the method
1413         
1414         cd.modifiers |= AccSemicolonBody; // remember semi-colon body
1415 }
1416 protected void consumeConstructorHeader() {
1417         // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
1418
1419         AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
1420
1421         if (this.currentToken == TokenNameLBRACE){ 
1422                 method.bodyStart = this.scanner.currentPosition;
1423         }
1424         // recovery
1425         if (this.currentElement != null){
1426                 if (this.currentToken == TokenNameSEMICOLON){ // for invalid constructors
1427                         method.modifiers |= AccSemicolonBody;                   
1428                         method.declarationSourceEnd = this.scanner.currentPosition-1;
1429                         method.bodyEnd = this.scanner.currentPosition-1;
1430                         if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
1431                                 this.currentElement = this.currentElement.parent;
1432                         }
1433                 }               
1434                 this.restartRecovery = true; // used to avoid branching back into the regular automaton
1435         }               
1436 }
1437 protected void consumeConstructorHeaderName() {
1438
1439         /* recovering - might be an empty message send */
1440         if (this.currentElement != null){
1441                 if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
1442                         this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position                            
1443                         this.restartRecovery = true;
1444                         return;
1445                 }
1446         }
1447         
1448         // ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
1449         ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
1450
1451         //name -- this is not really revelant but we do .....
1452         cd.selector = this.identifierStack[this.identifierPtr];
1453         long selectorSource = this.identifierPositionStack[this.identifierPtr--];
1454         this.identifierLengthPtr--;
1455
1456         //modifiers
1457         cd.declarationSourceStart = this.intStack[this.intPtr--];
1458         cd.modifiers = this.intStack[this.intPtr--];
1459         // javadoc
1460         cd.javadoc = this.javadoc;
1461         this.javadoc = null;
1462
1463         //highlight starts at the selector starts
1464         cd.sourceStart = (int) (selectorSource >>> 32);
1465         pushOnAstStack(cd);
1466         cd.sourceEnd = this.lParenPos;
1467         cd.bodyStart = this.lParenPos+1;
1468         this.listLength = 0; // initialize listLength before reading parameters/throws
1469
1470         // recovery
1471         if (this.currentElement != null){
1472                 this.lastCheckPoint = cd.bodyStart;
1473                 if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
1474                         || cd.modifiers != 0){
1475                         this.currentElement = this.currentElement.add(cd, 0);
1476                         this.lastIgnoredToken = -1;
1477                 }
1478         }       
1479 }
1480 protected void consumeDefaultLabel() {
1481         // SwitchLabel ::= 'default' ':'
1482         pushOnAstStack(new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]));
1483 }
1484 protected void consumeDefaultModifiers() {
1485         checkComment(); // might update modifiers with AccDeprecated
1486         pushOnIntStack(this.modifiers); // modifiers
1487         pushOnIntStack(
1488                 this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition); 
1489         resetModifiers();
1490 }
1491 protected void consumeDiet() {
1492         // Diet ::= $empty
1493         checkComment();
1494         pushOnIntStack(this.modifiersSourceStart); // push the start position of a javadoc comment if there is one
1495         resetModifiers();
1496         jumpOverMethodBody();
1497 }
1498 protected void consumeDims() {
1499         // Dims ::= DimsLoop
1500         pushOnIntStack(this.dimensions);
1501         this.dimensions = 0;
1502 }
1503 protected void consumeDimWithOrWithOutExpr() {
1504         // DimWithOrWithOutExpr ::= '[' ']'
1505         pushOnExpressionStack(null);
1506         
1507         if(this.currentElement != null && this.currentToken == TokenNameLBRACE) {
1508                 this.ignoreNextOpeningBrace = true;
1509                 this.currentElement.bracketBalance++; 
1510         }
1511 }
1512 protected void consumeDimWithOrWithOutExprs() {
1513         // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
1514         concatExpressionLists();
1515 }
1516 protected void consumeEmptyArgumentListopt() {
1517         // ArgumentListopt ::= $empty
1518         pushOnExpressionStackLengthStack(0);
1519 }
1520 protected void consumeEmptyArrayInitializer() {
1521         // ArrayInitializer ::= '{' ,opt '}'
1522         arrayInitializer(0);
1523 }
1524 protected void consumeEmptyArrayInitializeropt() {
1525         // ArrayInitializeropt ::= $empty
1526         pushOnExpressionStackLengthStack(0);
1527 }
1528 protected void consumeEmptyBlockStatementsopt() {
1529         // BlockStatementsopt ::= $empty
1530         pushOnAstLengthStack(0);
1531 }
1532 protected void consumeEmptyCatchesopt() {
1533         // Catchesopt ::= $empty
1534         pushOnAstLengthStack(0);
1535 }
1536 protected void consumeEmptyClassBodyDeclarationsopt() {
1537         // ClassBodyDeclarationsopt ::= $empty
1538         pushOnAstLengthStack(0);
1539 }
1540 protected void consumeEmptyClassMemberDeclaration() {
1541         // ClassMemberDeclaration ::= ';'
1542         pushOnAstLengthStack(0);
1543         problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
1544         flushCommentsDefinedPriorTo(this.endStatementPosition);
1545 }
1546 protected void consumeEmptyDimsopt() {
1547         // Dimsopt ::= $empty
1548         pushOnIntStack(0);
1549 }
1550 protected void consumeEmptyExpression() {
1551         // Expressionopt ::= $empty
1552         pushOnExpressionStackLengthStack(0);
1553 }
1554 protected void consumeEmptyForInitopt() {
1555         // ForInitopt ::= $empty
1556         pushOnAstLengthStack(0);
1557 }
1558 protected void consumeEmptyForUpdateopt() {
1559         // ForUpdateopt ::= $empty
1560         pushOnExpressionStackLengthStack(0);
1561 }
1562 protected void consumeEmptyImportDeclarationsopt() {
1563         // ImportDeclarationsopt ::= $empty
1564         pushOnAstLengthStack(0);
1565 }
1566 protected void consumeEmptyInterfaceMemberDeclaration() {
1567         // InterfaceMemberDeclaration ::= ';'
1568         pushOnAstLengthStack(0);
1569 }
1570 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
1571         // InterfaceMemberDeclarationsopt ::= $empty
1572         pushOnAstLengthStack(0);
1573 }
1574 protected void consumeEmptyStatement() {
1575         // EmptyStatement ::= ';'
1576         if (this.scanner.source[this.endStatementPosition] == ';') {
1577                 pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition));
1578         } else {
1579                 // we have a Unicode for the ';' (/u003B)
1580                 pushOnAstStack(new EmptyStatement(this.endStatementPosition - 5, this.endStatementPosition));
1581         }
1582 }
1583 protected void consumeEmptySwitchBlock() {
1584         // SwitchBlock ::= '{' '}'
1585         pushOnAstLengthStack(0);
1586 }
1587 protected void consumeEmptyTypeDeclaration() {
1588         // TypeDeclaration ::= ';' 
1589         pushOnAstLengthStack(0);
1590         problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
1591         flushCommentsDefinedPriorTo(this.endStatementPosition);
1592 }
1593 protected void consumeEmptyTypeDeclarationsopt() {
1594         // TypeDeclarationsopt ::= $empty
1595         pushOnAstLengthStack(0); 
1596 }
1597 protected void consumeEnterAnonymousClassBody() {
1598         // EnterAnonymousClassBody ::= $empty
1599         QualifiedAllocationExpression alloc;
1600         TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult); 
1601         anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
1602         anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
1603         alloc = anonymousType.allocation = new QualifiedAllocationExpression(anonymousType); 
1604         markEnclosingMemberWithLocalType();
1605         pushOnAstStack(anonymousType);
1606
1607         alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
1608         int argumentLength;
1609         if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1610                 this.expressionPtr -= argumentLength;
1611                 System.arraycopy(
1612                         this.expressionStack, 
1613                         this.expressionPtr + 1, 
1614                         alloc.arguments = new Expression[argumentLength], 
1615                         0, 
1616                         argumentLength); 
1617         }
1618         alloc.type = getTypeReference(0);
1619
1620         anonymousType.sourceEnd = alloc.sourceEnd;
1621         //position at the type while it impacts the anonymous declaration
1622         anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
1623         alloc.sourceStart = this.intStack[this.intPtr--];
1624         pushOnExpressionStack(alloc);
1625
1626         anonymousType.bodyStart = this.scanner.currentPosition; 
1627         this.listLength = 0; // will be updated when reading super-interfaces
1628         // recovery
1629         if (this.currentElement != null){ 
1630                 this.lastCheckPoint = anonymousType.bodyStart;          
1631                 this.currentElement = this.currentElement.add(anonymousType, 0);
1632                 this.currentToken = 0; // opening brace already taken into account
1633                 this.lastIgnoredToken = -1;
1634         }       
1635 }
1636 protected void consumeEnterCompilationUnit() {
1637         // EnterCompilationUnit ::= $empty
1638         // do nothing by default
1639 }
1640 protected void consumeEnterVariable() {
1641         // EnterVariable ::= $empty
1642         // do nothing by default
1643
1644         char[] identifierName = this.identifierStack[this.identifierPtr];
1645         long namePosition = this.identifierPositionStack[this.identifierPtr];
1646         int extendedDimension = this.intStack[this.intPtr--];
1647         AbstractVariableDeclaration declaration;
1648         // create the ast node
1649         boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0; 
1650         if (isLocalDeclaration) {
1651                 // create the local variable declarations
1652                 declaration = 
1653                         this.createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
1654         } else {
1655                 // create the field declaration
1656                 declaration = 
1657                         this.createFieldDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition); 
1658         }
1659         
1660         this.identifierPtr--;
1661         this.identifierLengthPtr--;
1662         TypeReference type;
1663         int variableIndex = this.variablesCounter[this.nestedType];
1664         int typeDim = 0;
1665         if (variableIndex == 0) {
1666                 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
1667                 if (isLocalDeclaration) {
1668                         declaration.declarationSourceStart = this.intStack[this.intPtr--];
1669                         declaration.modifiers = this.intStack[this.intPtr--];
1670                         type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
1671                         if (declaration.declarationSourceStart == -1) {
1672                                 // this is true if there is no modifiers for the local variable declaration
1673                                 declaration.declarationSourceStart = type.sourceStart;
1674                         }
1675                         pushOnAstStack(type);
1676                 } else {
1677                         type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
1678                         pushOnAstStack(type);
1679                         declaration.declarationSourceStart = this.intStack[this.intPtr--];
1680                         declaration.modifiers = this.intStack[this.intPtr--];
1681                         
1682                         // Store javadoc only on first declaration as it is the same for all ones
1683                         FieldDeclaration fieldDeclaration = (FieldDeclaration) declaration;
1684                         fieldDeclaration.javadoc = this.javadoc;
1685                         this.javadoc = null;
1686                 }
1687         } else {
1688                 type = (TypeReference) this.astStack[this.astPtr - variableIndex];
1689                 typeDim = type.dimensions();
1690                 AbstractVariableDeclaration previousVariable = 
1691                         (AbstractVariableDeclaration) this.astStack[this.astPtr]; 
1692                 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
1693                 declaration.modifiers = previousVariable.modifiers;
1694         }
1695
1696         if (extendedDimension == 0) {
1697                 declaration.type = type;
1698         } else {
1699                 int dimension = typeDim + extendedDimension;
1700                 //on the identifierLengthStack there is the information about the type....
1701                 int baseType;
1702                 if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
1703                         //it was a baseType
1704                         int typeSourceStart = type.sourceStart;
1705                         int typeSourceEnd = type.sourceEnd;
1706                         type = TypeReference.baseTypeReference(-baseType, dimension);
1707                         type.sourceStart = typeSourceStart;
1708                         type.sourceEnd = typeSourceEnd;
1709                         declaration.type = type;
1710                 } else {
1711                         declaration.type = this.copyDims(type, dimension);
1712                 }
1713         }
1714         this.variablesCounter[this.nestedType]++;
1715         pushOnAstStack(declaration);
1716         // recovery
1717         if (this.currentElement != null) {
1718                 if (!(this.currentElement instanceof RecoveredType)
1719                         && (this.currentToken == TokenNameDOT
1720                                 //|| declaration.modifiers != 0
1721                                 || (this.scanner.getLineNumber(declaration.type.sourceStart)
1722                                                 != this.scanner.getLineNumber((int) (namePosition >>> 32))))){
1723                         this.lastCheckPoint = (int) (namePosition >>> 32);
1724                         this.restartRecovery = true;
1725                         return;
1726                 }
1727                 if (isLocalDeclaration){
1728                         LocalDeclaration localDecl = (LocalDeclaration) this.astStack[this.astPtr];
1729                         this.lastCheckPoint = localDecl.sourceEnd + 1;
1730                         this.currentElement = this.currentElement.add(localDecl, 0);
1731                 } else {
1732                         FieldDeclaration fieldDecl = (FieldDeclaration) this.astStack[this.astPtr];
1733                         this.lastCheckPoint = fieldDecl.sourceEnd + 1;
1734                         this.currentElement = this.currentElement.add(fieldDecl, 0);
1735                 }
1736                 this.lastIgnoredToken = -1;
1737         }
1738 }
1739 protected void consumeEqualityExpression(int op) {
1740         // EqualityExpression ::= EqualityExpression '==' RelationalExpression
1741         // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
1742
1743         //optimize the push/pop
1744
1745         this.expressionPtr--;
1746         this.expressionLengthPtr--;
1747         this.expressionStack[this.expressionPtr] =
1748                 new EqualExpression(
1749                         this.expressionStack[this.expressionPtr],
1750                         this.expressionStack[this.expressionPtr + 1],
1751                         op);
1752 }
1753 protected void consumeExitTryBlock() {
1754         //ExitTryBlock ::= $empty
1755         if(this.currentElement != null) {
1756                 this.restartRecovery = true;
1757         }
1758 }
1759 protected void consumeExitVariableWithInitialization() {
1760         // ExitVariableWithInitialization ::= $empty
1761         // do nothing by default
1762         this.expressionLengthPtr--;
1763         AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
1764         variableDecl.initialization = this.expressionStack[this.expressionPtr--];
1765         // we need to update the declarationSourceEnd of the local variable declaration to the
1766         // source end position of the initialization expression
1767         variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
1768         variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
1769         
1770         this.recoveryExitFromVariable();
1771 }
1772 protected void consumeExitVariableWithoutInitialization() {
1773         // ExitVariableWithoutInitialization ::= $empty
1774         // do nothing by default
1775         
1776         AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
1777         variableDecl.declarationSourceEnd = variableDecl.declarationEnd;
1778         
1779         this.recoveryExitFromVariable();
1780 }
1781 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
1782
1783         /* flag allows to distinguish 3 cases :
1784         (0) :   
1785         ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
1786         ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
1787         (1) :
1788         ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
1789         ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
1790         (2) :
1791         ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
1792         ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
1793         */
1794         int startPosition = this.intStack[this.intPtr--];
1795         ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
1796         int length;
1797         if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1798                 this.expressionPtr -= length;
1799                 System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
1800         }
1801         switch (flag) {
1802                 case 0 :
1803                         ecc.sourceStart = startPosition;
1804                         break;
1805                 case 1 :
1806                         this.expressionLengthPtr--;
1807                         ecc.sourceStart = (ecc.qualification = this.expressionStack[this.expressionPtr--]).sourceStart;
1808                         break;
1809                 case 2 :
1810                         ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
1811                         break;
1812         }
1813         pushOnAstStack(ecc);
1814         ecc.sourceEnd = this.endPosition;
1815 }
1816 protected void consumeExpressionStatement() {
1817         // ExpressionStatement ::= StatementExpression ';'
1818         this.expressionLengthPtr--;
1819         pushOnAstStack(this.expressionStack[this.expressionPtr--]);
1820 }
1821 protected void consumeFieldAccess(boolean isSuperAccess) {
1822         // FieldAccess ::= Primary '.' 'Identifier'
1823         // FieldAccess ::= 'super' '.' 'Identifier'
1824
1825         FieldReference fr =
1826                 new FieldReference(
1827                         this.identifierStack[this.identifierPtr],
1828                         this.identifierPositionStack[this.identifierPtr--]);
1829         this.identifierLengthPtr--;
1830         if (isSuperAccess) {
1831                 //considerates the fieldReference beginning at the 'super' .... 
1832                 fr.sourceStart = this.intStack[this.intPtr--];
1833                 fr.receiver = new SuperReference(fr.sourceStart, this.endPosition);
1834                 pushOnExpressionStack(fr);
1835         } else {
1836                 //optimize push/pop
1837                 if ((fr.receiver = this.expressionStack[this.expressionPtr]).isThis()) {
1838                         //fieldreference begins at the this
1839                         fr.sourceStart = fr.receiver.sourceStart;
1840                 }
1841                 this.expressionStack[this.expressionPtr] = fr;
1842         }
1843 }
1844 protected void consumeFieldDeclaration() {
1845         // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
1846         // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
1847
1848         /*
1849         astStack : 
1850         expressionStack: Expression Expression ...... Expression
1851         identifierStack : type  identifier identifier ...... identifier
1852         intStack : typeDim      dim        dim               dim
1853          ==>
1854         astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
1855         expressionStack :
1856         identifierStack : 
1857         intStack : 
1858           
1859         */
1860         int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
1861
1862         for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
1863                 FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
1864                 fieldDeclaration.declarationSourceEnd = this.endStatementPosition; 
1865                 fieldDeclaration.declarationEnd = this.endStatementPosition;    // semi-colon included
1866         }
1867         
1868         updateSourceDeclarationParts(variableDeclaratorsCounter);
1869         int endPos = flushCommentsDefinedPriorTo(this.endStatementPosition);
1870         if (endPos != this.endStatementPosition) {
1871                 for (int i = 0; i < variableDeclaratorsCounter; i++) {
1872                         FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
1873                         fieldDeclaration.declarationSourceEnd = endPos;
1874                 }
1875         }
1876         // update the astStack, astPtr and astLengthStack
1877         int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
1878         System.arraycopy(
1879                 this.astStack, 
1880                 startIndex, 
1881                 this.astStack, 
1882                 startIndex - 1, 
1883                 variableDeclaratorsCounter); 
1884         this.astPtr--; // remove the type reference
1885         this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
1886
1887         // recovery
1888         if (this.currentElement != null) {
1889                 this.lastCheckPoint = endPos + 1;
1890                 if (this.currentElement.parent != null && this.currentElement instanceof RecoveredField){
1891                         if (!(this.currentElement instanceof RecoveredInitializer)) {
1892                                 this.currentElement = this.currentElement.parent;
1893                         }
1894                 }
1895                 this.restartRecovery = true;
1896         }
1897         this.variablesCounter[this.nestedType] = 0;
1898 }
1899 protected void consumeForceNoDiet() {
1900         // ForceNoDiet ::= $empty
1901         this.dietInt++;
1902 }
1903 protected void consumeForInit() {
1904         // ForInit ::= StatementExpressionList
1905         pushOnAstLengthStack(-1);
1906 }
1907 protected void consumeFormalParameter() {
1908         // FormalParameter ::= Type VariableDeclaratorId ==> false
1909         // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
1910         /*
1911         astStack : 
1912         identifierStack : type identifier
1913         intStack : dim dim
1914          ==>
1915         astStack : Argument
1916         identifierStack :  
1917         intStack :  
1918         */
1919
1920         this.identifierLengthPtr--;
1921         char[] identifierName = this.identifierStack[this.identifierPtr];
1922         long namePositions = this.identifierPositionStack[this.identifierPtr--];
1923         TypeReference type = getTypeReference(this.intStack[this.intPtr--] + this.intStack[this.intPtr--]);
1924         int modifierPositions = this.intStack[this.intPtr--];
1925         this.intPtr--;
1926         Argument arg = 
1927                 new Argument(
1928                         identifierName, 
1929                         namePositions, 
1930                         type, 
1931                         this.intStack[this.intPtr + 1] & ~AccDeprecated); // modifiers
1932         arg.declarationSourceStart = modifierPositions;
1933         pushOnAstStack(arg);
1934
1935         /* if incomplete method header, listLength counter will not have been reset,
1936                 indicating that some arguments are available on the stack */
1937         this.listLength++;      
1938 }
1939 protected void consumeFormalParameterList() {
1940         // FormalParameterList ::= FormalParameterList ',' FormalParameter
1941         optimizedConcatNodeLists();
1942 }
1943 protected void consumeFormalParameterListopt() {
1944         // FormalParameterListopt ::= $empty
1945         pushOnAstLengthStack(0);
1946 }
1947 protected void consumeImportDeclarations() {
1948         // ImportDeclarations ::= ImportDeclarations ImportDeclaration 
1949         optimizedConcatNodeLists();
1950 }
1951 protected void consumeImportDeclarationsopt() {
1952         // ImportDeclarationsopt ::= ImportDeclarations
1953         int length;
1954         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1955                 this.astPtr -= length;
1956                 System.arraycopy(
1957                         this.astStack,
1958                         this.astPtr + 1,
1959                         this.compilationUnit.imports = new ImportReference[length],
1960                         0,
1961                         length);
1962         }
1963 }
1964 protected void consumeInsideCastExpression() {
1965         // InsideCastExpression ::= $empty
1966 }
1967 protected void consumeInsideCastExpressionLL1() {
1968         // InsideCastExpressionLL1 ::= $empty
1969 }
1970
1971 protected void consumeInstanceOfExpression(int op) {
1972         // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
1973         //optimize the push/pop
1974
1975         //by construction, no base type may be used in getTypeReference
1976         Expression exp;
1977         this.expressionStack[this.expressionPtr] = exp =
1978                 new InstanceOfExpression(
1979                         this.expressionStack[this.expressionPtr],
1980                         getTypeReference(this.intStack[this.intPtr--]),
1981                         op);
1982         if (exp.sourceEnd == 0) {
1983                 //array on base type....
1984                 exp.sourceEnd = this.scanner.startPosition - 1;
1985         }
1986         //the scanner is on the next token already....
1987 }
1988 protected void consumeInterfaceDeclaration() {
1989         // see consumeClassDeclaration in case of changes: duplicated code
1990         // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
1991         int length;
1992         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1993                 //there are length declarations
1994                 //dispatch.....according to the type of the declarations
1995                 dispatchDeclarationInto(length);
1996         }
1997
1998         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1999         
2000         // mark initializers with local type mark if needed
2001         markInitializersWithLocalType(typeDecl);
2002
2003         //convert constructor that do not have the type's name into methods
2004         typeDecl.checkConstructors(this);
2005         
2006         //always add <clinit> (will be remove at code gen time if empty)
2007         if (this.scanner.containsAssertKeyword) {
2008                 typeDecl.bits |= ASTNode.AddAssertionMASK;
2009         }
2010         typeDecl.addClinit();
2011         typeDecl.bodyEnd = this.endStatementPosition;
2012         if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
2013                 typeDecl.bits |= ASTNode.UndocumentedEmptyBlockMASK;
2014         }
2015         typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition); 
2016 }
2017 protected void consumeInterfaceHeader() {
2018         // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2019
2020         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];        
2021         if (this.currentToken == TokenNameLBRACE){ 
2022                 typeDecl.bodyStart = this.scanner.currentPosition;
2023         }
2024         if (this.currentElement != null){
2025                 this.restartRecovery = true; // used to avoid branching back into the regular automaton         
2026         }
2027         // flush the comments related to the interface header
2028         this.scanner.commentPtr = -1;   
2029 }
2030 protected void consumeInterfaceHeaderExtends() {
2031         // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2032         int length = this.astLengthStack[this.astLengthPtr--];
2033         //super interfaces
2034         this.astPtr -= length;
2035         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2036         System.arraycopy(
2037                 this.astStack, 
2038                 this.astPtr + 1, 
2039                 typeDecl.superInterfaces = new TypeReference[length], 
2040                 0, 
2041                 length); 
2042         typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;          
2043         this.listLength = 0; // reset after having read super-interfaces                
2044         // recovery
2045         if (this.currentElement != null) { 
2046                 this.lastCheckPoint = typeDecl.bodyStart;
2047         }
2048 }
2049 protected void consumeInterfaceHeaderName() {
2050         // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2051         TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2052
2053         if (this.nestedMethod[this.nestedType] == 0) {
2054                 if (this.nestedType != 0) {
2055                         typeDecl.bits |= ASTNode.IsMemberTypeMASK;
2056                 }
2057         } else {
2058                 // Record that the block has a declaration for local types
2059                 typeDecl.bits |= ASTNode.IsLocalTypeMASK;
2060                 markEnclosingMemberWithLocalType();
2061                 blockReal();
2062         }
2063
2064         //highlight the name of the type
2065         long pos = this.identifierPositionStack[this.identifierPtr];
2066         typeDecl.sourceEnd = (int) pos;
2067         typeDecl.sourceStart = (int) (pos >>> 32);
2068         typeDecl.name = this.identifierStack[this.identifierPtr--];
2069         this.identifierLengthPtr--;
2070
2071         //compute the declaration source too
2072         // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2073         // we want to keep the beginning position but get rid of the end position
2074         // it is only used for the ClassLiteralAccess positions.
2075         typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
2076         this.intPtr--; // remove the end position of the class token
2077         typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
2078         typeDecl.modifiers = this.intStack[this.intPtr--];
2079         if (typeDecl.modifiersSourceStart >= 0) {
2080                 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2081         }
2082         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2083         pushOnAstStack(typeDecl);
2084         this.listLength = 0; // will be updated when reading super-interfaces
2085         // recovery
2086         if (this.currentElement != null){ // is recovering
2087                 this.lastCheckPoint = typeDecl.bodyStart;
2088                 this.currentElement = this.currentElement.add(typeDecl, 0);
2089                 this.lastIgnoredToken = -1;             
2090         }
2091         // javadoc
2092         typeDecl.javadoc = this.javadoc;
2093         this.javadoc = null;
2094 }
2095 protected void consumeInterfaceMemberDeclarations() {
2096         // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2097         concatNodeLists();
2098 }
2099 protected void consumeInterfaceMemberDeclarationsopt() {
2100         // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2101         this.nestedType--;
2102 }
2103 protected void consumeInterfaceType() {
2104         // InterfaceType ::= ClassOrInterfaceType
2105         pushOnAstStack(getTypeReference(0));
2106         /* if incomplete type header, listLength counter will not have been reset,
2107                 indicating that some interfaces are available on the stack */
2108         this.listLength++;      
2109 }
2110 protected void consumeInterfaceTypeList() {
2111         // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2112         optimizedConcatNodeLists();
2113 }
2114 protected void consumeLeftParen() {
2115         // PushLPAREN ::= '('
2116         pushOnIntStack(this.lParenPos);
2117 }
2118 protected void consumeLocalVariableDeclaration() {
2119         // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2120
2121         /*
2122         astStack : 
2123         expressionStack: Expression Expression ...... Expression
2124         identifierStack : type  identifier identifier ...... identifier
2125         intStack : typeDim      dim        dim               dim
2126          ==>
2127         astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2128         expressionStack :
2129         identifierStack : 
2130         intStack : 
2131           
2132         */
2133         int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
2134
2135         // update the astStack, astPtr and astLengthStack
2136         int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
2137         System.arraycopy(
2138                 this.astStack, 
2139                 startIndex, 
2140                 this.astStack, 
2141                 startIndex - 1, 
2142                 variableDeclaratorsCounter); 
2143         this.astPtr--; // remove the type reference
2144         this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
2145         this.variablesCounter[this.nestedType] = 0;
2146 }
2147 protected void consumeLocalVariableDeclarationStatement() {
2148         // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2149         // see blockReal in case of change: duplicated code
2150         // increment the amount of declared variables for this block
2151         this.realBlockStack[this.realBlockPtr]++;
2152         
2153         // update source end to include the semi-colon
2154         int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
2155         for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2156                 LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr - i];
2157                 localDeclaration.declarationSourceEnd = this.endStatementPosition; 
2158                 localDeclaration.declarationEnd = this.endStatementPosition;    // semi-colon included
2159         }
2160
2161 }
2162 protected void consumeMethodBody() {
2163         // MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
2164         this.nestedMethod[this.nestedType] --;
2165 }
2166 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2167         // MethodDeclaration ::= MethodHeader MethodBody
2168         // AbstractMethodDeclaration ::= MethodHeader ';'
2169
2170         /*
2171         astStack : modifiers arguments throws statements
2172         identifierStack : type name
2173         intStack : dim dim dim
2174          ==>
2175         astStack : MethodDeclaration
2176         identifierStack :
2177         intStack : 
2178         */
2179
2180         int length;
2181         if (isNotAbstract) {
2182                 // pop the position of the {  (body of the method) pushed in block decl
2183                 this.intPtr--;
2184                 this.intPtr--;
2185         }
2186
2187         int explicitDeclarations = 0;
2188         Statement[] statements = null;
2189         if (isNotAbstract) {
2190                 //statements
2191                 explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
2192                 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
2193                         System.arraycopy(
2194                                 this.astStack, 
2195                                 (this.astPtr -= length) + 1, 
2196                                 statements = new Statement[length], 
2197                                 0, 
2198                                 length); 
2199                 }
2200         }
2201
2202         // now we know that we have a method declaration at the top of the ast stack
2203         MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
2204         md.statements = statements;
2205         md.explicitDeclarations = explicitDeclarations;
2206
2207         // cannot be done in consumeMethodHeader because we have no idea whether or not there
2208         // is a body when we reduce the method header
2209         if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2210                 md.modifiers |= AccSemicolonBody;
2211         } else {
2212                 if (!this.diet && statements == null) {
2213                         if (!containsComment(md.bodyStart, this.endPosition)) {
2214                                 md.bits |= ASTNode.UndocumentedEmptyBlockMASK;
2215                         }
2216                 }
2217         }
2218         // store the endPosition (position just before the '}') in case there is
2219         // a trailing comment behind the end of the method
2220         md.bodyEnd = this.endPosition;
2221         md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2222 }
2223 protected void consumeMethodHeader() {
2224         // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2225         // retrieve end position of method declarator
2226         AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2227
2228         if (this.currentToken == TokenNameLBRACE){ 
2229                 method.bodyStart = this.scanner.currentPosition;
2230         }
2231         // recovery
2232         if (this.currentElement != null){
2233                 if (this.currentToken == TokenNameSEMICOLON){
2234                         method.modifiers |= AccSemicolonBody;                   
2235                         method.declarationSourceEnd = this.scanner.currentPosition-1;
2236                         method.bodyEnd = this.scanner.currentPosition-1;
2237                         if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
2238                                 this.currentElement = this.currentElement.parent;
2239                         }
2240                 }               
2241                 this.restartRecovery = true; // used to avoid branching back into the regular automaton
2242         }               
2243 }
2244 protected void consumeMethodHeaderExtendedDims() {
2245         // MethodHeaderExtendedDims ::= Dimsopt
2246         // now we update the returnType of the method
2247         MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
2248         int extendedDims = this.intStack[this.intPtr--];
2249         if (extendedDims != 0) {
2250                 TypeReference returnType = md.returnType;
2251                 md.sourceEnd = this.endPosition;
2252                 int dims = returnType.dimensions() + extendedDims;
2253                 int baseType;
2254                 if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
2255                         //it was a baseType
2256                         int sourceStart = returnType.sourceStart;
2257                         int sourceEnd =  returnType.sourceEnd;
2258                         returnType = TypeReference.baseTypeReference(-baseType, dims);
2259                         returnType.sourceStart = sourceStart;
2260                         returnType.sourceEnd = sourceEnd;
2261                         md.returnType = returnType;
2262                 } else {
2263                         md.returnType = this.copyDims(md.returnType, dims);
2264                 }
2265                 if (this.currentToken == TokenNameLBRACE){ 
2266                         md.bodyStart = this.endPosition + 1;
2267                 }
2268                 // recovery
2269                 if (this.currentElement != null){
2270                         this.lastCheckPoint = md.bodyStart;
2271                 }               
2272         }
2273 }
2274 protected void consumeMethodHeaderName() {
2275         // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2276         MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2277
2278         //name
2279         md.selector = this.identifierStack[this.identifierPtr];
2280         long selectorSource = this.identifierPositionStack[this.identifierPtr--];
2281         this.identifierLengthPtr--;
2282         //type
2283         md.returnType = getTypeReference(this.intStack[this.intPtr--]);
2284         //modifiers
2285         md.declarationSourceStart = this.intStack[this.intPtr--];
2286         md.modifiers = this.intStack[this.intPtr--];
2287         // javadoc
2288         md.javadoc = this.javadoc;
2289         this.javadoc = null;
2290
2291         //highlight starts at selector start
2292         md.sourceStart = (int) (selectorSource >>> 32);
2293         pushOnAstStack(md);
2294         md.sourceEnd = this.lParenPos;
2295         md.bodyStart = this.lParenPos+1;
2296         this.listLength = 0; // initialize listLength before reading parameters/throws
2297         
2298         // recovery
2299         if (this.currentElement != null){
2300                 if (this.currentElement instanceof RecoveredType 
2301                         //|| md.modifiers != 0
2302                         || (this.scanner.getLineNumber(md.returnType.sourceStart)
2303                                         == this.scanner.getLineNumber(md.sourceStart))){
2304                         this.lastCheckPoint = md.bodyStart;
2305                         this.currentElement = this.currentElement.add(md, 0);
2306                         this.lastIgnoredToken = -1;
2307                 } else {
2308                         this.lastCheckPoint = md.sourceStart;
2309                         this.restartRecovery = true;
2310                 }
2311         }               
2312 }
2313 protected void consumeMethodHeaderParameters() {
2314         // MethodHeaderParameters ::= FormalParameterListopt ')'
2315         int length = this.astLengthStack[this.astLengthPtr--];
2316         this.astPtr -= length;
2317         AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
2318         md.sourceEnd =  this.rParenPos;
2319         //arguments
2320         if (length != 0) {
2321                 System.arraycopy(
2322                         this.astStack, 
2323                         this.astPtr + 1, 
2324                         md.arguments = new Argument[length], 
2325                         0, 
2326                         length); 
2327         }
2328         md.bodyStart = this.rParenPos+1;
2329         this.listLength = 0; // reset listLength after having read all parameters
2330         // recovery
2331         if (this.currentElement != null){
2332                 this.lastCheckPoint = md.bodyStart;
2333                 if (this.currentElement.parseTree() == md) return;
2334
2335                 // might not have been attached yet - in some constructor scenarii
2336                 if (md.isConstructor()){
2337                         if ((length != 0)
2338                                 || (this.currentToken == TokenNameLBRACE) 
2339                                 || (this.currentToken == TokenNamethrows)){
2340                                 this.currentElement = this.currentElement.add(md, 0);
2341                                 this.lastIgnoredToken = -1;
2342                         }       
2343                 }       
2344         }       
2345 }
2346 protected void consumeMethodHeaderThrowsClause() {
2347         // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2348         int length = this.astLengthStack[this.astLengthPtr--];
2349         this.astPtr -= length;
2350         AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
2351         System.arraycopy(
2352                 this.astStack, 
2353                 this.astPtr + 1, 
2354                 md.thrownExceptions = new TypeReference[length], 
2355                 0, 
2356                 length);
2357         md.sourceEnd = md.thrownExceptions[length-1].sourceEnd;
2358         md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1;
2359         this.listLength = 0; // reset listLength after having read all thrown exceptions        
2360         // recovery
2361         if (this.currentElement != null){
2362                 this.lastCheckPoint = md.bodyStart;
2363         }               
2364 }
2365 protected void consumeMethodInvocationName() {
2366         // MethodInvocation ::= Name '(' ArgumentListopt ')'
2367
2368         // when the name is only an identifier...we have a message send to "this" (implicit)
2369
2370         MessageSend m = newMessageSend();
2371         m.sourceEnd = this.rParenPos;
2372         m.sourceStart = 
2373                 (int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32); 
2374         m.selector = this.identifierStack[this.identifierPtr--];
2375         if (this.identifierLengthStack[this.identifierLengthPtr] == 1) {
2376                 m.receiver = ThisReference.implicitThis();
2377                 this.identifierLengthPtr--;
2378         } else {
2379                 this.identifierLengthStack[this.identifierLengthPtr]--;
2380                 m.receiver = getUnspecifiedReference();
2381                 m.sourceStart = m.receiver.sourceStart;         
2382         }
2383         pushOnExpressionStack(m);
2384 }
2385 protected void consumeMethodInvocationPrimary() {
2386         //optimize the push/pop
2387         //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2388
2389         MessageSend m = newMessageSend();
2390         m.sourceStart = 
2391                 (int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32); 
2392         m.selector = this.identifierStack[this.identifierPtr--];
2393         this.identifierLengthPtr--;
2394         m.receiver = this.expressionStack[this.expressionPtr];
2395         m.sourceStart = m.receiver.sourceStart;
2396         m.sourceEnd = this.rParenPos;
2397         this.expressionStack[this.expressionPtr] = m;
2398 }
2399 protected void consumeMethodInvocationSuper() {
2400         // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2401
2402         MessageSend m = newMessageSend();
2403         m.sourceStart = this.intStack[this.intPtr--];
2404         m.sourceEnd = this.rParenPos;
2405         m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
2406         m.selector = this.identifierStack[this.identifierPtr--];
2407         this.identifierLengthPtr--;
2408         m.receiver = new SuperReference(m.sourceStart, this.endPosition);
2409         pushOnExpressionStack(m);
2410 }
2411 protected void consumeModifiers() {
2412         int savedModifiersSourceStart = this.modifiersSourceStart;      
2413         checkComment(); // might update modifiers with AccDeprecated
2414         pushOnIntStack(this.modifiers); // modifiers
2415         if (this.modifiersSourceStart >= savedModifiersSourceStart) {
2416                 this.modifiersSourceStart = savedModifiersSourceStart;
2417         }
2418         pushOnIntStack(this.modifiersSourceStart);
2419         resetModifiers();
2420 }
2421 protected void consumeNestedMethod() {
2422         // NestedMethod ::= $empty
2423         jumpOverMethodBody();
2424         this.nestedMethod[this.nestedType] ++;
2425         pushOnIntStack(this.scanner.currentPosition);
2426         consumeOpenBlock();
2427 }
2428 protected void consumeNestedType() {
2429         // NestedType ::= $empty
2430         int length = this.nestedMethod.length;
2431         if (++this.nestedType >= length) {
2432                 System.arraycopy(
2433                         this.nestedMethod, 0,
2434                         this.nestedMethod = new int[length + 30], 0,
2435                         length);
2436                 // increase the size of the variablesCounter as well. It has to be consistent with the size of the nestedMethod collection
2437                 System.arraycopy(
2438                         this.variablesCounter, 0,
2439                         this.variablesCounter = new int[length + 30], 0,
2440                         length);
2441         }
2442         this.nestedMethod[this.nestedType] = 0;
2443         this.variablesCounter[this.nestedType] = 0;
2444 }
2445 protected void consumeOneDimLoop() {
2446         // OneDimLoop ::= '[' ']'
2447         this.dimensions++;
2448 }
2449 protected void consumeOnlySynchronized() {
2450         // OnlySynchronized ::= 'synchronized'
2451         pushOnIntStack(this.synchronizedBlockSourceStart);
2452         resetModifiers();
2453 }
2454 protected void consumeOpenBlock() {
2455         // OpenBlock ::= $empty
2456
2457         pushOnIntStack(this.scanner.startPosition);
2458         int stackLength = this.realBlockStack.length;
2459         if (++this.realBlockPtr >= stackLength) {
2460                 System.arraycopy(
2461                         this.realBlockStack, 0,
2462                         this.realBlockStack = new int[stackLength + StackIncrement], 0,
2463                         stackLength);
2464         }
2465         this.realBlockStack[this.realBlockPtr] = 0;
2466 }
2467 protected void consumePackageDeclaration() {
2468         // PackageDeclaration ::= 'package' Name ';'
2469         /* build an ImportRef build from the last name 
2470         stored in the identifier stack. */
2471
2472         ImportReference impt = this.compilationUnit.currentPackage;
2473         // flush comments defined prior to import statements
2474         impt.declarationEnd = this.endStatementPosition;
2475         impt.declarationSourceEnd = this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
2476 }
2477 protected void consumePackageDeclarationName() {
2478         // PackageDeclarationName ::= 'package' Name
2479         /* build an ImportRef build from the last name 
2480         stored in the identifier stack. */
2481
2482         ImportReference impt;
2483         int length;
2484         char[][] tokens = 
2485                 new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][]; 
2486         this.identifierPtr -= length;
2487         long[] positions = new long[length];
2488         System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length);
2489         System.arraycopy(
2490                 this.identifierPositionStack, 
2491                 this.identifierPtr--, 
2492                 positions, 
2493                 0, 
2494                 length); 
2495         this.compilationUnit.currentPackage = 
2496                 impt = new ImportReference(tokens, positions, true, AccDefault); 
2497
2498         if (this.currentToken == TokenNameSEMICOLON){
2499                 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
2500         } else {
2501                 impt.declarationSourceEnd = impt.sourceEnd;
2502         }
2503         impt.declarationEnd = impt.declarationSourceEnd;
2504         //endPosition is just before the ;
2505         impt.declarationSourceStart = this.intStack[this.intPtr--];
2506
2507         // recovery
2508         if (this.currentElement != null){
2509                 this.lastCheckPoint = impt.declarationSourceEnd+1;
2510                 this.restartRecovery = true; // used to avoid branching back into the regular automaton         
2511         }       
2512 }
2513 protected void consumePostfixExpression() {
2514         // PostfixExpression ::= Name
2515         pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2516 }
2517 protected void consumePrimaryNoNewArray() {
2518         // PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN 
2519         final Expression parenthesizedExpression = this.expressionStack[this.expressionPtr];
2520         updateSourcePosition(parenthesizedExpression);
2521         int numberOfParenthesis = (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
2522         parenthesizedExpression.bits &= ~ASTNode.ParenthesizedMASK;
2523         parenthesizedExpression.bits |= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT;
2524 }
2525 protected void consumePrimaryNoNewArrayArrayType() {
2526         // PrimaryNoNewArray ::= ArrayType '.' 'class'
2527         this.intPtr--;
2528         pushOnExpressionStack(
2529                 new ClassLiteralAccess(this.intStack[this.intPtr--],
2530                 getTypeReference(this.intStack[this.intPtr--])));
2531 }
2532 protected void consumePrimaryNoNewArrayName() {
2533         // PrimaryNoNewArray ::= Name '.' 'class'
2534         this.intPtr--;
2535         pushOnExpressionStack(
2536                 new ClassLiteralAccess(this.intStack[this.intPtr--],
2537                 getTypeReference(0)));
2538 }
2539 protected void consumePrimaryNoNewArrayNameSuper() {
2540         // PrimaryNoNewArray ::= Name '.' 'super'
2541         pushOnExpressionStack(
2542                 new QualifiedSuperReference(
2543                         getTypeReference(0),
2544                         this.intStack[this.intPtr--],
2545                         this.endPosition));
2546 }
2547 protected void consumePrimaryNoNewArrayNameThis() {
2548         // PrimaryNoNewArray ::= Name '.' 'this'
2549         pushOnExpressionStack(
2550                 new QualifiedThisReference(
2551                         getTypeReference(0),
2552                         this.intStack[this.intPtr--],
2553                         this.endPosition));
2554 }
2555 protected void consumePrimaryNoNewArrayPrimitiveType() {
2556         // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
2557         this.intPtr--;
2558         pushOnExpressionStack(
2559                 new ClassLiteralAccess(this.intStack[this.intPtr--],
2560                 getTypeReference(0)));
2561 }
2562 protected void consumePrimaryNoNewArrayThis() {
2563         // PrimaryNoNewArray ::= 'this'
2564         pushOnExpressionStack(new ThisReference(this.intStack[this.intPtr--], this.endPosition));
2565 }
2566 protected void consumePrimitiveType() {
2567         // Type ::= PrimitiveType
2568         pushOnIntStack(0);
2569 }
2570 protected void consumePushModifiers() {
2571         pushOnIntStack(this.modifiers); // modifiers
2572         pushOnIntStack(this.modifiersSourceStart);
2573         resetModifiers();
2574 }
2575 protected void consumePushPosition() {
2576         // for source managment purpose
2577         // PushPosition ::= $empty
2578         pushOnIntStack(this.endPosition);
2579 }
2580 protected void consumeQualifiedName() {
2581         // QualifiedName ::= Name '.' SimpleName 
2582         /*back from the recursive loop of QualifiedName.
2583         Updates identifier length into the length stack*/
2584
2585         this.identifierLengthStack[--this.identifierLengthPtr]++;
2586 }
2587 protected void consumeReferenceType() {
2588         // ReferenceType ::= ClassOrInterfaceType
2589         pushOnIntStack(0);
2590 }
2591 protected void consumeRestoreDiet() {
2592         // RestoreDiet ::= $empty
2593         this.dietInt--;
2594 }
2595 protected void consumeRightParen() {
2596         // PushRPAREN ::= ')'
2597         pushOnIntStack(this.rParenPos);
2598 }
2599 // This method is part of an automatic generation : do NOT edit-modify  
2600 protected void consumeRule(int act) {
2601         switch ( act ) {
2602         case 26 : // System.out.println("Type ::= PrimitiveType");  //$NON-NLS-1$
2603                 consumePrimitiveType();  
2604                 break ;
2605                 
2606         case 40 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");  //$NON-NLS-1$
2607                 consumeReferenceType();   
2608                 break ;
2609                 
2610         case 49 : // System.out.println("QualifiedName ::= Name DOT SimpleName");  //$NON-NLS-1$
2611                 consumeQualifiedName();  
2612                 break ;
2613                 
2614         case 50 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt...");  //$NON-NLS-1$
2615                 consumeCompilationUnit();  
2616                 break ;
2617                 
2618         case 51 : // System.out.println("EnterCompilationUnit ::=");  //$NON-NLS-1$
2619                 consumeEnterCompilationUnit();  
2620                 break ;
2621                 
2622         case 64 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");  //$NON-NLS-1$
2623                 consumeCatchHeader();  
2624                 break ;
2625                 
2626         case 66 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");  //$NON-NLS-1$
2627                 consumeImportDeclarations();  
2628                 break ;
2629                 
2630         case 68 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");  //$NON-NLS-1$
2631                 consumeTypeDeclarations();  
2632                 break ;
2633                 
2634         case 69 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");  //$NON-NLS-1$
2635                 consumePackageDeclaration();  
2636                 break ;
2637                 
2638         case 70 : // System.out.println("PackageDeclarationName ::= package Name");  //$NON-NLS-1$
2639                 consumePackageDeclarationName();  
2640                 break ;
2641                 
2642         case 73 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName...");  //$NON-NLS-1$
2643                 consumeSingleTypeImportDeclaration();  
2644                 break ;
2645                 
2646         case 74 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");  //$NON-NLS-1$
2647                 consumeSingleTypeImportDeclarationName();  
2648                 break ;
2649                 
2650         case 75 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName");  //$NON-NLS-1$
2651                 consumeTypeImportOnDemandDeclaration();  
2652                 break ;
2653                 
2654         case 76 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");  //$NON-NLS-1$
2655                 consumeTypeImportOnDemandDeclarationName();  
2656                 break ;
2657                 
2658         case 79 : // System.out.println("TypeDeclaration ::= SEMICOLON");  //$NON-NLS-1$
2659                 consumeEmptyTypeDeclaration();  
2660                 break ;
2661                 
2662         case 93 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");  //$NON-NLS-1$
2663                 consumeClassDeclaration();  
2664                 break ;
2665                 
2666         case 94 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt...");  //$NON-NLS-1$
2667                 consumeClassHeader();  
2668                 break ;
2669                 
2670         case 95 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");  //$NON-NLS-1$
2671                 consumeClassHeaderName();  
2672                 break ;
2673                 
2674         case 96 : // System.out.println("ClassHeaderExtends ::= extends ClassType");  //$NON-NLS-1$
2675                 consumeClassHeaderExtends();  
2676                 break ;
2677                 
2678         case 97 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");  //$NON-NLS-1$
2679                 consumeClassHeaderImplements();  
2680                 break ;
2681                 
2682         case 99 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");  //$NON-NLS-1$
2683                 consumeInterfaceTypeList();  
2684                 break ;
2685                 
2686         case 100 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");  //$NON-NLS-1$
2687                 consumeInterfaceType();  
2688                 break ;
2689                 
2690         case 103 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");  //$NON-NLS-1$
2691                 consumeClassBodyDeclarations();  
2692                 break ;
2693                 
2694         case 107 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");  //$NON-NLS-1$
2695                 consumeClassBodyDeclaration();  
2696                 break ;
2697                 
2698         case 108 : // System.out.println("Diet ::=");  //$NON-NLS-1$
2699                 consumeDiet();  
2700                 break ;
2701
2702         case 109 : // System.out.println("Initializer ::= Diet NestedMethod Block");  //$NON-NLS-1$
2703                 consumeClassBodyDeclaration();  
2704                 break ;
2705                 
2706         case 116 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");  //$NON-NLS-1$
2707                 consumeEmptyClassMemberDeclaration();  
2708                 break ;
2709
2710         case 117 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");  //$NON-NLS-1$
2711                 consumeFieldDeclaration();  
2712                 break ;
2713                 
2714         case 119 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");  //$NON-NLS-1$
2715                 consumeVariableDeclarators();  
2716                 break ;
2717                 
2718         case 122 : // System.out.println("EnterVariable ::=");  //$NON-NLS-1$
2719                 consumeEnterVariable();  
2720                 break ;
2721                 
2722         case 123 : // System.out.println("ExitVariableWithInitialization ::=");  //$NON-NLS-1$
2723                 consumeExitVariableWithInitialization();  
2724                 break ;
2725                 
2726         case 124 : // System.out.println("ExitVariableWithoutInitialization ::=");  //$NON-NLS-1$
2727                 consumeExitVariableWithoutInitialization();  
2728                 break ;
2729                 
2730         case 125 : // System.out.println("ForceNoDiet ::=");  //$NON-NLS-1$
2731                 consumeForceNoDiet();  
2732                 break ;
2733                 
2734         case 126 : // System.out.println("RestoreDiet ::=");  //$NON-NLS-1$
2735                 consumeRestoreDiet();  
2736                 break ;
2737                 
2738         case 131 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");  //$NON-NLS-1$
2739                 // set to true to consume a method with a body
2740                 consumeMethodDeclaration(true);   
2741                 break ;
2742                 
2743         case 132 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");  //$NON-NLS-1$
2744                 // set to false to consume a method without body
2745                 consumeMethodDeclaration(false);  
2746                 break ;
2747                 
2748         case 133 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters...");  //$NON-NLS-1$
2749                 consumeMethodHeader();  
2750                 break ;
2751                 
2752         case 134 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");  //$NON-NLS-1$
2753                 consumeMethodHeaderName();  
2754                 break ;
2755                 
2756         case 135 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");  //$NON-NLS-1$
2757                 consumeMethodHeaderParameters();  
2758                 break ;
2759                 
2760         case 136 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");  //$NON-NLS-1$
2761                 consumeMethodHeaderExtendedDims();  
2762                 break ;
2763                 
2764         case 137 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");  //$NON-NLS-1$
2765                 consumeMethodHeaderThrowsClause();  
2766                 break ;
2767                 
2768         case 138 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters");  //$NON-NLS-1$
2769                 consumeConstructorHeader();  
2770                 break ;
2771                 
2772         case 139 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");  //$NON-NLS-1$
2773                 consumeConstructorHeaderName();  
2774                 break ;
2775                 
2776         case 141 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");  //$NON-NLS-1$
2777                 consumeFormalParameterList();  
2778                 break ;
2779                 
2780         case 142 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");  //$NON-NLS-1$
2781                 // the boolean is used to know if the modifiers should be reset
2782                 consumeFormalParameter();  
2783                 break ;
2784                 
2785         case 144 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");  //$NON-NLS-1$
2786                 consumeClassTypeList();  
2787                 break ;
2788                 
2789         case 145 : // System.out.println("ClassTypeElt ::= ClassType");  //$NON-NLS-1$
2790                 consumeClassTypeElt();  
2791                 break ;
2792                 
2793         case 146 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");  //$NON-NLS-1$
2794                 consumeMethodBody();  
2795                 break ;
2796                 
2797         case 147 : // System.out.println("NestedMethod ::=");  //$NON-NLS-1$
2798                 consumeNestedMethod();  
2799                 break ;
2800                 
2801         case 148 : // System.out.println("StaticInitializer ::= StaticOnly Block");  //$NON-NLS-1$
2802                 consumeStaticInitializer();  
2803                 break ;
2804
2805         case 149 : // System.out.println("StaticOnly ::= static");  //$NON-NLS-1$
2806                 consumeStaticOnly();  
2807                 break ;
2808                 
2809         case 150 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody");  //$NON-NLS-1$
2810                 consumeConstructorDeclaration() ;  
2811                 break ;
2812                 
2813         case 151 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");  //$NON-NLS-1$
2814                 consumeInvalidConstructorDeclaration() ;  
2815                 break ;
2816                 
2817         case 152 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN");  //$NON-NLS-1$
2818                 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This);  
2819                 break ;
2820                 
2821         case 153 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt...");  //$NON-NLS-1$
2822                 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super);  
2823                 break ;
2824                 
2825         case 154 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN...");  //$NON-NLS-1$
2826                 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);  
2827                 break ;
2828                 
2829         case 155 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN...");  //$NON-NLS-1$
2830                 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);  
2831                 break ;
2832                 
2833         case 156 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN...");  //$NON-NLS-1$
2834                 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);  
2835                 break ;
2836                 
2837         case 157 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN...");  //$NON-NLS-1$
2838                 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);  
2839                 break ;
2840                 
2841         case 158 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");  //$NON-NLS-1$
2842                 consumeInterfaceDeclaration();  
2843                 break ;
2844                 
2845         case 159 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");  //$NON-NLS-1$
2846                 consumeInterfaceHeader();  
2847                 break ;
2848                 
2849         case 160 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");  //$NON-NLS-1$
2850                 consumeInterfaceHeaderName();  
2851                 break ;
2852                 
2853         case 162 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");  //$NON-NLS-1$
2854                 consumeInterfaceHeaderExtends();  
2855                 break ;
2856                 
2857         case 165 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");  //$NON-NLS-1$
2858                 consumeInterfaceMemberDeclarations();  
2859                 break ;
2860                 
2861         case 166 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");  //$NON-NLS-1$
2862                 consumeEmptyInterfaceMemberDeclaration();  
2863                 break ;
2864                 
2865         case 169 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");  //$NON-NLS-1$
2866                 ignoreMethodBody();  
2867                 break ;
2868                 
2869         case 170 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader MethodBody");  //$NON-NLS-1$
2870                 ignoreInvalidConstructorDeclaration(true);   
2871                 break ;
2872                 
2873         case 171 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");  //$NON-NLS-1$
2874                 ignoreInvalidConstructorDeclaration(false);   
2875                 break ;
2876                 
2877         case 177 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");  //$NON-NLS-1$
2878                 consumeEmptyArrayInitializer();  
2879                 break ;
2880                 
2881         case 178 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");  //$NON-NLS-1$
2882                 consumeArrayInitializer();  
2883                 break ;
2884                 
2885         case 179 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");  //$NON-NLS-1$
2886                 consumeArrayInitializer();  
2887                 break ;
2888                 
2889         case 181 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA...");  //$NON-NLS-1$
2890                 consumeVariableInitializers();  
2891                 break ;
2892                 
2893         case 182 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");  //$NON-NLS-1$
2894                 consumeBlock();  
2895                 break ;
2896                 
2897         case 183 : // System.out.println("OpenBlock ::=");  //$NON-NLS-1$
2898                 consumeOpenBlock() ;  
2899                 break ;
2900                 
2901         case 185 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");  //$NON-NLS-1$
2902                 consumeBlockStatements() ;  
2903                 break ;
2904                 
2905         case 189 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");  //$NON-NLS-1$
2906                 ignoreInterfaceDeclaration();  
2907                 break ;
2908                 
2909         case 190 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration...");  //$NON-NLS-1$
2910                 consumeLocalVariableDeclarationStatement();  
2911                 break ;
2912                 
2913         case 191 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");  //$NON-NLS-1$
2914                 consumeLocalVariableDeclaration();  
2915                 break ;
2916                 
2917         case 192 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers...");  //$NON-NLS-1$
2918                 consumeLocalVariableDeclaration();  
2919                 break ;
2920                 
2921         case 193 : // System.out.println("PushModifiers ::=");  //$NON-NLS-1$
2922                 consumePushModifiers();  
2923                 break ;
2924                 
2925         case 217 : // System.out.println("EmptyStatement ::= SEMICOLON");  //$NON-NLS-1$
2926                 consumeEmptyStatement();  
2927                 break ;
2928                 
2929         case 218 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");  //$NON-NLS-1$
2930                 consumeStatementLabel() ;  
2931                 break ;
2932                 
2933         case 219 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");  //$NON-NLS-1$
2934                 consumeStatementLabel() ;  
2935                 break ;
2936                 
2937         case 220 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");  //$NON-NLS-1$
2938                 consumeExpressionStatement();  
2939                 break ;
2940                 
2941         case 229 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");  //$NON-NLS-1$
2942                 consumeStatementIfNoElse();  
2943                 break ;
2944                 
2945         case 230 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN...");  //$NON-NLS-1$
2946                 consumeStatementIfWithElse();  
2947                 break ;
2948                 
2949         case 231 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN...");  //$NON-NLS-1$
2950                 consumeStatementIfWithElse();  
2951                 break ;
2952                 
2953         case 232 : // System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN OpenBlock...");  //$NON-NLS-1$
2954                 consumeStatementSwitch() ;  
2955                 break ;
2956                 
2957         case 233 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");  //$NON-NLS-1$
2958                 consumeEmptySwitchBlock() ;  
2959                 break ;
2960                 
2961         case 236 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");  //$NON-NLS-1$
2962                 consumeSwitchBlock() ;  
2963                 break ;
2964                 
2965         case 238 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");  //$NON-NLS-1$
2966                 consumeSwitchBlockStatements() ;  
2967                 break ;
2968                 
2969         case 239 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");  //$NON-NLS-1$
2970                 consumeSwitchBlockStatement() ;  
2971                 break ;
2972                 
2973         case 241 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");  //$NON-NLS-1$
2974                 consumeSwitchLabels() ;  
2975                 break ;
2976                 
2977         case 242 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");  //$NON-NLS-1$
2978                 consumeCaseLabel();  
2979                 break ;
2980                 
2981         case 243 : // System.out.println("SwitchLabel ::= default COLON");  //$NON-NLS-1$
2982                 consumeDefaultLabel();  
2983                 break ;
2984                 
2985         case 244 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");  //$NON-NLS-1$
2986                 consumeStatementWhile() ;  
2987                 break ;
2988                 
2989         case 245 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN...");  //$NON-NLS-1$
2990                 consumeStatementWhile() ;  
2991                 break ;
2992                 
2993         case 246 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN...");  //$NON-NLS-1$
2994                 consumeStatementDo() ;  
2995                 break ;
2996                 
2997         case 247 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt...");  //$NON-NLS-1$
2998                 consumeStatementFor() ;  
2999                 break ;
3000                 
3001         case 248 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON...");  //$NON-NLS-1$
3002                 consumeStatementFor() ;  
3003                 break ;
3004                 
3005         case 249 : // System.out.println("ForInit ::= StatementExpressionList");  //$NON-NLS-1$
3006                 consumeForInit() ;  
3007                 break ;
3008                 
3009         case 253 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA...");  //$NON-NLS-1$
3010                 consumeStatementExpressionList() ;  
3011                 break ;
3012                 
3013         case 254 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");  //$NON-NLS-1$
3014                 consumeSimpleAssertStatement() ;  
3015                 break ;
3016                 
3017         case 255 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");  //$NON-NLS-1$
3018                 consumeAssertStatement() ;  
3019                 break ;
3020                 
3021         case 256 : // System.out.println("BreakStatement ::= break SEMICOLON");  //$NON-NLS-1$
3022                 consumeStatementBreak() ;  
3023                 break ;
3024                 
3025         case 257 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");  //$NON-NLS-1$
3026                 consumeStatementBreakWithLabel() ;  
3027                 break ;
3028                 
3029         case 258 : // System.out.println("ContinueStatement ::= continue SEMICOLON");  //$NON-NLS-1$
3030                 consumeStatementContinue() ;  
3031                 break ;
3032                 
3033         case 259 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");  //$NON-NLS-1$
3034                 consumeStatementContinueWithLabel() ;  
3035                 break ;
3036                 
3037         case 260 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");  //$NON-NLS-1$
3038                 consumeStatementReturn() ;  
3039                 break ;
3040                 
3041         case 261 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");  //$NON-NLS-1$
3042                 consumeStatementThrow();
3043                 
3044                 break ;
3045                 
3046         case 262 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN");  //$NON-NLS-1$
3047                 consumeStatementSynchronized();  
3048                 break ;
3049                 
3050         case 263 : // System.out.println("OnlySynchronized ::= synchronized");  //$NON-NLS-1$
3051                 consumeOnlySynchronized();  
3052                 break ;
3053                 
3054         case 264 : // System.out.println("TryStatement ::= try TryBlock Catches");  //$NON-NLS-1$
3055                 consumeStatementTry(false);  
3056                 break ;
3057                 
3058         case 265 : // System.out.println("TryStatement ::= try TryBlock Catchesopt Finally");  //$NON-NLS-1$
3059                 consumeStatementTry(true);  
3060                 break ;
3061                 
3062         case 267 : // System.out.println("ExitTryBlock ::=");  //$NON-NLS-1$
3063                 consumeExitTryBlock();  
3064                 break ;
3065                 
3066         case 269 : // System.out.println("Catches ::= Catches CatchClause");  //$NON-NLS-1$
3067                 consumeCatches();  
3068                 break ;
3069                 
3070         case 270 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");  //$NON-NLS-1$
3071                 consumeStatementCatch() ;  
3072                 break ;
3073                 
3074         case 272 : // System.out.println("PushLPAREN ::= LPAREN");  //$NON-NLS-1$
3075                 consumeLeftParen();  
3076                 break ;
3077                 
3078         case 273 : // System.out.println("PushRPAREN ::= RPAREN");  //$NON-NLS-1$
3079                 consumeRightParen();  
3080                 break ;
3081                 
3082         case 278 : // System.out.println("PrimaryNoNewArray ::= this");  //$NON-NLS-1$
3083                 consumePrimaryNoNewArrayThis();  
3084                 break ;
3085                 
3086         case 279 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");  //$NON-NLS-1$
3087                 consumePrimaryNoNewArray();  
3088                 break ;
3089                 
3090         case 282 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");  //$NON-NLS-1$
3091                 consumePrimaryNoNewArrayNameThis();  
3092                 break ;
3093                 
3094         case 283 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");  //$NON-NLS-1$
3095                 consumePrimaryNoNewArrayNameSuper();  
3096                 break ;
3097                 
3098         case 284 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");  //$NON-NLS-1$
3099                 consumePrimaryNoNewArrayName();  
3100                 break ;
3101                 
3102         case 285 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");  //$NON-NLS-1$
3103                 consumePrimaryNoNewArrayArrayType();  
3104                 break ;
3105                 
3106         case 286 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");  //$NON-NLS-1$
3107                 consumePrimaryNoNewArrayPrimitiveType();  
3108                 break ;
3109                 
3110         case 289 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");  //$NON-NLS-1$
3111                 consumeAllocationHeader();  
3112                 break ;
3113                 
3114         case 290 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN...");  //$NON-NLS-1$
3115                 consumeClassInstanceCreationExpression();  
3116                 break ;
3117                 
3118         case 291 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName...");  //$NON-NLS-1$
3119                 consumeClassInstanceCreationExpressionQualified() ;  
3120                 break ;
3121                 
3122         case 292 : // System.out.println("ClassInstanceCreationExpression ::=...");  //$NON-NLS-1$
3123                 consumeClassInstanceCreationExpressionQualified() ;  
3124                 break ;
3125                 
3126         case 293 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");  //$NON-NLS-1$
3127                 consumeClassInstanceCreationExpressionName() ;  
3128                 break ;
3129                 
3130         case 294 : // System.out.println("ClassBodyopt ::=");  //$NON-NLS-1$
3131                 consumeClassBodyopt();  
3132                 break ;
3133                 
3134         case 296 : // System.out.println("EnterAnonymousClassBody ::=");  //$NON-NLS-1$
3135                 consumeEnterAnonymousClassBody();  
3136                 break ;
3137                 
3138         case 298 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");  //$NON-NLS-1$
3139                 consumeArgumentList();  
3140                 break ;
3141                 
3142         case 299 : // System.out.println("ArrayCreationHeader ::= new PrimitiveType DimWithOrWithOutExprs");  //$NON-NLS-1$
3143                 consumeArrayCreationHeader();  
3144                 break ;
3145                 
3146         case 300 : // System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType...");  //$NON-NLS-1$
3147                 consumeArrayCreationHeader();  
3148                 break ;
3149                 
3150         case 301 : // System.out.println("ArrayCreationWithoutArrayInitializer ::= new PrimitiveType...");  //$NON-NLS-1$
3151                 consumeArrayCreationExpressionWithoutInitializer();  
3152                 break ;
3153                 
3154         case 302 : // System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType...");  //$NON-NLS-1$
3155                 consumeArrayCreationExpressionWithInitializer();  
3156                 break ;
3157                 
3158         case 303 : // System.out.println("ArrayCreationWithoutArrayInitializer ::= new ClassOrInterfaceType...");  //$NON-NLS-1$
3159                 consumeArrayCreationExpressionWithoutInitializer();  
3160                 break ;
3161                 
3162         case 304 : // System.out.println("ArrayCreationWithArrayInitializer ::= new ClassOrInterfaceType...");  //$NON-NLS-1$
3163                 consumeArrayCreationExpressionWithInitializer();  
3164                 break ;
3165                 
3166         case 306 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");  //$NON-NLS-1$
3167                 consumeDimWithOrWithOutExprs();  
3168                 break ;
3169                 
3170         case 308 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");  //$NON-NLS-1$
3171                 consumeDimWithOrWithOutExpr();  
3172                 break ;
3173                 
3174         case 309 : // System.out.println("Dims ::= DimsLoop");  //$NON-NLS-1$
3175                 consumeDims();  
3176                 break ;
3177                 
3178         case 312 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");  //$NON-NLS-1$
3179                 consumeOneDimLoop();  
3180                 break ;
3181                 
3182         case 313 : // System.out.println("FieldAccess ::= Primary DOT Identifier");  //$NON-NLS-1$
3183                 consumeFieldAccess(false);  
3184                 break ;
3185                 
3186         case 314 : // System.out.println("FieldAccess ::= super DOT Identifier");  //$NON-NLS-1$
3187                 consumeFieldAccess(true);  
3188                 break ;
3189                 
3190         case 315 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");  //$NON-NLS-1$
3191                 consumeMethodInvocationName();  
3192                 break ;
3193                 
3194         case 316 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt");  //$NON-NLS-1$
3195                 consumeMethodInvocationPrimary();  
3196                 break ;
3197                 
3198         case 317 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt...");  //$NON-NLS-1$
3199                 consumeMethodInvocationSuper();  
3200                 break ;
3201                 
3202         case 318 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");  //$NON-NLS-1$
3203                 consumeArrayAccess(true);  
3204                 break ;
3205                 
3206         case 319 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");  //$NON-NLS-1$
3207                 consumeArrayAccess(false);  
3208                 break ;
3209                 
3210         case 320 : // System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer LBRACKET...");  //$NON-NLS-1$
3211                 consumeArrayAccess(false);  
3212                 break ;
3213                 
3214         case 322 : // System.out.println("PostfixExpression ::= Name");  //$NON-NLS-1$
3215                 consumePostfixExpression();  
3216                 break ;
3217                 
3218         case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");  //$NON-NLS-1$
3219                 consumeUnaryExpression(OperatorIds.PLUS,true);  
3220                 break ;
3221                 
3222         case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");  //$NON-NLS-1$
3223                 consumeUnaryExpression(OperatorIds.MINUS,true);  
3224                 break ;
3225                 
3226         case 327 : // System.out.println("PushPosition ::=");  //$NON-NLS-1$
3227                 consumePushPosition();  
3228                 break ;
3229                 
3230         case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");  //$NON-NLS-1$
3231                 consumeUnaryExpression(OperatorIds.PLUS);  
3232                 break ;
3233                 
3234         case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");  //$NON-NLS-1$
3235                 consumeUnaryExpression(OperatorIds.MINUS);  
3236                 break ;
3237                 
3238         case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");  //$NON-NLS-1$
3239                 consumeUnaryExpression(OperatorIds.PLUS,false);  
3240                 break ;
3241                 
3242         case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");  //$NON-NLS-1$
3243                 consumeUnaryExpression(OperatorIds.MINUS,false);  
3244                 break ;
3245                 
3246         case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");  //$NON-NLS-1$
3247                 consumeUnaryExpression(OperatorIds.TWIDDLE);  
3248                 break ;
3249                 
3250         case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");  //$NON-NLS-1$
3251                 consumeUnaryExpression(OperatorIds.NOT);  
3252                 break ;
3253                 
3254         case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN...");  //$NON-NLS-1$
3255                 consumeCastExpression();  
3256                 break ;
3257                 
3258         case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN...");  //$NON-NLS-1$
3259                 consumeCastExpression();  
3260                 break ;
3261                 
3262         case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN...");  //$NON-NLS-1$
3263                 consumeCastExpressionLL1();  
3264                 break ;
3265                 
3266         case 342 : // System.out.println("InsideCastExpression ::=");  //$NON-NLS-1$
3267                 consumeInsideCastExpression();  
3268                 break ;
3269                 
3270         case 343 : // System.out.println("InsideCastExpressionLL1 ::=");  //$NON-NLS-1$
3271                 consumeInsideCastExpressionLL1();  
3272                 break ;
3273                 
3274         case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY...");  //$NON-NLS-1$
3275                 consumeBinaryExpression(OperatorIds.MULTIPLY);  
3276                 break ;
3277                 
3278         case 346 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE...");  //$NON-NLS-1$
3279                 consumeBinaryExpression(OperatorIds.DIVIDE);  
3280                 break ;
3281                 
3282         case 347 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER...");  //$NON-NLS-1$
3283                 consumeBinaryExpression(OperatorIds.REMAINDER);  
3284                 break ;
3285                 
3286         case 349 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS...");  //$NON-NLS-1$
3287                 consumeBinaryExpression(OperatorIds.PLUS);  
3288                 break ;
3289                 
3290         case 350 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS...");  //$NON-NLS-1$
3291                 consumeBinaryExpression(OperatorIds.MINUS);  
3292                 break ;
3293                 
3294         case 352 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");  //$NON-NLS-1$
3295                 consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
3296                 break ;
3297                 
3298         case 353 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");  //$NON-NLS-1$
3299                 consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
3300                 break ;
3301                 
3302         case 354 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT...");  //$NON-NLS-1$
3303                 consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
3304                 break ;
3305                 
3306         case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");  //$NON-NLS-1$
3307                 consumeBinaryExpression(OperatorIds.LESS);  
3308                 break ;
3309                 
3310         case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER...");  //$NON-NLS-1$
3311                 consumeBinaryExpression(OperatorIds.GREATER);  
3312                 break ;
3313                 
3314         case 358 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL...");  //$NON-NLS-1$
3315                 consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
3316                 break ;
3317                 
3318         case 359 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL...");  //$NON-NLS-1$
3319                 consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
3320                 break ;
3321                 
3322         case 360 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof...");  //$NON-NLS-1$
3323                 consumeInstanceOfExpression(OperatorIds.INSTANCEOF);  
3324                 break ;
3325                 
3326         case 362 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL...");  //$NON-NLS-1$
3327                 consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
3328                 break ;
3329                 
3330         case 363 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL...");  //$NON-NLS-1$
3331                 consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
3332                 break ;
3333                 
3334         case 365 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");  //$NON-NLS-1$
3335                 consumeBinaryExpression(OperatorIds.AND);  
3336                 break ;
3337                 
3338         case 367 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");  //$NON-NLS-1$
3339                 consumeBinaryExpression(OperatorIds.XOR);  
3340                 break ;
3341                 
3342         case 369 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR...");  //$NON-NLS-1$
3343                 consumeBinaryExpression(OperatorIds.OR);  
3344                 break ;
3345                 
3346         case 371 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND...");  //$NON-NLS-1$
3347                 consumeBinaryExpression(OperatorIds.AND_AND);  
3348                 break ;
3349                 
3350         case 373 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR...");  //$NON-NLS-1$
3351                 consumeBinaryExpression(OperatorIds.OR_OR);  
3352                 break ;
3353                 
3354         case 375 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION...");  //$NON-NLS-1$
3355                 consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
3356                 break ;
3357                 
3358         case 378 : // System.out.println("Assignment ::= PostfixExpression AssignmentOperator...");  //$NON-NLS-1$
3359                 consumeAssignment();  
3360                 break ;
3361                 
3362         case 380 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");  //$NON-NLS-1$
3363                 ignoreExpressionAssignment(); 
3364                 break ;
3365                 
3366         case 381 : // System.out.println("AssignmentOperator ::= EQUAL");  //$NON-NLS-1$
3367                 consumeAssignmentOperator(EQUAL);  
3368                 break ;
3369                 
3370         case 382 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");  //$NON-NLS-1$
3371                 consumeAssignmentOperator(MULTIPLY);  
3372                 break ;
3373                 
3374         case 383 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");  //$NON-NLS-1$
3375                 consumeAssignmentOperator(DIVIDE);  
3376                 break ;
3377                 
3378         case 384 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");  //$NON-NLS-1$
3379                 consumeAssignmentOperator(REMAINDER);  
3380                 break ;
3381                 
3382         case 385 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");  //$NON-NLS-1$
3383                 consumeAssignmentOperator(PLUS);  
3384                 break ;
3385                 
3386         case 386 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");  //$NON-NLS-1$
3387                 consumeAssignmentOperator(MINUS);  
3388                 break ;
3389                 
3390         case 387 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");  //$NON-NLS-1$
3391                 consumeAssignmentOperator(LEFT_SHIFT);  
3392                 break ;
3393                 
3394         case 388 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");  //$NON-NLS-1$
3395                 consumeAssignmentOperator(RIGHT_SHIFT);  
3396                 break ;
3397                 
3398         case 389 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");  //$NON-NLS-1$
3399                 consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
3400                 break ;
3401                 
3402         case 390 : // System.out.println("AssignmentOperator ::= AND_EQUAL");  //$NON-NLS-1$
3403                 consumeAssignmentOperator(AND);  
3404                 break ;
3405                 
3406         case 391 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");  //$NON-NLS-1$
3407                 consumeAssignmentOperator(XOR);  
3408                 break ;
3409                 
3410         case 392 : // System.out.println("AssignmentOperator ::= OR_EQUAL");  //$NON-NLS-1$
3411                 consumeAssignmentOperator(OR);  
3412                 break ;
3413                 
3414         case 399 : // System.out.println("Expressionopt ::=");  //$NON-NLS-1$
3415                 consumeEmptyExpression();  
3416                 break ;
3417                 
3418         case 403 : // System.out.println("ImportDeclarationsopt ::=");  //$NON-NLS-1$
3419                 consumeEmptyImportDeclarationsopt();  
3420                 break ;
3421                 
3422         case 404 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");  //$NON-NLS-1$
3423                 consumeImportDeclarationsopt();  
3424                 break ;
3425                 
3426         case 405 : // System.out.println("TypeDeclarationsopt ::=");  //$NON-NLS-1$
3427                 consumeEmptyTypeDeclarationsopt();  
3428                 break ;
3429                 
3430         case 406 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");  //$NON-NLS-1$
3431                 consumeTypeDeclarationsopt();  
3432                 break ;
3433                 
3434         case 407 : // System.out.println("ClassBodyDeclarationsopt ::=");  //$NON-NLS-1$
3435                 consumeEmptyClassBodyDeclarationsopt();  
3436                 break ;
3437                 
3438         case 408 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");  //$NON-NLS-1$
3439                 consumeClassBodyDeclarationsopt();  
3440                 break ;
3441                 
3442         case 409 : // System.out.println("Modifiersopt ::=");  //$NON-NLS-1$
3443                 consumeDefaultModifiers();  
3444                 break ;
3445                 
3446         case 410 : // System.out.println("Modifiersopt ::= Modifiers");  //$NON-NLS-1$
3447                 consumeModifiers();  
3448                 break ;
3449                 
3450         case 411 : // System.out.println("BlockStatementsopt ::=");  //$NON-NLS-1$
3451                 consumeEmptyBlockStatementsopt();  
3452                 break ;
3453                 
3454         case 413 : // System.out.println("Dimsopt ::=");  //$NON-NLS-1$
3455                 consumeEmptyDimsopt();  
3456                 break ;
3457                 
3458         case 415 : // System.out.println("ArgumentListopt ::=");  //$NON-NLS-1$
3459                 consumeEmptyArgumentListopt();  
3460                 break ;
3461                 
3462         case 419 : // System.out.println("FormalParameterListopt ::=");  //$NON-NLS-1$
3463                 consumeFormalParameterListopt();  
3464                 break ;
3465                 
3466         case 423 : // System.out.println("InterfaceMemberDeclarationsopt ::=");  //$NON-NLS-1$
3467                 consumeEmptyInterfaceMemberDeclarationsopt();  
3468                 break ;
3469                 
3470         case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType...");  //$NON-NLS-1$
3471                 consumeInterfaceMemberDeclarationsopt();  
3472                 break ;
3473                 
3474         case 425 : // System.out.println("NestedType ::=");  //$NON-NLS-1$
3475                 consumeNestedType();  
3476                 break ;
3477
3478         case 426 : // System.out.println("ForInitopt ::=");  //$NON-NLS-1$
3479                 consumeEmptyForInitopt();  
3480                 break ;
3481                 
3482         case 428 : // System.out.println("ForUpdateopt ::=");  //$NON-NLS-1$
3483                 consumeEmptyForUpdateopt();  
3484                 break ;
3485                 
3486         case 432 : // System.out.println("Catchesopt ::=");  //$NON-NLS-1$
3487                 consumeEmptyCatchesopt();  
3488                 break ;
3489                 
3490         }
3491
3492 protected void consumeSimpleAssertStatement() {
3493         // AssertStatement ::= 'assert' Expression ';'
3494         this.expressionLengthPtr--;
3495         pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));  
3496 }
3497         
3498 protected void consumeSingleTypeImportDeclaration() {
3499         // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
3500
3501         ImportReference impt = (ImportReference) this.astStack[this.astPtr];
3502         // flush comments defined prior to import statements
3503         impt.declarationEnd = this.endStatementPosition;
3504         impt.declarationSourceEnd = 
3505                 this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd); 
3506
3507         // recovery
3508         if (this.currentElement != null) {
3509                 this.lastCheckPoint = impt.declarationSourceEnd + 1;
3510                 this.currentElement = this.currentElement.add(impt, 0);
3511                 this.lastIgnoredToken = -1;
3512                 this.restartRecovery = true; 
3513                 // used to avoid branching back into the regular automaton
3514         }
3515 }
3516 protected void consumeSingleTypeImportDeclarationName() {
3517         // SingleTypeImportDeclarationName ::= 'import' Name
3518         /* push an ImportRef build from the last name 
3519         stored in the identifier stack. */
3520
3521         ImportReference impt;
3522         int length;
3523         char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
3524         this.identifierPtr -= length;
3525         long[] positions = new long[length];
3526         System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
3527         System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
3528         pushOnAstStack(impt = new ImportReference(tokens, positions, false, AccDefault));
3529
3530         if (this.currentToken == TokenNameSEMICOLON){
3531                 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
3532         } else {
3533                 impt.declarationSourceEnd = impt.sourceEnd;
3534         }
3535         impt.declarationEnd = impt.declarationSourceEnd;
3536         //endPosition is just before the ;
3537         impt.declarationSourceStart = this.intStack[this.intPtr--];
3538
3539         // recovery
3540         if (this.currentElement != null){
3541                 this.lastCheckPoint = impt.declarationSourceEnd+1;
3542                 this.currentElement = this.currentElement.add(impt, 0);
3543                 this.lastIgnoredToken = -1;
3544                 this.restartRecovery = true; // used to avoid branching back into the regular automaton         
3545         }
3546 }
3547 protected void consumeStatementBreak() {
3548         // BreakStatement ::= 'break' ';'
3549         // break pushs a position on intStack in case there is no label
3550
3551         pushOnAstStack(new BreakStatement(null, this.intStack[this.intPtr--], this.endPosition));
3552 }
3553 protected void consumeStatementBreakWithLabel() {
3554         // BreakStatement ::= 'break' Identifier ';'
3555         // break pushs a position on intStack in case there is no label
3556
3557         pushOnAstStack(
3558                 new BreakStatement(
3559                         this.identifierStack[this.identifierPtr--],
3560                         this.intStack[this.intPtr--],
3561                         this.endPosition)); 
3562         this.identifierLengthPtr--;
3563 }
3564 protected void consumeStatementCatch() {
3565         // CatchClause ::= 'catch' '(' FormalParameter ')'    Block
3566
3567         //catch are stored directly into the Try
3568         //has they always comes two by two....
3569         //we remove one entry from the astlengthPtr.
3570         //The construction of the try statement must
3571         //then fetch the catches using  2*i and 2*i + 1
3572
3573         this.astLengthPtr--;
3574         this.listLength = 0; // reset formalParameter counter (incremented for catch variable)
3575 }
3576 protected void consumeStatementContinue() {
3577         // ContinueStatement ::= 'continue' ';'
3578         // continue pushs a position on intStack in case there is no label
3579
3580         pushOnAstStack(
3581                 new ContinueStatement(
3582                         null,
3583                         this.intStack[this.intPtr--],
3584                         this.endPosition));
3585 }
3586 protected void consumeStatementContinueWithLabel() {
3587         // ContinueStatement ::= 'continue' Identifier ';'
3588         // continue pushs a position on intStack in case there is no label
3589
3590         pushOnAstStack(
3591                 new ContinueStatement(
3592                         this.identifierStack[this.identifierPtr--], 
3593                         this.intStack[this.intPtr--], 
3594                         this.endPosition)); 
3595         this.identifierLengthPtr--;
3596 }
3597 protected void consumeStatementDo() {
3598         // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
3599
3600         //the 'while' pushes a value on intStack that we need to remove
3601         this.intPtr--;
3602
3603         Statement statement = (Statement) this.astStack[this.astPtr];
3604         this.expressionLengthPtr--;
3605         this.astStack[this.astPtr] = 
3606                 new DoStatement(
3607                         this.expressionStack[this.expressionPtr--], 
3608                         statement, 
3609                         this.intStack[this.intPtr--], 
3610                         this.endPosition); 
3611 }
3612 protected void consumeStatementExpressionList() {
3613         // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
3614         concatExpressionLists();
3615 }
3616 protected void consumeStatementFor() {
3617         // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
3618         // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
3619
3620         int length;
3621         Expression cond = null;
3622         Statement[] inits, updates;
3623         boolean scope = true;
3624
3625         //statements
3626         this.astLengthPtr--;
3627         Statement statement = (Statement) this.astStack[this.astPtr--];
3628
3629         //updates are on the expresion stack
3630         if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) == 0) {
3631                 updates = null;
3632         } else {
3633                 this.expressionPtr -= length;
3634                 System.arraycopy(
3635                         this.expressionStack, 
3636                         this.expressionPtr + 1, 
3637                         updates = new Statement[length], 
3638                         0, 
3639                         length); 
3640         }
3641
3642         if (this.expressionLengthStack[this.expressionLengthPtr--] != 0)
3643                 cond = this.expressionStack[this.expressionPtr--];
3644
3645         //inits may be on two different stacks
3646         if ((length = this.astLengthStack[this.astLengthPtr--]) == 0) {
3647                 inits = null;
3648                 scope = false;
3649         } else {
3650                 if (length == -1) { //on expressionStack
3651                         scope = false;
3652                         length = this.expressionLengthStack[this.expressionLengthPtr--];
3653                         this.expressionPtr -= length;
3654                         System.arraycopy(
3655                                 this.expressionStack, 
3656                                 this.expressionPtr + 1, 
3657                                 inits = new Statement[length], 
3658                                 0, 
3659                                 length); 
3660                 } else { //on astStack
3661                         this.astPtr -= length;
3662                         System.arraycopy(
3663                                 this.astStack, 
3664                                 this.astPtr + 1, 
3665                                 inits = new Statement[length], 
3666                                 0, 
3667                                 length); 
3668                 }
3669         }
3670         pushOnAstStack(
3671                 new ForStatement(
3672                         inits, 
3673                         cond, 
3674                         updates, 
3675                         statement, 
3676                         scope, 
3677                         this.intStack[this.intPtr--], 
3678                         this.endStatementPosition)); 
3679 }
3680 protected void consumeStatementIfNoElse() {
3681         // IfThenStatement ::=  'if' '(' Expression ')' Statement
3682
3683         //optimize the push/pop
3684         this.expressionLengthPtr--;
3685         Statement thenStatement = (Statement) this.astStack[this.astPtr];
3686         this.astStack[this.astPtr] = 
3687                 new IfStatement(
3688                         this.expressionStack[this.expressionPtr--], 
3689                         thenStatement, 
3690                         this.intStack[this.intPtr--], 
3691                         this.endStatementPosition); 
3692 }
3693 protected void consumeStatementIfWithElse() {
3694         // IfThenElseStatement ::=  'if' '(' Expression ')' StatementNoShortIf 'else' Statement
3695         // IfThenElseStatementNoShortIf ::=  'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
3696
3697         this.expressionLengthPtr--;
3698
3699         // optimized {..., Then, Else } ==> {..., If }
3700         this.astLengthPtr--;
3701
3702         //optimize the push/pop
3703         this.astStack[--this.astPtr] = 
3704                 new IfStatement(
3705                         this.expressionStack[this.expressionPtr--], 
3706                         (Statement) this.astStack[this.astPtr], 
3707                         (Statement) this.astStack[this.astPtr + 1], 
3708                         this.intStack[this.intPtr--], 
3709                         this.endStatementPosition); 
3710 }
3711 protected void consumeStatementLabel() {
3712         // LabeledStatement ::= 'Identifier' ':' Statement
3713         // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
3714
3715         //optimize push/pop
3716         Statement stmt = (Statement) this.astStack[this.astPtr];
3717         this.astStack[this.astPtr] = 
3718                 new LabeledStatement(
3719                         this.identifierStack[this.identifierPtr], 
3720                         stmt, 
3721                         (int) (this.identifierPositionStack[this.identifierPtr--] >>> 32), 
3722                         this.endStatementPosition); 
3723         this.identifierLengthPtr--;
3724 }
3725 protected void consumeStatementReturn() {
3726         // ReturnStatement ::= 'return' Expressionopt ';'
3727         // return pushs a position on intStack in case there is no expression
3728
3729         if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) {
3730                 pushOnAstStack(
3731                         new ReturnStatement(
3732                                 this.expressionStack[this.expressionPtr--], 
3733                                 this.intStack[this.intPtr--], 
3734                                 this.endPosition)
3735                 );
3736         } else {
3737                 pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endPosition));
3738         }
3739 }
3740 protected void consumeStatementSwitch() {
3741         // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
3742
3743         //OpenBlock just makes the semantic action blockStart()
3744         //the block is inlined but a scope need to be created
3745         //if some declaration occurs.
3746
3747         int length;
3748         SwitchStatement switchStatement = new SwitchStatement();
3749         this.expressionLengthPtr--;
3750         switchStatement.expression = this.expressionStack[this.expressionPtr--];
3751         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
3752                 this.astPtr -= length;
3753                 System.arraycopy(
3754                         this.astStack, 
3755                         this.astPtr + 1, 
3756                         switchStatement.statements = new Statement[length], 
3757                         0, 
3758                         length); 
3759         }
3760         switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
3761         pushOnAstStack(switchStatement);
3762         switchStatement.blockStart = this.intStack[this.intPtr--];
3763         switchStatement.sourceStart = this.intStack[this.intPtr--];
3764         switchStatement.sourceEnd = this.endStatementPosition;
3765         if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) {
3766                 switchStatement.bits |= ASTNode.UndocumentedEmptyBlockMASK;
3767         }
3768 }
3769 protected void consumeStatementSynchronized() {
3770         // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
3771         //optimize the push/pop
3772
3773         if (this.astLengthStack[this.astLengthPtr] == 0) {
3774                 this.astLengthStack[this.astLengthPtr] = 1;
3775                 this.expressionLengthPtr--;
3776                 this.astStack[++this.astPtr] = 
3777                         new SynchronizedStatement(
3778                                 this.expressionStack[this.expressionPtr--], 
3779                                 null, 
3780                                 this.intStack[this.intPtr--], 
3781                                 this.endStatementPosition); 
3782         } else {
3783                 this.expressionLengthPtr--;
3784                 this.astStack[this.astPtr] = 
3785                         new SynchronizedStatement(
3786                                 this.expressionStack[this.expressionPtr--], 
3787                                 (Block) this.astStack[this.astPtr], 
3788                                 this.intStack[this.intPtr--], 
3789                                 this.endStatementPosition); 
3790         }
3791         resetModifiers();
3792 }
3793 protected void consumeStatementThrow() {
3794         // ThrowStatement ::= 'throw' Expression ';'
3795         this.expressionLengthPtr--;
3796         pushOnAstStack(new ThrowStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
3797 }
3798 protected void consumeStatementTry(boolean withFinally) {
3799         //TryStatement ::= 'try'  Block Catches
3800         //TryStatement ::= 'try'  Block Catchesopt Finally
3801
3802         int length;
3803         TryStatement tryStmt = new TryStatement();
3804         //finally
3805         if (withFinally) {
3806                 this.astLengthPtr--;
3807                 tryStmt.finallyBlock = (Block) this.astStack[this.astPtr--];
3808         }
3809         //catches are handle by two <argument-block> [see statementCatch]
3810         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
3811                 if (length == 1) {
3812                         tryStmt.catchBlocks = new Block[] {(Block) this.astStack[this.astPtr--]};
3813                         tryStmt.catchArguments = new Argument[] {(Argument) this.astStack[this.astPtr--]};
3814                 } else {
3815                         Block[] bks = (tryStmt.catchBlocks = new Block[length]);
3816                         Argument[] args = (tryStmt.catchArguments = new Argument[length]);
3817                         while (length-- > 0) {
3818                                 bks[length] = (Block) this.astStack[this.astPtr--];
3819                                 args[length] = (Argument) this.astStack[this.astPtr--];
3820                         }
3821                 }
3822         }
3823         //try
3824         this.astLengthPtr--;
3825         tryStmt.tryBlock = (Block) this.astStack[this.astPtr--];
3826
3827         //positions
3828         tryStmt.sourceEnd = this.endStatementPosition;
3829         tryStmt.sourceStart = this.intStack[this.intPtr--];
3830         pushOnAstStack(tryStmt);
3831 }
3832 protected void consumeStatementWhile() {
3833         // WhileStatement ::= 'while' '(' Expression ')' Statement
3834         // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
3835
3836         this.expressionLengthPtr--;
3837         Statement statement = (Statement) this.astStack[this.astPtr];
3838         this.astStack[this.astPtr] = 
3839                 new WhileStatement(
3840                         this.expressionStack[this.expressionPtr--], 
3841                         statement, 
3842                         this.intStack[this.intPtr--], 
3843                         this.endStatementPosition); 
3844 }
3845 protected void consumeStaticInitializer() {
3846         // StaticInitializer ::=  StaticOnly Block
3847         //push an Initializer
3848         //optimize the push/pop
3849         Block block = (Block) this.astStack[this.astPtr];
3850         if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlockMASK; // clear bit set since was diet
3851         Initializer initializer = new Initializer(block, AccStatic);
3852         this.astStack[this.astPtr] = initializer;
3853         initializer.sourceEnd = this.endStatementPosition;      
3854         initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3855         this.nestedMethod[this.nestedType] --;
3856         initializer.declarationSourceStart = this.intStack[this.intPtr--];
3857         initializer.bodyStart = this.intStack[this.intPtr--];
3858         initializer.bodyEnd = this.endPosition;
3859         // doc comment
3860         initializer.javadoc = this.javadoc;
3861         this.javadoc = null;
3862         
3863         // recovery
3864         if (this.currentElement != null){
3865                 this.lastCheckPoint = initializer.declarationSourceEnd;
3866                 this.currentElement = this.currentElement.add(initializer, 0);
3867                 this.lastIgnoredToken = -1;
3868         }
3869 }
3870 protected void consumeStaticOnly() {
3871         // StaticOnly ::= 'static'
3872         int savedModifiersSourceStart = this.modifiersSourceStart;
3873         checkComment(); // might update declaration source start
3874         if (this.modifiersSourceStart >= savedModifiersSourceStart) {
3875                 this.modifiersSourceStart = savedModifiersSourceStart;
3876         }
3877         pushOnIntStack(this.scanner.currentPosition);
3878         pushOnIntStack(
3879                 this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
3880         jumpOverMethodBody();
3881         this.nestedMethod[this.nestedType]++;
3882         resetModifiers();
3883
3884         // recovery
3885         if (this.currentElement != null){
3886                 this.recoveredStaticInitializerStart = this.intStack[this.intPtr]; // remember start position only for static initializers
3887         }
3888 }
3889 protected void consumeSwitchBlock() {
3890         // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
3891         concatNodeLists();
3892 }
3893 protected void consumeSwitchBlockStatement() {
3894         // SwitchBlockStatement ::= SwitchLabels BlockStatements
3895         concatNodeLists();
3896 }
3897 protected void consumeSwitchBlockStatements() {
3898         // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
3899         concatNodeLists();
3900 }
3901 protected void consumeSwitchLabels() {
3902         // SwitchLabels ::= SwitchLabels SwitchLabel
3903         optimizedConcatNodeLists();
3904 }
3905 protected void consumeToken(int type) {
3906         /* remember the last consumed value */
3907         /* try to minimize the number of build values */
3908         checkNonExternalizedStringLiteral();
3909 //      // clear the commentPtr of the scanner in case we read something different from a modifier
3910 //      switch(type) {
3911 //              case TokenNameabstract :
3912 //              case TokenNamestrictfp :
3913 //              case TokenNamefinal :
3914 //              case TokenNamenative :
3915 //              case TokenNameprivate :
3916 //              case TokenNameprotected :
3917 //              case TokenNamepublic :
3918 //              case TokenNametransient :
3919 //              case TokenNamevolatile :
3920 //              case TokenNamestatic :
3921 //              case TokenNamesynchronized :
3922 //                      break;
3923 //              default:
3924 //                      this.scanner.commentPtr = -1;
3925 //      }
3926         //System.out.println(this.scanner.toStringAction(type));
3927         switch (type) {
3928                 case TokenNameIdentifier :
3929                         pushIdentifier();
3930                         if (this.scanner.useAssertAsAnIndentifier) {
3931                                 long positions = this.identifierPositionStack[this.identifierPtr];
3932                                 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
3933                         }
3934 //                      this.scanner.commentPtr = -1;
3935                         break;
3936                 case TokenNameinterface :
3937                         adjustInterfaceModifiers();
3938                         //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
3939                         pushOnIntStack(this.scanner.currentPosition - 1);                       
3940                         pushOnIntStack(this.scanner.startPosition);
3941 //                      this.scanner.commentPtr = -1;
3942                         break;
3943                 case TokenNameabstract :
3944                         checkAndSetModifiers(AccAbstract);
3945                         break;
3946                 case TokenNamestrictfp :
3947                         checkAndSetModifiers(AccStrictfp);
3948                         break;
3949                 case TokenNamefinal :
3950                         checkAndSetModifiers(AccFinal);
3951                         break;
3952                 case TokenNamenative :
3953                         checkAndSetModifiers(AccNative);
3954                         break;
3955                 case TokenNameprivate :
3956                         checkAndSetModifiers(AccPrivate);
3957                         break;
3958                 case TokenNameprotected :
3959                         checkAndSetModifiers(AccProtected);
3960                         break;
3961                 case TokenNamepublic :
3962                         checkAndSetModifiers(AccPublic);
3963                         break;
3964                 case TokenNametransient :
3965                         checkAndSetModifiers(AccTransient);
3966                         break;
3967                 case TokenNamevolatile :
3968                         checkAndSetModifiers(AccVolatile);
3969                         break;
3970                 case TokenNamestatic :
3971                         checkAndSetModifiers(AccStatic);
3972                         break;
3973                 case TokenNamesynchronized :
3974                         this.synchronizedBlockSourceStart = this.scanner.startPosition; 
3975                         checkAndSetModifiers(AccSynchronized);
3976                         break;
3977                         //==============================
3978                 case TokenNamevoid :
3979                         pushIdentifier(-T_void);
3980                         pushOnIntStack(this.scanner.currentPosition - 1);                               
3981                         pushOnIntStack(this.scanner.startPosition);
3982 //                      this.scanner.commentPtr = -1;
3983                         break;
3984                         //push a default dimension while void is not part of the primitive
3985                         //declaration baseType and so takes the place of a type without getting into
3986                         //regular type parsing that generates a dimension on intStack
3987                 case TokenNameboolean :
3988                         pushIdentifier(-T_boolean);
3989                         pushOnIntStack(this.scanner.currentPosition - 1);                               
3990                         pushOnIntStack(this.scanner.startPosition);             
3991 //                      this.scanner.commentPtr = -1;
3992                         break;
3993                 case TokenNamebyte :
3994                         pushIdentifier(-T_byte);
3995                         pushOnIntStack(this.scanner.currentPosition - 1);                               
3996                         pushOnIntStack(this.scanner.startPosition);                                     
3997 //                      this.scanner.commentPtr = -1;
3998                         break;
3999                 case TokenNamechar :
4000                         pushIdentifier(-T_char);
4001                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4002                         pushOnIntStack(this.scanner.startPosition);                                     
4003 //                      this.scanner.commentPtr = -1;
4004                         break;
4005                 case TokenNamedouble :
4006                         pushIdentifier(-T_double);
4007                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4008                         pushOnIntStack(this.scanner.startPosition);                                     
4009 //                      this.scanner.commentPtr = -1;
4010                         break;
4011                 case TokenNamefloat :
4012                         pushIdentifier(-T_float);
4013                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4014                         pushOnIntStack(this.scanner.startPosition);                                     
4015 //                      this.scanner.commentPtr = -1;
4016                         break;
4017                 case TokenNameint :
4018                         pushIdentifier(-T_int);
4019                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4020                         pushOnIntStack(this.scanner.startPosition);                                     
4021 //                      this.scanner.commentPtr = -1;
4022                         break;
4023                 case TokenNamelong :
4024                         pushIdentifier(-T_long);
4025                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4026                         pushOnIntStack(this.scanner.startPosition);                                     
4027 //                      this.scanner.commentPtr = -1;
4028                         break;
4029                 case TokenNameshort :
4030                         pushIdentifier(-T_short);
4031                         pushOnIntStack(this.scanner.currentPosition - 1);                               
4032                         pushOnIntStack(this.scanner.startPosition);                                     
4033 //                      this.scanner.commentPtr = -1;
4034                         break;
4035                         //==============================
4036                 case TokenNameIntegerLiteral :
4037                         pushOnExpressionStack(
4038                                 new IntLiteral(
4039                                         this.scanner.getCurrentTokenSource(), 
4040                                         this.scanner.startPosition, 
4041                                         this.scanner.currentPosition - 1)); 
4042 //                      this.scanner.commentPtr = -1;
4043                         break;
4044                 case TokenNameLongLiteral :
4045                         pushOnExpressionStack(
4046                                 new LongLiteral(
4047                                         this.scanner.getCurrentTokenSource(), 
4048                                         this.scanner.startPosition, 
4049                                         this.scanner.currentPosition - 1)); 
4050 //                      this.scanner.commentPtr = -1;
4051                         break;
4052                 case TokenNameFloatingPointLiteral :
4053                         pushOnExpressionStack(
4054                                 new FloatLiteral(
4055                                         this.scanner.getCurrentTokenSource(), 
4056                                         this.scanner.startPosition, 
4057                                         this.scanner.currentPosition - 1)); 
4058 //                      this.scanner.commentPtr = -1;
4059                         break;
4060                 case TokenNameDoubleLiteral :
4061                         pushOnExpressionStack(
4062                                 new DoubleLiteral(
4063                                         this.scanner.getCurrentTokenSource(), 
4064                                         this.scanner.startPosition, 
4065                                         this.scanner.currentPosition - 1)); 
4066 //                      this.scanner.commentPtr = -1;
4067                         break;
4068                 case TokenNameCharacterLiteral :
4069                         pushOnExpressionStack(
4070                                 new CharLiteral(
4071                                         this.scanner.getCurrentTokenSource(), 
4072                                         this.scanner.startPosition, 
4073                                         this.scanner.currentPosition - 1)); 
4074 //                      this.scanner.commentPtr = -1;
4075                         break;
4076                 case TokenNameStringLiteral :
4077                         StringLiteral stringLiteral = new StringLiteral(
4078                                         this.scanner.getCurrentTokenSourceString(), 
4079                                         this.scanner.startPosition, 
4080                                         this.scanner.currentPosition - 1); 
4081                         pushOnExpressionStack(stringLiteral); 
4082 //                      this.scanner.commentPtr = -1;
4083                         break;
4084                 case TokenNamefalse :
4085                         pushOnExpressionStack(
4086                                 new FalseLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); 
4087 //                      this.scanner.commentPtr = -1;
4088                         break;
4089                 case TokenNametrue :
4090                         pushOnExpressionStack(
4091                                 new TrueLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); 
4092                         break;
4093                 case TokenNamenull :
4094                         pushOnExpressionStack(
4095                                 new NullLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); 
4096                         break;
4097                         //============================
4098                 case TokenNamesuper :
4099                 case TokenNamethis :
4100                         this.endPosition = this.scanner.currentPosition - 1;
4101                         pushOnIntStack(this.scanner.startPosition);
4102                         break;
4103                 case TokenNameassert :
4104                 case TokenNameimport :
4105                 case TokenNamepackage :
4106                 case TokenNamethrow :
4107                 case TokenNamedo :
4108                 case TokenNameif :
4109                 case TokenNamefor :
4110                 case TokenNameswitch :
4111                 case TokenNametry :
4112                 case TokenNamewhile :
4113                 case TokenNamebreak :
4114                 case TokenNamecontinue :
4115                 case TokenNamereturn :
4116                 case TokenNamecase :
4117                         pushOnIntStack(this.scanner.startPosition);
4118                         break;
4119                 case TokenNamenew :
4120                         // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954
4121                         resetModifiers();
4122                         pushOnIntStack(this.scanner.startPosition);
4123                         break;
4124                 case TokenNameclass :
4125                         pushOnIntStack(this.scanner.currentPosition - 1);
4126                         pushOnIntStack(this.scanner.startPosition);
4127                         break;
4128                 case TokenNamedefault :
4129                         pushOnIntStack(this.scanner.startPosition);
4130                         pushOnIntStack(this.scanner.currentPosition - 1);
4131                         break;
4132                         //let extra semantic action decide when to push
4133                 case TokenNameRBRACKET :
4134                 case TokenNamePLUS :
4135                 case TokenNameMINUS :
4136                 case TokenNameNOT :
4137                 case TokenNameTWIDDLE :
4138                         this.endPosition = this.scanner.startPosition;
4139                         break;
4140                 case TokenNamePLUS_PLUS :
4141                 case TokenNameMINUS_MINUS :
4142                         this.endPosition = this.scanner.startPosition;
4143                         this.endStatementPosition = this.scanner.currentPosition - 1;
4144                         break;
4145                 case TokenNameRBRACE:
4146                 case TokenNameSEMICOLON :
4147                         this.endStatementPosition = this.scanner.currentPosition - 1;
4148                         this.endPosition = this.scanner.startPosition - 1; 
4149                         //the item is not part of the potential futur expression/statement
4150                         break;
4151                         // in order to handle ( expression) ////// (cast)expression///// foo(x)
4152                 case TokenNameRPAREN :
4153                         this.rParenPos = this.scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4154                         break;
4155                 case TokenNameLPAREN :
4156                         this.lParenPos = this.scanner.startPosition;
4157                         break;
4158                         //  case TokenNameQUESTION  :
4159                         //  case TokenNameCOMMA :
4160                         //  case TokenNameCOLON  :
4161                         //  case TokenNameEQUAL  :
4162                         //  case TokenNameLBRACKET  :
4163                         //  case TokenNameDOT :
4164                         //  case TokenNameERROR :
4165                         //  case TokenNameEOF  :
4166                         //  case TokenNamecase  :
4167                         //  case TokenNamecatch  :
4168                         //  case TokenNameelse  :
4169                         //  case TokenNameextends  :
4170                         //  case TokenNamefinally  :
4171                         //  case TokenNameimplements  :
4172                         //  case TokenNamethrows  :
4173                         //  case TokenNameinstanceof  :
4174                         //  case TokenNameEQUAL_EQUAL  :
4175                         //  case TokenNameLESS_EQUAL  :
4176                         //  case TokenNameGREATER_EQUAL  :
4177                         //  case TokenNameNOT_EQUAL  :
4178                         //  case TokenNameLEFT_SHIFT  :
4179                         //  case TokenNameRIGHT_SHIFT  :
4180                         //  case TokenNameUNSIGNED_RIGHT_SHIFT :
4181                         //  case TokenNamePLUS_EQUAL  :
4182                         //  case TokenNameMINUS_EQUAL  :
4183                         //  case TokenNameMULTIPLY_EQUAL  :
4184                         //  case TokenNameDIVIDE_EQUAL  :
4185                         //  case TokenNameAND_EQUAL  :
4186                         //  case TokenNameOR_EQUAL  :
4187                         //  case TokenNameXOR_EQUAL  :
4188                         //  case TokenNameREMAINDER_EQUAL  :
4189                         //  case TokenNameLEFT_SHIFT_EQUAL  :
4190                         //  case TokenNameRIGHT_SHIFT_EQUAL  :
4191                         //  case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL  :
4192                         //  case TokenNameOR_OR  :
4193                         //  case TokenNameAND_AND  :
4194                         //  case TokenNameREMAINDER :
4195                         //  case TokenNameXOR  :
4196                         //  case TokenNameAND  :
4197                         //  case TokenNameMULTIPLY :
4198                         //  case TokenNameOR  :
4199                         //  case TokenNameDIVIDE :
4200                         //  case TokenNameGREATER  :
4201                         //  case TokenNameLESS  :
4202         }
4203 }
4204 protected void consumeTypeDeclarations() {
4205         // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4206         concatNodeLists();
4207 }
4208 protected void consumeTypeDeclarationsopt() {
4209         // TypeDeclarationsopt ::= TypeDeclarations
4210         int length;
4211         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4212                 this.astPtr -= length;
4213                 System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types = new TypeDeclaration[length], 0, length);
4214         }
4215 }
4216 protected void consumeTypeImportOnDemandDeclaration() {
4217         // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4218
4219         ImportReference impt = (ImportReference) this.astStack[this.astPtr];
4220         // flush comments defined prior to import statements
4221         impt.declarationEnd = this.endStatementPosition;
4222         impt.declarationSourceEnd = 
4223                 this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd); 
4224
4225         // recovery
4226         if (this.currentElement != null) {
4227                 this.lastCheckPoint = impt.declarationSourceEnd + 1;
4228                 this.currentElement = this.currentElement.add(impt, 0);
4229                 this.restartRecovery = true;
4230                 this.lastIgnoredToken = -1;
4231                 // used to avoid branching back into the regular automaton
4232         }
4233 }
4234 protected void consumeTypeImportOnDemandDeclarationName() {
4235         // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4236         /* push an ImportRef build from the last name 
4237         stored in the identifier stack. */
4238
4239         ImportReference impt;
4240         int length;
4241         char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
4242         this.identifierPtr -= length;
4243         long[] positions = new long[length];
4244         System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4245         System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4246         pushOnAstStack(impt = new ImportReference(tokens, positions, true, AccDefault));
4247
4248         if (this.currentToken == TokenNameSEMICOLON){
4249                 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
4250         } else {
4251                 impt.declarationSourceEnd = impt.sourceEnd;
4252         }
4253         impt.declarationEnd = impt.declarationSourceEnd;
4254         //endPosition is just before the ;
4255         impt.declarationSourceStart = this.intStack[this.intPtr--];
4256
4257         // recovery
4258         if (this.currentElement != null){
4259                 this.lastCheckPoint = impt.declarationSourceEnd+1;
4260                 this.currentElement = this.currentElement.add(impt, 0);
4261                 this.lastIgnoredToken = -1;
4262                 this.restartRecovery = true; // used to avoid branching back into the regular automaton         
4263         }       
4264 }
4265 protected void consumeUnaryExpression(int op) {
4266         // UnaryExpression ::= '+' PushPosition UnaryExpression
4267         // UnaryExpression ::= '-' PushPosition UnaryExpression
4268         // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4269         // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4270
4271         //optimize the push/pop
4272
4273         //handle manually the -2147483648 while it is not a real
4274         //computation of an - and 2147483648 (notice that 2147483648
4275         //is Integer.MAX_VALUE+1.....)
4276         //Same for -9223372036854775808L ............
4277
4278         //intStack have the position of the operator
4279
4280         Expression r, exp = this.expressionStack[this.expressionPtr];
4281         if (op == MINUS) {
4282                 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4283                         r = this.expressionStack[this.expressionPtr] = new IntLiteralMinValue();
4284                 } else {
4285                         if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4286                                 r = this.expressionStack[this.expressionPtr] = new LongLiteralMinValue();
4287                         } else {
4288                                 r = this.expressionStack[this.expressionPtr] = new UnaryExpression(exp, op);
4289                         }
4290                 }
4291         } else {
4292                 r = this.expressionStack[this.expressionPtr] = new UnaryExpression(exp, op);
4293         }
4294         r.sourceStart = this.intStack[this.intPtr--];
4295         r.sourceEnd = exp.sourceEnd;
4296 }
4297 protected void consumeUnaryExpression(int op, boolean post) {
4298         // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4299         // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4300
4301         // ++ and -- operators
4302         //optimize the push/pop
4303
4304         //intStack has the position of the operator when prefix
4305
4306         Expression leftHandSide = this.expressionStack[this.expressionPtr];
4307         if (leftHandSide instanceof Reference) {
4308                 // ++foo()++ is unvalid 
4309                 if (post) {
4310                         this.expressionStack[this.expressionPtr] = 
4311                                 new PostfixExpression(
4312                                         leftHandSide,
4313                                         IntLiteral.One,
4314                                         op,
4315                                         this.endStatementPosition); 
4316                 } else {
4317                         this.expressionStack[this.expressionPtr] = 
4318                                 new PrefixExpression(
4319                                         leftHandSide,
4320                                         IntLiteral.One,
4321                                         op,
4322                                         this.intStack[this.intPtr--]); 
4323                 }
4324         } else {
4325                 //the ++ or the -- is NOT taken into account if code gen proceeds
4326                 if (!post) {
4327                         this.intPtr--;
4328                 }
4329                 problemReporter().invalidUnaryExpression(leftHandSide);
4330         }
4331 }
4332 protected void consumeVariableDeclarators() {
4333         // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4334         optimizedConcatNodeLists();
4335 }
4336 protected void consumeVariableInitializers() {
4337         // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4338         concatExpressionLists();
4339 }
4340 /**
4341  * Given the current comment stack, answer whether some comment is available in a certain exclusive range
4342  * 
4343  * @param sourceStart int
4344  * @param sourceEnd int
4345  * @return boolean
4346  */
4347 public boolean containsComment(int sourceStart, int sourceEnd) {
4348         int iComment = this.scanner.commentPtr;
4349         for (; iComment >= 0; iComment--) {
4350                 int commentStart = this.scanner.commentStarts[iComment];
4351                 // ignore comments before start
4352                 if (commentStart < sourceStart) continue;
4353                 // ignore comments after end
4354                 if (commentStart > sourceEnd) continue;
4355                 return true;
4356         }
4357         return false;
4358 }
4359 public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
4360         MethodDeclaration m = new MethodDeclaration(compilationResult);
4361         m.sourceStart = c.sourceStart;
4362         m.sourceEnd = c.sourceEnd;
4363         m.bodyStart = c.bodyStart;
4364         m.bodyEnd = c.bodyEnd;
4365         m.declarationSourceEnd = c.declarationSourceEnd;
4366         m.declarationSourceStart = c.declarationSourceStart;
4367         m.selector = c.selector;
4368         m.statements = c.statements;
4369         m.modifiers = c.modifiers;
4370         m.arguments = c.arguments;
4371         m.thrownExceptions = c.thrownExceptions;
4372         m.explicitDeclarations = c.explicitDeclarations;
4373         m.returnType = null;
4374         return m;
4375 }
4376 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4377         return typeRef.copyDims(dim);
4378 }
4379 protected FieldDeclaration createFieldDeclaration(char[] fieldDeclarationName, int sourceStart, int sourceEnd) {
4380         return new FieldDeclaration(fieldDeclarationName, sourceStart, sourceEnd);
4381 }
4382
4383 protected LocalDeclaration createLocalDeclaration(char[] localDeclarationName, int sourceStart, int sourceEnd) {
4384         return new LocalDeclaration(localDeclarationName, sourceStart, sourceEnd);
4385 }
4386
4387 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4388
4389         CompilationUnitDeclaration parsedUnit;
4390         boolean old = this.diet;
4391         try {
4392                 this.diet = true;
4393                 parsedUnit = parse(sourceUnit, compilationResult);
4394         }
4395         finally {
4396                 this.diet = old;
4397         }
4398         return parsedUnit;
4399 }
4400 protected void dispatchDeclarationInto(int length) {
4401         /* they are length on astStack that should go into
4402            methods fields constructors lists of the typeDecl
4403
4404            Return if there is a constructor declaration in the methods declaration */
4405            
4406         
4407         // Looks for the size of each array . 
4408
4409         if (length == 0)
4410                 return;
4411         int[] flag = new int[length + 1]; //plus one -- see <HERE>
4412         int size1 = 0, size2 = 0, size3 = 0;
4413         for (int i = length - 1; i >= 0; i--) {
4414                 ASTNode astNode = this.astStack[this.astPtr--];
4415                 if (astNode instanceof AbstractMethodDeclaration) {
4416                         //methods and constructors have been regrouped into one single list
4417                         flag[i] = 3;
4418                         size2++;
4419                 } else {
4420                         if (astNode instanceof TypeDeclaration) {
4421                                 flag[i] = 4;
4422                                 size3++;
4423                         } else {
4424                                 //field
4425                                 flag[i] = 1;
4426                                 size1++;
4427                         }
4428                 }
4429         }
4430
4431         //arrays creation
4432         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4433         if (size1 != 0)
4434                 typeDecl.fields = new FieldDeclaration[size1];
4435         if (size2 != 0)
4436                 typeDecl.methods = new AbstractMethodDeclaration[size2];
4437         if (size3 != 0)
4438                 typeDecl.memberTypes = new TypeDeclaration[size3];
4439
4440         //arrays fill up
4441         size1 = size2 = size3 = 0;
4442         int flagI = flag[0], start = 0;
4443         int length2;
4444         for (int end = 0; end <= length; end++) //<HERE> the plus one allows to 
4445                 {
4446                 if (flagI != flag[end]) //treat the last element as a ended flag.....
4447                         { //array copy
4448                         switch (flagI) {
4449                                 case 1 :
4450                                         size1 += (length2 = end - start);
4451                                         System.arraycopy(
4452                                                 this.astStack, 
4453                                                 this.astPtr + start + 1, 
4454                                                 typeDecl.fields, 
4455                                                 size1 - length2, 
4456                                                 length2); 
4457                                         break;
4458                                 case 3 :
4459                                         size2 += (length2 = end - start);
4460                                         System.arraycopy(
4461                                                 this.astStack, 
4462                                                 this.astPtr + start + 1, 
4463                                                 typeDecl.methods, 
4464                                                 size2 - length2, 
4465                                                 length2); 
4466                                         break;
4467                                 case 4 :
4468                                         size3 += (length2 = end - start);
4469                                         System.arraycopy(
4470                                                 this.astStack, 
4471                                                 this.astPtr + start + 1, 
4472                                                 typeDecl.memberTypes, 
4473                                                 size3 - length2, 
4474                                                 length2); 
4475                                         break;
4476                         }
4477                         flagI = flag[start = end];
4478                 }
4479         }
4480
4481         if (typeDecl.memberTypes != null) {
4482                 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4483                         typeDecl.memberTypes[i].enclosingType = typeDecl;
4484                 }
4485         }
4486 }
4487 protected CompilationUnitDeclaration endParse(int act) {
4488
4489         this.lastAct = act;
4490
4491         if (this.currentElement != null){
4492                 this.currentElement.topElement().updateParseTree();
4493                 if (VERBOSE_RECOVERY){
4494                         System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4495                         System.out.println("--------------------------");                //$NON-NLS-1$
4496                         System.out.println(this.compilationUnit);               
4497                         System.out.println("----------------------------------"); //$NON-NLS-1$
4498                 }               
4499         } else {
4500                 if (this.diet & VERBOSE_RECOVERY){
4501                         System.out.print(Util.bind("parser.regularParse"));      //$NON-NLS-1$
4502                         System.out.println("--------------------------");        //$NON-NLS-1$
4503                         System.out.println(this.compilationUnit);               
4504                         System.out.println("----------------------------------"); //$NON-NLS-1$
4505                 }
4506         }
4507         persistLineSeparatorPositions();
4508         for (int i = 0; i < this.scanner.foundTaskCount; i++){
4509                 problemReporter().task(
4510                         new String(this.scanner.foundTaskTags[i]), 
4511                         new String(this.scanner.foundTaskMessages[i]),
4512                         this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]), 
4513                         this.scanner.foundTaskPositions[i][0], 
4514                         this.scanner.foundTaskPositions[i][1]);
4515         }
4516         return this.compilationUnit;
4517 }
4518 /*
4519  * Flush comments defined prior to a given positions.
4520  *
4521  * Note: comments are stacked in syntactical order
4522  *
4523  * Either answer given <position>, or the end position of a comment line 
4524  * immediately following the <position> (same line)
4525  *
4526  * e.g.
4527  * void foo(){
4528  * } // end of method foo
4529  */
4530  
4531 public int flushCommentsDefinedPriorTo(int position) {
4532
4533         int lastCommentIndex = this.scanner.commentPtr;
4534         if (lastCommentIndex < 0) return position; // no comment
4535
4536         // compute the index of the first obsolete comment
4537         int index = lastCommentIndex;
4538         int validCount = 0;
4539         while (index >= 0){
4540                 int commentEnd = this.scanner.commentStops[index];
4541                 if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
4542                 if (commentEnd <= position){
4543                         break;
4544                 }
4545                 index--;
4546                 validCount++;
4547         }
4548         // if the source at <position> is immediately followed by a line comment, then
4549         // flush this comment and shift <position> to the comment end.
4550         if (validCount > 0){
4551                 int immediateCommentEnd = -this.scanner.commentStops[index+1]; //non-javadoc comment end positions are negative
4552                 if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments
4553                         // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
4554                         immediateCommentEnd--; // comment end in one char too far
4555                         if (this.scanner.getLineNumber(position) == this.scanner.getLineNumber(immediateCommentEnd)){
4556                                 position = immediateCommentEnd;
4557                                 validCount--; // flush this comment
4558                                 index++;
4559                         }
4560                 }
4561         }
4562
4563         if (index < 0) return position; // no obsolete comment
4564
4565         if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
4566                 System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
4567                 System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);               
4568         }
4569         this.scanner.commentPtr = validCount - 1;
4570         return position;
4571 }
4572 public final int getFirstToken() {
4573         // the first token is a virtual token that
4574         // allows the parser to parse several goals
4575         // even if they aren't LALR(1)....
4576         // Goal ::= '++' CompilationUnit
4577         // Goal ::= '--' MethodBody
4578         // Goal ::= '==' ConstructorBody
4579         // -- Initializer
4580         // Goal ::= '>>' StaticInitializer
4581         // Goal ::= '>>' Block
4582         // -- error recovery
4583         // Goal ::= '>>>' Headers
4584         // Goal ::= '*' BlockStatements
4585         // Goal ::= '*' MethodPushModifiersHeader
4586         // -- JDOM
4587         // Goal ::= '&&' FieldDeclaration
4588         // Goal ::= '||' ImportDeclaration
4589         // Goal ::= '?' PackageDeclaration
4590         // Goal ::= '+' TypeDeclaration
4591         // Goal ::= '/' GenericMethodDeclaration
4592         // Goal ::= '&' ClassBodyDeclaration
4593         // -- code snippet
4594         // Goal ::= '%' Expression
4595         // -- completion parser
4596         // Goal ::= '!' ConstructorBlockStatementsopt
4597         // Goal ::= '~' BlockStatementsopt
4598         
4599         return this.firstToken;
4600 }
4601 /*
4602  * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
4603  * The array is a flattened structure: 2*n entries with consecutives start and end positions.
4604  *
4605  * If no JavaDoc is available, then null is answered instead of an empty array.
4606  *
4607  * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
4608  */
4609 public int[] getJavaDocPositions() {
4610
4611         int javadocCount = 0;
4612         for (int i = 0, max = this.scanner.commentPtr; i <= max; i++){
4613                 // javadoc only (non javadoc comment have negative end positions.)
4614                 if (this.scanner.commentStops[i] > 0){
4615                         javadocCount++;
4616                 }
4617         }
4618         if (javadocCount == 0) return null;
4619
4620         int[] positions = new int[2*javadocCount];
4621         int index = 0;
4622         for (int i = 0, max = this.scanner.commentPtr; i <= max; i++){
4623                 // javadoc only (non javadoc comment have negative end positions.)
4624                 if (this.scanner.commentStops[i] > 0){
4625                         positions[index++] = this.scanner.commentStarts[i];
4626                         positions[index++] = this.scanner.commentStops[i]-1; //stop is one over                 
4627                 }
4628         }
4629         return positions;
4630 }
4631         public void getMethodBodies(CompilationUnitDeclaration unit) {
4632                 //fill the methods bodies in order for the code to be generated
4633
4634                 if (unit == null) return;
4635                 
4636                 if (unit.ignoreMethodBodies) {
4637                         unit.ignoreFurtherInvestigation = true;
4638                         return;
4639                         // if initial diet parse did not work, no need to dig into method bodies.
4640                 }
4641
4642                 if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
4643                         return; //work already done ...
4644
4645                 //real parse of the method....
4646                 char[] contents = unit.compilationResult.compilationUnit.getContents();
4647                 this.scanner.setSource(contents);
4648                 
4649                 // save existing values to restore them at the end of the parsing process
4650                 // see bug 47079 for more details
4651                 int[] oldLineEnds = this.scanner.lineEnds;
4652                 int oldLinePtr = this.scanner.linePtr;
4653
4654                 final int[] lineSeparatorPositions = unit.compilationResult.lineSeparatorPositions;
4655                 this.scanner.lineEnds = lineSeparatorPositions;
4656                 this.scanner.linePtr = lineSeparatorPositions.length - 1;
4657
4658                 if (this.javadocParser != null && this.javadocParser.checkDocComment) {
4659                         this.javadocParser.scanner.setSource(contents);
4660                 }
4661                 if (unit.types != null) {
4662                         for (int i = unit.types.length; --i >= 0;)
4663                                 unit.types[i].parseMethod(this, unit);
4664                 }
4665                 
4666                 // tag unit has having read bodies
4667                 unit.bits |= ASTNode.HasAllMethodBodies;
4668
4669                 // this is done to prevent any side effects on the compilation unit result
4670                 // line separator positions array.
4671                 this.scanner.lineEnds = oldLineEnds;
4672                 this.scanner.linePtr = oldLinePtr;
4673         }
4674 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
4675 This variable is a type reference and dim will be its dimensions*/
4676
4677         int length;
4678         TypeReference ref;
4679         if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
4680                 // single variable reference
4681                 if (dim == 0) {
4682                         ref = 
4683                                 new SingleTypeReference(
4684                                         this.identifierStack[this.identifierPtr], 
4685                                         this.identifierPositionStack[this.identifierPtr--]); 
4686                 } else {
4687                         ref = 
4688                                 new ArrayTypeReference(
4689                                         this.identifierStack[this.identifierPtr], 
4690                                         dim, 
4691                                         this.identifierPositionStack[this.identifierPtr--]); 
4692                         ref.sourceEnd = this.endPosition;                       
4693                 }
4694         } else {
4695                 if (length < 0) { //flag for precompiled type reference on base types
4696                         ref = TypeReference.baseTypeReference(-length, dim);
4697                         ref.sourceStart = this.intStack[this.intPtr--];
4698                         if (dim == 0) {
4699                                 ref.sourceEnd = this.intStack[this.intPtr--];
4700                         } else {
4701                                 this.intPtr--;
4702                                 ref.sourceEnd = this.endPosition;
4703                         }
4704                 } else { //Qualified variable reference
4705                         char[][] tokens = new char[length][];
4706                         this.identifierPtr -= length;
4707                         long[] positions = new long[length];
4708                         System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4709                         System.arraycopy(
4710                                 this.identifierPositionStack, 
4711                                 this.identifierPtr + 1, 
4712                                 positions, 
4713                                 0, 
4714                                 length); 
4715                         if (dim == 0) {
4716                                 ref = new QualifiedTypeReference(tokens, positions);
4717                         } else {
4718                                 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
4719                                 ref.sourceEnd = this.endPosition;
4720                         }
4721                 }
4722         }
4723         return ref;
4724 }
4725 protected Expression getTypeReference(Expression exp) {
4726         
4727         exp.bits &= ~ASTNode.RestrictiveFlagMASK;
4728         exp.bits |= TYPE;
4729         return exp;
4730 }
4731 protected NameReference getUnspecifiedReference() {
4732         /* build a (unspecified) NameReference which may be qualified*/
4733
4734         int length;
4735         NameReference ref;
4736         if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1)
4737                 // single variable reference
4738                 ref = 
4739                         new SingleNameReference(
4740                                 this.identifierStack[this.identifierPtr], 
4741                                 this.identifierPositionStack[this.identifierPtr--]); 
4742         else
4743                 //Qualified variable reference
4744                 {
4745                 char[][] tokens = new char[length][];
4746                 this.identifierPtr -= length;
4747                 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4748                 long[] positions = new long[length];
4749                 System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4750                 ref = 
4751                         new QualifiedNameReference(tokens, 
4752                                 positions,
4753                                 (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
4754                                 (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
4755         }
4756         return ref;
4757 }
4758 protected NameReference getUnspecifiedReferenceOptimized() {
4759         /* build a (unspecified) NameReference which may be qualified
4760         The optimization occurs for qualified reference while we are
4761         certain in this case the last item of the qualified name is
4762         a field access. This optimization is IMPORTANT while it results
4763         that when a NameReference is build, the type checker should always
4764         look for that it is not a type reference */
4765
4766         int length;
4767         NameReference ref;
4768         if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
4769                 // single variable reference
4770                 ref = 
4771                         new SingleNameReference(
4772                                 this.identifierStack[this.identifierPtr], 
4773                                 this.identifierPositionStack[this.identifierPtr--]); 
4774                 ref.bits &= ~ASTNode.RestrictiveFlagMASK;
4775                 ref.bits |= LOCAL | FIELD;
4776                 return ref;
4777         }
4778
4779         //Qualified-variable-reference
4780         //In fact it is variable-reference DOT field-ref , but it would result in a type
4781         //conflict tha can be only reduce by making a superclass (or inetrface ) between
4782         //nameReference and FiledReference or putting FieldReference under NameReference
4783         //or else..........This optimisation is not really relevant so just leave as it is
4784
4785         char[][] tokens = new char[length][];
4786         this.identifierPtr -= length;
4787         System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4788         long[] positions = new long[length];
4789         System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4790         ref = new QualifiedNameReference(
4791                         tokens,
4792                         positions, 
4793                         (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
4794                         (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
4795         ref.bits &= ~ASTNode.RestrictiveFlagMASK;
4796         ref.bits |= LOCAL | FIELD;
4797         return ref;
4798 }
4799 public void goForBlockStatementsopt() {
4800         //tells the scanner to go for block statements opt parsing
4801
4802         this.firstToken = TokenNameTWIDDLE;
4803         this.scanner.recordLineSeparator = false;
4804 }
4805 public void goForBlockStatementsOrCatchHeader() {
4806         //tells the scanner to go for block statements or method headers parsing 
4807
4808         this.firstToken = TokenNameMULTIPLY;
4809         this.scanner.recordLineSeparator = false;
4810 }
4811 public void goForClassBodyDeclarations() {
4812         //tells the scanner to go for any body declarations parsing
4813
4814         this.firstToken = TokenNameAND;
4815         this.scanner.recordLineSeparator = true;
4816 }
4817 public void goForCompilationUnit(){
4818         //tells the scanner to go for compilation unit parsing
4819
4820         this.firstToken = TokenNamePLUS_PLUS ;
4821         this.scanner.linePtr = -1;      
4822         this.scanner.foundTaskCount = 0;
4823         this.scanner.recordLineSeparator = true;
4824         this.scanner.currentLine= null;
4825 }
4826 public void goForExpression() {
4827         //tells the scanner to go for an expression parsing
4828
4829         this.firstToken = TokenNameREMAINDER;
4830         this.scanner.recordLineSeparator = true; // recovery goals must record line separators
4831 }
4832 public void goForFieldDeclaration(){
4833         //tells the scanner to go for field declaration parsing
4834
4835         this.firstToken = TokenNameAND_AND ;
4836         this.scanner.recordLineSeparator = true;
4837 }
4838 public void goForGenericMethodDeclaration(){
4839         //tells the scanner to go for generic method declarations parsing
4840
4841         this.firstToken = TokenNameDIVIDE;
4842         this.scanner.recordLineSeparator = true;
4843 }
4844 public void goForHeaders(){
4845         //tells the scanner to go for headers only parsing
4846
4847         this.firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
4848         this.scanner.recordLineSeparator = true; // recovery goals must record line separators
4849 }
4850 public void goForImportDeclaration(){
4851         //tells the scanner to go for import declaration parsing
4852
4853         this.firstToken = TokenNameOR_OR ;
4854         this.scanner.recordLineSeparator = true;
4855 }
4856 public void goForInitializer(){
4857         //tells the scanner to go for initializer parsing
4858
4859         this.firstToken = TokenNameRIGHT_SHIFT ;
4860         this.scanner.recordLineSeparator = false;
4861 }
4862 public void goForMethodBody(){
4863         //tells the scanner to go for method body parsing
4864
4865         this.firstToken = TokenNameMINUS_MINUS ;
4866         this.scanner.recordLineSeparator = false;
4867 }
4868 public void goForPackageDeclaration() {
4869         //tells the scanner to go for package declaration parsing
4870
4871         this.firstToken = TokenNameQUESTION;
4872         this.scanner.recordLineSeparator = true;
4873 }
4874 public void goForTypeDeclaration() {
4875         //tells the scanner to go for type (interface or class) declaration parsing
4876
4877         this.firstToken = TokenNamePLUS;
4878         this.scanner.recordLineSeparator = true;
4879 }
4880 protected void ignoreExpressionAssignment() {
4881         // Assignment ::= InvalidArrayInitializerAssignement
4882         // encoded operator would be: this.intStack[this.intPtr]
4883         this.intPtr--;
4884         ArrayInitializer arrayInitializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
4885         this.expressionLengthPtr -- ;
4886         // report a syntax error and abort parsing
4887         problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);      
4888 }
4889 protected void ignoreInterfaceDeclaration() {
4890         // BlockStatement ::= InvalidInterfaceDeclaration
4891         //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
4892
4893         // length declarations
4894         int length;
4895         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4896                 //there are length declarations
4897                 //dispatch according to the type of the declarations
4898                 dispatchDeclarationInto(length);
4899         }
4900         
4901         flushCommentsDefinedPriorTo(this.endStatementPosition);
4902
4903         // report the problem and continue parsing
4904         TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4905         typeDecl.bodyEnd = this.endStatementPosition;
4906         problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
4907
4908         // mark initializers with local type mark if needed
4909         markInitializersWithLocalType(typeDecl);
4910
4911         // remove the ast node created in interface header
4912         this.astPtr--;
4913         pushOnAstLengthStack(-1);
4914         concatNodeLists();
4915 }
4916 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
4917         // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
4918         // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
4919
4920         /*
4921         astStack : modifiers arguments throws statements
4922         identifierStack : name
4923          ==>
4924         astStack : MethodDeclaration
4925         identifierStack :
4926         */
4927         if (hasBody) {
4928                 // pop the position of the {  (body of the method) pushed in block decl
4929                 this.intPtr--;
4930         }
4931
4932         //statements
4933         if (hasBody) {
4934                 this.realBlockPtr--;
4935         }
4936
4937         int length;
4938         if (hasBody && ((length = this.astLengthStack[this.astLengthPtr--]) != 0)) {
4939                 this.astPtr -= length;
4940         }
4941         ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) this.astStack[this.astPtr];
4942         constructorDeclaration.bodyEnd = this.endStatementPosition;
4943         constructorDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
4944         if (!hasBody) {
4945                 constructorDeclaration.modifiers |= AccSemicolonBody;
4946         }
4947 }
4948 protected void ignoreMethodBody() {
4949         // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
4950
4951         /*
4952         astStack : modifiers arguments throws statements
4953         identifierStack : type name
4954         intStack : dim dim dim
4955          ==>
4956         astStack : MethodDeclaration
4957         identifierStack :
4958         intStack : 
4959         */
4960
4961         // pop the position of the {  (body of the method) pushed in block decl
4962         this.intPtr--;
4963         // retrieve end position of method declarator
4964
4965         //statements
4966         this.realBlockPtr--;
4967         int length;
4968         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4969                 this.astPtr -= length;
4970         }
4971
4972         //watch for } that could be given as a unicode ! ( u007D is '}' )
4973         MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
4974         md.bodyEnd = this.endPosition;
4975         md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
4976
4977         // report the problem and continue the parsing - narrowing the problem onto the method
4978         problemReporter().abstractMethodNeedingNoBody(md);
4979 }
4980 public void initialize() {
4981         //positionning the parser for a new compilation unit
4982         //avoiding stack reallocation and all that....
4983         this.astPtr = -1;
4984         this.astLengthPtr = -1;
4985         this.expressionPtr = -1;
4986         this.expressionLengthPtr = -1;
4987         this.identifierPtr = -1;        
4988         this.identifierLengthPtr        = -1;
4989         this.intPtr = -1;
4990         this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
4991         this.variablesCounter[this.nestedType] = 0;
4992         this.dimensions = 0 ;
4993         this.realBlockPtr = -1;
4994         this.compilationUnit = null;
4995         this.referenceContext = null;
4996         this.endStatementPosition = 0;
4997
4998         //remove objects from stack too, while the same parser/compiler couple is
4999         //re-used between two compilations ....
5000         
5001         int astLength = this.astStack.length;
5002         if (this.noAstNodes.length < astLength){
5003                 this.noAstNodes = new ASTNode[astLength];
5004                 //System.out.println("Resized AST stacks : "+ astLength);
5005                 
5006         }
5007         System.arraycopy(this.noAstNodes, 0, this.astStack, 0, astLength);
5008
5009         int expressionLength = this.expressionStack.length;
5010         if (this.noExpressions.length < expressionLength){
5011                 this.noExpressions = new Expression[expressionLength];
5012                 //System.out.println("Resized EXPR stacks : "+ expressionLength);
5013         }
5014         System.arraycopy(this.noExpressions, 0, this.expressionStack, 0, expressionLength);
5015
5016         // reset scanner state
5017         this.scanner.commentPtr = -1;
5018         this.scanner.foundTaskCount = 0;
5019         this.scanner.eofPosition = Integer.MAX_VALUE;
5020         this.scanner.wasNonExternalizedStringLiteral = false;
5021         this.scanner.nonNLSStrings = null;
5022         this.scanner.currentLine = null;        
5023
5024         resetModifiers();
5025
5026         // recovery
5027         this.lastCheckPoint = -1;
5028         this.currentElement = null;
5029         this.restartRecovery = false;
5030         this.hasReportedError = false;
5031         this.recoveredStaticInitializerStart = 0;
5032         this.lastIgnoredToken = -1;
5033         this.lastErrorEndPosition = -1;
5034         this.listLength = 0;
5035         
5036         this.rBraceStart = 0;
5037         this.rBraceEnd = 0;
5038         this.rBraceSuccessorStart = 0;
5039 }
5040 public void initializeScanner(){
5041         this.scanner = new Scanner(
5042                 false /*comment*/, 
5043                 false /*whitespace*/, 
5044                 this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /*nls*/, 
5045                 this.options.sourceLevel /*sourceLevel*/, 
5046                 this.options.taskTags/*taskTags*/,
5047                 this.options.taskPriorites/*taskPriorities*/,
5048                 this.options.isTaskCaseSensitive/*taskCaseSensitive*/);
5049 }
5050 public final static void initTables() throws java.io.IOException {
5051
5052         final String prefix = FILEPREFIX;
5053         int i = 0;
5054         lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5055         char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5056         check_table = new short[chars.length];
5057         for (int c = chars.length; c-- > 0;) {
5058                 check_table[c] = (short) (chars[c] - 32768);
5059         }
5060         asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5061         asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5062         nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5063         nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5064         terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5065         non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5066         term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5067         
5068         scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5069         scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5070         scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5071         scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5072         scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5073         scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5074         in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5075         
5076         rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5077         term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5078         scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5079         
5080         name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5081         readableName = readReadableNameTable(READABLE_NAMES);
5082         
5083         base_action = lhs;
5084 }
5085 public static int in_symbol(int state) {
5086         return in_symb[original_state(state)];
5087 }
5088 public final void jumpOverMethodBody() {
5089         //on diet parsing.....do not buffer method statements
5090
5091         //the scanner.diet is reinitialized to false
5092         //automatically by the scanner once it has jumped over
5093         //the statements
5094
5095         if (this.diet && (this.dietInt == 0))
5096                 this.scanner.diet = true;
5097 }
5098 protected void markEnclosingMemberWithLocalType() {
5099         if (this.currentElement != null) return; // this is already done in the recovery code
5100         for (int i = this.astPtr; i >= 0; i--) {
5101                 ASTNode node = this.astStack[i];
5102                 if (node instanceof AbstractMethodDeclaration 
5103                                 || node instanceof FieldDeclaration
5104                                 || node instanceof TypeDeclaration) { // mark type for now: all initializers will be marked when added to this type
5105                         node.bits |= ASTNode.HasLocalTypeMASK;
5106                         return;
5107                 }
5108         }
5109         // default to reference context (case of parse method body)
5110         if (this.referenceContext instanceof AbstractMethodDeclaration
5111                         || this.referenceContext instanceof TypeDeclaration) {
5112                 ((ASTNode)this.referenceContext).bits |= ASTNode.HasLocalTypeMASK;
5113         }
5114 }
5115 protected void markInitializersWithLocalType(TypeDeclaration type) {
5116         if (type.fields == null || (type.bits & ASTNode.HasLocalTypeMASK) == 0) return;
5117         for (int i = 0, length = type.fields.length; i < length; i++) {
5118                 FieldDeclaration field = type.fields[i];
5119                 if (field instanceof Initializer) {
5120                         field.bits |= ASTNode.HasLocalTypeMASK;
5121                 }
5122         }
5123 }
5124 /*
5125  * Move checkpoint location (current implementation is moving it by one token)
5126  *
5127  * Answers true if successfully moved checkpoint (in other words, it did not attempt to move it
5128  * beyond end of file).
5129  */
5130 protected boolean moveRecoveryCheckpoint() {
5131
5132         int pos = this.lastCheckPoint;
5133         /* reset scanner, and move checkpoint by one token */
5134         this.scanner.startPosition = pos;
5135         this.scanner.currentPosition = pos;
5136         this.scanner.diet = false; // quit jumping over method bodies
5137         
5138         /* if about to restart, then no need to shift token */
5139         if (this.restartRecovery){
5140                 this.lastIgnoredToken = -1;
5141                 this.scanner.currentLine = null;
5142                 return true;
5143         }
5144         
5145         /* protect against shifting on an invalid token */
5146         this.lastIgnoredToken = this.nextIgnoredToken;
5147         this.nextIgnoredToken = -1;
5148         do {
5149                 try {
5150                         this.nextIgnoredToken = this.scanner.getNextToken();
5151                         if(this.scanner.currentPosition == this.scanner.startPosition){
5152                                 this.scanner.currentPosition++; // on fake completion identifier
5153                                 this.nextIgnoredToken = -1;
5154                         }
5155                         
5156                 } catch(InvalidInputException e){
5157                         pos = this.scanner.currentPosition;
5158                 }
5159         } while (this.nextIgnoredToken < 0);
5160         
5161         if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
5162                 if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
5163                         this.scanner.currentLine = null;
5164                         return false;
5165                 }
5166         }
5167         this.lastCheckPoint = this.scanner.currentPosition;
5168         
5169         /* reset scanner again to previous checkpoint location*/
5170         this.scanner.startPosition = pos;
5171         this.scanner.currentPosition = pos;
5172         this.scanner.commentPtr = -1;
5173         this.scanner.foundTaskCount = 0;
5174         this.scanner.currentLine = null;
5175
5176         return true;
5177
5178 /*
5179         The following implementation moves the checkpoint location by one line:
5180          
5181         int pos = this.lastCheckPoint;
5182         // reset scanner, and move checkpoint by one token
5183         this.scanner.startPosition = pos;
5184         this.scanner.currentPosition = pos;
5185         this.scanner.diet = false; // quit jumping over method bodies
5186         
5187         // if about to restart, then no need to shift token
5188         if (this.restartRecovery){
5189                 this.lastIgnoredToken = -1;
5190                 return true;
5191         }
5192         
5193         // protect against shifting on an invalid token
5194         this.lastIgnoredToken = this.nextIgnoredToken;
5195         this.nextIgnoredToken = -1;
5196         
5197         boolean wasTokenizingWhiteSpace = this.scanner.tokenizeWhiteSpace;
5198         this.scanner.tokenizeWhiteSpace = true;
5199         checkpointMove: 
5200                 do {
5201                         try {
5202                                 this.nextIgnoredToken = this.scanner.getNextToken();
5203                                 switch(this.nextIgnoredToken){
5204                                         case Scanner.TokenNameWHITESPACE :
5205                                                 if(this.scanner.getLineNumber(this.scanner.startPosition)
5206                                                         == this.scanner.getLineNumber(this.scanner.currentPosition)){
5207                                                         this.nextIgnoredToken = -1;
5208                                                         }
5209                                                 break;
5210                                         case TokenNameSEMICOLON :
5211                                         case TokenNameLBRACE :
5212                                         case TokenNameRBRACE :
5213                                                 break;
5214                                         case TokenNameIdentifier :
5215                                                 if(this.scanner.currentPosition == this.scanner.startPosition){
5216                                                         this.scanner.currentPosition++; // on fake completion identifier
5217                                                 }
5218                                         default:                                                
5219                                                 this.nextIgnoredToken = -1;
5220                                                 break;
5221                                         case TokenNameEOF :
5222                                                 break checkpointMove;
5223                                 }
5224                         } catch(InvalidInputException e){
5225                                 pos = this.scanner.currentPosition;
5226                         }
5227                 } while (this.nextIgnoredToken < 0);
5228         this.scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
5229         
5230         if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
5231                 if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
5232                         return false;
5233                 }
5234         }
5235         this.lastCheckPoint = this.scanner.currentPosition;
5236         
5237         // reset scanner again to previous checkpoint location
5238         this.scanner.startPosition = pos;
5239         this.scanner.currentPosition = pos;
5240         this.scanner.commentPtr = -1;
5241
5242         return true;
5243 */
5244 }
5245 protected MessageSend newMessageSend() {
5246         // '(' ArgumentListopt ')'
5247         // the arguments are on the expression stack
5248
5249         MessageSend m = new MessageSend();
5250         int length;
5251         if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
5252                 this.expressionPtr -= length;
5253                 System.arraycopy(
5254                         this.expressionStack, 
5255                         this.expressionPtr + 1, 
5256                         m.arguments = new Expression[length], 
5257                         0, 
5258                         length); 
5259         }
5260         return m;
5261 }
5262 public static int nasi(int state) {
5263         return nasb[original_state(state)];
5264 }
5265 public static int ntAction(int state, int sym) {
5266         return base_action[state + sym];
5267 }
5268 private final void optimizedConcatNodeLists() {
5269         /*back from a recursive loop. Virtualy group the
5270         astNode into an array using astLengthStack*/
5271
5272         /*
5273          * This is a case where you have two sublists into the astStack that you want
5274          * to merge in one list. There is no action required on the astStack. The only
5275          * thing you need to do is merge the two lengths specified on the astStackLength.
5276          * The top two length are for example:
5277          * ... p   n
5278          * and you want to result in a list like:
5279          * ... n+p 
5280          * This means that the p could be equals to 0 in case there is no astNode pushed
5281          * on the astStack.
5282          * Look at the InterfaceMemberDeclarations for an example.
5283          * This case optimizes the fact that p == 1.
5284          */
5285
5286         this.astLengthStack[--this.astLengthPtr]++;
5287 }
5288 protected static int original_state(int state) {
5289         return -base_check(state);
5290 }
5291 /*main loop of the automat
5292 When a rule is reduced, the method consumeRule(int) is called with the number
5293 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is 
5294 called in order to remember (when needed) the consumed token */
5295 // (int)asr[asi(act)]
5296 // name[symbol_index[currentKind]]
5297 protected void parse() {
5298         boolean isDietParse = this.diet;
5299         int oldFirstToken = getFirstToken();
5300         this.hasError = false;
5301         
5302         this.hasReportedError = false;
5303         int act = START_STATE;
5304         this.stateStackTop = -1;
5305         this.currentToken = getFirstToken();
5306         ProcessTerminals : for (;;) {
5307                 int stackLength = this.stack.length;
5308                 if (++this.stateStackTop >= stackLength) {
5309                         System.arraycopy(
5310                                 this.stack, 0,
5311                                 this.stack = new int[stackLength + StackIncrement], 0,
5312                                 stackLength);
5313                 }
5314                 this.stack[this.stateStackTop] = act;
5315
5316                 act = tAction(act, this.currentToken);
5317
5318                 if (act == ERROR_ACTION || this.restartRecovery) {
5319                         int errorPos = this.scanner.currentPosition;
5320                         if (!this.hasReportedError){
5321                                 this.hasError = true;
5322                         }
5323                         if (resumeOnSyntaxError()) {
5324                                 if (act == ERROR_ACTION) this.lastErrorEndPosition = errorPos;
5325                                 act = START_STATE;
5326                                 this.stateStackTop = -1;
5327                                 this.currentToken = getFirstToken();
5328                                 continue ProcessTerminals;
5329                         }
5330                         act = ERROR_ACTION;
5331                         break ProcessTerminals;
5332                 }
5333                 if (act <= NUM_RULES) {
5334                         this.stateStackTop--;
5335                         
5336                 } else if (act > ERROR_ACTION) { /* shift-reduce */
5337                         consumeToken(this.currentToken);
5338                         if (this.currentElement != null) this.recoveryTokenCheck();
5339                         try {
5340                                 this.currentToken = this.scanner.getNextToken();
5341                         } catch(InvalidInputException e){
5342                                 if (!this.hasReportedError){
5343                                         this.problemReporter().scannerError(this, e.getMessage());
5344                                         this.hasReportedError = true;
5345                                 }
5346                                 this.lastCheckPoint = this.scanner.currentPosition;
5347                                 this.restartRecovery = true;
5348                         }                                       
5349                         act -= ERROR_ACTION;
5350                         
5351                 } else {
5352                     if (act < ACCEPT_ACTION) { /* shift */
5353                                 consumeToken(this.currentToken);
5354                                 if (this.currentElement != null) this.recoveryTokenCheck();
5355                                 try{
5356                                         this.currentToken = this.scanner.getNextToken();
5357                                 } catch(InvalidInputException e){
5358                                         if (!this.hasReportedError){
5359                                                 this.problemReporter().scannerError(this, e.getMessage());
5360                                                 this.hasReportedError = true;
5361                                         }
5362                                         this.lastCheckPoint = this.scanner.currentPosition;
5363                                         this.restartRecovery = true;
5364                                 }                                       
5365                                 continue ProcessTerminals;
5366                         }
5367                         break ProcessTerminals;
5368                 }
5369                 ProcessNonTerminals : do { /* reduce */
5370                         consumeRule(act);
5371                         this.stateStackTop -= (rhs[act] - 1);
5372                         act = ntAction(this.stack[this.stateStackTop], lhs[act]);
5373                 } while (act <= NUM_RULES);
5374         }
5375         endParse(act);
5376         
5377         if (this.reportSyntaxErrorIsRequired && this.hasError) {
5378                 reportSyntaxErrors(isDietParse, oldFirstToken);
5379         }
5380 }
5381 // A P I
5382 protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) {
5383         if(this.referenceContext instanceof MethodDeclaration) {
5384                 MethodDeclaration methodDeclaration = (MethodDeclaration) this.referenceContext;
5385                 if(methodDeclaration.errorInSignature){
5386                         return;
5387                 }
5388         }
5389         this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5390         this.scanner.recordLineSeparator = false;
5391         
5392         int start = this.scanner.initialPosition;
5393         int end = this.scanner.eofPosition <= Integer.MAX_VALUE ? this.scanner.eofPosition - 1 : this.scanner.eofPosition;
5394         if(isDietParse) {
5395                 TypeDeclaration[] types = this.compilationUnit.types;
5396                 
5397                 int[][] intervalToSkip = org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types);
5398                 DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2]);
5399                 diagnoseParser.diagnoseParse();
5400                 
5401                 reportSyntaxErrorsForSkippedMethod(types);
5402                 this.scanner.resetTo(start, end);
5403         } else {
5404                 DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end);
5405                 diagnoseParser.diagnoseParse();
5406         }
5407 }
5408 private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types){
5409         if(types != null) {
5410                 for (int i = 0; i < types.length; i++) {
5411                         TypeDeclaration[] memberTypes = types[i].memberTypes;
5412                         if(memberTypes != null) {
5413                                 reportSyntaxErrorsForSkippedMethod(memberTypes);
5414                         }
5415                         
5416                         AbstractMethodDeclaration[] methods = types[i].methods;
5417                         if(methods != null) {
5418                                 for (int j = 0; j < methods.length; j++) {
5419                                         AbstractMethodDeclaration method = methods[j];
5420                                         if(methods[j].errorInSignature) {
5421                                                 DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd);
5422                                                 diagnoseParser.diagnoseParse();
5423                                         }
5424                                 }
5425                         }
5426                         
5427                         FieldDeclaration[] fields = types[i].fields;
5428                         if (fields != null) {
5429                                 int length = fields.length;
5430                                 for (int j = 0; j < length; j++) {
5431                                         if (fields[j] instanceof Initializer) {
5432                                                 Initializer initializer = (Initializer)fields[j];
5433                                                 if(initializer.errorInSignature){
5434                                                         DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd);
5435                                                         diagnoseParser.diagnoseParse();
5436                                                 }
5437                                         }
5438                                 }
5439                         }
5440                 }
5441         }
5442 }
5443 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
5444         parse(cd, unit, false);
5445 }
5446 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit, boolean recordLineSeparator) {
5447         //only parse the method body of cd
5448         //fill out its statements
5449
5450         //convert bugs into parse error
5451
5452         initialize();
5453         goForBlockStatementsopt();
5454         if (recordLineSeparator) {
5455                 this.scanner.recordLineSeparator = true;
5456         }
5457         this.nestedMethod[this.nestedType]++;
5458         pushOnRealBlockStack(0);
5459         
5460         this.referenceContext = cd;
5461         this.compilationUnit = unit;
5462
5463         this.scanner.resetTo(cd.bodyStart, cd.bodyEnd);
5464         try {
5465                 parse();
5466         } catch (AbortCompilation ex) {
5467                 this.lastAct = ERROR_ACTION;
5468         } finally {
5469                 this.nestedMethod[this.nestedType]--;
5470         }
5471
5472         checkNonNLSAfterBodyEnd(cd.declarationSourceEnd);
5473         
5474         if (this.lastAct == ERROR_ACTION) {
5475                 initialize();
5476                 return;
5477         }
5478
5479         //statements
5480         cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5481         int length;
5482         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
5483                 this.astPtr -= length;
5484                 if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
5485                         //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
5486                         {
5487                         System.arraycopy(
5488                                 this.astStack, 
5489                                 this.astPtr + 2, 
5490                                 cd.statements = new Statement[length - 1], 
5491                                 0, 
5492                                 length - 1); 
5493                         cd.constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
5494                 } else { //need to add explicitly the super();
5495                         System.arraycopy(
5496                                 this.astStack, 
5497                                 this.astPtr + 1, 
5498                                 cd.statements = new Statement[length], 
5499                                 0, 
5500                                 length); 
5501                         cd.constructorCall = SuperReference.implicitSuperConstructorCall();
5502                 }
5503         } else {
5504                 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
5505                 if (!containsComment(cd.bodyStart, cd.bodyEnd)) {
5506                         cd.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5507                 }               
5508         }
5509
5510         if (cd.constructorCall.sourceEnd == 0) {
5511                 cd.constructorCall.sourceEnd = cd.sourceEnd;
5512                 cd.constructorCall.sourceStart = cd.sourceStart;
5513         }
5514 }
5515 // A P I
5516
5517 public void parse(
5518         FieldDeclaration field, 
5519         TypeDeclaration type, 
5520         CompilationUnitDeclaration unit,
5521         char[] initializationSource) {
5522         //only parse the initializationSource of the given field
5523
5524         //convert bugs into parse error
5525
5526         initialize();
5527         goForExpression();
5528         this.nestedMethod[this.nestedType]++;
5529
5530         this.referenceContext = type;
5531         this.compilationUnit = unit;
5532
5533         this.scanner.setSource(initializationSource);
5534         this.scanner.resetTo(0, initializationSource.length-1);
5535         try {
5536                 parse();
5537         } catch (AbortCompilation ex) {
5538                 this.lastAct = ERROR_ACTION;
5539         } finally {
5540                 this.nestedMethod[this.nestedType]--;
5541         }
5542
5543         if (this.lastAct == ERROR_ACTION) {
5544                 return;
5545         }
5546
5547         field.initialization = this.expressionStack[this.expressionPtr];
5548         
5549         // mark field with local type if one was found during parsing
5550         if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
5551                 field.bits |= ASTNode.HasLocalTypeMASK;
5552         }       
5553 }
5554 // A P I
5555
5556 public void parse(
5557         Initializer initializer, 
5558         TypeDeclaration type, 
5559         CompilationUnitDeclaration unit) {
5560         //only parse the method body of md
5561         //fill out method statements
5562
5563         //convert bugs into parse error
5564
5565         initialize();
5566         goForBlockStatementsopt();
5567         this.nestedMethod[this.nestedType]++;
5568         pushOnRealBlockStack(0);
5569         
5570         this.referenceContext = type;
5571         this.compilationUnit = unit;
5572
5573         this.scanner.resetTo(initializer.bodyStart, initializer.bodyEnd); // just on the beginning {
5574         try {
5575                 parse();
5576         } catch (AbortCompilation ex) {
5577                 this.lastAct = ERROR_ACTION;
5578         } finally {
5579                 this.nestedMethod[this.nestedType]--;
5580         }
5581
5582         checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd);
5583         
5584         if (this.lastAct == ERROR_ACTION) {
5585                 return;
5586         }
5587         
5588         //refill statements
5589         initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5590         int length;
5591         if ((length = this.astLengthStack[this.astLengthPtr--]) > 0) {
5592                 System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length); 
5593         } else {
5594                 // check whether this block at least contains some comment in it
5595                 if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) {
5596                         initializer.block.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5597                 }
5598         }
5599         
5600         // mark initializer with local type if one was found during parsing
5601         if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
5602                 initializer.bits |= ASTNode.HasLocalTypeMASK;
5603         }       
5604 }
5605 // A P I
5606
5607 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
5608         //only parse the method body of md
5609         //fill out method statements
5610
5611         //convert bugs into parse error
5612
5613         if (md.isAbstract())
5614                 return;
5615         if (md.isNative())
5616                 return;
5617         if ((md.modifiers & AccSemicolonBody) != 0)
5618                 return;
5619
5620         initialize();
5621         goForBlockStatementsopt();
5622         this.nestedMethod[this.nestedType]++;
5623         pushOnRealBlockStack(0);
5624
5625         this.referenceContext = md;
5626         this.compilationUnit = unit;
5627
5628         this.scanner.resetTo(md.bodyStart, md.bodyEnd);
5629         // reset the scanner to parser from { down to }
5630         try {
5631                 parse();
5632         } catch (AbortCompilation ex) {
5633                 this.lastAct = ERROR_ACTION;
5634         } finally {
5635                 this.nestedMethod[this.nestedType]--;           
5636         }
5637
5638         checkNonNLSAfterBodyEnd(md.declarationSourceEnd);
5639         
5640         if (this.lastAct == ERROR_ACTION) {
5641                 return;
5642         }
5643
5644         //refill statements
5645         md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5646         int length;
5647         if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
5648                 System.arraycopy(
5649                         this.astStack, 
5650                         (this.astPtr -= length) + 1, 
5651                         md.statements = new Statement[length], 
5652                         0, 
5653                         length); 
5654         } else {
5655                 if (!containsComment(md.bodyStart, md.bodyEnd)) {
5656                         md.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5657                 }
5658         }
5659 }
5660 // A P I
5661
5662 public CompilationUnitDeclaration parse(
5663         ICompilationUnit sourceUnit, 
5664         CompilationResult compilationResult) {
5665         // parses a compilation unit and manages error handling (even bugs....)
5666
5667         return parse(sourceUnit, compilationResult, -1, -1/*parse without reseting the scanner*/);
5668 }
5669 // A P I
5670
5671 public CompilationUnitDeclaration parse(
5672         ICompilationUnit sourceUnit, 
5673         CompilationResult compilationResult,
5674         int start,
5675         int end) {
5676         // parses a compilation unit and manages error handling (even bugs....)
5677
5678         CompilationUnitDeclaration unit;
5679         try {
5680                 /* automaton initialization */
5681                 initialize();
5682                 goForCompilationUnit();
5683
5684                 /* scanners initialization */
5685                 char[] contents = sourceUnit.getContents();
5686                 this.scanner.setSource(contents);
5687                 if (end != -1) this.scanner.resetTo(start, end);
5688                 if (this.javadocParser != null && this.javadocParser.checkDocComment) {
5689                         this.javadocParser.scanner.setSource(contents);
5690                         if (end != -1) {
5691                                 this.javadocParser.scanner.resetTo(start, end);
5692                         }
5693                 }
5694                 /* unit creation */
5695                 this.referenceContext = 
5696                         this.compilationUnit = 
5697                                 new CompilationUnitDeclaration(
5698                                         this.problemReporter, 
5699                                         compilationResult, 
5700                                         this.scanner.source.length);
5701                 /* run automaton */
5702                 parse();
5703         } finally {
5704                 unit = this.compilationUnit;
5705                 this.compilationUnit = null; // reset parser
5706                 // tag unit has having read bodies
5707                 if (!this.diet) unit.bits |= ASTNode.HasAllMethodBodies;                
5708         }
5709         return unit;
5710 }
5711 public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
5712         /* automaton initialization */
5713         initialize();
5714         goForClassBodyDeclarations();
5715         /* scanner initialization */
5716         this.scanner.setSource(source);
5717         this.scanner.resetTo(offset, offset + length - 1);
5718         if (this.javadocParser != null && this.javadocParser.checkDocComment) {
5719                 this.javadocParser.scanner.setSource(source);
5720                 this.javadocParser.scanner.resetTo(offset, offset + length - 1);
5721         }
5722
5723         /* type declaration should be parsed as member type declaration */      
5724         this.nestedType = 1;
5725
5726         /* unit creation */
5727         this.referenceContext = unit;
5728         this.compilationUnit = unit;
5729
5730         /* run automaton */
5731         try {
5732                 parse();
5733         } catch (AbortCompilation ex) {
5734                 this.lastAct = ERROR_ACTION;
5735         }
5736
5737         if (this.lastAct == ERROR_ACTION) {
5738                 return null;
5739         }
5740         int astLength;
5741         if ((astLength = this.astLengthStack[this.astLengthPtr--]) != 0) {
5742                 ASTNode[] result = new ASTNode[astLength];
5743                 this.astPtr -= astLength;
5744                 System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength);
5745                 return result;
5746         }
5747         return null;
5748 }
5749 public Expression parseExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
5750
5751         initialize();
5752         goForExpression();
5753         this.nestedMethod[this.nestedType]++;
5754
5755         this.referenceContext = unit;
5756         this.compilationUnit = unit;
5757
5758         this.scanner.setSource(source);
5759         this.scanner.resetTo(offset, offset + length - 1);
5760         try {
5761                 parse();
5762         } catch (AbortCompilation ex) {
5763                 this.lastAct = ERROR_ACTION;
5764         } finally {
5765                 this.nestedMethod[this.nestedType]--;
5766         }
5767
5768         if (this.lastAct == ERROR_ACTION) {
5769                 return null;
5770         }
5771
5772         return this.expressionStack[this.expressionPtr];
5773 }
5774 public void persistLineSeparatorPositions() {
5775         if (this.scanner.recordLineSeparator) {
5776                 this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5777         }
5778 }
5779 /**
5780  * Returns this parser's problem reporter initialized with its reference context.
5781  * Also it is assumed that a problem is going to be reported, so initializes
5782  * the compilation result's line positions.
5783  * 
5784  * @return ProblemReporter
5785  */
5786 public ProblemReporter problemReporter(){
5787         if (this.scanner.recordLineSeparator) {
5788                 this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5789         }
5790         this.problemReporter.referenceContext = this.referenceContext;
5791         return this.problemReporter;
5792 }
5793 protected void pushIdentifier() {
5794         /*push the consumeToken on the identifier stack.
5795         Increase the total number of identifier in the stack.
5796         identifierPtr points on the next top */
5797
5798         int stackLength = this.identifierStack.length;
5799         if (++this.identifierPtr >= stackLength) {
5800                 System.arraycopy(
5801                         this.identifierStack, 0,
5802                         this.identifierStack = new char[stackLength + 20][], 0,
5803                         stackLength);
5804                 System.arraycopy(
5805                         this.identifierPositionStack, 0,
5806                         this.identifierPositionStack = new long[stackLength + 20], 0,
5807                         stackLength);
5808         }
5809         this.identifierStack[this.identifierPtr] = this.scanner.getCurrentIdentifierSource();
5810         this.identifierPositionStack[this.identifierPtr] =
5811                 (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1); 
5812
5813         stackLength = this.identifierLengthStack.length;
5814         if (++this.identifierLengthPtr >= stackLength) {
5815                 System.arraycopy(
5816                         this.identifierLengthStack, 0,
5817                         this.identifierLengthStack = new int[stackLength + 10], 0,
5818                         stackLength);
5819         }
5820         this.identifierLengthStack[this.identifierLengthPtr] = 1;
5821 }
5822 protected void pushIdentifier(int flag) {
5823         /*push a special flag on the stack :
5824         -zero stands for optional Name
5825         -negative number for direct ref to base types.
5826         identifierLengthPtr points on the top */
5827
5828         int stackLength = this.identifierLengthStack.length;
5829         if (++this.identifierLengthPtr >= stackLength) {
5830                 System.arraycopy(
5831                         this.identifierLengthStack, 0,
5832                         this.identifierLengthStack = new int[stackLength + 10], 0,
5833                         stackLength);
5834         }
5835         this.identifierLengthStack[this.identifierLengthPtr] = flag;
5836 }
5837 protected void pushOnAstLengthStack(int pos) {
5838
5839         int stackLength = this.astLengthStack.length;
5840         if (++this.astLengthPtr >= stackLength) {
5841                 System.arraycopy(
5842                         this.astLengthStack, 0,
5843                         this.astLengthStack = new int[stackLength + StackIncrement], 0,
5844                         stackLength);
5845         }
5846         this.astLengthStack[this.astLengthPtr] = pos;
5847 }
5848 protected void pushOnAstStack(ASTNode node) {
5849         /*add a new obj on top of the ast stack
5850         astPtr points on the top*/
5851
5852         int stackLength = this.astStack.length;
5853         if (++this.astPtr >= stackLength) {
5854                 System.arraycopy(
5855                         this.astStack, 0,
5856                         this.astStack = new ASTNode[stackLength + AstStackIncrement], 0,
5857                         stackLength);
5858                 this.astPtr = stackLength;
5859         }
5860         this.astStack[this.astPtr] = node;
5861
5862         stackLength = this.astLengthStack.length;
5863         if (++this.astLengthPtr >= stackLength) {
5864                 System.arraycopy(
5865                         this.astLengthStack, 0,
5866                         this.astLengthStack = new int[stackLength + AstStackIncrement], 0,
5867                         stackLength);
5868         }
5869         this.astLengthStack[this.astLengthPtr] = 1;
5870 }
5871 protected void pushOnExpressionStack(Expression expr) {
5872
5873         int stackLength = this.expressionStack.length;
5874         if (++this.expressionPtr >= stackLength) {
5875                 System.arraycopy(
5876                         this.expressionStack, 0,
5877                         this.expressionStack = new Expression[stackLength + ExpressionStackIncrement], 0,
5878                         stackLength);
5879         }
5880         this.expressionStack[this.expressionPtr] = expr;
5881
5882         stackLength = this.expressionLengthStack.length;
5883         if (++this.expressionLengthPtr >= stackLength) {
5884                 System.arraycopy(
5885                         this.expressionLengthStack, 0,
5886                         this.expressionLengthStack = new int[stackLength + ExpressionStackIncrement], 0,
5887                         stackLength);
5888         }
5889         this.expressionLengthStack[this.expressionLengthPtr] = 1;
5890 }
5891 protected void pushOnExpressionStackLengthStack(int pos) {
5892
5893         int stackLength = this.expressionLengthStack.length;
5894         if (++this.expressionLengthPtr >= stackLength) {
5895                 System.arraycopy(
5896                         this.expressionLengthStack, 0,
5897                         this.expressionLengthStack = new int[stackLength + StackIncrement], 0,
5898                         stackLength);
5899         }
5900         this.expressionLengthStack[this.expressionLengthPtr] = pos;
5901 }
5902 protected void pushOnIntStack(int pos) {
5903
5904         int stackLength = this.intStack.length;
5905         if (++this.intPtr >= stackLength) {
5906                 System.arraycopy(
5907                         this.intStack, 0,
5908                         this.intStack = new int[stackLength + StackIncrement], 0,
5909                         stackLength);
5910         }
5911         this.intStack[this.intPtr] = pos;
5912 }
5913 protected void pushOnRealBlockStack(int i){
5914         
5915         int stackLength = this.realBlockStack.length;
5916         if (++this.realBlockPtr >= stackLength) {
5917                 System.arraycopy(
5918                         this.realBlockStack, 0,
5919                         this.realBlockStack = new int[stackLength + StackIncrement], 0,
5920                         stackLength);
5921         }
5922         this.realBlockStack[this.realBlockPtr] = i;
5923 }
5924 protected static char[] readTable(String filename) throws java.io.IOException {
5925
5926         //files are located at Parser.class directory
5927
5928         InputStream stream = Parser.class.getResourceAsStream(filename);
5929         if (stream == null) {
5930                 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
5931         }
5932         byte[] bytes = null;
5933         try {
5934                 stream = new BufferedInputStream(stream);
5935                 bytes = Util.getInputStreamAsByteArray(stream, -1);
5936         } finally {
5937                 try {
5938                         stream.close();
5939                 } catch (IOException e) {
5940                         // ignore
5941                 }
5942         }
5943
5944         //minimal integrity check (even size expected)
5945         int length = bytes.length;
5946         if (length % 2 != 0)
5947                 throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
5948
5949         // convert bytes into chars
5950         char[] chars = new char[length / 2];
5951         int i = 0;
5952         int charIndex = 0;
5953
5954         while (true) {
5955                 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
5956                 if (i == length)
5957                         break;
5958         }
5959         return chars;
5960 }
5961 protected static byte[] readByteTable(String filename) throws java.io.IOException {
5962
5963         //files are located at Parser.class directory
5964
5965         InputStream stream = Parser.class.getResourceAsStream(filename);
5966         if (stream == null) {
5967                 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
5968         }
5969         byte[] bytes = null;
5970         try {
5971                 stream = new BufferedInputStream(stream);
5972                 bytes = Util.getInputStreamAsByteArray(stream, -1);
5973         } finally {
5974                 try {
5975                         stream.close();
5976                 } catch (IOException e) {
5977                         // ignore
5978                 }
5979         }
5980         return bytes;
5981 }
5982 protected static String[] readReadableNameTable(String filename) {
5983         String[] result = new String[name.length];
5984
5985         ResourceBundle bundle;
5986         try {
5987                 bundle = ResourceBundle.getBundle(filename, Locale.getDefault());
5988         } catch(MissingResourceException e) {
5989                 System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
5990                 throw e;
5991         }
5992         for (int i = 0; i < NT_OFFSET + 1; i++) {
5993                 result[i] = name[i];
5994         }
5995         for (int i = NT_OFFSET; i < name.length; i++) {
5996                 try {
5997                         String n = bundle.getString(name[i]);
5998                         if(n != null && n.length() > 0) {
5999                                 result[i] = n;
6000                         } else {
6001                                 result[i] = name[i];
6002                         }
6003                 } catch(MissingResourceException e) {
6004                         result[i] = name[i];
6005                 }
6006         }
6007         return result;
6008 }
6009         
6010 protected static String[] readNameTable(String filename) throws java.io.IOException {
6011         char[] contents = readTable(filename);
6012         char[][] nameAsChar = CharOperation.splitOn('\n', contents);
6013
6014         String[] result = new String[nameAsChar.length + 1];
6015         result[0] = null;
6016         for (int i = 0; i < nameAsChar.length; i++) {
6017                 result[i + 1] = new String(nameAsChar[i]);
6018         }
6019         
6020         return result;
6021 }
6022 public void recoveryExitFromVariable() {
6023         if(this.currentElement != null && this.currentElement.parent != null) {
6024                 if(this.currentElement instanceof RecoveredLocalVariable) {
6025                         
6026                         int end = ((RecoveredLocalVariable)this.currentElement).localDeclaration.sourceEnd;
6027                         this.currentElement.updateSourceEndIfNecessary(end);
6028                         this.currentElement = this.currentElement.parent;
6029                 } else if(this.currentElement instanceof RecoveredField
6030                         && !(this.currentElement instanceof RecoveredInitializer)) {
6031                                 
6032                         int end = ((RecoveredField)this.currentElement).fieldDeclaration.sourceEnd;
6033                         this.currentElement.updateSourceEndIfNecessary(end);
6034                         this.currentElement = this.currentElement.parent;
6035                 }
6036         }
6037 }
6038 /* Token check performed on every token shift once having entered
6039  * recovery mode.
6040  */
6041 public void recoveryTokenCheck() {
6042         switch (this.currentToken) {
6043                 case TokenNameLBRACE : 
6044                         RecoveredElement newElement = null;
6045                         if(!this.ignoreNextOpeningBrace) {
6046                                 newElement = this.currentElement.updateOnOpeningBrace(this.scanner.startPosition - 1, this.scanner.currentPosition - 1);
6047                         }
6048                         this.lastCheckPoint = this.scanner.currentPosition;                             
6049                         if (newElement != null){ // null means nothing happened
6050                                 this.restartRecovery = true; // opening brace detected
6051                                 this.currentElement = newElement;
6052                         }
6053                         break;
6054                 
6055                 case TokenNameRBRACE : 
6056                         this.rBraceStart = this.scanner.startPosition - 1;
6057                         this.rBraceEnd = this.scanner.currentPosition - 1;
6058                         this.endPosition = this.flushCommentsDefinedPriorTo(this.rBraceEnd);
6059                         newElement =
6060                                 this.currentElement.updateOnClosingBrace(this.scanner.startPosition, this.rBraceEnd);
6061                                 this.lastCheckPoint = this.scanner.currentPosition;
6062                         if (newElement != this.currentElement){
6063                                 this.currentElement = newElement;
6064                         }
6065                         break;
6066                 case TokenNameSEMICOLON :
6067                         this.endStatementPosition = this.scanner.currentPosition - 1;
6068                         this.endPosition = this.scanner.startPosition - 1; 
6069                         // fall through
6070                 default : {
6071                         if (this.rBraceEnd > this.rBraceSuccessorStart && this.scanner.currentPosition != this.scanner.startPosition){
6072                                 this.rBraceSuccessorStart = this.scanner.startPosition;
6073                         }
6074                         break;
6075                 }
6076         }
6077         this.ignoreNextOpeningBrace = false;
6078 }
6079 protected void resetModifiers() {
6080         this.modifiers = AccDefault;
6081         this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
6082         this.scanner.commentPtr = -1;
6083 }
6084 /*
6085  * Reset context so as to resume to regular parse loop
6086  */
6087 protected void resetStacks() {
6088
6089         this.astPtr = -1;
6090         this.astLengthPtr = -1;
6091         this.expressionPtr = -1;
6092         this.expressionLengthPtr = -1;
6093         this.identifierPtr = -1;        
6094         this.identifierLengthPtr        = -1;
6095         this.intPtr = -1;
6096         this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
6097         this.variablesCounter[this.nestedType] = 0;
6098         this.dimensions = 0 ;
6099         this.realBlockStack[this.realBlockPtr = 0] = 0;
6100         this.recoveredStaticInitializerStart = 0;
6101         this.listLength = 0;
6102         // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=29365
6103         if (this.scanner != null) this.scanner.currentLine = null;
6104 }
6105 /*
6106  * Reset context so as to resume to regular parse loop
6107  * If unable to reset for resuming, answers false.
6108  *
6109  * Move checkpoint location, reset internal stacks and
6110  * decide which grammar goal is activated.
6111  */
6112 protected boolean resumeAfterRecovery() {
6113
6114         // Reset javadoc before restart parsing after recovery
6115         this.javadoc = null;
6116
6117         // reset internal stacks 
6118         this.resetStacks();
6119         
6120         /* attempt to move checkpoint location */
6121         if (!this.moveRecoveryCheckpoint()) {
6122                 return false;
6123         }
6124
6125         // only look for headers
6126         if (this.referenceContext instanceof CompilationUnitDeclaration){
6127                 goForHeaders();
6128                 this.diet = true; // passed this point, will not consider method bodies
6129                 return true;
6130         }
6131         // does not know how to restart
6132         return false;
6133 }
6134 /*
6135  * Syntax error was detected. Will attempt to perform some recovery action in order
6136  * to resume to the regular parse loop.
6137  */
6138 protected boolean resumeOnSyntaxError() {
6139
6140         /* request recovery initialization */
6141         if (this.currentElement == null){
6142                 this.currentElement = 
6143                         this.buildInitialRecoveryState(); // build some recovered elements
6144         }
6145         /* do not investigate deeper in recovery when no recovered element */
6146         if (this.currentElement == null) return false;
6147         
6148         /* manual forced recovery restart - after headers */
6149         if (this.restartRecovery){
6150                 this.restartRecovery = false;
6151         }
6152         /* update recovery state with current error state of the parser */
6153         this.updateRecoveryState();
6154         
6155         /* attempt to reset state in order to resume to parse loop */
6156         return this.resumeAfterRecovery();
6157 }
6158 public static int tAction(int state, int sym) {
6159         return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
6160 }
6161 public String toString() {
6162
6163         String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
6164         for (int i = 0; i <= this.identifierPtr; i++) {
6165                 s = s + "\"" + String.valueOf(this.identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
6166         }
6167         s = s + "}\n"; //$NON-NLS-1$
6168
6169         s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
6170         for (int i = 0; i <= this.identifierLengthPtr; i++) {
6171                 s = s + this.identifierLengthStack[i] + ","; //$NON-NLS-1$
6172         }
6173         s = s + "}\n"; //$NON-NLS-1$
6174
6175         s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
6176         for (int i = 0; i <= this.astLengthPtr; i++) {
6177                 s = s + this.astLengthStack[i] + ","; //$NON-NLS-1$
6178         }
6179         s = s + "}\n"; //$NON-NLS-1$
6180         s = s + "astPtr : int = " + String.valueOf(this.astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
6181
6182         s = s + "intStack : int[] = {"; //$NON-NLS-1$
6183         for (int i = 0; i <= this.intPtr; i++) {
6184                 s = s + this.intStack[i] + ","; //$NON-NLS-1$
6185         }
6186         s = s + "}\n"; //$NON-NLS-1$
6187
6188         s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
6189         for (int i = 0; i <= this.expressionLengthPtr; i++) {
6190                 s = s + this.expressionLengthStack[i] + ","; //$NON-NLS-1$
6191         }
6192         s = s + "}\n"; //$NON-NLS-1$
6193
6194         s = s + "expressionPtr : int = " + String.valueOf(this.expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
6195
6196         s = s + "\n\n\n----------------Scanner--------------\n" + this.scanner.toString(); //$NON-NLS-1$
6197         return s;
6198
6199 }
6200 /*
6201  * Update recovery state based on current parser/scanner state
6202  */
6203 protected void updateRecoveryState() {
6204
6205         /* expose parser state to recovery state */
6206         this.currentElement.updateFromParserState();
6207
6208         /* check and update recovered state based on current token,
6209                 this action is also performed when shifting token after recovery
6210                 got activated once. 
6211         */
6212         this.recoveryTokenCheck();
6213 }
6214 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
6215         //fields is a definition of fields that are grouped together like in
6216         //public int[] a, b[], c
6217         //which results into 3 fields.
6218
6219         FieldDeclaration field;
6220         int endTypeDeclarationPosition = 
6221                 -1 + this.astStack[this.astPtr - variableDeclaratorsCounter + 1].sourceStart; 
6222         for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
6223                 //last one is special(see below)
6224                 field = (FieldDeclaration) this.astStack[this.astPtr - i - 1];
6225                 field.endPart1Position = endTypeDeclarationPosition;
6226                 field.endPart2Position = -1 + this.astStack[this.astPtr - i].sourceStart;
6227         }
6228         //last one
6229         (field = (FieldDeclaration) this.astStack[this.astPtr]).endPart1Position = 
6230                 endTypeDeclarationPosition; 
6231         field.endPart2Position = field.declarationSourceEnd;
6232
6233 }
6234 protected void updateSourcePosition(Expression exp) {
6235         //update the source Position of the expression
6236
6237         //intStack : int int
6238         //-->
6239         //intStack : 
6240
6241         exp.sourceEnd = this.intStack[this.intPtr--];
6242         exp.sourceStart = this.intStack[this.intPtr--];
6243 }
6244 }