KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > Parser


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * 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 JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Locale JavaDoc;
20 import java.util.MissingResourceException JavaDoc;
21 import java.util.ResourceBundle JavaDoc;
22
23 import org.eclipse.jdt.core.compiler.CharOperation;
24 import org.eclipse.jdt.core.compiler.InvalidInputException;
25 import org.eclipse.jdt.internal.compiler.ASTVisitor;
26 import org.eclipse.jdt.internal.compiler.CompilationResult;
27 import org.eclipse.jdt.internal.compiler.ast.*;
28 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
29 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
30 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
31 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
32 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
33 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
34 import org.eclipse.jdt.internal.compiler.lookup.Binding;
35 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
36 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
37 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
38 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
39 import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
40 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
41 import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
42 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
43 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
44 import org.eclipse.jdt.internal.compiler.util.Messages;
45 import org.eclipse.jdt.internal.compiler.util.Util;
46
47 public class Parser implements ParserBasicInformation, TerminalTokens, OperatorIds, TypeIds {
48     protected static final int THIS_CALL = ExplicitConstructorCall.This;
49     protected static final int SUPER_CALL = ExplicitConstructorCall.Super;
50
51     public static char asb[] = null;
52     public static char asr[] = null;
53     //ast stack
54
protected final static int AstStackIncrement = 100;
55     public static char base_action[] = null;
56     public static final int BracketKinds = 3;
57     
58     public static short check_table[] = null;
59     public static final int CurlyBracket = 2;
60     private static final boolean DEBUG = false;
61     private static final boolean DEBUG_AUTOMATON = false;
62     private static final String JavaDoc EOF_TOKEN = "$eof" ; //$NON-NLS-1$
63
private static final String JavaDoc ERROR_TOKEN = "$error" ; //$NON-NLS-1$
64
//expression stack
65
protected final static int ExpressionStackIncrement = 100;
66
67     protected final static int GenericsStackIncrement = 10;
68     
69     private final static String JavaDoc FILEPREFIX = "parser"; //$NON-NLS-1$
70
public static char in_symb[] = null;
71     private static final String JavaDoc INVALID_CHARACTER = "Invalid Character" ; //$NON-NLS-1$
72
public static char lhs[] = null;
73
74     public static String JavaDoc name[] = null;
75     public static char nasb[] = null;
76     public static char nasr[] = null;
77     public static char non_terminal_index[] = null;
78     private final static String JavaDoc READABLE_NAMES_FILE = "readableNames"; //$NON-NLS-1$
79
private final static String JavaDoc READABLE_NAMES_FILE_NAME =
80         "org.eclipse.jdt.internal.compiler.parser." + READABLE_NAMES_FILE; //$NON-NLS-1$
81
public static String JavaDoc readableName[] = null;
82     
83     public static byte rhs[] = null;
84     
85     public static int[] reverse_index = null;
86     public static char[] recovery_templates_index = null;
87     public static char[] recovery_templates = null;
88     public static char[] statements_recovery_filter = null;
89     
90     public static long rules_compliance[] = null;
91     
92     public static final int RoundBracket = 0;
93     
94     public static byte scope_la[] = null;
95     public static char scope_lhs[] = null;
96     
97     public static char scope_prefix[] = null;
98     public static char scope_rhs[] = null;
99     public static char scope_state[] = null;
100
101     public static char scope_state_set[] = null;
102     public static char scope_suffix[] = null;
103     public static final int SquareBracket = 1;
104         
105     //internal data for the automat
106
protected final static int StackIncrement = 255;
107     
108     public static char term_action[] = null;
109     public static byte term_check[] = null;
110
111     public static char terminal_index[] = null;
112
113     private static final String JavaDoc UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
114
public static boolean VERBOSE_RECOVERY = false;
115
116
117
118     protected int astLengthPtr;
119     protected int[] astLengthStack;
120     protected int astPtr;
121     protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
122     public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
123     protected RecoveredElement currentElement;
124     public int currentToken;
125     protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
126
protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
127
protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
128
protected int endStatementPosition;
129     protected int expressionLengthPtr;
130     protected int[] expressionLengthStack;
131     protected int expressionPtr;
132     protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
133     public int firstToken ; // handle for multiple parsing goals
134

135     // generics management
136
protected int genericsIdentifiersLengthPtr;
137     protected int[] genericsIdentifiersLengthStack = new int[GenericsStackIncrement];
138     protected int genericsLengthPtr;
139     protected int[] genericsLengthStack = new int[GenericsStackIncrement];
140     protected int genericsPtr;
141     protected ASTNode[] genericsStack = new ASTNode[GenericsStackIncrement];
142     
143     protected boolean hasError;
144     protected boolean hasReportedError;
145
146     //identifiers stacks
147
protected int identifierLengthPtr;
148     protected int[] identifierLengthStack;
149     protected long[] identifierPositionStack;
150     protected int identifierPtr;
151     protected char[][] identifierStack;
152     
153     protected boolean ignoreNextOpeningBrace;
154     //positions , dimensions , .... (int stacks)
155
protected int intPtr;
156     protected int[] intStack;
157     public int lastAct ; //handle for multiple parsing goals
158

159     //error recovery management
160
protected int lastCheckPoint;
161     protected int lastErrorEndPosition;
162     protected int lastErrorEndPositionBeforeRecovery = -1;
163     protected int lastIgnoredToken, nextIgnoredToken;
164     protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
165
protected int listTypeParameterLength; // for recovering some incomplete list (type parameters)
166
protected int lParenPos,rParenPos; //accurate only when used !
167
protected int modifiers;
168     protected int modifiersSourceStart;
169     protected int[] nestedMethod; //the ptr is nestedType
170
protected int nestedType, dimensions;
171     ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
172     Expression [] noExpressions = new Expression[ExpressionStackIncrement];
173     //modifiers dimensions nestedType etc.......
174
protected boolean optimizeStringLiterals =true;
175     protected CompilerOptions options;
176     protected ProblemReporter problemReporter;
177     protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
178
protected int realBlockPtr;
179     protected int[] realBlockStack;
180     protected int recoveredStaticInitializerStart;
181     public ReferenceContext referenceContext;
182     public boolean reportOnlyOneSyntaxError = false;
183     public boolean reportSyntaxErrorIsRequired = true;
184     protected boolean restartRecovery;
185     
186     // statement recovery
187
// public boolean statementRecoveryEnabled = true;
188
public boolean methodRecoveryActivated = false;
189     protected boolean statementRecoveryActivated = false;
190     protected TypeDeclaration[] recoveredTypes;
191     protected int recoveredTypePtr;
192     protected int nextTypeStart;
193     protected TypeDeclaration pendingRecoveredType;
194     
195     public RecoveryScanner recoveryScanner;
196     
197     //scanner token
198
public Scanner scanner;
199     protected int[] stack = new int[StackIncrement];
200     protected int stateStackTop;
201     protected int synchronizedBlockSourceStart;
202     protected int[] variablesCounter;
203
204     protected boolean checkExternalizeStrings;
205     protected boolean recordStringLiterals;
206     
207     // javadoc
208
public Javadoc javadoc;
209     public JavadocParser javadocParser;
210     // used for recovery
211
protected int lastJavadocEnd;
212     
213     static {
214         try{
215             initTables();
216         } catch(java.io.IOException JavaDoc ex){
217             throw new ExceptionInInitializerError JavaDoc(ex.getMessage());
218         }
219     }
220 public static int asi(int state) {
221
222     return asb[original_state(state)];
223 }
224 public final static short base_check(int i) {
225     return check_table[i - (NUM_RULES + 1)];
226 }
227 private final static void buildFile(String JavaDoc filename, List JavaDoc listToDump) {
228     BufferedWriter writer = null;
229     try {
230         writer = new BufferedWriter(new FileWriter(filename));
231         for (Iterator JavaDoc iterator = listToDump.iterator(); iterator.hasNext(); ) {
232             writer.write(String.valueOf(iterator.next()));
233         }
234         writer.flush();
235     } catch(IOException e) {
236         // ignore
237
} finally {
238         if (writer != null) {
239             try {
240                 writer.close();
241             } catch (IOException e1) {
242                 // ignore
243
}
244         }
245     }
246     System.out.println(filename + " creation complete"); //$NON-NLS-1$
247
}
248 private final static String JavaDoc[] buildFileForName(String JavaDoc filename, String JavaDoc contents) {
249     String JavaDoc[] result = new String JavaDoc[contents.length()];
250     result[0] = null;
251     int resultCount = 1;
252     
253     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
254     
255     int start = contents.indexOf("name[]"); //$NON-NLS-1$
256
start = contents.indexOf('\"', start);
257     int end = contents.indexOf("};", start); //$NON-NLS-1$
258

259     contents = contents.substring(start, end);
260     
261     boolean addLineSeparator = false;
262     int tokenStart = -1;
263     StringBuffer JavaDoc currentToken = new StringBuffer JavaDoc();
264     for (int i = 0; i < contents.length(); i++) {
265         char c = contents.charAt(i);
266         if(c == '\"') {
267             if(tokenStart == -1) {
268                 tokenStart = i + 1;
269             } else {
270                 if(addLineSeparator) {
271                     buffer.append('\n');
272                     result[resultCount++] = currentToken.toString();
273                     currentToken = new StringBuffer JavaDoc();
274                 }
275                 String JavaDoc token = contents.substring(tokenStart, i);
276                 if(token.equals(ERROR_TOKEN)){
277                     token = INVALID_CHARACTER;
278                 } else if(token.equals(EOF_TOKEN)) {
279                     token = UNEXPECTED_EOF;
280                 }
281                 buffer.append(token);
282                 currentToken.append(token);
283                 addLineSeparator = true;
284                 tokenStart = -1;
285             }
286         }
287         if(tokenStart == -1 && c == '+'){
288             addLineSeparator = false;
289         }
290     }
291     if(currentToken.length() > 0) {
292         result[resultCount++] = currentToken.toString();
293     }
294     
295     buildFileForTable(filename, buffer.toString().toCharArray());
296     
297     System.arraycopy(result, 0, result = new String JavaDoc[resultCount], 0, resultCount);
298     return result;
299 }
300 private static void buildFileForReadableName(
301     String JavaDoc file,
302     char[] newLhs,
303     char[] newNonTerminalIndex,
304     String JavaDoc[] newName,
305     String JavaDoc[] tokens) {
306
307     ArrayList JavaDoc entries = new ArrayList JavaDoc();
308     
309     boolean[] alreadyAdded = new boolean[newName.length];
310     
311     for (int i = 0; i < tokens.length; i = i + 3) {
312         if("1".equals(tokens[i])) { //$NON-NLS-1$
313
int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i + 1])]];
314             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
315             if(!alreadyAdded[index]) {
316                 alreadyAdded[index] = true;
317                 buffer.append(newName[index]);
318                 buffer.append('=');
319                 buffer.append(tokens[i+2].trim());
320                 buffer.append('\n');
321                 entries.add(String.valueOf(buffer));
322             }
323         }
324     }
325     int i = 1;
326     while(!INVALID_CHARACTER.equals(newName[i])) i++;
327     i++;
328     for (; i < alreadyAdded.length; i++) {
329         if(!alreadyAdded[i]) {
330             System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
331
}
332     }
333     Collections.sort(entries);
334     buildFile(file, entries);
335 }
336 private static void buildFilesForRecoveryTemplates(
337     String JavaDoc indexFilename,
338     String JavaDoc templatesFilename,
339     char[] newTerminalIndex,
340     char[] newNonTerminalIndex,
341     String JavaDoc[] newName,
342     char[] newLhs,
343     String JavaDoc[] tokens) {
344     
345     int[] newReverse = computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName);
346     
347     char[] newRecoveyTemplatesIndex = new char[newNonTerminalIndex.length];
348     char[] newRecoveyTemplates = new char[newNonTerminalIndex.length];
349     int newRecoveyTemplatesPtr = 0;
350     
351     for (int i = 0; i < tokens.length; i = i + 3) {
352         if("3".equals(tokens[i])) { //$NON-NLS-1$
353
int length = newRecoveyTemplates.length;
354             if(length == newRecoveyTemplatesPtr + 1) {
355                 System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
356             }
357             newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
358             
359             int index = newLhs[Integer.parseInt(tokens[i + 1])];
360             
361             newRecoveyTemplatesIndex[index] = (char)newRecoveyTemplatesPtr;
362             
363             String JavaDoc token = tokens[i + 2].trim();
364             java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(new String JavaDoc(token), " "); //$NON-NLS-1$
365
String JavaDoc[] terminalNames = new String JavaDoc[st.countTokens()];
366             int t = 0;
367             while (st.hasMoreTokens()) {
368                 terminalNames[t++] = st.nextToken();
369             }
370             
371             for (int j = 0; j < terminalNames.length; j++) {
372                 int symbol = getSymbol(terminalNames[j], newName, newReverse);
373                 if(symbol > -1) {
374                     length = newRecoveyTemplates.length;
375                     if(length == newRecoveyTemplatesPtr + 1) {
376                         System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
377                     }
378                     newRecoveyTemplates[newRecoveyTemplatesPtr++] = (char)symbol;
379                 }
380             }
381         }
382     }
383     newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
384     System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr);
385     
386     buildFileForTable(indexFilename, newRecoveyTemplatesIndex);
387     buildFileForTable(templatesFilename, newRecoveyTemplates);
388 }
389 private static void buildFilesForStatementsRecoveryFilter(
390         String JavaDoc filename,
391         char[] newNonTerminalIndex,
392         char[] newLhs,
393         String JavaDoc[] tokens) {
394         
395         char[] newStatementsRecoveryFilter = new char[newNonTerminalIndex.length];
396         
397         for (int i = 0; i < tokens.length; i = i + 3) {
398             if("4".equals(tokens[i])) { //$NON-NLS-1$
399
int index = newLhs[Integer.parseInt(tokens[i + 1])];
400                 
401                 newStatementsRecoveryFilter[index] = 1;
402             }
403         }
404         buildFileForTable(filename, newStatementsRecoveryFilter);
405     }
406 private static void buildFileForCompliance(
407         String JavaDoc file,
408         int length,
409         String JavaDoc[] tokens) {
410
411         byte[] result = new byte[length * 8];
412         
413         for (int i = 0; i < tokens.length; i = i + 3) {
414             if("2".equals(tokens[i])) { //$NON-NLS-1$
415
int index = Integer.parseInt(tokens[i + 1]);
416                 String JavaDoc token = tokens[i + 2].trim();
417                 long compliance = 0;
418                 if("1.4".equals(token)) { //$NON-NLS-1$
419
compliance = ClassFileConstants.JDK1_4;
420                 } else if("1.5".equals(token)) { //$NON-NLS-1$
421
compliance = ClassFileConstants.JDK1_5;
422                 } else if("recovery".equals(token)) { //$NON-NLS-1$
423
compliance = ClassFileConstants.JDK_DEFERRED;
424                 }
425                 
426                 int j = index * 8;
427                 result[j] = (byte)(compliance >>> 56);
428                 result[j + 1] = (byte)(compliance >>> 48);
429                 result[j + 2] = (byte)(compliance >>> 40);
430                 result[j + 3] = (byte)(compliance >>> 32);
431                 result[j + 4] = (byte)(compliance >>> 24);
432                 result[j + 5] = (byte)(compliance >>> 16);
433                 result[j + 6] = (byte)(compliance >>> 8);
434                 result[j + 7] = (byte)(compliance);
435             }
436         }
437
438         buildFileForTable(file, result);
439     }
440 private final static void buildFileForTable(String JavaDoc filename, byte[] bytes) {
441     java.io.FileOutputStream JavaDoc stream = null;
442     try {
443         stream = new java.io.FileOutputStream JavaDoc(filename);
444         stream.write(bytes);
445     } catch(IOException e) {
446         // ignore
447
} finally {
448         if (stream != null) {
449             try {
450                 stream.close();
451             } catch (IOException e) {
452                 // ignore
453
}
454         }
455     }
456     System.out.println(filename + " creation complete"); //$NON-NLS-1$
457
}
458 private final static void buildFileForTable(String JavaDoc filename, char[] chars) {
459     byte[] bytes = new byte[chars.length * 2];
460     for (int i = 0; i < chars.length; i++) {
461         bytes[2 * i] = (byte) (chars[i] >>> 8);
462         bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
463     }
464
465     java.io.FileOutputStream JavaDoc stream = null;
466     try {
467         stream = new java.io.FileOutputStream JavaDoc(filename);
468         stream.write(bytes);
469     } catch(IOException e) {
470         // ignore
471
} finally {
472         if (stream != null) {
473             try {
474                 stream.close();
475             } catch (IOException e) {
476                 // ignore
477
}
478         }
479     }
480     System.out.println(filename + " creation complete"); //$NON-NLS-1$
481
}
482 private final static byte[] buildFileOfByteFor(String JavaDoc filename, String JavaDoc tag, String JavaDoc[] tokens) {
483
484     //transform the String tokens into chars before dumping then into file
485

486     int i = 0;
487     //read upto the tag
488
while (!tokens[i++].equals(tag)){/*empty*/}
489     //read upto the }
490

491     byte[] bytes = new byte[tokens.length]; //can't be bigger
492
int ic = 0;
493     String JavaDoc token;
494     while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
495
int c = Integer.parseInt(token);
496         bytes[ic++] = (byte) c;
497     }
498
499     //resize
500
System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
501
502     buildFileForTable(filename, bytes);
503     return bytes;
504 }
505 private final static char[] buildFileOfIntFor(String JavaDoc filename, String JavaDoc tag, String JavaDoc[] tokens) {
506
507     //transform the String tokens into chars before dumping then into file
508

509     int i = 0;
510     //read upto the tag
511
while (!tokens[i++].equals(tag)){/*empty*/}
512     //read upto the }
513

514     char[] chars = new char[tokens.length]; //can't be bigger
515
int ic = 0;
516     String JavaDoc token;
517     while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
518
int c = Integer.parseInt(token);
519         chars[ic++] = (char) c;
520     }
521
522     //resize
523
System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
524
525     buildFileForTable(filename, chars);
526     return chars;
527 }
528 private final static void buildFileOfShortFor(String JavaDoc filename, String JavaDoc tag, String JavaDoc[] tokens) {
529
530     //transform the String tokens into chars before dumping then into file
531

532     int i = 0;
533     //read upto the tag
534
while (!tokens[i++].equals(tag)){/*empty*/}
535     //read upto the }
536

537     char[] chars = new char[tokens.length]; //can't be bigger
538
int ic = 0;
539     String JavaDoc token;
540     while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
541
int c = Integer.parseInt(token);
542         chars[ic++] = (char) (c + 32768);
543     }
544
545     //resize
546
System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
547
548     buildFileForTable(filename, chars);
549 }
550 public final static void buildFilesFromLPG(String JavaDoc dataFilename, String JavaDoc dataFilename2) {
551
552     //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
553

554     //build from the lpg javadcl.java files that represents the parser tables
555
//lhs check_table asb asr symbol_index
556

557     //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
558
char[] contents = CharOperation.NO_CHAR;
559     try {
560         contents = Util.getFileCharContent(new File(dataFilename), null);
561     } catch (IOException ex) {
562         System.out.println(Messages.parser_incorrectPath);
563         return;
564     }
565     java.util.StringTokenizer JavaDoc st =
566         new java.util.StringTokenizer JavaDoc(new String JavaDoc(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
567
String JavaDoc[] tokens = new String JavaDoc[st.countTokens()];
568     int j = 0;
569     while (st.hasMoreTokens()) {
570         tokens[j++] = st.nextToken();
571     }
572     final String JavaDoc prefix = FILEPREFIX;
573     int i = 0;
574     
575     char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
576
buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
577
buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
578
buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
579
buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
580
buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
581
char[] newTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
582
char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
583
buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
584

585     buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
586
buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
587
buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
588
buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
589
buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
590
buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
591
buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
592

593     byte[] newRhs = buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
594
buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
595
buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
596

597     String JavaDoc[] newName = buildFileForName(prefix + (++i) + ".rsc", new String JavaDoc(contents)); //$NON-NLS-1$
598

599     contents = CharOperation.NO_CHAR;
600     try {
601         contents = Util.getFileCharContent(new File(dataFilename2), null);
602     } catch (IOException ex) {
603         System.out.println(Messages.parser_incorrectPath);
604         return;
605     }
606     st = new java.util.StringTokenizer JavaDoc(new String JavaDoc(contents), "\t\n\r#"); //$NON-NLS-1$
607
tokens = new String JavaDoc[st.countTokens()];
608     j = 0;
609     while (st.hasMoreTokens()) {
610         tokens[j++] = st.nextToken();
611     }
612     
613     buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
614
buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
615

616     buildFilesForRecoveryTemplates(
617             prefix + (++i) + ".rsc", //$NON-NLS-1$
618
prefix + (++i) + ".rsc", //$NON-NLS-1$
619
newTerminalIndex,
620             newNonTerminalIndex,
621             newName,
622             newLhs,
623             tokens);
624     
625     buildFilesForStatementsRecoveryFilter(
626             prefix + (++i) + ".rsc", //$NON-NLS-1$
627
newNonTerminalIndex,
628             newLhs,
629             tokens);
630
631     
632     System.out.println(Messages.parser_moveFiles);
633 }
634 public static int in_symbol(int state) {
635     return in_symb[original_state(state)];
636 }
637 public final static void initTables() throws java.io.IOException JavaDoc {
638
639     final String JavaDoc prefix = FILEPREFIX;
640     int i = 0;
641     lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
642
char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
643
check_table = new short[chars.length];
644     for (int c = chars.length; c-- > 0;) {
645         check_table[c] = (short) (chars[c] - 32768);
646     }
647     asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
648
asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
649
nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
650
nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
651
terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
652
non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
653
term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
654

655     scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
656
scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
657
scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
658
scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
659
scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
660
scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
661
in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
662

663     rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
664
term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
665
scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
666

667     name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
668

669     rules_compliance = readLongTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
670

671     readableName = readReadableNameTable(READABLE_NAMES_FILE_NAME);
672     
673     reverse_index = computeReverseTable(terminal_index, non_terminal_index, name);
674     
675     recovery_templates_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
676
recovery_templates = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
677

678     statements_recovery_filter = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
679

680     base_action = lhs;
681 }
682 public static int nasi(int state) {
683     return nasb[original_state(state)];
684 }
685 public static int ntAction(int state, int sym) {
686     return base_action[state + sym];
687 }
688 protected static int original_state(int state) {
689     return -base_check(state);
690 }
691 protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String JavaDoc[] newName) {
692     int[] newReverseTable = new int[newName.length];
693     for (int j = 0; j < newName.length; j++) {
694         found : {
695             for (int k = 0; k < newTerminalIndex.length; k++) {
696                 if(newTerminalIndex[k] == j) {
697                     newReverseTable[j] = k;
698                     break found;
699                 }
700             }
701             for (int k = 0; k < newNonTerminalIndex.length; k++) {
702                 if(newNonTerminalIndex[k] == j) {
703                     newReverseTable[j] = -k;
704                     break found;
705                 }
706             }
707         }
708     }
709     return newReverseTable;
710 }
711
712 private static int getSymbol(String JavaDoc terminalName, String JavaDoc[] newName, int[] newReverse) {
713     for (int j = 0; j < newName.length; j++) {
714         if(terminalName.equals(newName[j])) {
715             return newReverse[j];
716         }
717     }
718     return -1;
719 }
720
721 protected static byte[] readByteTable(String JavaDoc filename) throws java.io.IOException JavaDoc {
722
723     //files are located at Parser.class directory
724

725     InputStream stream = Parser.class.getResourceAsStream(filename);
726     if (stream == null) {
727         throw new java.io.IOException JavaDoc(Messages.bind(Messages.parser_missingFile, filename));
728     }
729     byte[] bytes = null;
730     try {
731         stream = new BufferedInputStream(stream);
732         bytes = Util.getInputStreamAsByteArray(stream, -1);
733     } finally {
734         try {
735             stream.close();
736         } catch (IOException e) {
737             // ignore
738
}
739     }
740     return bytes;
741 }
742     
743 protected static String JavaDoc[] readNameTable(String JavaDoc filename) throws java.io.IOException JavaDoc {
744     char[] contents = readTable(filename);
745     char[][] nameAsChar = CharOperation.splitOn('\n', contents);
746
747     String JavaDoc[] result = new String JavaDoc[nameAsChar.length + 1];
748     result[0] = null;
749     for (int i = 0; i < nameAsChar.length; i++) {
750         result[i + 1] = new String JavaDoc(nameAsChar[i]);
751     }
752     
753     return result;
754 }
755 protected static String JavaDoc[] readReadableNameTable(String JavaDoc filename) {
756     String JavaDoc[] result = new String JavaDoc[name.length];
757
758     ResourceBundle JavaDoc bundle;
759     try {
760         bundle = ResourceBundle.getBundle(filename, Locale.getDefault());
761     } catch(MissingResourceException JavaDoc e) {
762         System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
763
throw e;
764     }
765     for (int i = 0; i < NT_OFFSET + 1; i++) {
766         result[i] = name[i];
767     }
768     for (int i = NT_OFFSET; i < name.length; i++) {
769         try {
770             String JavaDoc n = bundle.getString(name[i]);
771             if(n != null && n.length() > 0) {
772                 result[i] = n;
773             } else {
774                 result[i] = name[i];
775             }
776         } catch(MissingResourceException JavaDoc e) {
777             result[i] = name[i];
778         }
779     }
780     return result;
781 }
782 protected static char[] readTable(String JavaDoc filename) throws java.io.IOException JavaDoc {
783
784     //files are located at Parser.class directory
785

786     InputStream stream = Parser.class.getResourceAsStream(filename);
787     if (stream == null) {
788         throw new java.io.IOException JavaDoc(Messages.bind(Messages.parser_missingFile, filename));
789     }
790     byte[] bytes = null;
791     try {
792         stream = new BufferedInputStream(stream);
793         bytes = Util.getInputStreamAsByteArray(stream, -1);
794     } finally {
795         try {
796             stream.close();
797         } catch (IOException e) {
798             // ignore
799
}
800     }
801
802     //minimal integrity check (even size expected)
803
int length = bytes.length;
804     if ((length & 1) != 0)
805         throw new java.io.IOException JavaDoc(Messages.bind(Messages.parser_corruptedFile, filename));
806
807     // convert bytes into chars
808
char[] chars = new char[length / 2];
809     int i = 0;
810     int charIndex = 0;
811
812     while (true) {
813         chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
814         if (i == length)
815             break;
816     }
817     return chars;
818 }
819 protected static long[] readLongTable(String JavaDoc filename) throws java.io.IOException JavaDoc {
820
821     //files are located at Parser.class directory
822

823     InputStream stream = Parser.class.getResourceAsStream(filename);
824     if (stream == null) {
825         throw new java.io.IOException JavaDoc(Messages.bind(Messages.parser_missingFile, filename));
826     }
827     byte[] bytes = null;
828     try {
829         stream = new BufferedInputStream(stream);
830         bytes = Util.getInputStreamAsByteArray(stream, -1);
831     } finally {
832         try {
833             stream.close();
834         } catch (IOException e) {
835             // ignore
836
}
837     }
838
839     //minimal integrity check (even size expected)
840
int length = bytes.length;
841     if (length % 8 != 0)
842         throw new java.io.IOException JavaDoc(Messages.bind(Messages.parser_corruptedFile, filename));
843
844     // convert bytes into longs
845
long[] longs = new long[length / 8];
846     int i = 0;
847     int longIndex = 0;
848
849     while (true) {
850         longs[longIndex++] =
851           (((long) (bytes[i++] & 0xFF)) << 56)
852         + (((long) (bytes[i++] & 0xFF)) << 48)
853         + (((long) (bytes[i++] & 0xFF)) << 40)
854         + (((long) (bytes[i++] & 0xFF)) << 32)
855         + (((long) (bytes[i++] & 0xFF)) << 24)
856         + (((long) (bytes[i++] & 0xFF)) << 16)
857         + (((long) (bytes[i++] & 0xFF)) << 8)
858         + (bytes[i++] & 0xFF);
859         
860         if (i == length)
861             break;
862     }
863     return longs;
864 }
865 public static int tAction(int state, int sym) {
866     return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
867 }
868
869 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
870         
871     this.problemReporter = problemReporter;
872     this.options = problemReporter.options;
873     this.optimizeStringLiterals = optimizeStringLiterals;
874     this.initializeScanner();
875     this.astLengthStack = new int[50];
876     this.expressionLengthStack = new int[30];
877     this.intStack = new int[50];
878     this.identifierStack = new char[30][];
879     this.identifierLengthStack = new int[30];
880     this.nestedMethod = new int[30];
881     this.realBlockStack = new int[30];
882     this.identifierPositionStack = new long[30];
883     this.variablesCounter = new int[30];
884     
885     // javadoc support
886
this.javadocParser = createJavadocParser();
887 }
888 protected void annotationRecoveryCheckPoint(int start, int end) {
889     if(this.lastCheckPoint > start && this.lastCheckPoint < end) {
890         this.lastCheckPoint = end + 1;
891     }
892 }
893 public void arrayInitializer(int length) {
894     //length is the size of the array Initializer
895
//expressionPtr points on the last elt of the arrayInitializer,
896
// in other words, it has not been decremented yet.
897

898     ArrayInitializer ai = new ArrayInitializer();
899     if (length != 0) {
900         this.expressionPtr -= length;
901         System.arraycopy(this.expressionStack, this.expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
902     }
903     pushOnExpressionStack(ai);
904     //positionning
905
ai.sourceEnd = this.endStatementPosition;
906     ai.sourceStart = this.intStack[this.intPtr--];
907 }
908 protected void blockReal() {
909     // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
910
// increment the amount of declared variables for this block
911
this.realBlockStack[this.realBlockPtr]++;
912 }
913 /*
914  * Build initial recovery state.
915  * Recovery state is inferred from the current state of the parser (reduced node stack).
916  */

917 public RecoveredElement buildInitialRecoveryState(){
918
919     /* initialize recovery by retrieving available reduced nodes
920      * also rebuild bracket balance
921      */

922     this.lastCheckPoint = 0;
923     this.lastErrorEndPositionBeforeRecovery = this.scanner.currentPosition;
924
925     RecoveredElement element = null;
926     if (this.referenceContext instanceof CompilationUnitDeclaration){
927         element = new RecoveredUnit(this.compilationUnit, 0, this);
928         
929         /* ignore current stack state, since restarting from the beginnning
930            since could not trust simple brace count */

931         if (true){ // experimenting restart recovery from scratch
932
this.compilationUnit.currentPackage = null;
933             this.compilationUnit.imports = null;
934             this.compilationUnit.types = null;
935             this.currentToken = 0;
936             this.listLength = 0;
937             this.listTypeParameterLength = 0;
938             this.endPosition = 0;
939             this.endStatementPosition = 0;
940             return element;
941         }
942         if (this.compilationUnit.currentPackage != null){
943             this.lastCheckPoint = this.compilationUnit.currentPackage.declarationSourceEnd+1;
944         }
945         if (this.compilationUnit.imports != null){
946             this.lastCheckPoint = this.compilationUnit.imports[this.compilationUnit.imports.length -1].declarationSourceEnd+1;
947         }
948     } else {
949         if (this.referenceContext instanceof AbstractMethodDeclaration){
950             element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
951             this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
952             if(this.statementRecoveryActivated) {
953                 element = element.add(new Block(0), 0);
954             }
955         } else {
956             /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
957             if (this.referenceContext instanceof TypeDeclaration){
958                 TypeDeclaration type = (TypeDeclaration) this.referenceContext;
959                 for (int i = 0; i < type.fields.length; i++){
960                     FieldDeclaration field = type.fields[i];
961                     if (field != null
962                         && field.getKind() == AbstractVariableDeclaration.INITIALIZER
963                         && field.declarationSourceStart <= this.scanner.initialPosition
964                         && this.scanner.initialPosition <= field.declarationSourceEnd
965                         && this.scanner.eofPosition <= field.declarationSourceEnd+1){
966                         element = new RecoveredInitializer(field, null, 1, this);
967                         this.lastCheckPoint = field.declarationSourceStart;
968                         break;
969                     }
970                 }
971             }
972         }
973     }
974
975     if (element == null) return element;
976     
977     for(int i = 0; i <= this.astPtr; i++){
978         ASTNode node = this.astStack[i];
979         if (node instanceof AbstractMethodDeclaration){
980             AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
981             if (method.declarationSourceEnd == 0){
982                 element = element.add(method, 0);
983                 this.lastCheckPoint = method.bodyStart;
984             } else {
985                 element = element.add(method, 0);
986                 this.lastCheckPoint = method.declarationSourceEnd + 1;
987             }
988             continue;
989         }
990         if (node instanceof Initializer){
991             Initializer initializer = (Initializer) node;
992             if (initializer.declarationSourceEnd == 0){
993                 element = element.add(initializer, 1);
994                 this.lastCheckPoint = initializer.sourceStart;
995             } else {
996                 element = element.add(initializer, 0);
997                 this.lastCheckPoint = initializer.declarationSourceEnd + 1;
998             }
999             continue;
1000        }
1001        if (node instanceof FieldDeclaration){
1002            FieldDeclaration field = (FieldDeclaration) node;
1003            if (field.declarationSourceEnd == 0){
1004                element = element.add(field, 0);
1005                if (field.initialization == null){
1006                    this.lastCheckPoint = field.sourceEnd + 1;
1007                } else {
1008                    this.lastCheckPoint = field.initialization.sourceEnd + 1;
1009                }
1010            } else {
1011                element = element.add(field, 0);
1012                this.lastCheckPoint = field.declarationSourceEnd + 1;
1013            }
1014            continue;
1015        }
1016        if (node instanceof TypeDeclaration){
1017            TypeDeclaration type = (TypeDeclaration) node;
1018            if (type.declarationSourceEnd == 0){
1019                element = element.add(type, 0);
1020                this.lastCheckPoint = type.bodyStart;
1021            } else {
1022                element = element.add(type, 0);
1023                this.lastCheckPoint = type.declarationSourceEnd + 1;
1024            }
1025            continue;
1026        }
1027        if (node instanceof ImportReference){
1028            ImportReference importRef = (ImportReference) node;
1029            element = element.add(importRef, 0);
1030            this.lastCheckPoint = importRef.declarationSourceEnd + 1;
1031        }
1032        if(this.statementRecoveryActivated) {
1033            if(node instanceof Block) {
1034                Block block = (Block) node;
1035                element = element.add(block, 0);
1036                this.lastCheckPoint = block.sourceEnd + 1;
1037            } else if(node instanceof LocalDeclaration) {
1038                LocalDeclaration statement = (LocalDeclaration) node;
1039                element = element.add(statement, 0);
1040                this.lastCheckPoint = statement.sourceEnd + 1;
1041            } else if(node instanceof Expression) {
1042                if(node instanceof Assignment ||
1043                        node instanceof PrefixExpression ||
1044                        node instanceof PostfixExpression ||
1045                        node instanceof MessageSend ||
1046                        node instanceof AllocationExpression) {
1047                    // recover only specific expressions
1048
Expression statement = (Expression) node;
1049                    element = element.add(statement, 0);
1050                    if(statement.statementEnd != -1) {
1051                        this.lastCheckPoint = statement.statementEnd + 1;
1052                    } else {
1053                        this.lastCheckPoint = statement.sourceEnd + 1;
1054                    }
1055                }
1056            } else if(node instanceof Statement) {
1057                Statement statement = (Statement) node;
1058                element = element.add(statement, 0);
1059                this.lastCheckPoint = statement.sourceEnd + 1;
1060            }
1061        }
1062    }
1063    
1064    if (this.statementRecoveryActivated) {
1065        if (this.pendingRecoveredType != null &&
1066                this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) {
1067            // Add the pending type to the AST if this type isn't already added in the AST.
1068
element = element.add(this.pendingRecoveredType, 0);
1069            this.lastCheckPoint = this.pendingRecoveredType.declarationSourceEnd + 1;
1070            this.pendingRecoveredType = null;
1071        }
1072    }
1073    return element;
1074}
1075
1076protected void checkAndSetModifiers(int flag){
1077    /*modify the current modifiers buffer.
1078    When the startPosition of the modifiers is 0
1079    it means that the modifier being parsed is the first
1080    of a list of several modifiers. The startPosition
1081    is zeroed when a copy of modifiers-buffer is push
1082    onto the this.astStack. */

1083
1084    if ((this.modifiers & flag) != 0){ // duplicate modifier
1085
this.modifiers |= ExtraCompilerModifiers.AccAlternateModifierProblem;
1086    }
1087    this.modifiers |= flag;
1088            
1089    if (this.modifiersSourceStart < 0) this.modifiersSourceStart = this.scanner.startPosition;
1090}
1091public void checkComment() {
1092
1093    // discard obsolete comments while inside methods or fields initializer (see bug 74369)
1094
if (!(this.diet && this.dietInt==0) && this.scanner.commentPtr >= 0) {
1095        flushCommentsDefinedPriorTo(this.endStatementPosition);
1096    }
1097    
1098    int lastComment = this.scanner.commentPtr;
1099    
1100    if (this.modifiersSourceStart >= 0) {
1101        // eliminate comments located after modifierSourceStart if positionned
1102
while (lastComment >= 0 && this.scanner.commentStarts[lastComment] > this.modifiersSourceStart) lastComment--;
1103    }
1104    if (lastComment >= 0) {
1105        // consider all remaining leading comments to be part of current declaration
1106
this.modifiersSourceStart = this.scanner.commentStarts[0];
1107    
1108        // check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)
1109
while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
1110
if (lastComment >= 0 && this.javadocParser != null) {
1111            int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over,
1112
// do not report problem before last parsed comment while recovering code...
1113
this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
1114            if (this.javadocParser.checkDeprecation(lastComment)) {
1115                checkAndSetModifiers(ClassFileConstants.AccDeprecated);
1116            }
1117            this.javadoc = this.javadocParser.docComment; // null if check javadoc is not activated
1118
if (currentElement == null) this.lastJavadocEnd = commentEnd;
1119        }
1120    }
1121}
1122protected void checkNonNLSAfterBodyEnd(int declarationEnd){
1123    if(this.scanner.currentPosition - 1 <= declarationEnd) {
1124        this.scanner.eofPosition = declarationEnd < Integer.MAX_VALUE ? declarationEnd + 1 : declarationEnd;
1125        try {
1126            while(this.scanner.getNextToken() != TokenNameEOF){/*empty*/}
1127        } catch (InvalidInputException e) {
1128            // Nothing to do
1129
}
1130    }
1131}
1132protected void classInstanceCreation(boolean isQualified) {
1133    // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1134

1135    // ClassBodyopt produces a null item on the astStak if it produces NO class body
1136
// An empty class body produces a 0 on the length stack.....
1137

1138    AllocationExpression alloc;
1139    int length;
1140    if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
1141        && (this.astStack[this.astPtr] == null)) {
1142        //NO ClassBody
1143
this.astPtr--;
1144        if (isQualified) {
1145            alloc = new QualifiedAllocationExpression();
1146        } else {
1147            alloc = new AllocationExpression();
1148        }
1149        alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
1150

1151        if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1152            this.expressionPtr -= length;
1153            System.arraycopy(
1154                this.expressionStack,
1155                this.expressionPtr + 1,
1156                alloc.arguments = new Expression[length],
1157                0,
1158                length);
1159        }
1160        alloc.type = getTypeReference(0);
1161        
1162        //the default constructor with the correct number of argument
1163
//will be created and added by the TC (see createsInternalConstructorWithBinding)
1164
alloc.sourceStart = this.intStack[this.intPtr--];
1165        pushOnExpressionStack(alloc);
1166    } else {
1167        dispatchDeclarationInto(length);
1168        TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
1169        anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
1170        anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
1171        if (anonymousTypeDeclaration.allocation != null) {
1172            anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
1173        }
1174        if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
1175            anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
1176        }
1177        this.astPtr--;
1178        this.astLengthPtr--;
1179
1180        // mark initializers with local type mark if needed
1181
markInitializersWithLocalType(anonymousTypeDeclaration);
1182    }
1183}
1184protected void concatExpressionLists() {
1185    this.expressionLengthStack[--this.expressionLengthPtr]++;
1186}
1187protected void concatGenericsLists() {
1188    this.genericsLengthStack[this.genericsLengthPtr - 1] += this.genericsLengthStack[this.genericsLengthPtr--];
1189}
1190protected void concatNodeLists() {
1191    /*
1192     * This is a case where you have two sublists into the this.astStack that you want
1193     * to merge in one list. There is no action required on the this.astStack. The only
1194     * thing you need to do is merge the two lengths specified on the astStackLength.
1195     * The top two length are for example:
1196     * ... p n
1197     * and you want to result in a list like:
1198     * ... n+p
1199     * This means that the p could be equals to 0 in case there is no astNode pushed
1200     * on the this.astStack.
1201     * Look at the InterfaceMemberDeclarations for an example.
1202     */

1203
1204    this.astLengthStack[this.astLengthPtr - 1] += this.astLengthStack[this.astLengthPtr--];
1205}
1206protected void consumeAdditionalBound() {
1207    pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
1208}
1209protected void consumeAdditionalBound1() {
1210    // nothing to be done.
1211
// The reference type1 is consumed by consumeReferenceType1 method.
1212
}
1213protected void consumeAdditionalBoundList() {
1214    concatGenericsLists();
1215}
1216protected void consumeAdditionalBoundList1() {
1217    concatGenericsLists();
1218}
1219protected void consumeAllocationHeader() {
1220    // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1221

1222    // ClassBodyopt produces a null item on the astStak if it produces NO class body
1223
// An empty class body produces a 0 on the length stack.....
1224

1225    if (this.currentElement == null){
1226        return; // should never occur, this consumeRule is only used in recovery mode
1227
}
1228    if (this.currentToken == TokenNameLBRACE){
1229        // beginning of an anonymous type
1230
TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
1231        anonymousType.name = CharOperation.NO_CHAR;
1232        anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
1233        anonymousType.sourceStart = this.intStack[this.intPtr--];
1234        anonymousType.sourceEnd = this.rParenPos; // closing parenthesis
1235
QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
1236        alloc.type = getTypeReference(0);
1237        alloc.sourceStart = anonymousType.sourceStart;
1238        alloc.sourceEnd = anonymousType.sourceEnd ;
1239        this.lastCheckPoint = anonymousType.bodyStart = this.scanner.currentPosition;
1240        this.currentElement = this.currentElement.add(anonymousType, 0);
1241        this.lastIgnoredToken = -1;
1242        this.currentToken = 0; // opening brace already taken into account
1243
return;
1244    }
1245    this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
1246
this.restartRecovery = true; // request to restart from here on
1247
}
1248protected void consumeAnnotationAsModifier() {
1249    Expression expression = this.expressionStack[this.expressionPtr];
1250    int sourceStart = expression.sourceStart;
1251    if (this.modifiersSourceStart < 0) {
1252        this.modifiersSourceStart = sourceStart;
1253    }
1254}
1255protected void consumeAnnotationName() {
1256    if(this.currentElement != null) {
1257        int start = this.intStack[this.intPtr];
1258        int end = (int) (this.identifierPositionStack[this.identifierPtr] & 0x00000000FFFFFFFFL);
1259        annotationRecoveryCheckPoint(start, end);
1260    }
1261    this.recordStringLiterals = false;
1262}
1263protected void consumeAnnotationTypeDeclaration() {
1264    int length;
1265    if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1266        //there are length declarations
1267
//dispatch according to the type of the declarations
1268
dispatchDeclarationInto(length);
1269    }
1270
1271    TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1272    
1273    // mark initializers with local type mark if needed
1274
markInitializersWithLocalType(typeDecl);
1275
1276    //convert constructor that do not have the type's name into methods
1277
typeDecl.checkConstructors(this);
1278    
1279    //always add <clinit> (will be remove at code gen time if empty)
1280
if (this.scanner.containsAssertKeyword) {
1281        typeDecl.bits |= ASTNode.ContainsAssertion;
1282    }
1283    typeDecl.addClinit();
1284    typeDecl.bodyEnd = this.endStatementPosition;
1285    if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
1286        typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
1287    }
1288    typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1289}
1290protected void consumeAnnotationTypeDeclarationHeader() {
1291    if (this.currentElement != null) {
1292        this.restartRecovery = true; // used to avoid branching back into the regular automaton
1293
}
1294    // flush the comments related to the annotation type header
1295
this.scanner.commentPtr = -1;
1296}
1297protected void consumeAnnotationTypeDeclarationHeaderName() {
1298    // consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier
1299
// consumeAnnotationTypeDeclarationHeader ::= '@' PushModifiers interface Identifier
1300
TypeDeclaration annotationTypeDeclaration = new TypeDeclaration(this.compilationUnit.compilationResult);
1301    if (this.nestedMethod[this.nestedType] == 0) {
1302        if (this.nestedType != 0) {
1303            annotationTypeDeclaration.bits |= ASTNode.IsMemberType;
1304        }
1305    } else {
1306        // Record that the block has a declaration for local types
1307
annotationTypeDeclaration.bits |= ASTNode.IsLocalType;
1308        markEnclosingMemberWithLocalType();
1309        blockReal();
1310    }
1311
1312    //highlight the name of the type
1313
long pos = this.identifierPositionStack[this.identifierPtr];
1314    annotationTypeDeclaration.sourceEnd = (int) pos;
1315    annotationTypeDeclaration.sourceStart = (int) (pos >>> 32);
1316    annotationTypeDeclaration.name = this.identifierStack[this.identifierPtr--];
1317    this.identifierLengthPtr--;
1318
1319    //compute the declaration source too
1320
// 'interface' push two int positions: the beginning of the class token and its end.
1321
// we want to keep the beginning position but get rid of the end position
1322
// it is only used for the ClassLiteralAccess positions.
1323
this.intPtr--; // remove the start position of the interface token
1324
this.intPtr--; // remove the end position of the interface token
1325

1326    annotationTypeDeclaration.modifiersSourceStart = this.intStack[this.intPtr--];
1327    annotationTypeDeclaration.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface;
1328    if (annotationTypeDeclaration.modifiersSourceStart >= 0) {
1329        annotationTypeDeclaration.declarationSourceStart = annotationTypeDeclaration.modifiersSourceStart;
1330        this.intPtr--; // remove the position of the '@' token as we have modifiers
1331
} else {
1332        int atPosition = this.intStack[this.intPtr--];
1333        // remove the position of the '@' token as we don't have modifiers
1334
annotationTypeDeclaration.declarationSourceStart = atPosition;
1335    }
1336
1337    // Store secondary info
1338
if ((annotationTypeDeclaration.bits & ASTNode.IsMemberType) == 0 && (annotationTypeDeclaration.bits & ASTNode.IsLocalType) == 0) {
1339        if (this.compilationUnit != null && !CharOperation.equals(annotationTypeDeclaration.name, this.compilationUnit.getMainTypeName())) {
1340            annotationTypeDeclaration.bits |= ASTNode.IsSecondaryType;
1341        }
1342    }
1343
1344    // consume annotations
1345
int length;
1346    if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1347        System.arraycopy(
1348            this.expressionStack,
1349            (this.expressionPtr -= length) + 1,
1350            annotationTypeDeclaration.annotations = new Annotation[length],
1351            0,
1352            length);
1353    }
1354    annotationTypeDeclaration.bodyStart = annotationTypeDeclaration.sourceEnd + 1;
1355
1356    // javadoc
1357
annotationTypeDeclaration.javadoc = this.javadoc;
1358    this.javadoc = null;
1359    pushOnAstStack(annotationTypeDeclaration);
1360    if(!this.statementRecoveryActivated &&
1361            options.sourceLevel < ClassFileConstants.JDK1_5 &&
1362            this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
1363        this.problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration);
1364    }
1365    
1366    // recovery
1367
if (this.currentElement != null){
1368        this.lastCheckPoint = annotationTypeDeclaration.bodyStart;
1369        this.currentElement = this.currentElement.add(annotationTypeDeclaration, 0);
1370        this.lastIgnoredToken = -1;
1371    }
1372}
1373protected void consumeAnnotationTypeMemberDeclaration() {
1374    // AnnotationTypeMemberDeclaration ::= AnnotationTypeMemberDeclarationHeader AnnotationTypeMemberHeaderExtendedDims DefaultValueopt ';'
1375
AnnotationMethodDeclaration annotationTypeMemberDeclaration = (AnnotationMethodDeclaration) this.astStack[this.astPtr];
1376    annotationTypeMemberDeclaration.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
1377    // store the this.endPosition (position just before the '}') in case there is
1378
// a trailing comment behind the end of the method
1379
int declarationEndPosition = flushCommentsDefinedPriorTo(this.endStatementPosition);
1380    annotationTypeMemberDeclaration.bodyStart = this.endStatementPosition;
1381    annotationTypeMemberDeclaration.bodyEnd = declarationEndPosition;
1382    annotationTypeMemberDeclaration.declarationSourceEnd = declarationEndPosition;
1383}
1384protected void consumeAnnotationTypeMemberDeclarations() {
1385    // AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration
1386
concatNodeLists();
1387}
1388protected void consumeArgumentList() {
1389    // ArgumentList ::= ArgumentList ',' Expression
1390
concatExpressionLists();
1391}
1392protected void consumeArguments() {
1393    // Arguments ::= '(' ArgumentListopt ')'
1394
// nothing to do, the expression stack is already updated
1395
pushOnIntStack(rParenPos);
1396}
1397protected void consumeArrayAccess(boolean unspecifiedReference) {
1398    // ArrayAccess ::= Name '[' Expression ']' ==> true
1399
// ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
1400

1401
1402    //optimize push/pop
1403
Expression exp;
1404    if (unspecifiedReference) {
1405        exp =
1406            this.expressionStack[this.expressionPtr] =
1407                new ArrayReference(
1408                    getUnspecifiedReferenceOptimized(),
1409                    this.expressionStack[this.expressionPtr]);
1410    } else {
1411        this.expressionPtr--;
1412        this.expressionLengthPtr--;
1413        exp =
1414            this.expressionStack[this.expressionPtr] =
1415                new ArrayReference(
1416                    this.expressionStack[this.expressionPtr],
1417                    this.expressionStack[this.expressionPtr + 1]);
1418    }
1419    exp.sourceEnd = this.endStatementPosition;
1420}
1421protected void consumeArrayCreationExpressionWithInitializer() {
1422    // ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer
1423
// ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
1424

1425    int length;
1426    ArrayAllocationExpression arrayAllocation = new ArrayAllocationExpression();
1427    this.expressionLengthPtr -- ;
1428    arrayAllocation.initializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
1429        
1430    arrayAllocation.type = getTypeReference(0);
1431    arrayAllocation.type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
1432
length = (this.expressionLengthStack[this.expressionLengthPtr--]);
1433    this.expressionPtr -= length ;
1434    System.arraycopy(
1435        this.expressionStack,
1436        this.expressionPtr+1,
1437        arrayAllocation.dimensions = new Expression[length],
1438        0,
1439        length);
1440    arrayAllocation.sourceStart = this.intStack[this.intPtr--];
1441    if (arrayAllocation.initializer == null) {
1442        arrayAllocation.sourceEnd = this.endStatementPosition;
1443    } else {
1444        arrayAllocation.sourceEnd = arrayAllocation.initializer.sourceEnd ;
1445    }
1446    pushOnExpressionStack(arrayAllocation);
1447}
1448protected void consumeArrayCreationExpressionWithoutInitializer() {
1449    // ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
1450
// ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
1451

1452    int length;
1453    ArrayAllocationExpression arrayAllocation = new ArrayAllocationExpression();
1454    arrayAllocation.type = getTypeReference(0);
1455    arrayAllocation.type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
1456
length = (this.expressionLengthStack[this.expressionLengthPtr--]);
1457    this.expressionPtr -= length ;
1458    System.arraycopy(
1459        this.expressionStack,
1460        this.expressionPtr+1,
1461        arrayAllocation.dimensions = new Expression[length],
1462        0,
1463        length);
1464    arrayAllocation.sourceStart = this.intStack[this.intPtr--];
1465    if (arrayAllocation.initializer == null) {
1466        arrayAllocation.sourceEnd = this.endStatementPosition;
1467    } else {
1468        arrayAllocation.sourceEnd = arrayAllocation.initializer.sourceEnd ;
1469    }
1470    pushOnExpressionStack(arrayAllocation);
1471}
1472protected void consumeArrayCreationHeader() {
1473    // nothing to do
1474
}
1475protected void consumeArrayInitializer() {
1476    // ArrayInitializer ::= '{' VariableInitializers '}'
1477
// ArrayInitializer ::= '{' VariableInitializers , '}'
1478

1479    arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
1480}
1481protected void consumeArrayTypeWithTypeArgumentsName() {
1482    this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] += this.identifierLengthStack[this.identifierLengthPtr];
1483    pushOnGenericsLengthStack(0); // handle type arguments
1484
}
1485protected void consumeAssertStatement() {
1486    // AssertStatement ::= 'assert' Expression ':' Expression ';'
1487
this.expressionLengthPtr-=2;
1488    pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
1489}
1490protected void consumeAssignment() {
1491    // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
1492
//optimize the push/pop
1493

1494    int op = this.intStack[this.intPtr--] ; //<--the encoded operator
1495

1496    this.expressionPtr -- ; this.expressionLengthPtr -- ;
1497    this.expressionStack[this.expressionPtr] =
1498        (op != EQUAL ) ?
1499            new CompoundAssignment(
1500                this.expressionStack[this.expressionPtr] ,
1501                this.expressionStack[this.expressionPtr+1],
1502                op,
1503                this.scanner.startPosition - 1) :
1504            new Assignment(
1505                this.expressionStack[this.expressionPtr] ,
1506                this.expressionStack[this.expressionPtr+1],
1507                this.scanner.startPosition - 1);
1508                
1509    if (this.pendingRecoveredType != null) {
1510        // Used only in statements recovery.
1511
// This is not a real assignment but a placeholder for an existing anonymous type.
1512
// The assignment must be replace by the anonymous type.
1513
if (this.pendingRecoveredType.allocation != null &&
1514                this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) {
1515            this.expressionStack[this.expressionPtr] = this.pendingRecoveredType.allocation;
1516            this.pendingRecoveredType = null;
1517            return;
1518        }
1519        this.pendingRecoveredType = null;
1520    }
1521}
1522protected void consumeAssignmentOperator(int pos) {
1523    // AssignmentOperator ::= '='
1524
// AssignmentOperator ::= '*='
1525
// AssignmentOperator ::= '/='
1526
// AssignmentOperator ::= '%='
1527
// AssignmentOperator ::= '+='
1528
// AssignmentOperator ::= '-='
1529
// AssignmentOperator ::= '<<='
1530
// AssignmentOperator ::= '>>='
1531
// AssignmentOperator ::= '>>>='
1532
// AssignmentOperator ::= '&='
1533
// AssignmentOperator ::= '^='
1534
// AssignmentOperator ::= '|='
1535

1536    pushOnIntStack(pos);
1537}
1538protected void consumeBinaryExpression(int op) {
1539    // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
1540
// MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
1541
// MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
1542
// AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
1543
// AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
1544
// ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
1545
// ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
1546
// ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
1547
// RelationalExpression ::= RelationalExpression '<' ShiftExpression
1548
// RelationalExpression ::= RelationalExpression '>' ShiftExpression
1549
// RelationalExpression ::= RelationalExpression '<=' ShiftExpression
1550
// RelationalExpression ::= RelationalExpression '>=' ShiftExpression
1551
// AndExpression ::= AndExpression '&' EqualityExpression
1552
// ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
1553
// InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
1554
// ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
1555
// ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
1556

1557    //optimize the push/pop
1558

1559    this.expressionPtr--;
1560    this.expressionLengthPtr--;
1561    Expression expr1 = this.expressionStack[this.expressionPtr];
1562    Expression expr2 = this.expressionStack[this.expressionPtr + 1];
1563    switch(op) {
1564        case OR_OR :
1565            this.expressionStack[this.expressionPtr] =
1566                new OR_OR_Expression(
1567                    expr1,
1568                    expr2,
1569                    op);
1570            break;
1571        case AND_AND :
1572            this.expressionStack[this.expressionPtr] =
1573                new AND_AND_Expression(
1574                    expr1,
1575                    expr2,
1576                    op);
1577            break;
1578        case PLUS :
1579            // look for "string1" + "string2"
1580
if (this.optimizeStringLiterals) {
1581                if (expr1 instanceof StringLiteral) {
1582                    if (expr2 instanceof CharLiteral) { // string+char
1583
this.expressionStack[this.expressionPtr] =
1584                            ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1585                    } else if (expr2 instanceof StringLiteral) { //string+string
1586
this.expressionStack[this.expressionPtr] =
1587                            ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1588                    } else {
1589                        this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1590                    }
1591                } else if (expr1 instanceof CombinedBinaryExpression) {
1592                    CombinedBinaryExpression cursor;
1593                    // left branch is comprised of PLUS BEs
1594
// cursor is shifted upwards, while needed BEs are added
1595
// on demand; past the arityMax-th
1596
// consecutive BE, a CBE is inserted that holds a
1597
// full-fledged references table
1598
if ((cursor = (CombinedBinaryExpression)expr1).arity <
1599                                cursor.arityMax) {
1600                        cursor.left = new BinaryExpression(cursor.left,
1601                                cursor.right, PLUS);
1602                        cursor.arity++;
1603                    } else {
1604                        cursor.left = new CombinedBinaryExpression(cursor.left,
1605                                cursor.right, PLUS, cursor.arity);
1606                        cursor.arity = 0;
1607                        cursor.tuneArityMax();
1608                    }
1609                    cursor.right = expr2;
1610                    cursor.sourceEnd = expr2.sourceEnd;
1611                    this.expressionStack[this.expressionPtr] = cursor;
1612                    // BE_INSTRUMENTATION: neutralized in the released code
1613
// cursor.depthTracker = ((BinaryExpression)cursor.left).
1614
// depthTracker + 1;
1615
} else if (expr1 instanceof BinaryExpression &&
1616                            // single out the a + b case, which is a BE
1617
// instead of a CBE (slightly more than a half of
1618
// strings concatenation are one-deep binary
1619
// expressions)
1620
((expr1.bits & ASTNode.OperatorMASK) >>
1621                            ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
1622                    this.expressionStack[this.expressionPtr] =
1623                        new CombinedBinaryExpression(expr1, expr2, PLUS, 1);
1624                } else {
1625                    this.expressionStack[this.expressionPtr] =
1626                        new BinaryExpression(expr1, expr2, PLUS);
1627                }
1628            } else if (expr1 instanceof StringLiteral) {
1629                if (expr2 instanceof StringLiteral) {
1630                    // string + string
1631
this.expressionStack[this.expressionPtr] =
1632                        ((StringLiteral) expr1).extendsWith((StringLiteral) expr2);
1633                } else {
1634                    // single out the a + b case
1635
this.expressionStack[this.expressionPtr] =
1636                        new BinaryExpression(expr1, expr2, PLUS);
1637                }
1638            } else if (expr1 instanceof CombinedBinaryExpression) {
1639                    CombinedBinaryExpression cursor;
1640                    int numberOfParens = (expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
1641                    // shift cursor; create BE/CBE as needed
1642
if ((cursor = (CombinedBinaryExpression)expr1).arity <
1643                                cursor.arityMax) {
1644                        cursor.left = new BinaryExpression(cursor.left,
1645                                cursor.right, PLUS);
1646                        if (numberOfParens != 0) {
1647                            // clear the bits on cursor and put them back on cursor.left
1648
cursor.bits &= ~ASTNode.ParenthesizedMASK;
1649                            cursor.left.bits &= ~ASTNode.ParenthesizedMASK;
1650                            cursor.left.bits |= numberOfParens << ASTNode.ParenthesizedSHIFT;
1651                        }
1652                        cursor.arity++;
1653                    } else {
1654                        cursor.left = new CombinedBinaryExpression(cursor.left,
1655                                cursor.right, PLUS, cursor.arity);
1656                        if (numberOfParens != 0) {
1657                            // clear the bits on cursor and put them back on cursor.left
1658
cursor.bits &= ~ASTNode.ParenthesizedMASK;
1659                            cursor.left.bits &= ~ASTNode.ParenthesizedMASK;
1660                            cursor.left.bits |= numberOfParens << ASTNode.ParenthesizedSHIFT;
1661                        }
1662                        cursor.arity = 0;
1663                        cursor.tuneArityMax();
1664                    }
1665                    cursor.right = expr2;
1666                    cursor.sourceEnd = expr2.sourceEnd;
1667                    // BE_INSTRUMENTATION: neutralized in the released code
1668
// cursor.depthTracker = ((BinaryExpression)cursor.left).
1669
// depthTracker + 1;
1670
this.expressionStack[this.expressionPtr] = cursor;
1671            } else if (expr1 instanceof BinaryExpression
1672                    && ((expr1.bits & ASTNode.OperatorMASK) >>
1673                            ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
1674                // single out the a + b case
1675
this.expressionStack[this.expressionPtr] =
1676                    new CombinedBinaryExpression(expr1, expr2, PLUS, 1);
1677            } else {
1678                this.expressionStack[this.expressionPtr] =
1679                    new BinaryExpression(expr1, expr2, PLUS);
1680            }
1681            break;
1682        case LESS :
1683            this.intPtr--;
1684            this.expressionStack[this.expressionPtr] =
1685                new BinaryExpression(
1686                    expr1,
1687                    expr2,
1688                    op);
1689            break;
1690        default :
1691            this.expressionStack[this.expressionPtr] =
1692                new BinaryExpression(
1693                    expr1,
1694                    expr2,
1695                    op);
1696    }
1697}
1698/**
1699 * @param op binary operator
1700 */

1701protected void consumeBinaryExpressionWithName(int op) {
1702    pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1703    this.expressionPtr--;
1704    this.expressionLengthPtr--;
1705    /*
1706    if (op == OR_OR) {
1707        this.expressionStack[this.expressionPtr] =
1708            new OR_OR_Expression(
1709                this.expressionStack[this.expressionPtr + 1],
1710                this.expressionStack[this.expressionPtr],
1711                op);
1712    } else {
1713        if (op == AND_AND) {
1714            this.expressionStack[this.expressionPtr] =
1715                new AND_AND_Expression(
1716                    this.expressionStack[this.expressionPtr + 1],
1717                    this.expressionStack[this.expressionPtr],
1718                    op);
1719        } else {
1720            // look for "string1" + "string2"
1721            if ((op == PLUS) && this.optimizeStringLiterals) {
1722                Expression expr1, expr2;
1723                expr1 = this.expressionStack[this.expressionPtr + 1];
1724                expr2 = this.expressionStack[this.expressionPtr];
1725                if (expr1 instanceof StringLiteral) {
1726                    if (expr2 instanceof CharLiteral) { // string+char
1727                        this.expressionStack[this.expressionPtr] =
1728                            ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1729                    } else if (expr2 instanceof StringLiteral) { //string+string
1730                        this.expressionStack[this.expressionPtr] =
1731                            ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1732                    } else {
1733                        this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1734                    }
1735                } else {
1736                    this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1737                }
1738            } else {
1739                this.expressionStack[this.expressionPtr] =
1740                    new BinaryExpression(
1741                        this.expressionStack[this.expressionPtr + 1],
1742                        this.expressionStack[this.expressionPtr],
1743                        op);
1744            }
1745        }
1746    }
1747    */

1748    Expression expr1 = this.expressionStack[this.expressionPtr + 1];
1749    Expression expr2 = this.expressionStack[this.expressionPtr];
1750    // Note: we do not attempt to promote BinaryExpression-s to
1751
// IndexedBinaryExpression-s here since expr1 always holds a name
1752
switch(op) {
1753        case OR_OR :
1754            this.expressionStack[this.expressionPtr] =
1755                new OR_OR_Expression(
1756                    expr1,
1757                    expr2,
1758                    op);
1759            break;
1760        case AND_AND :
1761            this.expressionStack[this.expressionPtr] =
1762                new AND_AND_Expression(
1763                    expr1,
1764                    expr2,
1765                    op);
1766            break;
1767        case PLUS :
1768            // look for "string1" + "string2"
1769
if (this.optimizeStringLiterals) {
1770                if (expr1 instanceof StringLiteral) {
1771                    if (expr2 instanceof CharLiteral) { // string+char
1772
this.expressionStack[this.expressionPtr] =
1773                            ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1774                    } else if (expr2 instanceof StringLiteral) { //string+string
1775
this.expressionStack[this.expressionPtr] =
1776                            ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1777                    } else {
1778                        this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1779                    }
1780                } else {
1781                    this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1782                }
1783            } else if (expr1 instanceof StringLiteral) {
1784                if (expr2 instanceof StringLiteral) {
1785                    // string + string
1786
this.expressionStack[this.expressionPtr] =
1787                        ((StringLiteral) expr1).extendsWith((StringLiteral) expr2);
1788                } else {
1789                    this.expressionStack[this.expressionPtr] =
1790                        new BinaryExpression(
1791                            expr1,
1792                            expr2,
1793                            op);
1794                }
1795            } else {
1796                this.expressionStack[this.expressionPtr] =
1797                    new BinaryExpression(
1798                        expr1,
1799                        expr2,
1800                        op);
1801            }
1802            break;
1803        case LESS :
1804            this.intPtr--;
1805            this.expressionStack[this.expressionPtr] =
1806                new BinaryExpression(
1807                    expr1,
1808                    expr2,
1809                    op);
1810            break;
1811        default :
1812            this.expressionStack[this.expressionPtr] =
1813                new BinaryExpression(
1814                    expr1,
1815                    expr2,
1816                    op);
1817    }
1818}
1819protected void consumeBlock() {
1820    // Block ::= OpenBlock '{' BlockStatementsopt '}'
1821
// simpler action for empty blocks
1822

1823    int statementsLength = this.astLengthStack[this.astLengthPtr--];
1824    Block block;
1825    if (statementsLength == 0) { // empty block
1826
block = new Block(0);
1827        block.sourceStart = this.intStack[this.intPtr--];
1828        block.sourceEnd = this.endStatementPosition;
1829        // check whether this block at least contains some comment in it
1830
if (!containsComment(block.sourceStart, block.sourceEnd)) {
1831            block.bits |= ASTNode.UndocumentedEmptyBlock;
1832        }
1833        this.realBlockPtr--; // still need to pop the block variable counter
1834
} else {
1835        block = new Block(this.realBlockStack[this.realBlockPtr--]);
1836        this.astPtr -= statementsLength;
1837        System.arraycopy(
1838            this.astStack,
1839            this.astPtr + 1,
1840            block.statements = new Statement[statementsLength],
1841            0,
1842            statementsLength);
1843        block.sourceStart = this.intStack[this.intPtr--];
1844        block.sourceEnd = this.endStatementPosition;
1845    }
1846    pushOnAstStack(block);
1847}
1848protected void consumeBlockStatements() {
1849    // BlockStatements ::= BlockStatements BlockStatement
1850
concatNodeLists();
1851}
1852protected void consumeCaseLabel() {
1853    // SwitchLabel ::= 'case' ConstantExpression ':'
1854
this.expressionLengthPtr--;
1855    Expression expression = this.expressionStack[this.expressionPtr--];
1856    pushOnAstStack(new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]));
1857}
1858protected void consumeCastExpressionLL1() {
1859    //CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
1860
// Expression is used in order to make the grammar LL1
1861

1862    //optimize push/pop
1863

1864    Expression cast,exp;
1865    this.expressionPtr--;
1866    this.expressionStack[this.expressionPtr] =
1867        cast = new CastExpression(
1868            exp=this.expressionStack[this.expressionPtr+1] ,
1869            getTypeReference(this.expressionStack[this.expressionPtr]));
1870    this.expressionLengthPtr -- ;
1871    updateSourcePosition(cast);
1872    cast.sourceEnd=exp.sourceEnd;
1873}
1874protected void consumeCastExpressionWithGenericsArray() {
1875    // CastExpression ::= PushLPAREN Name TypeArguments Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1876

1877    Expression exp, cast, castType;
1878    int end = this.intStack[this.intPtr--];
1879
1880    int dim = this.intStack[this.intPtr--];
1881    pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
1882    
1883    this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(dim));
1884    intPtr--;
1885    castType.sourceEnd = end - 1;
1886    castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1887    cast.sourceEnd = exp.sourceEnd;
1888}
1889protected void consumeCastExpressionWithNameArray() {
1890    // CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1891

1892    Expression exp, cast, castType;
1893    int end = this.intStack[this.intPtr--];
1894    
1895    // handle type arguments
1896
pushOnGenericsLengthStack(0);
1897    pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
1898    
1899    this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
1900    castType.sourceEnd = end - 1;
1901    castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1902    cast.sourceEnd = exp.sourceEnd;
1903}
1904protected void consumeCastExpressionWithPrimitiveType() {
1905    // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression
1906

1907    //this.intStack : posOfLeftParen dim posOfRightParen
1908

1909    //optimize the push/pop
1910

1911    Expression exp, cast, castType;
1912    int end = this.intStack[this.intPtr--];
1913    this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
1914    castType.sourceEnd = end - 1;
1915    castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1916    cast.sourceEnd = exp.sourceEnd;
1917}
1918protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim) {
1919    int nameSize = this.identifierLengthStack[this.identifierLengthPtr];
1920    int tokensSize = nameSize;
1921    if (rightSide instanceof ParameterizedSingleTypeReference) {
1922        tokensSize ++;
1923    } else if (rightSide instanceof SingleTypeReference) {
1924        tokensSize ++;
1925    } else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
1926        tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
1927    } else if (rightSide instanceof QualifiedTypeReference) {
1928        tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
1929    }
1930    TypeReference[][] typeArguments = new TypeReference[tokensSize][];
1931    char[][] tokens = new char[tokensSize][];
1932    long[] positions = new long[tokensSize];
1933    if (rightSide instanceof ParameterizedSingleTypeReference) {
1934        ParameterizedSingleTypeReference singleParameterizedTypeReference = (ParameterizedSingleTypeReference) rightSide;
1935        tokens[nameSize] = singleParameterizedTypeReference.token;
1936        positions[nameSize] = (((long) singleParameterizedTypeReference.sourceStart) << 32) + singleParameterizedTypeReference.sourceEnd;
1937        typeArguments[nameSize] = singleParameterizedTypeReference.typeArguments;
1938    } else if (rightSide instanceof SingleTypeReference) {
1939        SingleTypeReference singleTypeReference = (SingleTypeReference) rightSide;
1940        tokens[nameSize] = singleTypeReference.token;
1941        positions[nameSize] = (((long) singleTypeReference.sourceStart) << 32) + singleTypeReference.sourceEnd;
1942    } else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
1943        ParameterizedQualifiedTypeReference parameterizedTypeReference = (ParameterizedQualifiedTypeReference) rightSide;
1944        TypeReference[][] rightSideTypeArguments = parameterizedTypeReference.typeArguments;
1945        System.arraycopy(rightSideTypeArguments, 0, typeArguments, nameSize, rightSideTypeArguments.length);
1946        char[][] rightSideTokens = parameterizedTypeReference.tokens;
1947        System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
1948        long[] rightSidePositions = parameterizedTypeReference.sourcePositions;
1949        System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
1950    } else if (rightSide instanceof QualifiedTypeReference) {
1951        QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) rightSide;
1952        char[][] rightSideTokens = qualifiedTypeReference.tokens;
1953        System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
1954        long[] rightSidePositions = qualifiedTypeReference.sourcePositions;
1955        System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
1956    }
1957
1958    int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
1959    TypeReference[] currentTypeArguments = new TypeReference[currentTypeArgumentsLength];
1960    this.genericsPtr -= currentTypeArgumentsLength;
1961    System.arraycopy(this.genericsStack, this.genericsPtr + 1, currentTypeArguments, 0, currentTypeArgumentsLength);
1962    
1963    if (nameSize == 1) {
1964        tokens[0] = this.identifierStack[this.identifierPtr];
1965        positions[0] = this.identifierPositionStack[this.identifierPtr--];
1966        typeArguments[0] = currentTypeArguments;
1967    } else {
1968        this.identifierPtr -= nameSize;
1969        System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, nameSize);
1970        System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, nameSize);
1971        typeArguments[nameSize - 1] = currentTypeArguments;
1972    }
1973    this.identifierLengthPtr--;
1974    return new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, positions);
1975}
1976protected void consumeCastExpressionWithQualifiedGenericsArray() {
1977    // CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1978
Expression exp, cast, castType;
1979    int end = this.intStack[this.intPtr--];
1980
1981    int dim = this.intStack[this.intPtr--];
1982    TypeReference rightSide = getTypeReference(0);
1983    
1984    ParameterizedQualifiedTypeReference qualifiedParameterizedTypeReference = computeQualifiedGenericsFromRightSide(rightSide, dim);
1985    intPtr--;
1986    this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = qualifiedParameterizedTypeReference);
1987    castType.sourceEnd = end - 1;
1988    castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1989    cast.sourceEnd = exp.sourceEnd;
1990}
1991protected void consumeCatches() {
1992    // Catches ::= Catches CatchClause
1993
optimizedConcatNodeLists();
1994}
1995protected void consumeCatchHeader() {
1996    // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1997

1998    if (this.currentElement == null){
1999        return; // should never occur, this consumeRule is only used in recovery mode
2000
}
2001    // current element should be a block due to the presence of the opening brace
2002
if (!(this.currentElement instanceof RecoveredBlock)){
2003        if(!(this.currentElement instanceof RecoveredMethod)) {
2004            return;
2005        }
2006        RecoveredMethod rMethod = (RecoveredMethod) this.currentElement;
2007        if(!(rMethod.methodBody == null && rMethod.bracketBalance > 0)) {
2008            return;
2009        }
2010    }
2011    
2012    Argument arg = (Argument)this.astStack[this.astPtr--];
2013    // convert argument to local variable
2014
LocalDeclaration localDeclaration = new LocalDeclaration(arg.name, arg.sourceStart, arg.sourceEnd);
2015    localDeclaration.type = arg.type;
2016    localDeclaration.declarationSourceStart = arg.declarationSourceStart;
2017    localDeclaration.declarationSourceEnd = arg.declarationSourceEnd;
2018    
2019    this.currentElement = this.currentElement.add(localDeclaration, 0);
2020    this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
2021
this.restartRecovery = true; // request to restart from here on
2022
this.lastIgnoredToken = -1;
2023}
2024protected void consumeClassBodyDeclaration() {
2025    // ClassBodyDeclaration ::= Diet Block
2026
//push an Initializer
2027
//optimize the push/pop
2028
this.nestedMethod[this.nestedType]--;
2029    Block block = (Block) this.astStack[this.astPtr];
2030    if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlock; // clear bit since was diet
2031
Initializer initializer = new Initializer(block, 0);
2032    this.intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
2033
initializer.bodyStart = this.intStack[this.intPtr--];
2034    this.realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
2035
int javadocCommentStart = this.intStack[this.intPtr--];
2036    if (javadocCommentStart != -1) {
2037        initializer.declarationSourceStart = javadocCommentStart;
2038        initializer.javadoc = this.javadoc;
2039        this.javadoc = null;
2040    }
2041    this.astStack[this.astPtr] = initializer;
2042    initializer.bodyEnd = this.endPosition;
2043    initializer.sourceEnd = this.endStatementPosition;
2044    initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2045}
2046protected void consumeClassBodyDeclarations() {
2047    // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
2048
concatNodeLists();
2049}
2050protected void consumeClassBodyDeclarationsopt() {
2051    // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
2052
this.nestedType-- ;
2053}
2054protected void consumeAnnotationTypeMemberDeclarationsopt() {
2055    this.nestedType-- ;
2056}
2057protected void consumeClassBodyopt() {
2058    // ClassBodyopt ::= $empty
2059
pushOnAstStack(null);
2060    this.endPosition = this.rParenPos;
2061}
2062protected void consumeClassDeclaration() {
2063    // ClassDeclaration ::= ClassHeader ClassBody
2064

2065    int length;
2066    if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
2067        //there are length declarations
2068
//dispatch according to the type of the declarations
2069
dispatchDeclarationInto(length);
2070    }
2071
2072    TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2073
2074    // mark initializers with local type mark if needed
2075
markInitializersWithLocalType(typeDecl);
2076
2077    //convert constructor that do not have the type's name into methods
2078
boolean hasConstructor = typeDecl.checkConstructors(this);
2079    
2080    //add the default constructor when needed (interface don't have it)
2081
if (!hasConstructor) {
2082        switch(TypeDeclaration.kind(typeDecl.modifiers)) {
2083            case TypeDeclaration.CLASS_DECL :
2084            case TypeDeclaration.ENUM_DECL :
2085                boolean insideFieldInitializer = false;
2086                if (this.diet) {
2087                    for (int i = this.nestedType; i > 0; i--){
2088                        if (this.variablesCounter[i] > 0) {
2089                            insideFieldInitializer = true;
2090                            break;
2091                        }
2092                    }
2093                }
2094                typeDecl.createDefaultConstructor(!this.diet || insideFieldInitializer, true);
2095        }
2096    }
2097    //always add <clinit> (will be remove at code gen time if empty)
2098
if (this.scanner.containsAssertKeyword) {
2099        typeDecl.bits |= ASTNode.ContainsAssertion;
2100    }
2101    typeDecl.addClinit();
2102    typeDecl.bodyEnd = this.endStatementPosition;
2103    if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
2104        typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
2105    }
2106
2107    typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2108}
2109protected void consumeClassHeader() {
2110    // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
2111

2112    TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2113    if (this.currentToken == TokenNameLBRACE) {
2114        typeDecl.bodyStart = this.scanner.currentPosition;
2115    }
2116    if (this.currentElement != null) {
2117        this.restartRecovery = true; // used to avoid branching back into the regular automaton
2118
}
2119    // flush the comments related to the class header
2120
this.scanner.commentPtr = -1;
2121}
2122protected void consumeClassHeaderExtends() {
2123    // ClassHeaderExtends ::= 'extends' ClassType
2124
//superclass
2125
TypeReference superClass = getTypeReference(0);
2126    // There is a class declaration on the top of stack
2127
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2128    typeDecl.superclass = superClass;
2129    superClass.bits |= ASTNode.IsSuperType;
2130    typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
2131    // recovery
2132
if (this.currentElement != null){
2133        this.lastCheckPoint = typeDecl.bodyStart;
2134    }
2135}
2136protected void consumeClassHeaderImplements() {
2137    // ClassHeaderImplements ::= 'implements' InterfaceTypeList
2138
int length = this.astLengthStack[this.astLengthPtr--];
2139    //super interfaces
2140
this.astPtr -= length;
2141    // There is a class declaration on the top of stack
2142
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2143    System.arraycopy(
2144        this.astStack,
2145        this.astPtr + 1,
2146        typeDecl.superInterfaces = new TypeReference[length],
2147        0,
2148        length);
2149    for (int i = 0, max = typeDecl.superInterfaces.length; i < max; i++) {
2150        typeDecl.superInterfaces[i].bits |= ASTNode.IsSuperType;
2151    }
2152    typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
2153    this.listLength = 0; // reset after having read super-interfaces
2154
// recovery
2155
if (this.currentElement != null) { // is recovering
2156
this.lastCheckPoint = typeDecl.bodyStart;
2157    }
2158}
2159protected void consumeClassHeaderName1() {
2160    // ClassHeaderName1 ::= Modifiersopt 'class' 'Identifier'
2161
TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2162    if (this.nestedMethod[this.nestedType] == 0) {
2163        if (this.nestedType != 0) {
2164            typeDecl.bits |= ASTNode.IsMemberType;
2165        }
2166    } else {
2167        // Record that the block has a declaration for local types
2168
typeDecl.bits |= ASTNode.IsLocalType;
2169        markEnclosingMemberWithLocalType();
2170        blockReal();
2171    }
2172
2173    //highlight the name of the type
2174
long pos = this.identifierPositionStack[this.identifierPtr];
2175    typeDecl.sourceEnd = (int) pos;
2176    typeDecl.sourceStart = (int) (pos >>> 32);
2177    typeDecl.name = this.identifierStack[this.identifierPtr--];
2178    this.identifierLengthPtr--;
2179
2180    //compute the declaration source too
2181
// 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2182
// we want to keep the beginning position but get rid of the end position
2183
// it is only used for the ClassLiteralAccess positions.
2184
typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
2185    this.intPtr--; // remove the end position of the class token
2186

2187    typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
2188    typeDecl.modifiers = this.intStack[this.intPtr--];
2189    if (typeDecl.modifiersSourceStart >= 0) {
2190        typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2191    }
2192
2193    // Store secondary info
2194
if ((typeDecl.bits & ASTNode.IsMemberType) == 0 && (typeDecl.bits & ASTNode.IsLocalType) == 0) {
2195        if (this.compilationUnit != null && !CharOperation.equals(typeDecl.name, this.compilationUnit.getMainTypeName())) {
2196            typeDecl.bits |= ASTNode.IsSecondaryType;
2197        }
2198    }
2199
2200    // consume annotations
2201
int length;
2202    if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2203        System.arraycopy(
2204            this.expressionStack,
2205            (this.expressionPtr -= length) + 1,
2206            typeDecl.annotations = new Annotation[length],
2207            0,
2208            length);
2209    }
2210    typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2211    pushOnAstStack(typeDecl);
2212
2213    this.listLength = 0; // will be updated when reading super-interfaces
2214
// recovery
2215
if (this.currentElement != null){
2216        this.lastCheckPoint = typeDecl.bodyStart;
2217        this.currentElement = this.currentElement.add(typeDecl, 0);
2218        this.lastIgnoredToken = -1;
2219    }
2220    // javadoc
2221
typeDecl.javadoc = this.javadoc;
2222    this.javadoc = null;
2223}
2224protected void consumeTypeHeaderNameWithTypeParameters() {
2225    // ClassHeaderName ::= ClassHeaderName1 TypeParameters
2226
// InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters
2227
TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
2228
2229    // consume type parameters
2230
int length = this.genericsLengthStack[this.genericsLengthPtr--];
2231    this.genericsPtr -= length;
2232    System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
2233
2234    typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
2235    
2236    this.listTypeParameterLength = 0;
2237    
2238    if (this.currentElement != null) { // is recovering
2239
RecoveredType recoveredType = (RecoveredType) this.currentElement;
2240        recoveredType.pendingTypeParameters = null;
2241        
2242        this.lastCheckPoint = typeDecl.bodyStart;
2243    }
2244}
2245protected void consumeClassInstanceCreationExpression() {
2246    // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
2247
classInstanceCreation(false);
2248}
2249protected void consumeClassInstanceCreationExpressionName() {
2250    // ClassInstanceCreationExpressionName ::= Name '.'
2251
pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2252}
2253protected void consumeClassInstanceCreationExpressionQualified() {
2254    // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
2255
// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
2256
classInstanceCreation(true);
2257
2258    this.expressionLengthPtr--;
2259    QualifiedAllocationExpression qae =
2260        (QualifiedAllocationExpression) this.expressionStack[this.expressionPtr--];
2261    qae.enclosingInstance = this.expressionStack[this.expressionPtr];
2262    this.expressionStack[this.expressionPtr] = qae;
2263    qae.sourceStart = qae.enclosingInstance.sourceStart;
2264}
2265protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
2266    // ClassInstanceCreationExpression ::= Primary '.' 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
2267
// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
2268

2269    QualifiedAllocationExpression alloc;
2270    int length;
2271    if (((length = this.astLengthStack[this.astLengthPtr--]) == 1) && (this.astStack[this.astPtr] == null)) {
2272        //NO ClassBody
2273
this.astPtr--;
2274        alloc = new QualifiedAllocationExpression();
2275        alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
2276

2277        if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2278            this.expressionPtr -= length;
2279            System.arraycopy(
2280                this.expressionStack,
2281                this.expressionPtr + 1,
2282                alloc.arguments = new Expression[length],
2283                0,
2284                length);
2285        }
2286        alloc.type = getTypeReference(0);
2287
2288        length = this.genericsLengthStack[this.genericsLengthPtr--];
2289        this.genericsPtr -= length;
2290        System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
2291        intPtr--;
2292
2293        //the default constructor with the correct number of argument
2294
//will be created and added by the TC (see createsInternalConstructorWithBinding)
2295
alloc.sourceStart = this.intStack[this.intPtr--];
2296        pushOnExpressionStack(alloc);
2297    } else {
2298        dispatchDeclarationInto(length);
2299        TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
2300        anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
2301        anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
2302        if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
2303            anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
2304        }
2305        this.astPtr--;
2306        this.astLengthPtr--;
2307
2308        QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
2309        if (allocationExpression != null) {
2310            allocationExpression.sourceEnd = this.endStatementPosition;
2311            // handle type arguments
2312
length = this.genericsLengthStack[this.genericsLengthPtr--];
2313            this.genericsPtr -= length;
2314            System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
2315            allocationExpression.sourceStart = intStack[intPtr--];
2316        }
2317        
2318        // mark initializers with local type mark if needed
2319
markInitializersWithLocalType(anonymousTypeDeclaration);
2320    }
2321
2322    this.expressionLengthPtr--;
2323    QualifiedAllocationExpression qae =
2324        (QualifiedAllocationExpression) this.expressionStack[this.expressionPtr--];
2325    qae.enclosingInstance = this.expressionStack[this.expressionPtr];
2326    this.expressionStack[this.expressionPtr] = qae;
2327    qae.sourceStart = qae.enclosingInstance.sourceStart;
2328}
2329protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
2330    // ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt
2331
AllocationExpression alloc;
2332    int length;
2333    if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
2334        && (this.astStack[this.astPtr] == null)) {
2335        //NO ClassBody
2336
this.astPtr--;
2337        alloc = new AllocationExpression();
2338        alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
2339

2340        if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2341            this.expressionPtr -= length;
2342            System.arraycopy(
2343                this.expressionStack,
2344                this.expressionPtr + 1,
2345                alloc.arguments = new Expression[length],
2346                0,
2347                length);
2348        }
2349        alloc.type = getTypeReference(0);
2350
2351        length = this.genericsLengthStack[this.genericsLengthPtr--];
2352        this.genericsPtr -= length;
2353        System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
2354        intPtr--;
2355        
2356        //the default constructor with the correct number of argument
2357
//will be created and added by the TC (see createsInternalConstructorWithBinding)
2358
alloc.sourceStart = this.intStack[this.intPtr--];
2359        pushOnExpressionStack(alloc);
2360    } else {
2361        dispatchDeclarationInto(length);
2362        TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
2363        anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
2364        anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
2365        if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
2366            anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
2367        }
2368        this.astPtr--;
2369        this.astLengthPtr--;
2370
2371        QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
2372        if (allocationExpression != null) {
2373            allocationExpression.sourceEnd = this.endStatementPosition;
2374            // handle type arguments
2375
length = this.genericsLengthStack[this.genericsLengthPtr--];
2376            this.genericsPtr -= length;
2377            System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
2378            allocationExpression.sourceStart = intStack[intPtr--];
2379        }
2380        
2381        // mark initializers with local type mark if needed
2382
markInitializersWithLocalType(anonymousTypeDeclaration);
2383    }
2384}
2385protected void consumeClassOrInterface() {
2386    this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] += this.identifierLengthStack[this.identifierLengthPtr];
2387    pushOnGenericsLengthStack(0); // handle type arguments
2388
}
2389protected void consumeClassOrInterfaceName() {
2390    pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
2391    pushOnGenericsLengthStack(0); // handle type arguments
2392
}
2393protected void consumeClassTypeElt() {
2394    // ClassTypeElt ::= ClassType
2395
pushOnAstStack(getTypeReference(0));
2396    /* if incomplete thrown exception list, this.listLength counter will not have been reset,
2397        indicating that some items are available on the stack */

2398    this.listLength++;
2399}
2400protected void consumeClassTypeList() {
2401    // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
2402
optimizedConcatNodeLists();
2403}
2404protected void consumeCompilationUnit() {
2405    // CompilationUnit ::= EnterCompilationUnit InternalCompilationUnit
2406
// do nothing by default
2407
}
2408protected void consumeConditionalExpression(int op) {
2409    // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
2410
//optimize the push/pop
2411
this.intPtr -= 2;//consume position of the question mark
2412
this.expressionPtr -= 2;
2413    this.expressionLengthPtr -= 2;
2414    this.expressionStack[this.expressionPtr] =
2415        new ConditionalExpression(
2416            this.expressionStack[this.expressionPtr],
2417            this.expressionStack[this.expressionPtr + 1],
2418            this.expressionStack[this.expressionPtr + 2]);
2419}
2420/**
2421 * @param op
2422 */

2423protected void consumeConditionalExpressionWithName(int op) {
2424    // ConditionalExpression ::= Name '?' Expression ':' ConditionalExpression
2425
this.intPtr -= 2;//consume position of the question mark
2426
pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2427    this.expressionPtr -= 2;
2428    this.expressionLengthPtr -= 2;
2429    this.expressionStack[this.expressionPtr] =
2430        new ConditionalExpression(
2431            this.expressionStack[this.expressionPtr + 2],
2432            this.expressionStack[this.expressionPtr],
2433            this.expressionStack[this.expressionPtr + 1]);
2434}
2435protected void consumeConstructorBlockStatements() {
2436    // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
2437
concatNodeLists(); // explictly add the first statement into the list of statements
2438
}
2439protected void consumeConstructorBody() {
2440    // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
2441
// ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
2442
this.nestedMethod[this.nestedType] --;
2443}
2444protected void consumeConstructorDeclaration() {
2445    // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
2446

2447    /*
2448    this.astStack : MethodDeclaration statements
2449    this.identifierStack : name
2450     ==>
2451    this.astStack : MethodDeclaration
2452    this.identifierStack :
2453    */

2454
2455    //must provide a default constructor call when needed
2456

2457    int length;
2458
2459    // pop the position of the { (body of the method) pushed in block decl
2460
this.intPtr--;
2461    this.intPtr--;
2462
2463    //statements
2464
this.realBlockPtr--;
2465    ExplicitConstructorCall constructorCall = null;
2466    Statement[] statements = null;
2467    if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
2468        this.astPtr -= length;
2469        if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) {
2470            //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
2471
System.arraycopy(
2472                this.astStack,
2473                this.astPtr + 2,
2474                statements = new Statement[length - 1],
2475                0,
2476                length - 1);
2477            constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
2478        } else { //need to add explicitly the super();
2479
System.arraycopy(
2480                this.astStack,
2481                this.astPtr + 1,
2482                statements = new Statement[length],
2483                0,
2484                length);
2485            constructorCall = SuperReference.implicitSuperConstructorCall();
2486        }
2487    } else {
2488        boolean insideFieldInitializer = false;
2489        if (this.diet) {
2490            for (int i = this.nestedType; i > 0; i--){
2491                if (this.variablesCounter[i] > 0) {
2492                    insideFieldInitializer = true;
2493                    break;
2494                }
2495            }
2496        }
2497        
2498        if (!this.diet || insideFieldInitializer){
2499            // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
2500
constructorCall = SuperReference.implicitSuperConstructorCall();
2501        }
2502    }
2503
2504    // now we know that the top of stack is a constructorDeclaration
2505
ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
2506    cd.constructorCall = constructorCall;
2507    cd.statements = statements;
2508
2509    //highlight of the implicit call on the method name
2510
if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
2511        cd.constructorCall.sourceEnd = cd.sourceEnd;
2512        cd.constructorCall.sourceStart = cd.sourceStart;
2513    }
2514
2515    if (!(this.diet && this.dietInt == 0)
2516            && statements == null
2517            && (constructorCall == null || constructorCall.isImplicitSuper())
2518            && !containsComment(cd.bodyStart, this.endPosition)) {
2519        cd.bits |= ASTNode.UndocumentedEmptyBlock;
2520    }
2521
2522    //watch for } that could be given as a unicode ! ( u007D is '}' )
2523
// store the this.endPosition (position just before the '}') in case there is
2524
// a trailing comment behind the end of the method
2525
cd.bodyEnd = this.endPosition;
2526    cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2527}
2528protected void consumeConstructorHeader() {
2529    // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
2530

2531    AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2532
2533    if (this.currentToken == TokenNameLBRACE){
2534        method.bodyStart = this.scanner.currentPosition;
2535    }
2536    // recovery
2537
if (this.currentElement != null){
2538        if (this.currentToken == TokenNameSEMICOLON){ // for invalid constructors
2539
method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
2540            method.declarationSourceEnd = this.scanner.currentPosition-1;
2541            method.bodyEnd = this.scanner.currentPosition-1;
2542            if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
2543                this.currentElement = this.currentElement.parent;
2544            }
2545        }
2546        this.restartRecovery = true; // used to avoid branching back into the regular automaton
2547
}
2548}
2549protected void consumeConstructorHeaderName() {
2550
2551    /* recovering - might be an empty message send */
2552    if (this.currentElement != null){
2553        if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
2554
this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
2555
this.restartRecovery = true;
2556            return;
2557        }
2558    }
2559    
2560    // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
2561
ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
2562
2563    //name -- this is not really revelant but we do .....
2564
cd.selector = this.identifierStack[this.identifierPtr];
2565    long selectorSource = this.identifierPositionStack[this.identifierPtr--];
2566    this.identifierLengthPtr--;
2567
2568    //modifiers
2569
cd.declarationSourceStart = this.intStack[this.intPtr--];
2570    cd.modifiers = this.intStack[this.intPtr--];
2571    // consume annotations
2572
int length;
2573    if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2574        System.arraycopy(
2575            this.expressionStack,
2576            (this.expressionPtr -= length) + 1,
2577            cd.annotations = new Annotation[length],
2578            0,
2579            length);
2580    }
2581    // javadoc
2582
cd.javadoc = this.javadoc;
2583    this.javadoc = null;
2584
2585    //highlight starts at the selector starts
2586
cd.sourceStart = (int) (selectorSource >>> 32);
2587    pushOnAstStack(cd);
2588    cd.sourceEnd = this.lParenPos;
2589    cd.bodyStart = this.lParenPos+1;
2590    this.listLength = 0; // initialize this.listLength before reading parameters/throws
2591

2592    // recovery
2593
if (this.currentElement != null){
2594        this.lastCheckPoint = cd.bodyStart;
2595        if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
2596            || cd.modifiers != 0){
2597            this.currentElement = this.currentElement.add(cd, 0);
2598            this.lastIgnoredToken = -1;
2599        }
2600    }
2601}
2602protected void consumeConstructorHeaderNameWithTypeParameters() {
2603
2604    /* recovering - might be an empty message send */
2605    if (this.currentElement != null){
2606        if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
2607
this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
2608
this.restartRecovery = true;
2609            return;
2610        }
2611    }
2612    
2613    // ConstructorHeaderName ::= Modifiersopt TypeParameters 'Identifier' '('
2614
ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
2615
2616    //name -- this is not really revelant but we do .....
2617
cd.selector = this.identifierStack[this.identifierPtr];
2618    long selectorSource = this.identifierPositionStack[this.identifierPtr--];
2619    this.identifierLengthPtr--;
2620
2621    // consume type parameters
2622
int length = this.genericsLengthStack[this.genericsLengthPtr--];
2623    this.genericsPtr -= length;
2624    System.arraycopy(this.genericsStack, this.genericsPtr + 1, cd.typeParameters = new TypeParameter[length], 0, length);
2625    
2626    //modifiers
2627
cd.declarationSourceStart = this.intStack[this.intPtr--];
2628    cd.modifiers = this.intStack[this.intPtr--];
2629    // consume annotations
2630
if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2631        System.arraycopy(
2632            this.expressionStack,
2633            (this.expressionPtr -= length) + 1,
2634            cd.annotations = new Annotation[length],
2635            0,
2636            length);
2637    }
2638    // javadoc
2639
cd.javadoc = this.javadoc;
2640    this.javadoc = null;
2641
2642    //highlight starts at the selector starts
2643
cd.sourceStart = (int) (selectorSource >>> 32);
2644    pushOnAstStack(cd);
2645    cd.sourceEnd = this.lParenPos;
2646    cd.bodyStart = this.lParenPos+1;
2647    this.listLength = 0; // initialize this.listLength before reading parameters/throws
2648

2649    // recovery
2650
if (this.currentElement != null){
2651        this.lastCheckPoint = cd.bodyStart;
2652        if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
2653            || cd.modifiers != 0){
2654            this.currentElement = this.currentElement.add(cd, 0);
2655            this.lastIgnoredToken = -1;
2656        }
2657    }
2658}
2659protected void consumeDefaultLabel() {
2660    // SwitchLabel ::= 'default' ':'
2661
pushOnAstStack(new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]));
2662}
2663protected void consumeDefaultModifiers() {
2664    checkComment(); // might update modifiers with AccDeprecated
2665
pushOnIntStack(this.modifiers); // modifiers
2666
pushOnIntStack(
2667        this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
2668    resetModifiers();
2669    pushOnExpressionStackLengthStack(0); // no annotation
2670
}
2671protected void consumeDiet() {
2672    // Diet ::= $empty
2673
checkComment();
2674    pushOnIntStack(this.modifiersSourceStart); // push the start position of a javadoc comment if there is one
2675
resetModifiers();
2676    jumpOverMethodBody();
2677}
2678protected void consumeDims() {
2679    // Dims ::= DimsLoop
2680
pushOnIntStack(this.dimensions);
2681    this.dimensions = 0;
2682}
2683protected void consumeDimWithOrWithOutExpr() {
2684    // DimWithOrWithOutExpr ::= '[' ']'
2685
pushOnExpressionStack(null);
2686    
2687    if(this.currentElement != null && this.currentToken == TokenNameLBRACE) {
2688        this.ignoreNextOpeningBrace = true;
2689        this.currentElement.bracketBalance++;
2690    }
2691}
2692protected void consumeDimWithOrWithOutExprs() {
2693    // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
2694
concatExpressionLists();
2695}
2696protected void consumeEmptyAnnotationTypeMemberDeclarationsopt() {
2697    // AnnotationTypeMemberDeclarationsopt ::= $empty
2698
pushOnAstLengthStack(0);
2699}
2700protected void consumeEmptyArgumentListopt() {
2701    // ArgumentListopt ::= $empty
2702
pushOnExpressionStackLengthStack(0);
2703}
2704protected void consumeEmptyArguments() {
2705    // Argumentsopt ::= $empty
2706
final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
2707    pushOnIntStack(fieldDeclaration.sourceEnd);
2708    pushOnExpressionStackLengthStack(0);
2709}
2710protected void consumeEmptyArrayInitializer() {
2711    // ArrayInitializer ::= '{' ,opt '}'
2712
arrayInitializer(0);
2713}
2714protected void consumeEmptyArrayInitializeropt() {
2715    // ArrayInitializeropt ::= $empty
2716
pushOnExpressionStackLengthStack(0);
2717}
2718protected void consumeEmptyBlockStatementsopt() {
2719    // BlockStatementsopt ::= $empty
2720
pushOnAstLengthStack(0);
2721}
2722protected void consumeEmptyCatchesopt() {
2723    // Catchesopt ::= $empty
2724
pushOnAstLengthStack(0);
2725}
2726protected void consumeEmptyClassBodyDeclarationsopt() {
2727    // ClassBodyDeclarationsopt ::= $empty
2728
pushOnAstLengthStack(0);
2729}
2730protected void consumeEmptyMethodHeaderDefaultValue() {
2731    // DefaultValueopt ::= $empty
2732
AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2733    if(method.isAnnotationMethod()) { //'method' can be a MethodDeclaration when recovery is started
2734
pushOnExpressionStackLengthStack(0);
2735    }
2736    this.recordStringLiterals = true;
2737}
2738protected void consumeEmptyDimsopt() {
2739    // Dimsopt ::= $empty
2740
pushOnIntStack(0);
2741}
2742protected void consumeEmptyEnumDeclarations() {
2743    // EnumBodyDeclarationsopt ::= $empty
2744
pushOnAstLengthStack(0);
2745}
2746protected void consumeEmptyExpression() {
2747    // Expressionopt ::= $empty
2748
pushOnExpressionStackLengthStack(0);
2749}
2750protected void consumeEmptyForInitopt() {
2751    // ForInitopt ::= $empty
2752
pushOnAstLengthStack(0);
2753}
2754protected void consumeEmptyForUpdateopt() {
2755    // ForUpdateopt ::= $empty
2756
pushOnExpressionStackLengthStack(0);
2757}
2758protected void consumeEmptyInterfaceMemberDeclarationsopt() {
2759    // InterfaceMemberDeclarationsopt ::= $empty
2760
pushOnAstLengthStack(0);
2761}
2762protected void consumeEmptyInternalCompilationUnit() {
2763    // InternalCompilationUnit ::= $empty
2764
// nothing to do by default
2765
if (this.compilationUnit.isPackageInfo()) {
2766        this.compilationUnit.types = new TypeDeclaration[1];
2767        // create a fake interface declaration
2768
TypeDeclaration declaration = new TypeDeclaration(compilationUnit.compilationResult);
2769        declaration.name = TypeConstants.PACKAGE_INFO_NAME;
2770        declaration.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccInterface;
2771        this.compilationUnit.types[0] = declaration;
2772        declaration.javadoc = this.compilationUnit.javadoc;
2773    }
2774}
2775protected void consumeEmptyMemberValuePairsopt() {
2776    // MemberValuePairsopt ::= $empty
2777
pushOnAstLengthStack(0);
2778}
2779protected void consumeEmptyMemberValueArrayInitializer() {
2780    // MemberValueArrayInitializer ::= '{' ',' '}'
2781
// MemberValueArrayInitializer ::= '{' '}'
2782
arrayInitializer(0);
2783}
2784protected void consumeEmptyStatement() {
2785    // EmptyStatement ::= ';'
2786
char[] source = this.scanner.source;
2787    if (source[this.endStatementPosition] == ';') {
2788        pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition));
2789    } else {
2790        if(source.length > 5) {
2791            int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
2792            int pos = this.endStatementPosition - 4;
2793            while (source[pos] == 'u') {
2794                pos--;
2795            }
2796            if (source[pos] == '\\' &&
2797                    !((c1 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 3])) > 15
2798                        || c1 < 0
2799                        || (c2 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 2])) > 15
2800                        || c2 < 0
2801                        || (c3 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 1])) > 15
2802                        || c3 < 0
2803                        || (c4 = ScannerHelper.getNumericValue(source[this.endStatementPosition])) > 15
2804                        || c4 < 0) &&
2805                    ((char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4)) == ';'){
2806                // we have a Unicode for the ';' (/u003B)
2807
pushOnAstStack(new EmptyStatement(pos, this.endStatementPosition));
2808                return;
2809            }
2810        }
2811        pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition));
2812    }
2813}
2814protected void consumeEmptySwitchBlock() {
2815    // SwitchBlock ::= '{' '}'
2816
pushOnAstLengthStack(0);
2817}
2818protected void consumeEmptyTypeDeclaration() {
2819    // ClassMemberDeclaration ::= ';'
2820
// InterfaceMemberDeclaration ::= ';'
2821
// TypeDeclaration ::= ';'
2822
pushOnAstLengthStack(0);
2823    if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2824    flushCommentsDefinedPriorTo(this.endStatementPosition);
2825}
2826protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
2827    TypeReference type;
2828
2829    char[] identifierName = this.identifierStack[this.identifierPtr];
2830    long namePosition = this.identifierPositionStack[this.identifierPtr];
2831    
2832    LocalDeclaration localDeclaration = createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
2833    localDeclaration.declarationSourceEnd = localDeclaration.declarationEnd;
2834    
2835    int extraDims = this.intStack[this.intPtr--];
2836    this.identifierPtr--;
2837    this.identifierLengthPtr--;
2838    // remove fake modifiers/modifiers start
2839
int declarationSourceStart = 0;
2840    int modifiersValue = 0;
2841    if (hasModifiers) {
2842        declarationSourceStart = this.intStack[this.intPtr--];
2843        modifiersValue = this.intStack[this.intPtr--];
2844    } else {
2845        this.intPtr-=2;
2846    }
2847
2848    type = getTypeReference(this.intStack[this.intPtr--] + extraDims); // type dimension
2849

2850    // consume annotations
2851
int length;
2852    if ((length = this.expressionLengthStack[this.expressionLengthPtr--])!= 0) {
2853        System.arraycopy(
2854            this.expressionStack,
2855            (this.expressionPtr -= length) + 1,
2856            localDeclaration.annotations = new Annotation[length],
2857            0,
2858            length);
2859    }
2860    if (hasModifiers) {
2861        localDeclaration.declarationSourceStart = declarationSourceStart;
2862        localDeclaration.modifiers = modifiersValue;
2863    } else {
2864        localDeclaration.declarationSourceStart = type.sourceStart;
2865    }
2866    localDeclaration.type = type;
2867
2868    ForeachStatement iteratorForStatement =
2869        new ForeachStatement(
2870            localDeclaration,
2871            this.intStack[this.intPtr--]);
2872    pushOnAstStack(iteratorForStatement);
2873    
2874    iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
2875}
2876protected void consumeEnhancedForStatementHeader(){
2877    // EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
2878
final ForeachStatement statement = (ForeachStatement) this.astStack[this.astPtr];
2879    //updates are on the expression stack
2880
this.expressionLengthPtr--;
2881    final Expression collection = this.expressionStack[this.expressionPtr--];
2882    statement.collection = collection;
2883    statement.sourceEnd = this.rParenPos;
2884    
2885    if(!this.statementRecoveryActivated &&
2886            options.sourceLevel < ClassFileConstants.JDK1_5 &&
2887            this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2888        this.problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
2889    }
2890}
2891protected void consumeEnhancedForStatement() {
2892    // EnhancedForStatement ::= EnhancedForStatementHeader Statement
2893
// EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf
2894

2895    //statements
2896
this.astLengthPtr--;
2897    Statement statement = (Statement) this.astStack[this.astPtr--];
2898
2899    // foreach statement is on the ast stack
2900
ForeachStatement foreachStatement = (ForeachStatement) this.astStack[this.astPtr];
2901    foreachStatement.action = statement;
2902    // remember useful empty statement
2903
if (statement instanceof EmptyStatement) statement.bits |= ASTNode.IsUsefulEmptyStatement;
2904    
2905    foreachStatement.sourceEnd = this.endStatementPosition;
2906}
2907protected void consumeEnterAnonymousClassBody() {
2908    // EnterAnonymousClassBody ::= $empty
2909
TypeReference typeReference = getTypeReference(0);
2910
2911    TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
2912    anonymousType.name = CharOperation.NO_CHAR;
2913    anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
2914    QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
2915    markEnclosingMemberWithLocalType();
2916    pushOnAstStack(anonymousType);
2917
2918    alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
2919
int argumentLength;
2920    if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2921        this.expressionPtr -= argumentLength;
2922        System.arraycopy(
2923            this.expressionStack,
2924            this.expressionPtr + 1,
2925            alloc.arguments = new Expression[argumentLength],
2926            0,
2927            argumentLength);
2928    }
2929    alloc.type = typeReference;
2930
2931    anonymousType.sourceEnd = alloc.sourceEnd;
2932    //position at the type while it impacts the anonymous declaration
2933
anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
2934    alloc.sourceStart = this.intStack[this.intPtr--];
2935    pushOnExpressionStack(alloc);
2936
2937    anonymousType.bodyStart = this.scanner.currentPosition;
2938    this.listLength = 0; // will be updated when reading super-interfaces
2939

2940    // flush the comments related to the anonymous
2941
this.scanner.commentPtr = -1;
2942    
2943    // recovery
2944
if (this.currentElement != null){
2945        this.lastCheckPoint = anonymousType.bodyStart;
2946        this.currentElement = this.currentElement.add(anonymousType, 0);
2947        this.currentToken = 0; // opening brace already taken into account
2948
this.lastIgnoredToken = -1;
2949    }
2950}
2951protected void consumeEnterCompilationUnit() {
2952    // EnterCompilationUnit ::= $empty
2953
// do nothing by default
2954
}
2955protected void consumeEnterMemberValue() {
2956    // EnterMemberValue ::= $empty
2957
// do nothing by default
2958
}
2959protected void consumeEnterMemberValueArrayInitializer() {
2960    // EnterMemberValueArrayInitializer ::= $empty
2961
if(this.currentElement != null) {
2962        this.ignoreNextOpeningBrace = true;
2963        this.currentElement.bracketBalance++;
2964    }
2965}
2966protected void consumeEnterVariable() {
2967    // EnterVariable ::= $empty
2968
// do nothing by default
2969

2970    char[] identifierName = this.identifierStack[this.identifierPtr];
2971    long namePosition = this.identifierPositionStack[this.identifierPtr];
2972    int extendedDimension = this.intStack[this.intPtr--];
2973    AbstractVariableDeclaration declaration;
2974    // create the ast node
2975
boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
2976    if (isLocalDeclaration) {
2977        // create the local variable declarations
2978
declaration =
2979            this.createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
2980    } else {
2981        // create the field declaration
2982
declaration =
2983            this.createFieldDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
2984    }
2985    
2986    this.identifierPtr--;
2987    this.identifierLengthPtr--;
2988    TypeReference type;
2989    int variableIndex = this.variablesCounter[this.nestedType];
2990    int typeDim = 0;
2991    if (variableIndex == 0) {
2992        // first variable of the declaration (FieldDeclaration or LocalDeclaration)
2993
if (isLocalDeclaration) {
2994            declaration.declarationSourceStart = this.intStack[this.intPtr--];
2995            declaration.modifiers = this.intStack[this.intPtr--];
2996            // consume annotations
2997
int length;
2998            if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
2999                System.arraycopy(
3000                    this.expressionStack,
3001                    (this.expressionPtr -= length) + 1,
3002                    declaration.annotations = new Annotation[length],
3003                    0,
3004                    length);
3005            }
3006            type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
3007
if (declaration.declarationSourceStart == -1) {
3008                // this is true if there is no modifiers for the local variable declaration
3009
declaration.declarationSourceStart = type.sourceStart;
3010            }
3011            pushOnAstStack(type);
3012        } else {
3013            type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
3014
pushOnAstStack(type);
3015            declaration.declarationSourceStart = this.intStack[this.intPtr--];
3016            declaration.modifiers = this.intStack[this.intPtr--];
3017            // consume annotations
3018
int length;
3019            if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3020                System.arraycopy(
3021                    this.expressionStack,
3022                    (this.expressionPtr -= length) + 1,
3023                    declaration.annotations = new Annotation[length],
3024                    0,
3025                    length);
3026            }
3027            // Store javadoc only on first declaration as it is the same for all ones
3028
FieldDeclaration fieldDeclaration = (FieldDeclaration) declaration;
3029            fieldDeclaration.javadoc = this.javadoc;
3030            this.javadoc = null;
3031        }
3032    } else {
3033        type = (TypeReference) this.astStack[this.astPtr - variableIndex];
3034        typeDim = type.dimensions();
3035        AbstractVariableDeclaration previousVariable =
3036            (AbstractVariableDeclaration) this.astStack[this.astPtr];
3037        declaration.declarationSourceStart = previousVariable.declarationSourceStart;
3038        declaration.modifiers = previousVariable.modifiers;
3039        final Annotation[] annotations = previousVariable.annotations;
3040        if (annotations != null) {
3041            final int annotationsLength = annotations.length;
3042            System.arraycopy(annotations, 0, declaration.annotations = new Annotation[annotationsLength], 0, annotationsLength);
3043        }
3044    }
3045
3046    if (extendedDimension == 0) {
3047        declaration.type = type;
3048    } else {
3049        int dimension = typeDim + extendedDimension;
3050        declaration.type = this.copyDims(type, dimension);
3051    }
3052    this.variablesCounter[this.nestedType]++;
3053    pushOnAstStack(declaration);
3054    // recovery
3055
if (this.currentElement != null) {
3056        if (!(this.currentElement instanceof RecoveredType)
3057            && (this.currentToken == TokenNameDOT
3058                //|| declaration.modifiers != 0
3059
|| (Util.getLineNumber(declaration.type.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
3060                        != Util.getLineNumber((int) (namePosition >>> 32), this.scanner.lineEnds, 0, this.scanner.linePtr)))){
3061            this.lastCheckPoint = (int) (namePosition >>> 32);
3062            this.restartRecovery = true;
3063            return;
3064        }
3065        if (isLocalDeclaration){
3066            LocalDeclaration localDecl = (LocalDeclaration) this.astStack[this.astPtr];
3067            this.lastCheckPoint = localDecl.sourceEnd + 1;
3068            this.currentElement = this.currentElement.add(localDecl, 0);
3069        } else {
3070            FieldDeclaration fieldDecl = (FieldDeclaration) this.astStack[this.astPtr];
3071            this.lastCheckPoint = fieldDecl.sourceEnd + 1;
3072            this.currentElement = this.currentElement.add(fieldDecl, 0);
3073        }
3074        this.lastIgnoredToken = -1;
3075    }
3076}
3077protected void consumeEnumBodyNoConstants() {
3078    // nothing to do
3079
// The 0 on the astLengthStack has been pushed by EnumBodyDeclarationsopt
3080
}
3081protected void consumeEnumBodyWithConstants() {
3082    // merge the constants values with the class body
3083
concatNodeLists();
3084}
3085protected void consumeEnumConstantHeaderName() {
3086    if (this.currentElement != null) {
3087        if (!(this.currentElement instanceof RecoveredType
3088                    || (this.currentElement instanceof RecoveredField && ((RecoveredField)currentElement).fieldDeclaration.type == null))
3089                || (this.lastIgnoredToken == TokenNameDOT)) {
3090            this.lastCheckPoint = this.scanner.startPosition;
3091            this.restartRecovery = true;
3092            return;
3093        }
3094    }
3095   long namePosition = this.identifierPositionStack[this.identifierPtr];
3096   char[] constantName = this.identifierStack[this.identifierPtr];
3097   final int sourceEnd = (int) namePosition;
3098   FieldDeclaration enumConstant = createFieldDeclaration(constantName, (int) (namePosition >>> 32), sourceEnd);
3099   this.identifierPtr--;
3100   this.identifierLengthPtr--;
3101   enumConstant.modifiersSourceStart = this.intStack[this.intPtr--];
3102   enumConstant.modifiers = this.intStack[this.intPtr--];
3103   enumConstant.declarationSourceStart = enumConstant.modifiersSourceStart;
3104
3105    // Store secondary info
3106
if ((enumConstant.bits & ASTNode.IsMemberType) == 0 && (enumConstant.bits & ASTNode.IsLocalType) == 0) {
3107        if (this.compilationUnit != null && !CharOperation.equals(enumConstant.name, this.compilationUnit.getMainTypeName())) {
3108            enumConstant.bits |= ASTNode.IsSecondaryType;
3109        }
3110    }
3111
3112    // consume annotations
3113
int length;
3114   if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3115      System.arraycopy(
3116         this.expressionStack,
3117         (this.expressionPtr -= length) + 1,
3118         enumConstant.annotations = new Annotation[length],
3119         0,
3120         length);
3121   }
3122   pushOnAstStack(enumConstant);
3123    if (this.currentElement != null){
3124        this.lastCheckPoint = enumConstant.sourceEnd + 1;
3125        this.currentElement = this.currentElement.add(enumConstant, 0);
3126    }
3127    // javadoc
3128
enumConstant.javadoc = this.javadoc;
3129    this.javadoc = null;
3130}
3131protected void consumeEnumConstantHeader() {
3132   FieldDeclaration enumConstant = (FieldDeclaration) this.astStack[this.astPtr];
3133   boolean foundOpeningBrace = this.currentToken == TokenNameLBRACE;
3134   if (foundOpeningBrace){
3135      // qualified allocation expression
3136
TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
3137      anonymousType.name = CharOperation.NO_CHAR;
3138      anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
3139      final int start = this.scanner.startPosition;
3140      anonymousType.declarationSourceStart = start;
3141      anonymousType.sourceStart = start;
3142      anonymousType.sourceEnd = start; // closing parenthesis
3143
anonymousType.modifiers = 0;
3144      anonymousType.bodyStart = this.scanner.currentPosition;
3145      markEnclosingMemberWithLocalType();
3146      pushOnAstStack(anonymousType);
3147      QualifiedAllocationExpression allocationExpression = new QualifiedAllocationExpression(anonymousType);
3148      allocationExpression.enumConstant = enumConstant;
3149      
3150      // fill arguments if needed
3151
int length;
3152      if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3153         this.expressionPtr -= length;
3154         System.arraycopy(
3155               this.expressionStack,
3156               this.expressionPtr + 1,
3157               allocationExpression.arguments = new Expression[length],
3158               0,
3159               length);
3160      }
3161      enumConstant.initialization = allocationExpression;
3162   } else {
3163      AllocationExpression allocationExpression = new AllocationExpression();
3164      allocationExpression.enumConstant = enumConstant;
3165      // fill arguments if needed
3166
int length;
3167      if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3168         this.expressionPtr -= length;
3169         System.arraycopy(
3170               this.expressionStack,
3171               this.expressionPtr + 1,
3172               allocationExpression.arguments = new Expression[length],
3173               0,
3174               length);
3175      }
3176      enumConstant.initialization = allocationExpression;
3177   }
3178   
3179   // recovery
3180
if (this.currentElement != null) {
3181      if(foundOpeningBrace) {
3182        TypeDeclaration anonymousType = (TypeDeclaration) this.astStack[this.astPtr];
3183        this.currentElement = this.currentElement.add(anonymousType, 0);
3184        this.lastCheckPoint = anonymousType.bodyStart;
3185        this.lastIgnoredToken = -1;
3186        this.currentToken = 0; // opening brace already taken into account
3187
} else {
3188          if(this.currentToken == TokenNameSEMICOLON) {
3189            RecoveredType currentType = this.currentRecoveryType();
3190            if(currentType != null) {
3191                currentType.insideEnumConstantPart = false;
3192            }
3193          }
3194          this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
3195
this.lastIgnoredToken = -1;
3196          this.restartRecovery = true;
3197      }
3198   }
3199}
3200protected void consumeEnumConstantNoClassBody() {
3201    // set declarationEnd and declarationSourceEnd
3202
int endOfEnumConstant = intStack[intPtr--];
3203    final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
3204    fieldDeclaration.declarationEnd = endOfEnumConstant;
3205    fieldDeclaration.declarationSourceEnd = endOfEnumConstant;
3206}
3207protected void consumeEnumConstants() {
3208    concatNodeLists();
3209}
3210protected void consumeEnumConstantWithClassBody() {
3211   dispatchDeclarationInto(this.astLengthStack[this.astLengthPtr--]);
3212   TypeDeclaration anonymousType = (TypeDeclaration) this.astStack[this.astPtr--]; // pop type
3213
this.astLengthPtr--;
3214   anonymousType.bodyEnd = this.endPosition;
3215   anonymousType.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3216   final FieldDeclaration fieldDeclaration = ((FieldDeclaration) this.astStack[this.astPtr]);
3217   fieldDeclaration.declarationEnd = this.endStatementPosition;
3218   fieldDeclaration.declarationSourceEnd = anonymousType.declarationSourceEnd;
3219   intPtr --; // remove end position of the arguments
3220
}
3221protected void consumeEnumDeclaration() {
3222    // EnumDeclaration ::= EnumHeader ClassHeaderImplementsopt EnumBody
3223
int length;
3224    if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
3225        //there are length declarations
3226
//dispatch according to the type of the declarations
3227
dispatchDeclarationIntoEnumDeclaration(length);
3228    }
3229
3230    TypeDeclaration enumDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
3231
3232    // mark initializers with local type mark if needed
3233
markInitializersWithLocalType(enumDeclaration);
3234
3235    //convert constructor that do not have the type's name into methods
3236
boolean hasConstructor = enumDeclaration.checkConstructors(this);
3237    
3238    //add the default constructor when needed
3239
if (!hasConstructor) {
3240        boolean insideFieldInitializer = false;
3241        if (this.diet) {
3242            for (int i = this.nestedType; i > 0; i--){
3243                if (this.variablesCounter[i] > 0) {
3244                    insideFieldInitializer = true;
3245                    break;
3246                }
3247            }
3248        }
3249        enumDeclaration.createDefaultConstructor(!this.diet || insideFieldInitializer, true);
3250    }
3251
3252    //always add <clinit> (will be remove at code gen time if empty)
3253
if (this.scanner.containsAssertKeyword) {
3254        enumDeclaration.bits |= ASTNode.ContainsAssertion;
3255    }
3256    enumDeclaration.addClinit();
3257    enumDeclaration.bodyEnd = this.endStatementPosition;
3258    if (length == 0 && !containsComment(enumDeclaration.bodyStart, enumDeclaration.bodyEnd)) {
3259        enumDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
3260    }
3261
3262    enumDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3263}
32