1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
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;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Locale;
20 import java.util.MissingResourceException;
21 import java.util.ResourceBundle;
23 import org.eclipse.jdt.core.compiler.CharOperation;
24 import org.eclipse.jdt.core.compiler.InvalidInputException;
25 import org.eclipse.jdt.internal.compiler.CompilationResult;
26 import org.eclipse.jdt.internal.compiler.ast.*;
27 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
28 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
29 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
30 import org.eclipse.jdt.internal.compiler.lookup.BindingIds;
31 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
32 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
33 import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
34 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
35 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
36 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
37 import org.eclipse.jdt.internal.compiler.util.Util;
39 public class Parser implements BindingIds, ParserBasicInformation, TerminalTokens, CompilerModifiers, OperatorIds, TypeIds {
40 protected ProblemReporter problemReporter;
41 protected CompilerOptions options;
42 public int firstToken ; // handle for multiple parsing goals
43 public int lastAct ; //handle for multiple parsing goals
44 public ReferenceContext referenceContext;
45 public int currentToken;
46 private int synchronizedBlockSourceStart;
48 //error recovery management
49 protected int lastCheckPoint;
50 protected RecoveredElement currentElement;
51 public static boolean VERBOSE_RECOVERY = false;
52 protected boolean restartRecovery;
53 protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
54 protected boolean hasError;
55 protected boolean hasReportedError;
56 public boolean reportSyntaxErrorIsRequired = true;
57 public boolean reportOnlyOneSyntaxError = false;
58 protected int recoveredStaticInitializerStart;
59 protected int lastIgnoredToken, nextIgnoredToken;
60 protected int lastErrorEndPosition;
61 protected boolean ignoreNextOpeningBrace;
63 //internal data for the automat
64 protected final static int StackIncrement = 255;
65 protected int stateStackTop;
66 protected int[] stack = new int[StackIncrement];
68 public Scanner scanner;
70 final static int AstStackIncrement = 100;
72 protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
73 protected int astLengthPtr;
74 protected int[] astLengthStack;
75 public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
76 ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
78 final static int ExpressionStackIncrement = 100;
79 protected int expressionPtr;
80 protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
81 protected int expressionLengthPtr;
82 protected int[] expressionLengthStack;
83 Expression [] noExpressions = new Expression[ExpressionStackIncrement];
85 protected int identifierPtr;
86 protected char[][] identifierStack;
87 protected int identifierLengthPtr;
88 protected int[] identifierLengthStack;
89 protected long[] identifierPositionStack;
90 //positions , dimensions , .... (int stacks)
92 protected int[] intStack;
93 protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
94 protected int endStatementPosition;
95 protected int lParenPos,rParenPos; //accurate only when used !
96 protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
97 //modifiers dimensions nestedType etc.......
98 protected boolean optimizeStringLiterals =true;
99 protected int modifiers;
100 protected int modifiersSourceStart;
101 protected int nestedType, dimensions;
102 protected int[] nestedMethod; //the ptr is nestedType
103 protected int[] realBlockStack;
104 protected int realBlockPtr;
105 protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
106 protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
107 protected int[] variablesCounter;
110 public JavadocParser javadocParser;
111 public Javadoc javadoc;
113 public static byte rhs[] = null;
114 public static char asb[] = null;
115 public static char asr[] = null;
116 public static char nasb[] = null;
117 public static char nasr[] = null;
119 public static char terminal_index[] = null;
120 public static char non_terminal_index[] = null;
122 public static char term_action[] = null;
123 public static byte term_check[] = null;
125 private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
126 private static final String INVALID_CHARACTER = "Invalid Character" ; //$NON-NLS-1$
127 private static final String EOF_TOKEN = "$eof" ; //$NON-NLS-1$
128 private static final String ERROR_TOKEN = "$error" ; //$NON-NLS-1$
130 public static String name[] = null;
131 public static String readableName[] = null;
133 public static short check_table[] = null;
134 public static char lhs[] = null;
135 public static char base_action[] = lhs;
137 public static char scope_prefix[] = null;
138 public static char scope_suffix[] = null;
139 public static char scope_lhs[] = null;
141 public static byte scope_la[] = null;
143 public static char scope_state_set[] = null;
144 public static char scope_rhs[] = null;
145 public static char scope_state[] = null;
146 public static char in_symb[] = null;
148 private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
149 private final static String READABLE_NAMES_FILE = "readableNames"; //$NON-NLS-1$
150 private final static String READABLE_NAMES =
151 "org.eclipse.jdt.internal.compiler.parser." + READABLE_NAMES_FILE; //$NON-NLS-1$
156 } catch(java.io.IOException ex){
157 throw new ExceptionInInitializerError(ex.getMessage());
161 public static final int RoundBracket = 0;
162 public static final int SquareBracket = 1;
163 public static final int CurlyBracket = 2;
164 public static final int BracketKinds = 3;
166 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
168 this.problemReporter = problemReporter;
169 this.options = problemReporter.options;
170 this.optimizeStringLiterals = optimizeStringLiterals;
171 this.initializeScanner();
172 this.astLengthStack = new int[50];
173 this.expressionLengthStack = new int[30];
174 this.intStack = new int[50];
175 this.identifierStack = new char[30][];
176 this.identifierLengthStack = new int[30];
177 this.nestedMethod = new int[30];
178 this.realBlockStack = new int[30];
179 this.identifierPositionStack = new long[30];
180 this.variablesCounter = new int[30];
183 this.javadocParser = new JavadocParser(this);
189 protected void adjustInterfaceModifiers() {
190 this.intStack[this.intPtr - 1] |= AccInterface;
192 public final void arrayInitializer(int length) {
193 //length is the size of the array Initializer
194 //expressionPtr points on the last elt of the arrayInitializer,
195 // in other words, it has not been decremented yet.
197 ArrayInitializer ai = new ArrayInitializer();
199 this.expressionPtr -= length;
200 System.arraycopy(this.expressionStack, this.expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
202 pushOnExpressionStack(ai);
204 ai.sourceEnd = this.endStatementPosition;
205 int searchPosition = length == 0 ? this.endPosition + 1 : ai.expressions[0].sourceStart;
207 //does not work with comments(that contain '{') nor '{' describes as a unicode....
208 while (this.scanner.source[--searchPosition] != '{'){/*empty*/}
209 } catch (IndexOutOfBoundsException ex) {
210 //should never occur (except for strange cases like whose describe above)
211 searchPosition = (length == 0 ? this.endPosition : ai.expressions[0].sourceStart) - 1;
213 ai.sourceStart = searchPosition;
215 public static int asi(int state) {
217 return asb[original_state(state)];
219 protected void blockReal() {
220 // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
221 // increment the amount of declared variables for this block
222 this.realBlockStack[this.realBlockPtr]++;
224 private final static void buildFileOfByteFor(String filename, String tag, String[] tokens) throws java.io.IOException {
226 //transform the String tokens into chars before dumping then into file
230 while (!tokens[i++].equals(tag)){/*empty*/}
233 byte[] bytes = new byte[tokens.length]; //can't be bigger
236 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
237 int c = Integer.parseInt(token);
238 bytes[ic++] = (byte) c;
242 System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
244 buildFileForTable(filename, bytes);
246 private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) throws java.io.IOException {
248 //transform the String tokens into chars before dumping then into file
252 while (!tokens[i++].equals(tag)){/*empty*/}
255 char[] chars = new char[tokens.length]; //can't be bigger
258 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
259 int c = Integer.parseInt(token);
260 chars[ic++] = (char) c;
264 System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
266 buildFileForTable(filename, chars);
269 private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) throws java.io.IOException {
271 //transform the String tokens into chars before dumping then into file
275 while (!tokens[i++].equals(tag)){/*empty*/}
278 char[] chars = new char[tokens.length]; //can't be bigger
281 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
282 int c = Integer.parseInt(token);
283 chars[ic++] = (char) (c + 32768);
287 System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
289 buildFileForTable(filename, chars);
291 private final static String[] buildFileForName(String filename, String contents) throws java.io.IOException {
292 String[] result = new String[contents.length()];
296 StringBuffer buffer = new StringBuffer();
298 int start = contents.indexOf("name[]"); //$NON-NLS-1$
299 start = contents.indexOf('\"', start);
300 int end = contents.indexOf("};", start); //$NON-NLS-1$
302 contents = contents.substring(start, end);
304 boolean addLineSeparator = false;
306 StringBuffer currentToken = new StringBuffer();
307 for (int i = 0; i < contents.length(); i++) {
308 char c = contents.charAt(i);
310 if(tokenStart == -1) {
313 if(addLineSeparator) {
315 result[resultCount++] = currentToken.toString();
316 currentToken = new StringBuffer();
318 String token = contents.substring(tokenStart, i);
319 if(token.equals(ERROR_TOKEN)){
320 token = INVALID_CHARACTER;
321 } else if(token.equals(EOF_TOKEN)) {
322 token = UNEXPECTED_EOF;
324 buffer.append(token);
325 currentToken.append(token);
326 addLineSeparator = true;
330 if(tokenStart == -1 && c == '+'){
331 addLineSeparator = false;
334 if(currentToken.length() > 0) {
335 result[resultCount++] = currentToken.toString();
338 buildFileForTable(filename, buffer.toString().toCharArray());
340 System.arraycopy(result, 0, result = new String[resultCount], 0, resultCount);
343 private static void buildFileForReadableName(
346 char[] newNonTerminalIndex,
348 String[] tokens) throws java.io.IOException {
350 ArrayList entries = new ArrayList();
352 boolean[] alreadyAdded = new boolean[newName.length];
354 for (int i = 0; i < tokens.length; i = i + 2) {
355 int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i])]];
356 StringBuffer buffer = new StringBuffer();
357 if(!alreadyAdded[index]) {
358 alreadyAdded[index] = true;
359 buffer.append(newName[index]);
361 buffer.append(tokens[i+1].trim());
363 entries.add(String.valueOf(buffer));
367 while(!INVALID_CHARACTER.equals(newName[i])) i++;
369 for (; i < alreadyAdded.length; i++) {
370 if(!alreadyAdded[i]) {
371 System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
374 Collections.sort(entries);
375 buildFile(file, entries);
377 private final static void buildFile(String filename, List listToDump) throws java.io.IOException {
378 BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
379 for (Iterator iterator = listToDump.iterator(); iterator.hasNext(); ) {
380 writer.write(String.valueOf(iterator.next()));
384 System.out.println(filename + " creation complete"); //$NON-NLS-1$
386 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
388 byte[] bytes = new byte[chars.length * 2];
389 for (int i = 0; i < chars.length; i++) {
390 bytes[2 * i] = (byte) (chars[i] >>> 8);
391 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
394 java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
397 System.out.println(filename + " creation complete"); //$NON-NLS-1$
399 private final static void buildFileForTable(String filename, byte[] bytes) throws java.io.IOException {
400 java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
403 System.out.println(filename + " creation complete"); //$NON-NLS-1$
405 public final static void buildFilesFromLPG(String dataFilename, String dataFilename2) throws java.io.IOException {
407 //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
409 //build from the lpg javadcl.java files that represents the parser tables
410 //lhs check_table asb asr symbol_index
412 //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
414 char[] contents = new char[] {};
416 contents = Util.getFileCharContent(new File(dataFilename), null);
417 } catch (IOException ex) {
418 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
421 java.util.StringTokenizer st =
422 new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
423 String[] tokens = new String[st.countTokens()];
425 while (st.hasMoreTokens()) {
426 tokens[i++] = st.nextToken();
428 final String prefix = FILEPREFIX;
431 char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
432 buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
433 buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
434 buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
435 buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
436 buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
437 buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
438 char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
439 buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
441 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
442 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
443 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
444 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
445 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
446 buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
447 buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
449 buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
450 buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
451 buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
453 String[] newName = buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$
455 contents = new char[] {};
457 contents = Util.getFileCharContent(new File(dataFilename2), null);
458 } catch (IOException ex) {
459 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
462 st = new java.util.StringTokenizer(new String(contents), "\t\n\r="); //$NON-NLS-1$
463 tokens = new String[st.countTokens()];
465 while (st.hasMoreTokens()) {
466 tokens[i++] = st.nextToken();
468 buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
470 System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
473 * Build initial recovery state.
474 * Recovery state is inferred from the current state of the parser (reduced node stack).
476 public RecoveredElement buildInitialRecoveryState(){
478 /* initialize recovery by retrieving available reduced nodes
479 * also rebuild bracket balance
481 this.lastCheckPoint = 0;
483 RecoveredElement element = null;
484 if (this.referenceContext instanceof CompilationUnitDeclaration){
485 element = new RecoveredUnit(this.compilationUnit, 0, this);
487 /* ignore current stack state, since restarting from the beginnning
488 since could not trust simple brace count */
489 if (true){ // experimenting restart recovery from scratch
490 this.compilationUnit.currentPackage = null;
491 this.compilationUnit.imports = null;
492 this.compilationUnit.types = null;
493 this.currentToken = 0;
495 this.endPosition = 0;
496 this.endStatementPosition = 0;
499 if (this.compilationUnit.currentPackage != null){
500 this.lastCheckPoint = this.compilationUnit.currentPackage.declarationSourceEnd+1;
502 if (this.compilationUnit.imports != null){
503 this.lastCheckPoint = this.compilationUnit.imports[this.compilationUnit.imports.length -1].declarationSourceEnd+1;
506 if (this.referenceContext instanceof AbstractMethodDeclaration){
507 element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
508 this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
510 /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
511 if (this.referenceContext instanceof TypeDeclaration){
512 TypeDeclaration type = (TypeDeclaration) this.referenceContext;
513 for (int i = 0; i < type.fields.length; i++){
514 FieldDeclaration field = type.fields[i];
517 && field.declarationSourceStart <= this.scanner.initialPosition
518 && this.scanner.initialPosition <= field.declarationSourceEnd
519 && this.scanner.eofPosition <= field.declarationSourceEnd+1){
520 element = new RecoveredInitializer(field, null, 1, this);
521 this.lastCheckPoint = field.declarationSourceStart;
529 if (element == null) return element;
531 for(int i = 0; i <= this.astPtr; i++){
532 ASTNode node = this.astStack[i];
533 if (node instanceof AbstractMethodDeclaration){
534 AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
535 if (method.declarationSourceEnd == 0){
536 element = element.add(method, 0);
537 this.lastCheckPoint = method.bodyStart;
539 element = element.add(method, 0);
540 this.lastCheckPoint = method.declarationSourceEnd + 1;
544 if (node instanceof Initializer){
545 Initializer initializer = (Initializer) node;
546 if (initializer.declarationSourceEnd == 0){
547 element = element.add(initializer, 1);
548 this.lastCheckPoint = initializer.sourceStart;
550 element = element.add(initializer, 0);
551 this.lastCheckPoint = initializer.declarationSourceEnd + 1;
555 if (node instanceof FieldDeclaration){
556 FieldDeclaration field = (FieldDeclaration) node;
557 if (field.declarationSourceEnd == 0){
558 element = element.add(field, 0);
559 if (field.initialization == null){
560 this.lastCheckPoint = field.sourceEnd + 1;
562 this.lastCheckPoint = field.initialization.sourceEnd + 1;
565 element = element.add(field, 0);
566 this.lastCheckPoint = field.declarationSourceEnd + 1;
570 if (node instanceof TypeDeclaration){
571 TypeDeclaration type = (TypeDeclaration) node;
572 if (type.declarationSourceEnd == 0){
573 element = element.add(type, 0);
574 this.lastCheckPoint = type.bodyStart;
576 element = element.add(type, 0);
577 this.lastCheckPoint = type.declarationSourceEnd + 1;
581 if (node instanceof ImportReference){
582 ImportReference importRef = (ImportReference) node;
583 element = element.add(importRef, 0);
584 this.lastCheckPoint = importRef.declarationSourceEnd + 1;
589 public final static short base_check(int i) {
590 return check_table[i - (NUM_RULES + 1)];
592 public final void checkAndSetModifiers(int flag){
593 /*modify the current modifiers buffer.
594 When the startPosition of the modifiers is 0
595 it means that the modifier being parsed is the first
596 of a list of several modifiers. The startPosition
597 is zeroed when a copy of modifiers-buffer is push
598 onto the astStack. */
600 if ((this.modifiers & flag) != 0){ // duplicate modifier
601 this.modifiers |= AccAlternateModifierProblem;
603 this.modifiers |= flag;
605 if (this.modifiersSourceStart < 0) this.modifiersSourceStart = this.scanner.startPosition;
607 public void checkComment() {
609 if (this.currentElement != null && this.scanner.commentPtr >= 0) {
610 flushCommentsDefinedPriorTo(this.endStatementPosition); // discard obsolete comments during recovery
613 int lastComment = this.scanner.commentPtr;
615 if (this.modifiersSourceStart >= 0) {
616 // eliminate comments located after modifierSourceStart if positionned
617 while (lastComment >= 0 && this.scanner.commentStarts[lastComment] > this.modifiersSourceStart) lastComment--;
619 if (lastComment >= 0) {
620 // consider all remaining leading comments to be part of current declaration
621 this.modifiersSourceStart = this.scanner.commentStarts[0];
623 // check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)
624 while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
625 if (lastComment >= 0 && this.javadocParser != null) {
626 if (this.javadocParser.checkDeprecation(
627 this.scanner.commentStarts[lastComment],
628 this.scanner.commentStops[lastComment] - 1)) { //stop is one over,
629 checkAndSetModifiers(AccDeprecated);
631 this.javadoc = this.javadocParser.docComment; // null if check javadoc is not activated
635 protected void checkNonExternalizedStringLiteral() {
636 if (this.scanner.wasNonExternalizedStringLiteral) {
637 StringLiteral[] literals = this.scanner.nonNLSStrings;
638 // could not reproduce, but this is the only NPE
639 // added preventive null check see PR 9035
640 if (literals != null) {
641 for (int i = 0, max = literals.length; i < max; i++) {
642 problemReporter().nonExternalizedStringLiteral(literals[i]);
645 this.scanner.wasNonExternalizedStringLiteral = false;
648 protected void checkNonNLSAfterBodyEnd(int declarationEnd){
649 if(this.scanner.currentPosition - 1 <= declarationEnd) {
650 this.scanner.eofPosition = declarationEnd < Integer.MAX_VALUE ? declarationEnd + 1 : declarationEnd;
652 while(this.scanner.getNextToken() != TokenNameEOF){/*empty*/}
653 checkNonExternalizedStringLiteral();
654 } catch (InvalidInputException e) {
659 protected char getNextCharacter(char[] comment, int[] index) {
660 char nextCharacter = comment[index[0]++];
661 switch(nextCharacter) {
665 while (comment[index[0]] == 'u') index[0]++;
666 if (!(((c1 = Character.getNumericValue(comment[index[0]++])) > 15
668 || ((c2 = Character.getNumericValue(comment[index[0]++])) > 15 || c2 < 0)
669 || ((c3 = Character.getNumericValue(comment[index[0]++])) > 15 || c3 < 0)
670 || ((c4 = Character.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) {
671 nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
675 return nextCharacter;
677 protected void classInstanceCreation(boolean alwaysQualified) {
678 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
680 // ClassBodyopt produces a null item on the astStak if it produces NO class body
681 // An empty class body produces a 0 on the length stack.....
683 AllocationExpression alloc;
685 if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
686 && (this.astStack[this.astPtr] == null)) {
689 if (alwaysQualified) {
690 alloc = new QualifiedAllocationExpression();
692 alloc = new AllocationExpression();
694 alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
696 if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
697 this.expressionPtr -= length;
699 this.expressionStack,
700 this.expressionPtr + 1,
701 alloc.arguments = new Expression[length],
705 alloc.type = getTypeReference(0);
706 //the default constructor with the correct number of argument
707 //will be created and added by the TC (see createsInternalConstructorWithBinding)
708 alloc.sourceStart = this.intStack[this.intPtr--];
709 pushOnExpressionStack(alloc);
711 dispatchDeclarationInto(length);
712 TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
713 anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
714 anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
715 if (anonymousTypeDeclaration.allocation != null) {
716 anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
718 if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
719 anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlockMASK;
724 // mark initializers with local type mark if needed
725 markInitializersWithLocalType(anonymousTypeDeclaration);
728 protected final void concatExpressionLists() {
729 this.expressionLengthStack[--this.expressionLengthPtr]++;
731 private final void concatNodeLists() {
733 * This is a case where you have two sublists into the astStack that you want
734 * to merge in one list. There is no action required on the astStack. The only
735 * thing you need to do is merge the two lengths specified on the astStackLength.
736 * The top two length are for example:
738 * and you want to result in a list like:
740 * This means that the p could be equals to 0 in case there is no astNode pushed
742 * Look at the InterfaceMemberDeclarations for an example.
745 this.astLengthStack[this.astLengthPtr - 1] += this.astLengthStack[this.astLengthPtr--];
747 protected void consumeAllocationHeader() {
748 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
750 // ClassBodyopt produces a null item on the astStak if it produces NO class body
751 // An empty class body produces a 0 on the length stack.....
753 if (this.currentElement == null){
754 return; // should never occur, this consumeRule is only used in recovery mode
756 if (this.currentToken == TokenNameLBRACE){
757 // beginning of an anonymous type
758 TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
759 anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
760 anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
761 anonymousType.sourceStart = this.intStack[this.intPtr--];
762 anonymousType.sourceEnd = this.rParenPos; // closing parenthesis
763 QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
764 alloc.type = getTypeReference(0);
765 alloc.sourceStart = anonymousType.sourceStart;
766 alloc.sourceEnd = anonymousType.sourceEnd ;
767 anonymousType.allocation = alloc;
768 this.lastCheckPoint = anonymousType.bodyStart = this.scanner.currentPosition;
769 this.currentElement = this.currentElement.add(anonymousType, 0);
770 this.lastIgnoredToken = -1;
771 this.currentToken = 0; // opening brace already taken into account
774 this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
775 this.restartRecovery = true; // request to restart from here on
777 protected void consumeArgumentList() {
778 // ArgumentList ::= ArgumentList ',' Expression
779 concatExpressionLists();
781 protected void consumeArrayAccess(boolean unspecifiedReference) {
782 // ArrayAccess ::= Name '[' Expression ']' ==> true
783 // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
788 if (unspecifiedReference) {
790 this.expressionStack[this.expressionPtr] =
792 getUnspecifiedReferenceOptimized(),
793 this.expressionStack[this.expressionPtr]);
795 this.expressionPtr--;
796 this.expressionLengthPtr--;
798 this.expressionStack[this.expressionPtr] =
800 this.expressionStack[this.expressionPtr],
801 this.expressionStack[this.expressionPtr + 1]);
803 exp.sourceEnd = this.endPosition;
805 protected void consumeArrayCreationExpressionWithoutInitializer() {
806 // ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
807 // ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
810 ArrayAllocationExpression aae = new ArrayAllocationExpression();
811 aae.type = getTypeReference(0);
812 length = (this.expressionLengthStack[this.expressionLengthPtr--]);
813 this.expressionPtr -= length ;
815 this.expressionStack,
816 this.expressionPtr+1,
817 aae.dimensions = new Expression[length],
820 aae.sourceStart = this.intStack[this.intPtr--];
821 if (aae.initializer == null) {
822 aae.sourceEnd = this.endPosition;
824 aae.sourceEnd = aae.initializer.sourceEnd ;
826 pushOnExpressionStack(aae);
829 protected void consumeArrayCreationHeader() {
832 protected void consumeArrayCreationExpressionWithInitializer() {
833 // ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer
834 // ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
837 ArrayAllocationExpression aae = new ArrayAllocationExpression();
838 this.expressionLengthPtr -- ;
839 aae.initializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
841 aae.type = getTypeReference(0);
842 length = (this.expressionLengthStack[this.expressionLengthPtr--]);
843 this.expressionPtr -= length ;
845 this.expressionStack,
846 this.expressionPtr+1,
847 aae.dimensions = new Expression[length],
850 aae.sourceStart = this.intStack[this.intPtr--];
851 if (aae.initializer == null) {
852 aae.sourceEnd = this.endPosition;
854 aae.sourceEnd = aae.initializer.sourceEnd ;
856 pushOnExpressionStack(aae);
858 protected void consumeArrayInitializer() {
859 // ArrayInitializer ::= '{' VariableInitializers '}'
860 // ArrayInitializer ::= '{' VariableInitializers , '}'
862 arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
865 protected void consumeAssertStatement() {
866 // AssertStatement ::= 'assert' Expression ':' Expression ';'
867 this.expressionLengthPtr-=2;
868 pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
871 protected void consumeAssignment() {
872 // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
873 //optimize the push/pop
875 int op = this.intStack[this.intPtr--] ; //<--the encoded operator
877 this.expressionPtr -- ; this.expressionLengthPtr -- ;
878 this.expressionStack[this.expressionPtr] =
880 new CompoundAssignment(
881 this.expressionStack[this.expressionPtr] ,
882 this.expressionStack[this.expressionPtr+1],
884 this.scanner.startPosition - 1) :
886 this.expressionStack[this.expressionPtr] ,
887 this.expressionStack[this.expressionPtr+1],
888 this.scanner.startPosition - 1);
890 protected void consumeAssignmentOperator(int pos) {
891 // AssignmentOperator ::= '='
892 // AssignmentOperator ::= '*='
893 // AssignmentOperator ::= '/='
894 // AssignmentOperator ::= '%='
895 // AssignmentOperator ::= '+='
896 // AssignmentOperator ::= '-='
897 // AssignmentOperator ::= '<<='
898 // AssignmentOperator ::= '>>='
899 // AssignmentOperator ::= '>>>='
900 // AssignmentOperator ::= '&='
901 // AssignmentOperator ::= '^='
902 // AssignmentOperator ::= '|='
906 protected void consumeBinaryExpression(int op) {
907 // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
908 // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
909 // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
910 // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
911 // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
912 // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
913 // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
914 // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
915 // RelationalExpression ::= RelationalExpression '<' ShiftExpression
916 // RelationalExpression ::= RelationalExpression '>' ShiftExpression
917 // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
918 // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
919 // AndExpression ::= AndExpression '&' EqualityExpression
920 // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
921 // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
922 // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
923 // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
925 //optimize the push/pop
927 this.expressionPtr--;
928 this.expressionLengthPtr--;
929 Expression expr1 = this.expressionStack[this.expressionPtr];
930 Expression expr2 = this.expressionStack[this.expressionPtr + 1];
933 this.expressionStack[this.expressionPtr] =
934 new OR_OR_Expression(
940 this.expressionStack[this.expressionPtr] =
941 new AND_AND_Expression(
947 // look for "string1" + "string2"
948 if (this.optimizeStringLiterals) {
949 if (expr1 instanceof StringLiteral) {
950 if (expr2 instanceof CharLiteral) { // string+char
951 this.expressionStack[this.expressionPtr] =
952 ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
953 } else if (expr2 instanceof StringLiteral) { //string+string
954 this.expressionStack[this.expressionPtr] =
955 ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
957 this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
960 this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
962 } else if (expr1 instanceof StringLiteral) {
963 if (expr2 instanceof StringLiteral) {
965 this.expressionStack[this.expressionPtr] =
966 ((StringLiteral) expr1).extendsWith((StringLiteral) expr2);
968 this.expressionStack[this.expressionPtr] =
969 new BinaryExpression(
975 this.expressionStack[this.expressionPtr] =
976 new BinaryExpression(
983 this.expressionStack[this.expressionPtr] =
984 new BinaryExpression(
990 protected void consumeBlock() {
991 // Block ::= OpenBlock '{' BlockStatementsopt '}'
992 // simpler action for empty blocks
994 int statementsLength = this.astLengthStack[this.astLengthPtr--];
996 if (statementsLength == 0) { // empty block
997 block = new Block(0);
998 block.sourceStart = this.intStack[this.intPtr--];
999 block.sourceEnd = this.endStatementPosition;
1000 // check whether this block at least contains some comment in it
1001 if (!containsComment(block.sourceStart, block.sourceEnd)) {
1002 block.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1004 this.realBlockPtr--; // still need to pop the block variable counter
1006 block = new Block(this.realBlockStack[this.realBlockPtr--]);
1007 this.astPtr -= statementsLength;
1011 block.statements = new Statement[statementsLength],
1014 block.sourceStart = this.intStack[this.intPtr--];
1015 block.sourceEnd = this.endStatementPosition;
1017 pushOnAstStack(block);
1019 protected void consumeBlockStatements() {
1020 // BlockStatements ::= BlockStatements BlockStatement
1023 protected void consumeCaseLabel() {
1024 // SwitchLabel ::= 'case' ConstantExpression ':'
1025 this.expressionLengthPtr--;
1026 Expression expression = this.expressionStack[this.expressionPtr--];
1027 pushOnAstStack(new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]));
1029 protected void consumeCastExpression() {
1030 // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression
1031 // CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1033 //this.intStack : posOfLeftParen dim posOfRightParen
1035 //optimize the push/pop
1037 Expression exp, cast, castType;
1038 int end = this.intStack[this.intPtr--];
1039 this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
1040 castType.sourceEnd = end - 1;
1041 castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1042 cast.sourceEnd = exp.sourceEnd;
1044 protected void consumeCastExpressionLL1() {
1045 //CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
1046 // Expression is used in order to make the grammar LL1
1050 Expression cast,exp;
1051 this.expressionPtr--;
1052 this.expressionStack[this.expressionPtr] =
1053 cast = new CastExpression(
1054 exp=this.expressionStack[this.expressionPtr+1] ,
1055 getTypeReference(this.expressionStack[this.expressionPtr]));
1056 this.expressionLengthPtr -- ;
1057 updateSourcePosition(cast);
1058 cast.sourceEnd=exp.sourceEnd;
1060 protected void consumeCatches() {
1061 // Catches ::= Catches CatchClause
1062 optimizedConcatNodeLists();
1064 protected void consumeCatchHeader() {
1065 // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1067 if (this.currentElement == null){
1068 return; // should never occur, this consumeRule is only used in recovery mode
1070 // current element should be a block due to the presence of the opening brace
1071 if (!(this.currentElement instanceof RecoveredBlock)){
1072 if(!(this.currentElement instanceof RecoveredMethod)) {
1075 RecoveredMethod rMethod = (RecoveredMethod) this.currentElement;
1076 if(!(rMethod.methodBody == null && rMethod.bracketBalance > 0)) {
1081 Argument arg = (Argument)this.astStack[this.astPtr--];
1082 // convert argument to local variable
1083 LocalDeclaration localDeclaration = new LocalDeclaration(arg.name, arg.sourceStart, arg.sourceEnd);
1084 localDeclaration.type = arg.type;
1085 localDeclaration.declarationSourceStart = arg.declarationSourceStart;
1086 localDeclaration.declarationSourceEnd = arg.declarationSourceEnd;
1088 this.currentElement = this.currentElement.add(localDeclaration, 0);
1089 this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
1090 this.restartRecovery = true; // request to restart from here on
1091 this.lastIgnoredToken = -1;
1093 protected void consumeClassBodyDeclaration() {
1094 // ClassBodyDeclaration ::= Diet Block
1095 //push an Initializer
1096 //optimize the push/pop
1097 this.nestedMethod[this.nestedType]--;
1098 Block block = (Block) this.astStack[this.astPtr];
1099 if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlockMASK; // clear bit since was diet
1100 Initializer initializer = new Initializer(block, 0);
1101 this.intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1102 initializer.bodyStart = this.intStack[this.intPtr--];
1103 this.realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1104 int javadocCommentStart = this.intStack[this.intPtr--];
1105 if (javadocCommentStart != -1) {
1106 initializer.declarationSourceStart = javadocCommentStart;
1107 initializer.javadoc = this.javadoc;
1108 this.javadoc = null;
1110 this.astStack[this.astPtr] = initializer;
1111 initializer.bodyEnd = this.endPosition;
1112 initializer.sourceEnd = this.endStatementPosition;
1113 initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1115 protected void consumeClassBodyDeclarations() {
1116 // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1119 protected void consumeClassBodyDeclarationsopt() {
1120 // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1123 protected void consumeClassBodyopt() {
1124 // ClassBodyopt ::= $empty
1125 pushOnAstStack(null);
1126 this.endPosition = this.scanner.startPosition - 1;
1128 protected void consumeClassDeclaration() {
1129 // ClassDeclaration ::= ClassHeader ClassBody
1132 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1133 //there are length declarations
1134 //dispatch according to the type of the declarations
1135 dispatchDeclarationInto(length);
1138 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1140 // mark initializers with local type mark if needed
1141 markInitializersWithLocalType(typeDecl);
1143 //convert constructor that do not have the type's name into methods
1144 boolean hasConstructor = typeDecl.checkConstructors(this);
1146 //add the default constructor when needed (interface don't have it)
1147 if (!hasConstructor && !typeDecl.isInterface()) {
1148 boolean insideFieldInitializer = false;
1150 for (int i = this.nestedType; i > 0; i--){
1151 if (this.variablesCounter[i] > 0) {
1152 insideFieldInitializer = true;
1157 typeDecl.createsInternalConstructor(!this.diet || insideFieldInitializer, true);
1160 //always add <clinit> (will be remove at code gen time if empty)
1161 if (this.scanner.containsAssertKeyword) {
1162 typeDecl.bits |= ASTNode.AddAssertionMASK;
1164 typeDecl.addClinit();
1165 typeDecl.bodyEnd = this.endStatementPosition;
1166 if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
1167 typeDecl.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1170 typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1172 protected void consumeClassHeader() {
1173 // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1175 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1176 if (this.currentToken == TokenNameLBRACE) {
1177 typeDecl.bodyStart = this.scanner.currentPosition;
1179 if (this.currentElement != null) {
1180 this.restartRecovery = true; // used to avoid branching back into the regular automaton
1182 // flush the comments related to the class header
1183 this.scanner.commentPtr = -1;
1185 protected void consumeClassHeaderExtends() {
1186 // ClassHeaderExtends ::= 'extends' ClassType
1187 // There is a class declaration on the top of stack
1188 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1190 typeDecl.superclass = getTypeReference(0);
1191 typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1193 if (this.currentElement != null){
1194 this.lastCheckPoint = typeDecl.bodyStart;
1197 protected void consumeClassHeaderImplements() {
1198 // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1199 int length = this.astLengthStack[this.astLengthPtr--];
1201 this.astPtr -= length;
1202 // There is a class declaration on the top of stack
1203 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
1207 typeDecl.superInterfaces = new TypeReference[length],
1210 typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
1211 this.listLength = 0; // reset after having read super-interfaces
1213 if (this.currentElement != null) { // is recovering
1214 this.lastCheckPoint = typeDecl.bodyStart;
1217 protected void consumeClassHeaderName() {
1218 // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1219 TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1220 if (this.nestedMethod[this.nestedType] == 0) {
1221 if (this.nestedType != 0) {
1222 typeDecl.bits |= ASTNode.IsMemberTypeMASK;
1225 // Record that the block has a declaration for local types
1226 typeDecl.bits |= ASTNode.IsLocalTypeMASK;
1227 markEnclosingMemberWithLocalType();
1231 //highlight the name of the type
1232 long pos = this.identifierPositionStack[this.identifierPtr];
1233 typeDecl.sourceEnd = (int) pos;
1234 typeDecl.sourceStart = (int) (pos >>> 32);
1235 typeDecl.name = this.identifierStack[this.identifierPtr--];
1236 this.identifierLengthPtr--;
1238 //compute the declaration source too
1239 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
1240 // we want to keep the beginning position but get rid of the end position
1241 // it is only used for the ClassLiteralAccess positions.
1242 typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
1243 this.intPtr--; // remove the end position of the class token
1245 typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
1246 typeDecl.modifiers = this.intStack[this.intPtr--];
1247 if (typeDecl.modifiersSourceStart >= 0) {
1248 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
1250 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
1251 pushOnAstStack(typeDecl);
1253 this.listLength = 0; // will be updated when reading super-interfaces
1255 if (this.currentElement != null){
1256 this.lastCheckPoint = typeDecl.bodyStart;
1257 this.currentElement = this.currentElement.add(typeDecl, 0);
1258 this.lastIgnoredToken = -1;
1261 typeDecl.javadoc = this.javadoc;
1262 this.javadoc = null;
1264 protected void consumeClassInstanceCreationExpression() {
1265 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1266 classInstanceCreation(false);
1268 protected void consumeClassInstanceCreationExpressionName() {
1269 // ClassInstanceCreationExpressionName ::= Name '.'
1270 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1272 protected void consumeClassInstanceCreationExpressionQualified() {
1273 // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1274 // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1276 classInstanceCreation(true); // <-- push the Qualifed....
1278 this.expressionLengthPtr--;
1279 QualifiedAllocationExpression qae =
1280 (QualifiedAllocationExpression) this.expressionStack[this.expressionPtr--];
1281 qae.enclosingInstance = this.expressionStack[this.expressionPtr];
1282 this.expressionStack[this.expressionPtr] = qae;
1283 qae.sourceStart = qae.enclosingInstance.sourceStart;
1285 protected void consumeClassTypeElt() {
1286 // ClassTypeElt ::= ClassType
1287 pushOnAstStack(getTypeReference(0));
1288 /* if incomplete thrown exception list, listLength counter will not have been reset,
1289 indicating that some items are available on the stack */
1292 protected void consumeClassTypeList() {
1293 // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
1294 optimizedConcatNodeLists();
1296 protected void consumeCompilationUnit() {
1297 // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
1298 // do nothing by default
1300 protected void consumeConditionalExpression(int op) {
1301 // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
1302 //optimize the push/pop
1304 this.expressionPtr -= 2;
1305 this.expressionLengthPtr -= 2;
1306 this.expressionStack[this.expressionPtr] =
1307 new ConditionalExpression(
1308 this.expressionStack[this.expressionPtr],
1309 this.expressionStack[this.expressionPtr + 1],
1310 this.expressionStack[this.expressionPtr + 2]);
1312 protected void consumeConstructorBlockStatements() {
1313 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
1314 concatNodeLists(); // explictly add the first statement into the list of statements
1316 protected void consumeConstructorBody() {
1317 // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
1318 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
1319 this.nestedMethod[this.nestedType] --;
1321 protected void consumeConstructorDeclaration() {
1322 // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
1325 astStack : MethodDeclaration statements
1326 identifierStack : name
1328 astStack : MethodDeclaration
1332 //must provide a default constructor call when needed
1336 // pop the position of the { (body of the method) pushed in block decl
1341 this.realBlockPtr--;
1342 ExplicitConstructorCall constructorCall = null;
1343 Statement[] statements = null;
1344 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1345 this.astPtr -= length;
1346 if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) {
1347 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
1351 statements = new Statement[length - 1],
1354 constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
1355 } else { //need to add explicitly the super();
1359 statements = new Statement[length],
1362 constructorCall = SuperReference.implicitSuperConstructorCall();
1365 boolean insideFieldInitializer = false;
1367 for (int i = this.nestedType; i > 0; i--){
1368 if (this.variablesCounter[i] > 0) {
1369 insideFieldInitializer = true;
1375 if (!this.diet || insideFieldInitializer){
1376 // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
1377 constructorCall = SuperReference.implicitSuperConstructorCall();
1381 // now we know that the top of stack is a constructorDeclaration
1382 ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
1383 cd.constructorCall = constructorCall;
1384 cd.statements = statements;
1386 //highlight of the implicit call on the method name
1387 if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
1388 cd.constructorCall.sourceEnd = cd.sourceEnd;
1389 cd.constructorCall.sourceStart = cd.sourceStart;
1392 if (!this.diet && (statements == null && constructorCall.isImplicitSuper())) {
1393 if (!containsComment(cd.bodyStart, this.endPosition)) {
1394 cd.bits |= ASTNode.UndocumentedEmptyBlockMASK;
1398 //watch for } that could be given as a unicode ! ( u007D is '}' )
1399 // store the endPosition (position just before the '}') in case there is
1400 // a trailing comment behind the end of the method
1401 cd.bodyEnd = this.endPosition;
1402 cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1405 protected void consumeInvalidConstructorDeclaration() {
1406 // ConstructorDeclaration ::= ConstructorHeader ';'
1407 // now we know that the top of stack is a constructorDeclaration
1408 ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
1410 cd.bodyEnd = this.endPosition; // position just before the trailing semi-colon
1411 cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
1412 // report the problem and continue the parsing - narrowing the problem onto the method
1414 cd.modifiers |= AccSemicolonBody; // remember semi-colon body
1416 protected void consumeConstructorHeader() {
1417 // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
1419 AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
1421 if (this.currentToken == TokenNameLBRACE){
1422 method.bodyStart = this.scanner.currentPosition;
1425 if (this.currentElement != null){
1426 if (this.currentToken == TokenNameSEMICOLON){ // for invalid constructors
1427 method.modifiers |= AccSemicolonBody;
1428 method.declarationSourceEnd = this.scanner.currentPosition-1;
1429 method.bodyEnd = this.scanner.currentPosition-1;
1430 if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
1431 this.currentElement = this.currentElement.parent;
1434 this.restartRecovery = true; // used to avoid branching back into the regular automaton
1437 protected void consumeConstructorHeaderName() {
1439 /* recovering - might be an empty message send */
1440 if (this.currentElement != null){
1441 if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
1442 this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
1443 this.restartRecovery = true;
1448 // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
1449 ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
1451 //name -- this is not really revelant but we do .....
1452 cd.selector = this.identifierStack[this.identifierPtr];
1453 long selectorSource = this.identifierPositionStack[this.identifierPtr--];
1454 this.identifierLengthPtr--;
1457 cd.declarationSourceStart = this.intStack[this.intPtr--];
1458 cd.modifiers = this.intStack[this.intPtr--];
1460 cd.javadoc = this.javadoc;
1461 this.javadoc = null;
1463 //highlight starts at the selector starts
1464 cd.sourceStart = (int) (selectorSource >>> 32);
1466 cd.sourceEnd = this.lParenPos;
1467 cd.bodyStart = this.lParenPos+1;
1468 this.listLength = 0; // initialize listLength before reading parameters/throws
1471 if (this.currentElement != null){
1472 this.lastCheckPoint = cd.bodyStart;
1473 if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
1474 || cd.modifiers != 0){
1475 this.currentElement = this.currentElement.add(cd, 0);
1476 this.lastIgnoredToken = -1;
1480 protected void consumeDefaultLabel() {
1481 // SwitchLabel ::= 'default' ':'
1482 pushOnAstStack(new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]));
1484 protected void consumeDefaultModifiers() {
1485 checkComment(); // might update modifiers with AccDeprecated
1486 pushOnIntStack(this.modifiers); // modifiers
1488 this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
1491 protected void consumeDiet() {
1494 pushOnIntStack(this.modifiersSourceStart); // push the start position of a javadoc comment if there is one
1496 jumpOverMethodBody();
1498 protected void consumeDims() {
1499 // Dims ::= DimsLoop
1500 pushOnIntStack(this.dimensions);
1501 this.dimensions = 0;
1503 protected void consumeDimWithOrWithOutExpr() {
1504 // DimWithOrWithOutExpr ::= '[' ']'
1505 pushOnExpressionStack(null);
1507 if(this.currentElement != null && this.currentToken == TokenNameLBRACE) {
1508 this.ignoreNextOpeningBrace = true;
1509 this.currentElement.bracketBalance++;
1512 protected void consumeDimWithOrWithOutExprs() {
1513 // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
1514 concatExpressionLists();
1516 protected void consumeEmptyArgumentListopt() {
1517 // ArgumentListopt ::= $empty
1518 pushOnExpressionStackLengthStack(0);
1520 protected void consumeEmptyArrayInitializer() {
1521 // ArrayInitializer ::= '{' ,opt '}'
1522 arrayInitializer(0);
1524 protected void consumeEmptyArrayInitializeropt() {
1525 // ArrayInitializeropt ::= $empty
1526 pushOnExpressionStackLengthStack(0);
1528 protected void consumeEmptyBlockStatementsopt() {
1529 // BlockStatementsopt ::= $empty
1530 pushOnAstLengthStack(0);
1532 protected void consumeEmptyCatchesopt() {
1533 // Catchesopt ::= $empty
1534 pushOnAstLengthStack(0);
1536 protected void consumeEmptyClassBodyDeclarationsopt() {
1537 // ClassBodyDeclarationsopt ::= $empty
1538 pushOnAstLengthStack(0);
1540 protected void consumeEmptyClassMemberDeclaration() {
1541 // ClassMemberDeclaration ::= ';'
1542 pushOnAstLengthStack(0);
1543 problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
1544 flushCommentsDefinedPriorTo(this.endStatementPosition);
1546 protected void consumeEmptyDimsopt() {
1547 // Dimsopt ::= $empty
1550 protected void consumeEmptyExpression() {
1551 // Expressionopt ::= $empty
1552 pushOnExpressionStackLengthStack(0);
1554 protected void consumeEmptyForInitopt() {
1555 // ForInitopt ::= $empty
1556 pushOnAstLengthStack(0);
1558 protected void consumeEmptyForUpdateopt() {
1559 // ForUpdateopt ::= $empty
1560 pushOnExpressionStackLengthStack(0);
1562 protected void consumeEmptyImportDeclarationsopt() {
1563 // ImportDeclarationsopt ::= $empty
1564 pushOnAstLengthStack(0);
1566 protected void consumeEmptyInterfaceMemberDeclaration() {
1567 // InterfaceMemberDeclaration ::= ';'
1568 pushOnAstLengthStack(0);
1570 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
1571 // InterfaceMemberDeclarationsopt ::= $empty
1572 pushOnAstLengthStack(0);
1574 protected void consumeEmptyStatement() {
1575 // EmptyStatement ::= ';'
1576 if (this.scanner.source[this.endStatementPosition] == ';') {
1577 pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition));
1579 // we have a Unicode for the ';' (/u003B)
1580 pushOnAstStack(new EmptyStatement(this.endStatementPosition - 5, this.endStatementPosition));
1583 protected void consumeEmptySwitchBlock() {
1584 // SwitchBlock ::= '{' '}'
1585 pushOnAstLengthStack(0);
1587 protected void consumeEmptyTypeDeclaration() {
1588 // TypeDeclaration ::= ';'
1589 pushOnAstLengthStack(0);
1590 problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
1591 flushCommentsDefinedPriorTo(this.endStatementPosition);
1593 protected void consumeEmptyTypeDeclarationsopt() {
1594 // TypeDeclarationsopt ::= $empty
1595 pushOnAstLengthStack(0);
1597 protected void consumeEnterAnonymousClassBody() {
1598 // EnterAnonymousClassBody ::= $empty
1599 QualifiedAllocationExpression alloc;
1600 TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
1601 anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
1602 anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
1603 alloc = anonymousType.allocation = new QualifiedAllocationExpression(anonymousType);
1604 markEnclosingMemberWithLocalType();
1605 pushOnAstStack(anonymousType);
1607 alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
1609 if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1610 this.expressionPtr -= argumentLength;
1612 this.expressionStack,
1613 this.expressionPtr + 1,
1614 alloc.arguments = new Expression[argumentLength],
1618 alloc.type = getTypeReference(0);
1620 anonymousType.sourceEnd = alloc.sourceEnd;
1621 //position at the type while it impacts the anonymous declaration
1622 anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
1623 alloc.sourceStart = this.intStack[this.intPtr--];
1624 pushOnExpressionStack(alloc);
1626 anonymousType.bodyStart = this.scanner.currentPosition;
1627 this.listLength = 0; // will be updated when reading super-interfaces
1629 if (this.currentElement != null){
1630 this.lastCheckPoint = anonymousType.bodyStart;
1631 this.currentElement = this.currentElement.add(anonymousType, 0);
1632 this.currentToken = 0; // opening brace already taken into account
1633 this.lastIgnoredToken = -1;
1636 protected void consumeEnterCompilationUnit() {
1637 // EnterCompilationUnit ::= $empty
1638 // do nothing by default
1640 protected void consumeEnterVariable() {
1641 // EnterVariable ::= $empty
1642 // do nothing by default
1644 char[] identifierName = this.identifierStack[this.identifierPtr];
1645 long namePosition = this.identifierPositionStack[this.identifierPtr];
1646 int extendedDimension = this.intStack[this.intPtr--];
1647 AbstractVariableDeclaration declaration;
1648 // create the ast node
1649 boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
1650 if (isLocalDeclaration) {
1651 // create the local variable declarations
1653 this.createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
1655 // create the field declaration
1657 this.createFieldDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
1660 this.identifierPtr--;
1661 this.identifierLengthPtr--;
1663 int variableIndex = this.variablesCounter[this.nestedType];
1665 if (variableIndex == 0) {
1666 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
1667 if (isLocalDeclaration) {
1668 declaration.declarationSourceStart = this.intStack[this.intPtr--];
1669 declaration.modifiers = this.intStack[this.intPtr--];
1670 type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
1671 if (declaration.declarationSourceStart == -1) {
1672 // this is true if there is no modifiers for the local variable declaration
1673 declaration.declarationSourceStart = type.sourceStart;
1675 pushOnAstStack(type);
1677 type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
1678 pushOnAstStack(type);
1679 declaration.declarationSourceStart = this.intStack[this.intPtr--];
1680 declaration.modifiers = this.intStack[this.intPtr--];
1682 // Store javadoc only on first declaration as it is the same for all ones
1683 FieldDeclaration fieldDeclaration = (FieldDeclaration) declaration;
1684 fieldDeclaration.javadoc = this.javadoc;
1685 this.javadoc = null;
1688 type = (TypeReference) this.astStack[this.astPtr - variableIndex];
1689 typeDim = type.dimensions();
1690 AbstractVariableDeclaration previousVariable =
1691 (AbstractVariableDeclaration) this.astStack[this.astPtr];
1692 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
1693 declaration.modifiers = previousVariable.modifiers;
1696 if (extendedDimension == 0) {
1697 declaration.type = type;
1699 int dimension = typeDim + extendedDimension;
1700 //on the identifierLengthStack there is the information about the type....
1702 if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
1704 int typeSourceStart = type.sourceStart;
1705 int typeSourceEnd = type.sourceEnd;
1706 type = TypeReference.baseTypeReference(-baseType, dimension);
1707 type.sourceStart = typeSourceStart;
1708 type.sourceEnd = typeSourceEnd;
1709 declaration.type = type;
1711 declaration.type = this.copyDims(type, dimension);
1714 this.variablesCounter[this.nestedType]++;
1715 pushOnAstStack(declaration);
1717 if (this.currentElement != null) {
1718 if (!(this.currentElement instanceof RecoveredType)
1719 && (this.currentToken == TokenNameDOT
1720 //|| declaration.modifiers != 0
1721 || (this.scanner.getLineNumber(declaration.type.sourceStart)
1722 != this.scanner.getLineNumber((int) (namePosition >>> 32))))){
1723 this.lastCheckPoint = (int) (namePosition >>> 32);
1724 this.restartRecovery = true;
1727 if (isLocalDeclaration){
1728 LocalDeclaration localDecl = (LocalDeclaration) this.astStack[this.astPtr];
1729 this.lastCheckPoint = localDecl.sourceEnd + 1;
1730 this.currentElement = this.currentElement.add(localDecl, 0);
1732 FieldDeclaration fieldDecl = (FieldDeclaration) this.astStack[this.astPtr];
1733 this.lastCheckPoint = fieldDecl.sourceEnd + 1;
1734 this.currentElement = this.currentElement.add(fieldDecl, 0);
1736 this.lastIgnoredToken = -1;
1739 protected void consumeEqualityExpression(int op) {
1740 // EqualityExpression ::= EqualityExpression '==' RelationalExpression
1741 // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
1743 //optimize the push/pop
1745 this.expressionPtr--;
1746 this.expressionLengthPtr--;
1747 this.expressionStack[this.expressionPtr] =
1748 new EqualExpression(
1749 this.expressionStack[this.expressionPtr],
1750 this.expressionStack[this.expressionPtr + 1],
1753 protected void consumeExitTryBlock() {
1754 //ExitTryBlock ::= $empty
1755 if(this.currentElement != null) {
1756 this.restartRecovery = true;
1759 protected void consumeExitVariableWithInitialization() {
1760 // ExitVariableWithInitialization ::= $empty
1761 // do nothing by default
1762 this.expressionLengthPtr--;
1763 AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
1764 variableDecl.initialization = this.expressionStack[this.expressionPtr--];
1765 // we need to update the declarationSourceEnd of the local variable declaration to the
1766 // source end position of the initialization expression
1767 variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
1768 variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
1770 this.recoveryExitFromVariable();
1772 protected void consumeExitVariableWithoutInitialization() {
1773 // ExitVariableWithoutInitialization ::= $empty
1774 // do nothing by default
1776 AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
1777 variableDecl.declarationSourceEnd = variableDecl.declarationEnd;
1779 this.recoveryExitFromVariable();
1781 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
1783 /* flag allows to distinguish 3 cases :
1785 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
1786 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
1788 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
1789 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
1791 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
1792 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
1794 int startPosition = this.intStack[this.intPtr--];
1795 ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
1797 if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
1798 this.expressionPtr -= length;
1799 System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
1803 ecc.sourceStart = startPosition;
1806 this.expressionLengthPtr--;
1807 ecc.sourceStart = (ecc.qualification = this.expressionStack[this.expressionPtr--]).sourceStart;
1810 ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
1813 pushOnAstStack(ecc);
1814 ecc.sourceEnd = this.endPosition;
1816 protected void consumeExpressionStatement() {
1817 // ExpressionStatement ::= StatementExpression ';'
1818 this.expressionLengthPtr--;
1819 pushOnAstStack(this.expressionStack[this.expressionPtr--]);
1821 protected void consumeFieldAccess(boolean isSuperAccess) {
1822 // FieldAccess ::= Primary '.' 'Identifier'
1823 // FieldAccess ::= 'super' '.' 'Identifier'
1827 this.identifierStack[this.identifierPtr],
1828 this.identifierPositionStack[this.identifierPtr--]);
1829 this.identifierLengthPtr--;
1830 if (isSuperAccess) {
1831 //considerates the fieldReference beginning at the 'super' ....
1832 fr.sourceStart = this.intStack[this.intPtr--];
1833 fr.receiver = new SuperReference(fr.sourceStart, this.endPosition);
1834 pushOnExpressionStack(fr);
1837 if ((fr.receiver = this.expressionStack[this.expressionPtr]).isThis()) {
1838 //fieldreference begins at the this
1839 fr.sourceStart = fr.receiver.sourceStart;
1841 this.expressionStack[this.expressionPtr] = fr;
1844 protected void consumeFieldDeclaration() {
1845 // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
1846 // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
1850 expressionStack: Expression Expression ...... Expression
1851 identifierStack : type identifier identifier ...... identifier
1852 intStack : typeDim dim dim dim
1854 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
1860 int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
1862 for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
1863 FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
1864 fieldDeclaration.declarationSourceEnd = this.endStatementPosition;
1865 fieldDeclaration.declarationEnd = this.endStatementPosition; // semi-colon included
1868 updateSourceDeclarationParts(variableDeclaratorsCounter);
1869 int endPos = flushCommentsDefinedPriorTo(this.endStatementPosition);
1870 if (endPos != this.endStatementPosition) {
1871 for (int i = 0; i < variableDeclaratorsCounter; i++) {
1872 FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
1873 fieldDeclaration.declarationSourceEnd = endPos;
1876 // update the astStack, astPtr and astLengthStack
1877 int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
1883 variableDeclaratorsCounter);
1884 this.astPtr--; // remove the type reference
1885 this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
1888 if (this.currentElement != null) {
1889 this.lastCheckPoint = endPos + 1;
1890 if (this.currentElement.parent != null && this.currentElement instanceof RecoveredField){
1891 if (!(this.currentElement instanceof RecoveredInitializer)) {
1892 this.currentElement = this.currentElement.parent;
1895 this.restartRecovery = true;
1897 this.variablesCounter[this.nestedType] = 0;
1899 protected void consumeForceNoDiet() {
1900 // ForceNoDiet ::= $empty
1903 protected void consumeForInit() {
1904 // ForInit ::= StatementExpressionList
1905 pushOnAstLengthStack(-1);
1907 protected void consumeFormalParameter() {
1908 // FormalParameter ::= Type VariableDeclaratorId ==> false
1909 // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
1912 identifierStack : type identifier
1920 this.identifierLengthPtr--;
1921 char[] identifierName = this.identifierStack[this.identifierPtr];
1922 long namePositions = this.identifierPositionStack[this.identifierPtr--];
1923 TypeReference type = getTypeReference(this.intStack[this.intPtr--] + this.intStack[this.intPtr--]);
1924 int modifierPositions = this.intStack[this.intPtr--];
1931 this.intStack[this.intPtr + 1] & ~AccDeprecated); // modifiers
1932 arg.declarationSourceStart = modifierPositions;
1933 pushOnAstStack(arg);
1935 /* if incomplete method header, listLength counter will not have been reset,
1936 indicating that some arguments are available on the stack */
1939 protected void consumeFormalParameterList() {
1940 // FormalParameterList ::= FormalParameterList ',' FormalParameter
1941 optimizedConcatNodeLists();
1943 protected void consumeFormalParameterListopt() {
1944 // FormalParameterListopt ::= $empty
1945 pushOnAstLengthStack(0);
1947 protected void consumeImportDeclarations() {
1948 // ImportDeclarations ::= ImportDeclarations ImportDeclaration
1949 optimizedConcatNodeLists();
1951 protected void consumeImportDeclarationsopt() {
1952 // ImportDeclarationsopt ::= ImportDeclarations
1954 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1955 this.astPtr -= length;
1959 this.compilationUnit.imports = new ImportReference[length],
1964 protected void consumeInsideCastExpression() {
1965 // InsideCastExpression ::= $empty
1967 protected void consumeInsideCastExpressionLL1() {
1968 // InsideCastExpressionLL1 ::= $empty
1971 protected void consumeInstanceOfExpression(int op) {
1972 // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
1973 //optimize the push/pop
1975 //by construction, no base type may be used in getTypeReference
1977 this.expressionStack[this.expressionPtr] = exp =
1978 new InstanceOfExpression(
1979 this.expressionStack[this.expressionPtr],
1980 getTypeReference(this.intStack[this.intPtr--]),
1982 if (exp.sourceEnd == 0) {
1983 //array on base type....
1984 exp.sourceEnd = this.scanner.startPosition - 1;
1986 //the scanner is on the next token already....
1988 protected void consumeInterfaceDeclaration() {
1989 // see consumeClassDeclaration in case of changes: duplicated code
1990 // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
1992 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
1993 //there are length declarations
1994 //dispatch.....according to the type of the declarations
1995 dispatchDeclarationInto(length);
1998 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2000 // mark initializers with local type mark if needed
2001 markInitializersWithLocalType(typeDecl);
2003 //convert constructor that do not have the type's name into methods
2004 typeDecl.checkConstructors(this);
2006 //always add <clinit> (will be remove at code gen time if empty)
2007 if (this.scanner.containsAssertKeyword) {
2008 typeDecl.bits |= ASTNode.AddAssertionMASK;
2010 typeDecl.addClinit();
2011 typeDecl.bodyEnd = this.endStatementPosition;
2012 if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
2013 typeDecl.bits |= ASTNode.UndocumentedEmptyBlockMASK;
2015 typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2017 protected void consumeInterfaceHeader() {
2018 // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2020 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2021 if (this.currentToken == TokenNameLBRACE){
2022 typeDecl.bodyStart = this.scanner.currentPosition;
2024 if (this.currentElement != null){
2025 this.restartRecovery = true; // used to avoid branching back into the regular automaton
2027 // flush the comments related to the interface header
2028 this.scanner.commentPtr = -1;
2030 protected void consumeInterfaceHeaderExtends() {
2031 // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2032 int length = this.astLengthStack[this.astLengthPtr--];
2034 this.astPtr -= length;
2035 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
2039 typeDecl.superInterfaces = new TypeReference[length],
2042 typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
2043 this.listLength = 0; // reset after having read super-interfaces
2045 if (this.currentElement != null) {
2046 this.lastCheckPoint = typeDecl.bodyStart;
2049 protected void consumeInterfaceHeaderName() {
2050 // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2051 TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2053 if (this.nestedMethod[this.nestedType] == 0) {
2054 if (this.nestedType != 0) {
2055 typeDecl.bits |= ASTNode.IsMemberTypeMASK;
2058 // Record that the block has a declaration for local types
2059 typeDecl.bits |= ASTNode.IsLocalTypeMASK;
2060 markEnclosingMemberWithLocalType();
2064 //highlight the name of the type
2065 long pos = this.identifierPositionStack[this.identifierPtr];
2066 typeDecl.sourceEnd = (int) pos;
2067 typeDecl.sourceStart = (int) (pos >>> 32);
2068 typeDecl.name = this.identifierStack[this.identifierPtr--];
2069 this.identifierLengthPtr--;
2071 //compute the declaration source too
2072 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2073 // we want to keep the beginning position but get rid of the end position
2074 // it is only used for the ClassLiteralAccess positions.
2075 typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
2076 this.intPtr--; // remove the end position of the class token
2077 typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
2078 typeDecl.modifiers = this.intStack[this.intPtr--];
2079 if (typeDecl.modifiersSourceStart >= 0) {
2080 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2082 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2083 pushOnAstStack(typeDecl);
2084 this.listLength = 0; // will be updated when reading super-interfaces
2086 if (this.currentElement != null){ // is recovering
2087 this.lastCheckPoint = typeDecl.bodyStart;
2088 this.currentElement = this.currentElement.add(typeDecl, 0);
2089 this.lastIgnoredToken = -1;
2092 typeDecl.javadoc = this.javadoc;
2093 this.javadoc = null;
2095 protected void consumeInterfaceMemberDeclarations() {
2096 // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2099 protected void consumeInterfaceMemberDeclarationsopt() {
2100 // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2103 protected void consumeInterfaceType() {
2104 // InterfaceType ::= ClassOrInterfaceType
2105 pushOnAstStack(getTypeReference(0));
2106 /* if incomplete type header, listLength counter will not have been reset,
2107 indicating that some interfaces are available on the stack */
2110 protected void consumeInterfaceTypeList() {
2111 // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2112 optimizedConcatNodeLists();
2114 protected void consumeLeftParen() {
2115 // PushLPAREN ::= '('
2116 pushOnIntStack(this.lParenPos);
2118 protected void consumeLocalVariableDeclaration() {
2119 // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2123 expressionStack: Expression Expression ...... Expression
2124 identifierStack : type identifier identifier ...... identifier
2125 intStack : typeDim dim dim dim
2127 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2133 int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
2135 // update the astStack, astPtr and astLengthStack
2136 int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
2142 variableDeclaratorsCounter);
2143 this.astPtr--; // remove the type reference
2144 this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
2145 this.variablesCounter[this.nestedType] = 0;
2147 protected void consumeLocalVariableDeclarationStatement() {
2148 // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2149 // see blockReal in case of change: duplicated code
2150 // increment the amount of declared variables for this block
2151 this.realBlockStack[this.realBlockPtr]++;
2153 // update source end to include the semi-colon
2154 int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
2155 for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2156 LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr - i];
2157 localDeclaration.declarationSourceEnd = this.endStatementPosition;
2158 localDeclaration.declarationEnd = this.endStatementPosition; // semi-colon included
2162 protected void consumeMethodBody() {
2163 // MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
2164 this.nestedMethod[this.nestedType] --;
2166 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2167 // MethodDeclaration ::= MethodHeader MethodBody
2168 // AbstractMethodDeclaration ::= MethodHeader ';'
2171 astStack : modifiers arguments throws statements
2172 identifierStack : type name
2173 intStack : dim dim dim
2175 astStack : MethodDeclaration
2181 if (isNotAbstract) {
2182 // pop the position of the { (body of the method) pushed in block decl
2187 int explicitDeclarations = 0;
2188 Statement[] statements = null;
2189 if (isNotAbstract) {
2191 explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
2192 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
2195 (this.astPtr -= length) + 1,
2196 statements = new Statement[length],
2202 // now we know that we have a method declaration at the top of the ast stack
2203 MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
2204 md.statements = statements;
2205 md.explicitDeclarations = explicitDeclarations;
2207 // cannot be done in consumeMethodHeader because we have no idea whether or not there
2208 // is a body when we reduce the method header
2209 if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2210 md.modifiers |= AccSemicolonBody;
2212 if (!this.diet && statements == null) {
2213 if (!containsComment(md.bodyStart, this.endPosition)) {
2214 md.bits |= ASTNode.UndocumentedEmptyBlockMASK;
2218 // store the endPosition (position just before the '}') in case there is
2219 // a trailing comment behind the end of the method
2220 md.bodyEnd = this.endPosition;
2221 md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
2223 protected void consumeMethodHeader() {
2224 // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2225 // retrieve end position of method declarator
2226 AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2228 if (this.currentToken == TokenNameLBRACE){
2229 method.bodyStart = this.scanner.currentPosition;
2232 if (this.currentElement != null){
2233 if (this.currentToken == TokenNameSEMICOLON){
2234 method.modifiers |= AccSemicolonBody;
2235 method.declarationSourceEnd = this.scanner.currentPosition-1;
2236 method.bodyEnd = this.scanner.currentPosition-1;
2237 if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
2238 this.currentElement = this.currentElement.parent;
2241 this.restartRecovery = true; // used to avoid branching back into the regular automaton
2244 protected void consumeMethodHeaderExtendedDims() {
2245 // MethodHeaderExtendedDims ::= Dimsopt
2246 // now we update the returnType of the method
2247 MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
2248 int extendedDims = this.intStack[this.intPtr--];
2249 if (extendedDims != 0) {
2250 TypeReference returnType = md.returnType;
2251 md.sourceEnd = this.endPosition;
2252 int dims = returnType.dimensions() + extendedDims;
2254 if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
2256 int sourceStart = returnType.sourceStart;
2257 int sourceEnd = returnType.sourceEnd;
2258 returnType = TypeReference.baseTypeReference(-baseType, dims);
2259 returnType.sourceStart = sourceStart;
2260 returnType.sourceEnd = sourceEnd;
2261 md.returnType = returnType;
2263 md.returnType = this.copyDims(md.returnType, dims);
2265 if (this.currentToken == TokenNameLBRACE){
2266 md.bodyStart = this.endPosition + 1;
2269 if (this.currentElement != null){
2270 this.lastCheckPoint = md.bodyStart;
2274 protected void consumeMethodHeaderName() {
2275 // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2276 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2279 md.selector = this.identifierStack[this.identifierPtr];
2280 long selectorSource = this.identifierPositionStack[this.identifierPtr--];
2281 this.identifierLengthPtr--;
2283 md.returnType = getTypeReference(this.intStack[this.intPtr--]);
2285 md.declarationSourceStart = this.intStack[this.intPtr--];
2286 md.modifiers = this.intStack[this.intPtr--];
2288 md.javadoc = this.javadoc;
2289 this.javadoc = null;
2291 //highlight starts at selector start
2292 md.sourceStart = (int) (selectorSource >>> 32);
2294 md.sourceEnd = this.lParenPos;
2295 md.bodyStart = this.lParenPos+1;
2296 this.listLength = 0; // initialize listLength before reading parameters/throws
2299 if (this.currentElement != null){
2300 if (this.currentElement instanceof RecoveredType
2301 //|| md.modifiers != 0
2302 || (this.scanner.getLineNumber(md.returnType.sourceStart)
2303 == this.scanner.getLineNumber(md.sourceStart))){
2304 this.lastCheckPoint = md.bodyStart;
2305 this.currentElement = this.currentElement.add(md, 0);
2306 this.lastIgnoredToken = -1;
2308 this.lastCheckPoint = md.sourceStart;
2309 this.restartRecovery = true;
2313 protected void consumeMethodHeaderParameters() {
2314 // MethodHeaderParameters ::= FormalParameterListopt ')'
2315 int length = this.astLengthStack[this.astLengthPtr--];
2316 this.astPtr -= length;
2317 AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
2318 md.sourceEnd = this.rParenPos;
2324 md.arguments = new Argument[length],
2328 md.bodyStart = this.rParenPos+1;
2329 this.listLength = 0; // reset listLength after having read all parameters
2331 if (this.currentElement != null){
2332 this.lastCheckPoint = md.bodyStart;
2333 if (this.currentElement.parseTree() == md) return;
2335 // might not have been attached yet - in some constructor scenarii
2336 if (md.isConstructor()){
2338 || (this.currentToken == TokenNameLBRACE)
2339 || (this.currentToken == TokenNamethrows)){
2340 this.currentElement = this.currentElement.add(md, 0);
2341 this.lastIgnoredToken = -1;
2346 protected void consumeMethodHeaderThrowsClause() {
2347 // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2348 int length = this.astLengthStack[this.astLengthPtr--];
2349 this.astPtr -= length;
2350 AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
2354 md.thrownExceptions = new TypeReference[length],
2357 md.sourceEnd = md.thrownExceptions[length-1].sourceEnd;
2358 md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1;
2359 this.listLength = 0; // reset listLength after having read all thrown exceptions
2361 if (this.currentElement != null){
2362 this.lastCheckPoint = md.bodyStart;
2365 protected void consumeMethodInvocationName() {
2366 // MethodInvocation ::= Name '(' ArgumentListopt ')'
2368 // when the name is only an identifier...we have a message send to "this" (implicit)
2370 MessageSend m = newMessageSend();
2371 m.sourceEnd = this.rParenPos;
2373 (int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
2374 m.selector = this.identifierStack[this.identifierPtr--];
2375 if (this.identifierLengthStack[this.identifierLengthPtr] == 1) {
2376 m.receiver = ThisReference.implicitThis();
2377 this.identifierLengthPtr--;
2379 this.identifierLengthStack[this.identifierLengthPtr]--;
2380 m.receiver = getUnspecifiedReference();
2381 m.sourceStart = m.receiver.sourceStart;
2383 pushOnExpressionStack(m);
2385 protected void consumeMethodInvocationPrimary() {
2386 //optimize the push/pop
2387 //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2389 MessageSend m = newMessageSend();
2391 (int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
2392 m.selector = this.identifierStack[this.identifierPtr--];
2393 this.identifierLengthPtr--;
2394 m.receiver = this.expressionStack[this.expressionPtr];
2395 m.sourceStart = m.receiver.sourceStart;
2396 m.sourceEnd = this.rParenPos;
2397 this.expressionStack[this.expressionPtr] = m;
2399 protected void consumeMethodInvocationSuper() {
2400 // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2402 MessageSend m = newMessageSend();
2403 m.sourceStart = this.intStack[this.intPtr--];
2404 m.sourceEnd = this.rParenPos;
2405 m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
2406 m.selector = this.identifierStack[this.identifierPtr--];
2407 this.identifierLengthPtr--;
2408 m.receiver = new SuperReference(m.sourceStart, this.endPosition);
2409 pushOnExpressionStack(m);
2411 protected void consumeModifiers() {
2412 int savedModifiersSourceStart = this.modifiersSourceStart;
2413 checkComment(); // might update modifiers with AccDeprecated
2414 pushOnIntStack(this.modifiers); // modifiers
2415 if (this.modifiersSourceStart >= savedModifiersSourceStart) {
2416 this.modifiersSourceStart = savedModifiersSourceStart;
2418 pushOnIntStack(this.modifiersSourceStart);
2421 protected void consumeNestedMethod() {
2422 // NestedMethod ::= $empty
2423 jumpOverMethodBody();
2424 this.nestedMethod[this.nestedType] ++;
2425 pushOnIntStack(this.scanner.currentPosition);
2428 protected void consumeNestedType() {
2429 // NestedType ::= $empty
2430 int length = this.nestedMethod.length;
2431 if (++this.nestedType >= length) {
2433 this.nestedMethod, 0,
2434 this.nestedMethod = new int[length + 30], 0,
2436 // increase the size of the variablesCounter as well. It has to be consistent with the size of the nestedMethod collection
2438 this.variablesCounter, 0,
2439 this.variablesCounter = new int[length + 30], 0,
2442 this.nestedMethod[this.nestedType] = 0;
2443 this.variablesCounter[this.nestedType] = 0;
2445 protected void consumeOneDimLoop() {
2446 // OneDimLoop ::= '[' ']'
2449 protected void consumeOnlySynchronized() {
2450 // OnlySynchronized ::= 'synchronized'
2451 pushOnIntStack(this.synchronizedBlockSourceStart);
2454 protected void consumeOpenBlock() {
2455 // OpenBlock ::= $empty
2457 pushOnIntStack(this.scanner.startPosition);
2458 int stackLength = this.realBlockStack.length;
2459 if (++this.realBlockPtr >= stackLength) {
2461 this.realBlockStack, 0,
2462 this.realBlockStack = new int[stackLength + StackIncrement], 0,
2465 this.realBlockStack[this.realBlockPtr] = 0;
2467 protected void consumePackageDeclaration() {
2468 // PackageDeclaration ::= 'package' Name ';'
2469 /* build an ImportRef build from the last name
2470 stored in the identifier stack. */
2472 ImportReference impt = this.compilationUnit.currentPackage;
2473 // flush comments defined prior to import statements
2474 impt.declarationEnd = this.endStatementPosition;
2475 impt.declarationSourceEnd = this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
2477 protected void consumePackageDeclarationName() {
2478 // PackageDeclarationName ::= 'package' Name
2479 /* build an ImportRef build from the last name
2480 stored in the identifier stack. */
2482 ImportReference impt;
2485 new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
2486 this.identifierPtr -= length;
2487 long[] positions = new long[length];
2488 System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length);
2490 this.identifierPositionStack,
2491 this.identifierPtr--,
2495 this.compilationUnit.currentPackage =
2496 impt = new ImportReference(tokens, positions, true, AccDefault);
2498 if (this.currentToken == TokenNameSEMICOLON){
2499 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
2501 impt.declarationSourceEnd = impt.sourceEnd;
2503 impt.declarationEnd = impt.declarationSourceEnd;
2504 //endPosition is just before the ;
2505 impt.declarationSourceStart = this.intStack[this.intPtr--];
2508 if (this.currentElement != null){
2509 this.lastCheckPoint = impt.declarationSourceEnd+1;
2510 this.restartRecovery = true; // used to avoid branching back into the regular automaton
2513 protected void consumePostfixExpression() {
2514 // PostfixExpression ::= Name
2515 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2517 protected void consumePrimaryNoNewArray() {
2518 // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
2519 final Expression parenthesizedExpression = this.expressionStack[this.expressionPtr];
2520 updateSourcePosition(parenthesizedExpression);
2521 int numberOfParenthesis = (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
2522 parenthesizedExpression.bits &= ~ASTNode.ParenthesizedMASK;
2523 parenthesizedExpression.bits |= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT;
2525 protected void consumePrimaryNoNewArrayArrayType() {
2526 // PrimaryNoNewArray ::= ArrayType '.' 'class'
2528 pushOnExpressionStack(
2529 new ClassLiteralAccess(this.intStack[this.intPtr--],
2530 getTypeReference(this.intStack[this.intPtr--])));
2532 protected void consumePrimaryNoNewArrayName() {
2533 // PrimaryNoNewArray ::= Name '.' 'class'
2535 pushOnExpressionStack(
2536 new ClassLiteralAccess(this.intStack[this.intPtr--],
2537 getTypeReference(0)));
2539 protected void consumePrimaryNoNewArrayNameSuper() {
2540 // PrimaryNoNewArray ::= Name '.' 'super'
2541 pushOnExpressionStack(
2542 new QualifiedSuperReference(
2543 getTypeReference(0),
2544 this.intStack[this.intPtr--],
2547 protected void consumePrimaryNoNewArrayNameThis() {
2548 // PrimaryNoNewArray ::= Name '.' 'this'
2549 pushOnExpressionStack(
2550 new QualifiedThisReference(
2551 getTypeReference(0),
2552 this.intStack[this.intPtr--],
2555 protected void consumePrimaryNoNewArrayPrimitiveType() {
2556 // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
2558 pushOnExpressionStack(
2559 new ClassLiteralAccess(this.intStack[this.intPtr--],
2560 getTypeReference(0)));
2562 protected void consumePrimaryNoNewArrayThis() {
2563 // PrimaryNoNewArray ::= 'this'
2564 pushOnExpressionStack(new ThisReference(this.intStack[this.intPtr--], this.endPosition));
2566 protected void consumePrimitiveType() {
2567 // Type ::= PrimitiveType
2570 protected void consumePushModifiers() {
2571 pushOnIntStack(this.modifiers); // modifiers
2572 pushOnIntStack(this.modifiersSourceStart);
2575 protected void consumePushPosition() {
2576 // for source managment purpose
2577 // PushPosition ::= $empty
2578 pushOnIntStack(this.endPosition);
2580 protected void consumeQualifiedName() {
2581 // QualifiedName ::= Name '.' SimpleName
2582 /*back from the recursive loop of QualifiedName.
2583 Updates identifier length into the length stack*/
2585 this.identifierLengthStack[--this.identifierLengthPtr]++;
2587 protected void consumeReferenceType() {
2588 // ReferenceType ::= ClassOrInterfaceType
2591 protected void consumeRestoreDiet() {
2592 // RestoreDiet ::= $empty
2595 protected void consumeRightParen() {
2596 // PushRPAREN ::= ')'
2597 pushOnIntStack(this.rParenPos);
2599 // This method is part of an automatic generation : do NOT edit-modify
2600 protected void consumeRule(int act) {
2602 case 26 : // System.out.println("Type ::= PrimitiveType"); //$NON-NLS-1$
2603 consumePrimitiveType();
2606 case 40 : // System.out.println("ReferenceType ::= ClassOrInterfaceType"); //$NON-NLS-1$
2607 consumeReferenceType();
2610 case 49 : // System.out.println("QualifiedName ::= Name DOT SimpleName"); //$NON-NLS-1$
2611 consumeQualifiedName();
2614 case 50 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt..."); //$NON-NLS-1$
2615 consumeCompilationUnit();
2618 case 51 : // System.out.println("EnterCompilationUnit ::="); //$NON-NLS-1$
2619 consumeEnterCompilationUnit();
2622 case 64 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE"); //$NON-NLS-1$
2623 consumeCatchHeader();
2626 case 66 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration"); //$NON-NLS-1$
2627 consumeImportDeclarations();
2630 case 68 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); //$NON-NLS-1$
2631 consumeTypeDeclarations();
2634 case 69 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); //$NON-NLS-1$
2635 consumePackageDeclaration();
2638 case 70 : // System.out.println("PackageDeclarationName ::= package Name"); //$NON-NLS-1$
2639 consumePackageDeclarationName();
2642 case 73 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName..."); //$NON-NLS-1$
2643 consumeSingleTypeImportDeclaration();
2646 case 74 : // System.out.println("SingleTypeImportDeclarationName ::= import Name"); //$NON-NLS-1$
2647 consumeSingleTypeImportDeclarationName();
2650 case 75 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName"); //$NON-NLS-1$
2651 consumeTypeImportOnDemandDeclaration();
2654 case 76 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY"); //$NON-NLS-1$
2655 consumeTypeImportOnDemandDeclarationName();
2658 case 79 : // System.out.println("TypeDeclaration ::= SEMICOLON"); //$NON-NLS-1$
2659 consumeEmptyTypeDeclaration();
2662 case 93 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); //$NON-NLS-1$
2663 consumeClassDeclaration();
2666 case 94 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); //$NON-NLS-1$
2667 consumeClassHeader();
2670 case 95 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier"); //$NON-NLS-1$
2671 consumeClassHeaderName();
2674 case 96 : // System.out.println("ClassHeaderExtends ::= extends ClassType"); //$NON-NLS-1$
2675 consumeClassHeaderExtends();
2678 case 97 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); //$NON-NLS-1$
2679 consumeClassHeaderImplements();
2682 case 99 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType"); //$NON-NLS-1$
2683 consumeInterfaceTypeList();
2686 case 100 : // System.out.println("InterfaceType ::= ClassOrInterfaceType"); //$NON-NLS-1$
2687 consumeInterfaceType();
2690 case 103 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration"); //$NON-NLS-1$
2691 consumeClassBodyDeclarations();
2694 case 107 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block"); //$NON-NLS-1$
2695 consumeClassBodyDeclaration();
2698 case 108 : // System.out.println("Diet ::="); //$NON-NLS-1$
2702 case 109 : // System.out.println("Initializer ::= Diet NestedMethod Block"); //$NON-NLS-1$
2703 consumeClassBodyDeclaration();
2706 case 116 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON"); //$NON-NLS-1$
2707 consumeEmptyClassMemberDeclaration();
2710 case 117 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON"); //$NON-NLS-1$
2711 consumeFieldDeclaration();
2714 case 119 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator"); //$NON-NLS-1$
2715 consumeVariableDeclarators();
2718 case 122 : // System.out.println("EnterVariable ::="); //$NON-NLS-1$
2719 consumeEnterVariable();
2722 case 123 : // System.out.println("ExitVariableWithInitialization ::="); //$NON-NLS-1$
2723 consumeExitVariableWithInitialization();
2726 case 124 : // System.out.println("ExitVariableWithoutInitialization ::="); //$NON-NLS-1$
2727 consumeExitVariableWithoutInitialization();
2730 case 125 : // System.out.println("ForceNoDiet ::="); //$NON-NLS-1$
2731 consumeForceNoDiet();
2734 case 126 : // System.out.println("RestoreDiet ::="); //$NON-NLS-1$
2735 consumeRestoreDiet();
2738 case 131 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); //$NON-NLS-1$
2739 // set to true to consume a method with a body
2740 consumeMethodDeclaration(true);
2743 case 132 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); //$NON-NLS-1$
2744 // set to false to consume a method without body
2745 consumeMethodDeclaration(false);
2748 case 133 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters..."); //$NON-NLS-1$
2749 consumeMethodHeader();
2752 case 134 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); //$NON-NLS-1$
2753 consumeMethodHeaderName();
2756 case 135 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN"); //$NON-NLS-1$
2757 consumeMethodHeaderParameters();
2760 case 136 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); //$NON-NLS-1$
2761 consumeMethodHeaderExtendedDims();
2764 case 137 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); //$NON-NLS-1$
2765 consumeMethodHeaderThrowsClause();
2768 case 138 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters"); //$NON-NLS-1$
2769 consumeConstructorHeader();
2772 case 139 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); //$NON-NLS-1$
2773 consumeConstructorHeaderName();
2776 case 141 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter"); //$NON-NLS-1$
2777 consumeFormalParameterList();
2780 case 142 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId"); //$NON-NLS-1$
2781 // the boolean is used to know if the modifiers should be reset
2782 consumeFormalParameter();
2785 case 144 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); //$NON-NLS-1$
2786 consumeClassTypeList();
2789 case 145 : // System.out.println("ClassTypeElt ::= ClassType"); //$NON-NLS-1$
2790 consumeClassTypeElt();
2793 case 146 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE"); //$NON-NLS-1$
2794 consumeMethodBody();
2797 case 147 : // System.out.println("NestedMethod ::="); //$NON-NLS-1$
2798 consumeNestedMethod();
2801 case 148 : // System.out.println("StaticInitializer ::= StaticOnly Block"); //$NON-NLS-1$
2802 consumeStaticInitializer();
2805 case 149 : // System.out.println("StaticOnly ::= static"); //$NON-NLS-1$
2806 consumeStaticOnly();
2809 case 150 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); //$NON-NLS-1$
2810 consumeConstructorDeclaration() ;
2813 case 151 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); //$NON-NLS-1$
2814 consumeInvalidConstructorDeclaration() ;
2817 case 152 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN"); //$NON-NLS-1$
2818 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This);
2821 case 153 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt..."); //$NON-NLS-1$
2822 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super);
2825 case 154 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN..."); //$NON-NLS-1$
2826 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
2829 case 155 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN..."); //$NON-NLS-1$
2830 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
2833 case 156 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN..."); //$NON-NLS-1$
2834 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
2837 case 157 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN..."); //$NON-NLS-1$
2838 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
2841 case 158 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); //$NON-NLS-1$
2842 consumeInterfaceDeclaration();
2845 case 159 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt"); //$NON-NLS-1$
2846 consumeInterfaceHeader();
2849 case 160 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier"); //$NON-NLS-1$
2850 consumeInterfaceHeaderName();
2853 case 162 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); //$NON-NLS-1$
2854 consumeInterfaceHeaderExtends();
2857 case 165 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations..."); //$NON-NLS-1$
2858 consumeInterfaceMemberDeclarations();
2861 case 166 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); //$NON-NLS-1$
2862 consumeEmptyInterfaceMemberDeclaration();
2865 case 169 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration"); //$NON-NLS-1$
2869 case 170 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader MethodBody"); //$NON-NLS-1$
2870 ignoreInvalidConstructorDeclaration(true);
2873 case 171 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON"); //$NON-NLS-1$
2874 ignoreInvalidConstructorDeclaration(false);
2877 case 177 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE"); //$NON-NLS-1$
2878 consumeEmptyArrayInitializer();
2881 case 178 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE"); //$NON-NLS-1$
2882 consumeArrayInitializer();
2885 case 179 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE"); //$NON-NLS-1$
2886 consumeArrayInitializer();
2889 case 181 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); //$NON-NLS-1$
2890 consumeVariableInitializers();
2893 case 182 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); //$NON-NLS-1$
2897 case 183 : // System.out.println("OpenBlock ::="); //$NON-NLS-1$
2898 consumeOpenBlock() ;
2901 case 185 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement"); //$NON-NLS-1$
2902 consumeBlockStatements() ;
2905 case 189 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration"); //$NON-NLS-1$
2906 ignoreInterfaceDeclaration();
2909 case 190 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration..."); //$NON-NLS-1$
2910 consumeLocalVariableDeclarationStatement();
2913 case 191 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators"); //$NON-NLS-1$
2914 consumeLocalVariableDeclaration();
2917 case 192 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers..."); //$NON-NLS-1$
2918 consumeLocalVariableDeclaration();
2921 case 193 : // System.out.println("PushModifiers ::="); //$NON-NLS-1$
2922 consumePushModifiers();
2925 case 217 : // System.out.println("EmptyStatement ::= SEMICOLON"); //$NON-NLS-1$
2926 consumeEmptyStatement();
2929 case 218 : // System.out.println("LabeledStatement ::= Identifier COLON Statement"); //$NON-NLS-1$
2930 consumeStatementLabel() ;
2933 case 219 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf"); //$NON-NLS-1$
2934 consumeStatementLabel() ;
2937 case 220 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); //$NON-NLS-1$
2938 consumeExpressionStatement();
2941 case 229 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement"); //$NON-NLS-1$
2942 consumeStatementIfNoElse();
2945 case 230 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); //$NON-NLS-1$
2946 consumeStatementIfWithElse();
2949 case 231 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN..."); //$NON-NLS-1$
2950 consumeStatementIfWithElse();
2953 case 232 : // System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN OpenBlock..."); //$NON-NLS-1$
2954 consumeStatementSwitch() ;
2957 case 233 : // System.out.println("SwitchBlock ::= LBRACE RBRACE"); //$NON-NLS-1$
2958 consumeEmptySwitchBlock() ;
2961 case 236 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE"); //$NON-NLS-1$
2962 consumeSwitchBlock() ;
2965 case 238 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement"); //$NON-NLS-1$
2966 consumeSwitchBlockStatements() ;
2969 case 239 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); //$NON-NLS-1$
2970 consumeSwitchBlockStatement() ;
2973 case 241 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); //$NON-NLS-1$
2974 consumeSwitchLabels() ;
2977 case 242 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON"); //$NON-NLS-1$
2981 case 243 : // System.out.println("SwitchLabel ::= default COLON"); //$NON-NLS-1$
2982 consumeDefaultLabel();
2985 case 244 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement"); //$NON-NLS-1$
2986 consumeStatementWhile() ;
2989 case 245 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN..."); //$NON-NLS-1$
2990 consumeStatementWhile() ;
2993 case 246 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN..."); //$NON-NLS-1$
2994 consumeStatementDo() ;
2997 case 247 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt..."); //$NON-NLS-1$
2998 consumeStatementFor() ;
3001 case 248 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON..."); //$NON-NLS-1$
3002 consumeStatementFor() ;
3005 case 249 : // System.out.println("ForInit ::= StatementExpressionList"); //$NON-NLS-1$
3009 case 253 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA..."); //$NON-NLS-1$
3010 consumeStatementExpressionList() ;
3013 case 254 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON"); //$NON-NLS-1$
3014 consumeSimpleAssertStatement() ;
3017 case 255 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON"); //$NON-NLS-1$
3018 consumeAssertStatement() ;
3021 case 256 : // System.out.println("BreakStatement ::= break SEMICOLON"); //$NON-NLS-1$
3022 consumeStatementBreak() ;
3025 case 257 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON"); //$NON-NLS-1$
3026 consumeStatementBreakWithLabel() ;
3029 case 258 : // System.out.println("ContinueStatement ::= continue SEMICOLON"); //$NON-NLS-1$
3030 consumeStatementContinue() ;
3033 case 259 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); //$NON-NLS-1$
3034 consumeStatementContinueWithLabel() ;
3037 case 260 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); //$NON-NLS-1$
3038 consumeStatementReturn() ;
3041 case 261 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); //$NON-NLS-1$
3042 consumeStatementThrow();
3046 case 262 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN"); //$NON-NLS-1$
3047 consumeStatementSynchronized();
3050 case 263 : // System.out.println("OnlySynchronized ::= synchronized"); //$NON-NLS-1$
3051 consumeOnlySynchronized();
3054 case 264 : // System.out.println("TryStatement ::= try TryBlock Catches"); //$NON-NLS-1$
3055 consumeStatementTry(false);
3058 case 265 : // System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); //$NON-NLS-1$
3059 consumeStatementTry(true);
3062 case 267 : // System.out.println("ExitTryBlock ::="); //$NON-NLS-1$
3063 consumeExitTryBlock();
3066 case 269 : // System.out.println("Catches ::= Catches CatchClause"); //$NON-NLS-1$
3070 case 270 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block"); //$NON-NLS-1$
3071 consumeStatementCatch() ;
3074 case 272 : // System.out.println("PushLPAREN ::= LPAREN"); //$NON-NLS-1$
3078 case 273 : // System.out.println("PushRPAREN ::= RPAREN"); //$NON-NLS-1$
3079 consumeRightParen();
3082 case 278 : // System.out.println("PrimaryNoNewArray ::= this"); //$NON-NLS-1$
3083 consumePrimaryNoNewArrayThis();
3086 case 279 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN"); //$NON-NLS-1$
3087 consumePrimaryNoNewArray();
3090 case 282 : // System.out.println("PrimaryNoNewArray ::= Name DOT this"); //$NON-NLS-1$
3091 consumePrimaryNoNewArrayNameThis();
3094 case 283 : // System.out.println("PrimaryNoNewArray ::= Name DOT super"); //$NON-NLS-1$
3095 consumePrimaryNoNewArrayNameSuper();
3098 case 284 : // System.out.println("PrimaryNoNewArray ::= Name DOT class"); //$NON-NLS-1$
3099 consumePrimaryNoNewArrayName();
3102 case 285 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class"); //$NON-NLS-1$
3103 consumePrimaryNoNewArrayArrayType();
3106 case 286 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); //$NON-NLS-1$
3107 consumePrimaryNoNewArrayPrimitiveType();
3110 case 289 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN"); //$NON-NLS-1$
3111 consumeAllocationHeader();
3114 case 290 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN..."); //$NON-NLS-1$
3115 consumeClassInstanceCreationExpression();
3118 case 291 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName..."); //$NON-NLS-1$
3119 consumeClassInstanceCreationExpressionQualified() ;
3122 case 292 : // System.out.println("ClassInstanceCreationExpression ::=..."); //$NON-NLS-1$
3123 consumeClassInstanceCreationExpressionQualified() ;
3126 case 293 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); //$NON-NLS-1$
3127 consumeClassInstanceCreationExpressionName() ;
3130 case 294 : // System.out.println("ClassBodyopt ::="); //$NON-NLS-1$
3131 consumeClassBodyopt();
3134 case 296 : // System.out.println("EnterAnonymousClassBody ::="); //$NON-NLS-1$
3135 consumeEnterAnonymousClassBody();
3138 case 298 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); //$NON-NLS-1$
3139 consumeArgumentList();
3142 case 299 : // System.out.println("ArrayCreationHeader ::= new PrimitiveType DimWithOrWithOutExprs"); //$NON-NLS-1$
3143 consumeArrayCreationHeader();
3146 case 300 : // System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); //$NON-NLS-1$
3147 consumeArrayCreationHeader();
3150 case 301 : // System.out.println("ArrayCreationWithoutArrayInitializer ::= new PrimitiveType..."); //$NON-NLS-1$
3151 consumeArrayCreationExpressionWithoutInitializer();
3154 case 302 : // System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType..."); //$NON-NLS-1$
3155 consumeArrayCreationExpressionWithInitializer();
3158 case 303 : // System.out.println("ArrayCreationWithoutArrayInitializer ::= new ClassOrInterfaceType..."); //$NON-NLS-1$
3159 consumeArrayCreationExpressionWithoutInitializer();
3162 case 304 : // System.out.println("ArrayCreationWithArrayInitializer ::= new ClassOrInterfaceType..."); //$NON-NLS-1$
3163 consumeArrayCreationExpressionWithInitializer();
3166 case 306 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr"); //$NON-NLS-1$
3167 consumeDimWithOrWithOutExprs();
3170 case 308 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); //$NON-NLS-1$
3171 consumeDimWithOrWithOutExpr();
3174 case 309 : // System.out.println("Dims ::= DimsLoop"); //$NON-NLS-1$
3178 case 312 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); //$NON-NLS-1$
3179 consumeOneDimLoop();
3182 case 313 : // System.out.println("FieldAccess ::= Primary DOT Identifier"); //$NON-NLS-1$
3183 consumeFieldAccess(false);
3186 case 314 : // System.out.println("FieldAccess ::= super DOT Identifier"); //$NON-NLS-1$
3187 consumeFieldAccess(true);
3190 case 315 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); //$NON-NLS-1$
3191 consumeMethodInvocationName();
3194 case 316 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt"); //$NON-NLS-1$
3195 consumeMethodInvocationPrimary();
3198 case 317 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt..."); //$NON-NLS-1$
3199 consumeMethodInvocationSuper();
3202 case 318 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); //$NON-NLS-1$
3203 consumeArrayAccess(true);
3206 case 319 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET"); //$NON-NLS-1$
3207 consumeArrayAccess(false);
3210 case 320 : // System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer LBRACKET..."); //$NON-NLS-1$
3211 consumeArrayAccess(false);
3214 case 322 : // System.out.println("PostfixExpression ::= Name"); //$NON-NLS-1$
3215 consumePostfixExpression();
3218 case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); //$NON-NLS-1$
3219 consumeUnaryExpression(OperatorIds.PLUS,true);
3222 case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS"); //$NON-NLS-1$
3223 consumeUnaryExpression(OperatorIds.MINUS,true);
3226 case 327 : // System.out.println("PushPosition ::="); //$NON-NLS-1$
3227 consumePushPosition();
3230 case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); //$NON-NLS-1$
3231 consumeUnaryExpression(OperatorIds.PLUS);
3234 case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); //$NON-NLS-1$
3235 consumeUnaryExpression(OperatorIds.MINUS);
3238 case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression"); //$NON-NLS-1$
3239 consumeUnaryExpression(OperatorIds.PLUS,false);
3242 case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression"); //$NON-NLS-1$
3243 consumeUnaryExpression(OperatorIds.MINUS,false);
3246 case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression"); //$NON-NLS-1$
3247 consumeUnaryExpression(OperatorIds.TWIDDLE);
3250 case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression"); //$NON-NLS-1$
3251 consumeUnaryExpression(OperatorIds.NOT);
3254 case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN..."); //$NON-NLS-1$
3255 consumeCastExpression();
3258 case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); //$NON-NLS-1$
3259 consumeCastExpression();
3262 case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN..."); //$NON-NLS-1$
3263 consumeCastExpressionLL1();
3266 case 342 : // System.out.println("InsideCastExpression ::="); //$NON-NLS-1$
3267 consumeInsideCastExpression();
3270 case 343 : // System.out.println("InsideCastExpressionLL1 ::="); //$NON-NLS-1$
3271 consumeInsideCastExpressionLL1();
3274 case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY..."); //$NON-NLS-1$
3275 consumeBinaryExpression(OperatorIds.MULTIPLY);
3278 case 346 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE..."); //$NON-NLS-1$
3279 consumeBinaryExpression(OperatorIds.DIVIDE);
3282 case 347 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER..."); //$NON-NLS-1$
3283 consumeBinaryExpression(OperatorIds.REMAINDER);
3286 case 349 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); //$NON-NLS-1$
3287 consumeBinaryExpression(OperatorIds.PLUS);
3290 case 350 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); //$NON-NLS-1$
3291 consumeBinaryExpression(OperatorIds.MINUS);
3294 case 352 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression"); //$NON-NLS-1$
3295 consumeBinaryExpression(OperatorIds.LEFT_SHIFT);
3298 case 353 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression"); //$NON-NLS-1$
3299 consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);
3302 case 354 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT..."); //$NON-NLS-1$
3303 consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);
3306 case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression"); //$NON-NLS-1$
3307 consumeBinaryExpression(OperatorIds.LESS);
3310 case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); //$NON-NLS-1$
3311 consumeBinaryExpression(OperatorIds.GREATER);
3314 case 358 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL..."); //$NON-NLS-1$
3315 consumeBinaryExpression(OperatorIds.LESS_EQUAL);
3318 case 359 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL..."); //$NON-NLS-1$
3319 consumeBinaryExpression(OperatorIds.GREATER_EQUAL);
3322 case 360 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof..."); //$NON-NLS-1$
3323 consumeInstanceOfExpression(OperatorIds.INSTANCEOF);
3326 case 362 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); //$NON-NLS-1$
3327 consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);
3330 case 363 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); //$NON-NLS-1$
3331 consumeEqualityExpression(OperatorIds.NOT_EQUAL);
3334 case 365 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); //$NON-NLS-1$
3335 consumeBinaryExpression(OperatorIds.AND);
3338 case 367 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression"); //$NON-NLS-1$
3339 consumeBinaryExpression(OperatorIds.XOR);
3342 case 369 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); //$NON-NLS-1$
3343 consumeBinaryExpression(OperatorIds.OR);
3346 case 371 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND..."); //$NON-NLS-1$
3347 consumeBinaryExpression(OperatorIds.AND_AND);
3350 case 373 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR..."); //$NON-NLS-1$
3351 consumeBinaryExpression(OperatorIds.OR_OR);
3354 case 375 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION..."); //$NON-NLS-1$
3355 consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;
3358 case 378 : // System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); //$NON-NLS-1$
3359 consumeAssignment();
3362 case 380 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); //$NON-NLS-1$
3363 ignoreExpressionAssignment();
3366 case 381 : // System.out.println("AssignmentOperator ::= EQUAL"); //$NON-NLS-1$
3367 consumeAssignmentOperator(EQUAL);
3370 case 382 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); //$NON-NLS-1$
3371 consumeAssignmentOperator(MULTIPLY);
3374 case 383 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); //$NON-NLS-1$
3375 consumeAssignmentOperator(DIVIDE);
3378 case 384 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); //$NON-NLS-1$
3379 consumeAssignmentOperator(REMAINDER);
3382 case 385 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL"); //$NON-NLS-1$
3383 consumeAssignmentOperator(PLUS);
3386 case 386 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL"); //$NON-NLS-1$
3387 consumeAssignmentOperator(MINUS);
3390 case 387 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); //$NON-NLS-1$
3391 consumeAssignmentOperator(LEFT_SHIFT);
3394 case 388 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); //$NON-NLS-1$
3395 consumeAssignmentOperator(RIGHT_SHIFT);
3398 case 389 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); //$NON-NLS-1$
3399 consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
3402 case 390 : // System.out.println("AssignmentOperator ::= AND_EQUAL"); //$NON-NLS-1$
3403 consumeAssignmentOperator(AND);
3406 case 391 : // System.out.println("AssignmentOperator ::= XOR_EQUAL"); //$NON-NLS-1$
3407 consumeAssignmentOperator(XOR);
3410 case 392 : // System.out.println("AssignmentOperator ::= OR_EQUAL"); //$NON-NLS-1$
3411 consumeAssignmentOperator(OR);
3414 case 399 : // System.out.println("Expressionopt ::="); //$NON-NLS-1$
3415 consumeEmptyExpression();
3418 case 403 : // System.out.println("ImportDeclarationsopt ::="); //$NON-NLS-1$
3419 consumeEmptyImportDeclarationsopt();
3422 case 404 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations"); //$NON-NLS-1$
3423 consumeImportDeclarationsopt();
3426 case 405 : // System.out.println("TypeDeclarationsopt ::="); //$NON-NLS-1$
3427 consumeEmptyTypeDeclarationsopt();
3430 case 406 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations"); //$NON-NLS-1$
3431 consumeTypeDeclarationsopt();
3434 case 407 : // System.out.println("ClassBodyDeclarationsopt ::="); //$NON-NLS-1$
3435 consumeEmptyClassBodyDeclarationsopt();
3438 case 408 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations"); //$NON-NLS-1$
3439 consumeClassBodyDeclarationsopt();
3442 case 409 : // System.out.println("Modifiersopt ::="); //$NON-NLS-1$
3443 consumeDefaultModifiers();
3446 case 410 : // System.out.println("Modifiersopt ::= Modifiers"); //$NON-NLS-1$
3450 case 411 : // System.out.println("BlockStatementsopt ::="); //$NON-NLS-1$
3451 consumeEmptyBlockStatementsopt();
3454 case 413 : // System.out.println("Dimsopt ::="); //$NON-NLS-1$
3455 consumeEmptyDimsopt();
3458 case 415 : // System.out.println("ArgumentListopt ::="); //$NON-NLS-1$
3459 consumeEmptyArgumentListopt();
3462 case 419 : // System.out.println("FormalParameterListopt ::="); //$NON-NLS-1$
3463 consumeFormalParameterListopt();
3466 case 423 : // System.out.println("InterfaceMemberDeclarationsopt ::="); //$NON-NLS-1$
3467 consumeEmptyInterfaceMemberDeclarationsopt();
3470 case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); //$NON-NLS-1$
3471 consumeInterfaceMemberDeclarationsopt();
3474 case 425 : // System.out.println("NestedType ::="); //$NON-NLS-1$
3475 consumeNestedType();
3478 case 426 : // System.out.println("ForInitopt ::="); //$NON-NLS-1$
3479 consumeEmptyForInitopt();
3482 case 428 : // System.out.println("ForUpdateopt ::="); //$NON-NLS-1$
3483 consumeEmptyForUpdateopt();
3486 case 432 : // System.out.println("Catchesopt ::="); //$NON-NLS-1$
3487 consumeEmptyCatchesopt();
3492 protected void consumeSimpleAssertStatement() {
3493 // AssertStatement ::= 'assert' Expression ';'
3494 this.expressionLengthPtr--;
3495 pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
3498 protected void consumeSingleTypeImportDeclaration() {
3499 // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
3501 ImportReference impt = (ImportReference) this.astStack[this.astPtr];
3502 // flush comments defined prior to import statements
3503 impt.declarationEnd = this.endStatementPosition;
3504 impt.declarationSourceEnd =
3505 this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
3508 if (this.currentElement != null) {
3509 this.lastCheckPoint = impt.declarationSourceEnd + 1;
3510 this.currentElement = this.currentElement.add(impt, 0);
3511 this.lastIgnoredToken = -1;
3512 this.restartRecovery = true;
3513 // used to avoid branching back into the regular automaton
3516 protected void consumeSingleTypeImportDeclarationName() {
3517 // SingleTypeImportDeclarationName ::= 'import' Name
3518 /* push an ImportRef build from the last name
3519 stored in the identifier stack. */
3521 ImportReference impt;
3523 char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
3524 this.identifierPtr -= length;
3525 long[] positions = new long[length];
3526 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
3527 System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
3528 pushOnAstStack(impt = new ImportReference(tokens, positions, false, AccDefault));
3530 if (this.currentToken == TokenNameSEMICOLON){
3531 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
3533 impt.declarationSourceEnd = impt.sourceEnd;
3535 impt.declarationEnd = impt.declarationSourceEnd;
3536 //endPosition is just before the ;
3537 impt.declarationSourceStart = this.intStack[this.intPtr--];
3540 if (this.currentElement != null){
3541 this.lastCheckPoint = impt.declarationSourceEnd+1;
3542 this.currentElement = this.currentElement.add(impt, 0);
3543 this.lastIgnoredToken = -1;
3544 this.restartRecovery = true; // used to avoid branching back into the regular automaton
3547 protected void consumeStatementBreak() {
3548 // BreakStatement ::= 'break' ';'
3549 // break pushs a position on intStack in case there is no label
3551 pushOnAstStack(new BreakStatement(null, this.intStack[this.intPtr--], this.endPosition));
3553 protected void consumeStatementBreakWithLabel() {
3554 // BreakStatement ::= 'break' Identifier ';'
3555 // break pushs a position on intStack in case there is no label
3559 this.identifierStack[this.identifierPtr--],
3560 this.intStack[this.intPtr--],
3562 this.identifierLengthPtr--;
3564 protected void consumeStatementCatch() {
3565 // CatchClause ::= 'catch' '(' FormalParameter ')' Block
3567 //catch are stored directly into the Try
3568 //has they always comes two by two....
3569 //we remove one entry from the astlengthPtr.
3570 //The construction of the try statement must
3571 //then fetch the catches using 2*i and 2*i + 1
3573 this.astLengthPtr--;
3574 this.listLength = 0; // reset formalParameter counter (incremented for catch variable)
3576 protected void consumeStatementContinue() {
3577 // ContinueStatement ::= 'continue' ';'
3578 // continue pushs a position on intStack in case there is no label
3581 new ContinueStatement(
3583 this.intStack[this.intPtr--],
3586 protected void consumeStatementContinueWithLabel() {
3587 // ContinueStatement ::= 'continue' Identifier ';'
3588 // continue pushs a position on intStack in case there is no label
3591 new ContinueStatement(
3592 this.identifierStack[this.identifierPtr--],
3593 this.intStack[this.intPtr--],
3595 this.identifierLengthPtr--;
3597 protected void consumeStatementDo() {
3598 // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
3600 //the 'while' pushes a value on intStack that we need to remove
3603 Statement statement = (Statement) this.astStack[this.astPtr];
3604 this.expressionLengthPtr--;
3605 this.astStack[this.astPtr] =
3607 this.expressionStack[this.expressionPtr--],
3609 this.intStack[this.intPtr--],
3612 protected void consumeStatementExpressionList() {
3613 // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
3614 concatExpressionLists();
3616 protected void consumeStatementFor() {
3617 // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
3618 // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
3621 Expression cond = null;
3622 Statement[] inits, updates;
3623 boolean scope = true;
3626 this.astLengthPtr--;
3627 Statement statement = (Statement) this.astStack[this.astPtr--];
3629 //updates are on the expresion stack
3630 if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) == 0) {
3633 this.expressionPtr -= length;
3635 this.expressionStack,
3636 this.expressionPtr + 1,
3637 updates = new Statement[length],
3642 if (this.expressionLengthStack[this.expressionLengthPtr--] != 0)
3643 cond = this.expressionStack[this.expressionPtr--];
3645 //inits may be on two different stacks
3646 if ((length = this.astLengthStack[this.astLengthPtr--]) == 0) {
3650 if (length == -1) { //on expressionStack
3652 length = this.expressionLengthStack[this.expressionLengthPtr--];
3653 this.expressionPtr -= length;
3655 this.expressionStack,
3656 this.expressionPtr + 1,
3657 inits = new Statement[length],
3660 } else { //on astStack
3661 this.astPtr -= length;
3665 inits = new Statement[length],
3677 this.intStack[this.intPtr--],
3678 this.endStatementPosition));
3680 protected void consumeStatementIfNoElse() {
3681 // IfThenStatement ::= 'if' '(' Expression ')' Statement
3683 //optimize the push/pop
3684 this.expressionLengthPtr--;
3685 Statement thenStatement = (Statement) this.astStack[this.astPtr];
3686 this.astStack[this.astPtr] =
3688 this.expressionStack[this.expressionPtr--],
3690 this.intStack[this.intPtr--],
3691 this.endStatementPosition);
3693 protected void consumeStatementIfWithElse() {
3694 // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
3695 // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
3697 this.expressionLengthPtr--;
3699 // optimized {..., Then, Else } ==> {..., If }
3700 this.astLengthPtr--;
3702 //optimize the push/pop
3703 this.astStack[--this.astPtr] =
3705 this.expressionStack[this.expressionPtr--],
3706 (Statement) this.astStack[this.astPtr],
3707 (Statement) this.astStack[this.astPtr + 1],
3708 this.intStack[this.intPtr--],
3709 this.endStatementPosition);
3711 protected void consumeStatementLabel() {
3712 // LabeledStatement ::= 'Identifier' ':' Statement
3713 // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
3716 Statement stmt = (Statement) this.astStack[this.astPtr];
3717 this.astStack[this.astPtr] =
3718 new LabeledStatement(
3719 this.identifierStack[this.identifierPtr],
3721 (int) (this.identifierPositionStack[this.identifierPtr--] >>> 32),
3722 this.endStatementPosition);
3723 this.identifierLengthPtr--;
3725 protected void consumeStatementReturn() {
3726 // ReturnStatement ::= 'return' Expressionopt ';'
3727 // return pushs a position on intStack in case there is no expression
3729 if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) {
3731 new ReturnStatement(
3732 this.expressionStack[this.expressionPtr--],
3733 this.intStack[this.intPtr--],
3737 pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endPosition));
3740 protected void consumeStatementSwitch() {
3741 // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
3743 //OpenBlock just makes the semantic action blockStart()
3744 //the block is inlined but a scope need to be created
3745 //if some declaration occurs.
3748 SwitchStatement switchStatement = new SwitchStatement();
3749 this.expressionLengthPtr--;
3750 switchStatement.expression = this.expressionStack[this.expressionPtr--];
3751 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
3752 this.astPtr -= length;
3756 switchStatement.statements = new Statement[length],
3760 switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
3761 pushOnAstStack(switchStatement);
3762 switchStatement.blockStart = this.intStack[this.intPtr--];
3763 switchStatement.sourceStart = this.intStack[this.intPtr--];
3764 switchStatement.sourceEnd = this.endStatementPosition;
3765 if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) {
3766 switchStatement.bits |= ASTNode.UndocumentedEmptyBlockMASK;
3769 protected void consumeStatementSynchronized() {
3770 // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
3771 //optimize the push/pop
3773 if (this.astLengthStack[this.astLengthPtr] == 0) {
3774 this.astLengthStack[this.astLengthPtr] = 1;
3775 this.expressionLengthPtr--;
3776 this.astStack[++this.astPtr] =
3777 new SynchronizedStatement(
3778 this.expressionStack[this.expressionPtr--],
3780 this.intStack[this.intPtr--],
3781 this.endStatementPosition);
3783 this.expressionLengthPtr--;
3784 this.astStack[this.astPtr] =
3785 new SynchronizedStatement(
3786 this.expressionStack[this.expressionPtr--],
3787 (Block) this.astStack[this.astPtr],
3788 this.intStack[this.intPtr--],
3789 this.endStatementPosition);
3793 protected void consumeStatementThrow() {
3794 // ThrowStatement ::= 'throw' Expression ';'
3795 this.expressionLengthPtr--;
3796 pushOnAstStack(new ThrowStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
3798 protected void consumeStatementTry(boolean withFinally) {
3799 //TryStatement ::= 'try' Block Catches
3800 //TryStatement ::= 'try' Block Catchesopt Finally
3803 TryStatement tryStmt = new TryStatement();
3806 this.astLengthPtr--;
3807 tryStmt.finallyBlock = (Block) this.astStack[this.astPtr--];
3809 //catches are handle by two <argument-block> [see statementCatch]
3810 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
3812 tryStmt.catchBlocks = new Block[] {(Block) this.astStack[this.astPtr--]};
3813 tryStmt.catchArguments = new Argument[] {(Argument) this.astStack[this.astPtr--]};
3815 Block[] bks = (tryStmt.catchBlocks = new Block[length]);
3816 Argument[] args = (tryStmt.catchArguments = new Argument[length]);
3817 while (length-- > 0) {
3818 bks[length] = (Block) this.astStack[this.astPtr--];
3819 args[length] = (Argument) this.astStack[this.astPtr--];
3824 this.astLengthPtr--;
3825 tryStmt.tryBlock = (Block) this.astStack[this.astPtr--];
3828 tryStmt.sourceEnd = this.endStatementPosition;
3829 tryStmt.sourceStart = this.intStack[this.intPtr--];
3830 pushOnAstStack(tryStmt);
3832 protected void consumeStatementWhile() {
3833 // WhileStatement ::= 'while' '(' Expression ')' Statement
3834 // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
3836 this.expressionLengthPtr--;
3837 Statement statement = (Statement) this.astStack[this.astPtr];
3838 this.astStack[this.astPtr] =
3840 this.expressionStack[this.expressionPtr--],
3842 this.intStack[this.intPtr--],
3843 this.endStatementPosition);
3845 protected void consumeStaticInitializer() {
3846 // StaticInitializer ::= StaticOnly Block
3847 //push an Initializer
3848 //optimize the push/pop
3849 Block block = (Block) this.astStack[this.astPtr];
3850 if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlockMASK; // clear bit set since was diet
3851 Initializer initializer = new Initializer(block, AccStatic);
3852 this.astStack[this.astPtr] = initializer;
3853 initializer.sourceEnd = this.endStatementPosition;
3854 initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
3855 this.nestedMethod[this.nestedType] --;
3856 initializer.declarationSourceStart = this.intStack[this.intPtr--];
3857 initializer.bodyStart = this.intStack[this.intPtr--];
3858 initializer.bodyEnd = this.endPosition;
3860 initializer.javadoc = this.javadoc;
3861 this.javadoc = null;
3864 if (this.currentElement != null){
3865 this.lastCheckPoint = initializer.declarationSourceEnd;
3866 this.currentElement = this.currentElement.add(initializer, 0);
3867 this.lastIgnoredToken = -1;
3870 protected void consumeStaticOnly() {
3871 // StaticOnly ::= 'static'
3872 int savedModifiersSourceStart = this.modifiersSourceStart;
3873 checkComment(); // might update declaration source start
3874 if (this.modifiersSourceStart >= savedModifiersSourceStart) {
3875 this.modifiersSourceStart = savedModifiersSourceStart;
3877 pushOnIntStack(this.scanner.currentPosition);
3879 this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
3880 jumpOverMethodBody();
3881 this.nestedMethod[this.nestedType]++;
3885 if (this.currentElement != null){
3886 this.recoveredStaticInitializerStart = this.intStack[this.intPtr]; // remember start position only for static initializers
3889 protected void consumeSwitchBlock() {
3890 // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
3893 protected void consumeSwitchBlockStatement() {
3894 // SwitchBlockStatement ::= SwitchLabels BlockStatements
3897 protected void consumeSwitchBlockStatements() {
3898 // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
3901 protected void consumeSwitchLabels() {
3902 // SwitchLabels ::= SwitchLabels SwitchLabel
3903 optimizedConcatNodeLists();
3905 protected void consumeToken(int type) {
3906 /* remember the last consumed value */
3907 /* try to minimize the number of build values */
3908 checkNonExternalizedStringLiteral();
3909 // // clear the commentPtr of the scanner in case we read something different from a modifier
3911 // case TokenNameabstract :
3912 // case TokenNamestrictfp :
3913 // case TokenNamefinal :
3914 // case TokenNamenative :
3915 // case TokenNameprivate :
3916 // case TokenNameprotected :
3917 // case TokenNamepublic :
3918 // case TokenNametransient :
3919 // case TokenNamevolatile :
3920 // case TokenNamestatic :
3921 // case TokenNamesynchronized :
3924 // this.scanner.commentPtr = -1;
3926 //System.out.println(this.scanner.toStringAction(type));
3928 case TokenNameIdentifier :
3930 if (this.scanner.useAssertAsAnIndentifier) {
3931 long positions = this.identifierPositionStack[this.identifierPtr];
3932 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
3934 // this.scanner.commentPtr = -1;
3936 case TokenNameinterface :
3937 adjustInterfaceModifiers();
3938 //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
3939 pushOnIntStack(this.scanner.currentPosition - 1);
3940 pushOnIntStack(this.scanner.startPosition);
3941 // this.scanner.commentPtr = -1;
3943 case TokenNameabstract :
3944 checkAndSetModifiers(AccAbstract);
3946 case TokenNamestrictfp :
3947 checkAndSetModifiers(AccStrictfp);
3949 case TokenNamefinal :
3950 checkAndSetModifiers(AccFinal);
3952 case TokenNamenative :
3953 checkAndSetModifiers(AccNative);
3955 case TokenNameprivate :
3956 checkAndSetModifiers(AccPrivate);
3958 case TokenNameprotected :
3959 checkAndSetModifiers(AccProtected);
3961 case TokenNamepublic :
3962 checkAndSetModifiers(AccPublic);
3964 case TokenNametransient :
3965 checkAndSetModifiers(AccTransient);
3967 case TokenNamevolatile :
3968 checkAndSetModifiers(AccVolatile);
3970 case TokenNamestatic :
3971 checkAndSetModifiers(AccStatic);
3973 case TokenNamesynchronized :
3974 this.synchronizedBlockSourceStart = this.scanner.startPosition;
3975 checkAndSetModifiers(AccSynchronized);
3977 //==============================
3978 case TokenNamevoid :
3979 pushIdentifier(-T_void);
3980 pushOnIntStack(this.scanner.currentPosition - 1);
3981 pushOnIntStack(this.scanner.startPosition);
3982 // this.scanner.commentPtr = -1;
3984 //push a default dimension while void is not part of the primitive
3985 //declaration baseType and so takes the place of a type without getting into
3986 //regular type parsing that generates a dimension on intStack
3987 case TokenNameboolean :
3988 pushIdentifier(-T_boolean);
3989 pushOnIntStack(this.scanner.currentPosition - 1);
3990 pushOnIntStack(this.scanner.startPosition);
3991 // this.scanner.commentPtr = -1;
3993 case TokenNamebyte :
3994 pushIdentifier(-T_byte);
3995 pushOnIntStack(this.scanner.currentPosition - 1);
3996 pushOnIntStack(this.scanner.startPosition);
3997 // this.scanner.commentPtr = -1;
3999 case TokenNamechar :
4000 pushIdentifier(-T_char);
4001 pushOnIntStack(this.scanner.currentPosition - 1);
4002 pushOnIntStack(this.scanner.startPosition);
4003 // this.scanner.commentPtr = -1;
4005 case TokenNamedouble :
4006 pushIdentifier(-T_double);
4007 pushOnIntStack(this.scanner.currentPosition - 1);
4008 pushOnIntStack(this.scanner.startPosition);
4009 // this.scanner.commentPtr = -1;
4011 case TokenNamefloat :
4012 pushIdentifier(-T_float);
4013 pushOnIntStack(this.scanner.currentPosition - 1);
4014 pushOnIntStack(this.scanner.startPosition);
4015 // this.scanner.commentPtr = -1;
4018 pushIdentifier(-T_int);
4019 pushOnIntStack(this.scanner.currentPosition - 1);
4020 pushOnIntStack(this.scanner.startPosition);
4021 // this.scanner.commentPtr = -1;
4023 case TokenNamelong :
4024 pushIdentifier(-T_long);
4025 pushOnIntStack(this.scanner.currentPosition - 1);
4026 pushOnIntStack(this.scanner.startPosition);
4027 // this.scanner.commentPtr = -1;
4029 case TokenNameshort :
4030 pushIdentifier(-T_short);
4031 pushOnIntStack(this.scanner.currentPosition - 1);
4032 pushOnIntStack(this.scanner.startPosition);
4033 // this.scanner.commentPtr = -1;
4035 //==============================
4036 case TokenNameIntegerLiteral :
4037 pushOnExpressionStack(
4039 this.scanner.getCurrentTokenSource(),
4040 this.scanner.startPosition,
4041 this.scanner.currentPosition - 1));
4042 // this.scanner.commentPtr = -1;
4044 case TokenNameLongLiteral :
4045 pushOnExpressionStack(
4047 this.scanner.getCurrentTokenSource(),
4048 this.scanner.startPosition,
4049 this.scanner.currentPosition - 1));
4050 // this.scanner.commentPtr = -1;
4052 case TokenNameFloatingPointLiteral :
4053 pushOnExpressionStack(
4055 this.scanner.getCurrentTokenSource(),
4056 this.scanner.startPosition,
4057 this.scanner.currentPosition - 1));
4058 // this.scanner.commentPtr = -1;
4060 case TokenNameDoubleLiteral :
4061 pushOnExpressionStack(
4063 this.scanner.getCurrentTokenSource(),
4064 this.scanner.startPosition,
4065 this.scanner.currentPosition - 1));
4066 // this.scanner.commentPtr = -1;
4068 case TokenNameCharacterLiteral :
4069 pushOnExpressionStack(
4071 this.scanner.getCurrentTokenSource(),
4072 this.scanner.startPosition,
4073 this.scanner.currentPosition - 1));
4074 // this.scanner.commentPtr = -1;
4076 case TokenNameStringLiteral :
4077 StringLiteral stringLiteral = new StringLiteral(
4078 this.scanner.getCurrentTokenSourceString(),
4079 this.scanner.startPosition,
4080 this.scanner.currentPosition - 1);
4081 pushOnExpressionStack(stringLiteral);
4082 // this.scanner.commentPtr = -1;
4084 case TokenNamefalse :
4085 pushOnExpressionStack(
4086 new FalseLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
4087 // this.scanner.commentPtr = -1;
4089 case TokenNametrue :
4090 pushOnExpressionStack(
4091 new TrueLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
4093 case TokenNamenull :
4094 pushOnExpressionStack(
4095 new NullLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
4097 //============================
4098 case TokenNamesuper :
4099 case TokenNamethis :
4100 this.endPosition = this.scanner.currentPosition - 1;
4101 pushOnIntStack(this.scanner.startPosition);
4103 case TokenNameassert :
4104 case TokenNameimport :
4105 case TokenNamepackage :
4106 case TokenNamethrow :
4110 case TokenNameswitch :
4112 case TokenNamewhile :
4113 case TokenNamebreak :
4114 case TokenNamecontinue :
4115 case TokenNamereturn :
4116 case TokenNamecase :
4117 pushOnIntStack(this.scanner.startPosition);
4120 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954
4122 pushOnIntStack(this.scanner.startPosition);
4124 case TokenNameclass :
4125 pushOnIntStack(this.scanner.currentPosition - 1);
4126 pushOnIntStack(this.scanner.startPosition);
4128 case TokenNamedefault :
4129 pushOnIntStack(this.scanner.startPosition);
4130 pushOnIntStack(this.scanner.currentPosition - 1);
4132 //let extra semantic action decide when to push
4133 case TokenNameRBRACKET :
4134 case TokenNamePLUS :
4135 case TokenNameMINUS :
4137 case TokenNameTWIDDLE :
4138 this.endPosition = this.scanner.startPosition;
4140 case TokenNamePLUS_PLUS :
4141 case TokenNameMINUS_MINUS :
4142 this.endPosition = this.scanner.startPosition;
4143 this.endStatementPosition = this.scanner.currentPosition - 1;
4145 case TokenNameRBRACE:
4146 case TokenNameSEMICOLON :
4147 this.endStatementPosition = this.scanner.currentPosition - 1;
4148 this.endPosition = this.scanner.startPosition - 1;
4149 //the item is not part of the potential futur expression/statement
4151 // in order to handle ( expression) ////// (cast)expression///// foo(x)
4152 case TokenNameRPAREN :
4153 this.rParenPos = this.scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4155 case TokenNameLPAREN :
4156 this.lParenPos = this.scanner.startPosition;
4158 // case TokenNameQUESTION :
4159 // case TokenNameCOMMA :
4160 // case TokenNameCOLON :
4161 // case TokenNameEQUAL :
4162 // case TokenNameLBRACKET :
4163 // case TokenNameDOT :
4164 // case TokenNameERROR :
4165 // case TokenNameEOF :
4166 // case TokenNamecase :
4167 // case TokenNamecatch :
4168 // case TokenNameelse :
4169 // case TokenNameextends :
4170 // case TokenNamefinally :
4171 // case TokenNameimplements :
4172 // case TokenNamethrows :
4173 // case TokenNameinstanceof :
4174 // case TokenNameEQUAL_EQUAL :
4175 // case TokenNameLESS_EQUAL :
4176 // case TokenNameGREATER_EQUAL :
4177 // case TokenNameNOT_EQUAL :
4178 // case TokenNameLEFT_SHIFT :
4179 // case TokenNameRIGHT_SHIFT :
4180 // case TokenNameUNSIGNED_RIGHT_SHIFT :
4181 // case TokenNamePLUS_EQUAL :
4182 // case TokenNameMINUS_EQUAL :
4183 // case TokenNameMULTIPLY_EQUAL :
4184 // case TokenNameDIVIDE_EQUAL :
4185 // case TokenNameAND_EQUAL :
4186 // case TokenNameOR_EQUAL :
4187 // case TokenNameXOR_EQUAL :
4188 // case TokenNameREMAINDER_EQUAL :
4189 // case TokenNameLEFT_SHIFT_EQUAL :
4190 // case TokenNameRIGHT_SHIFT_EQUAL :
4191 // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
4192 // case TokenNameOR_OR :
4193 // case TokenNameAND_AND :
4194 // case TokenNameREMAINDER :
4195 // case TokenNameXOR :
4196 // case TokenNameAND :
4197 // case TokenNameMULTIPLY :
4198 // case TokenNameOR :
4199 // case TokenNameDIVIDE :
4200 // case TokenNameGREATER :
4201 // case TokenNameLESS :
4204 protected void consumeTypeDeclarations() {
4205 // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4208 protected void consumeTypeDeclarationsopt() {
4209 // TypeDeclarationsopt ::= TypeDeclarations
4211 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4212 this.astPtr -= length;
4213 System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types = new TypeDeclaration[length], 0, length);
4216 protected void consumeTypeImportOnDemandDeclaration() {
4217 // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4219 ImportReference impt = (ImportReference) this.astStack[this.astPtr];
4220 // flush comments defined prior to import statements
4221 impt.declarationEnd = this.endStatementPosition;
4222 impt.declarationSourceEnd =
4223 this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
4226 if (this.currentElement != null) {
4227 this.lastCheckPoint = impt.declarationSourceEnd + 1;
4228 this.currentElement = this.currentElement.add(impt, 0);
4229 this.restartRecovery = true;
4230 this.lastIgnoredToken = -1;
4231 // used to avoid branching back into the regular automaton
4234 protected void consumeTypeImportOnDemandDeclarationName() {
4235 // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4236 /* push an ImportRef build from the last name
4237 stored in the identifier stack. */
4239 ImportReference impt;
4241 char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
4242 this.identifierPtr -= length;
4243 long[] positions = new long[length];
4244 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4245 System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4246 pushOnAstStack(impt = new ImportReference(tokens, positions, true, AccDefault));
4248 if (this.currentToken == TokenNameSEMICOLON){
4249 impt.declarationSourceEnd = this.scanner.currentPosition - 1;
4251 impt.declarationSourceEnd = impt.sourceEnd;
4253 impt.declarationEnd = impt.declarationSourceEnd;
4254 //endPosition is just before the ;
4255 impt.declarationSourceStart = this.intStack[this.intPtr--];
4258 if (this.currentElement != null){
4259 this.lastCheckPoint = impt.declarationSourceEnd+1;
4260 this.currentElement = this.currentElement.add(impt, 0);
4261 this.lastIgnoredToken = -1;
4262 this.restartRecovery = true; // used to avoid branching back into the regular automaton
4265 protected void consumeUnaryExpression(int op) {
4266 // UnaryExpression ::= '+' PushPosition UnaryExpression
4267 // UnaryExpression ::= '-' PushPosition UnaryExpression
4268 // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4269 // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4271 //optimize the push/pop
4273 //handle manually the -2147483648 while it is not a real
4274 //computation of an - and 2147483648 (notice that 2147483648
4275 //is Integer.MAX_VALUE+1.....)
4276 //Same for -9223372036854775808L ............
4278 //intStack have the position of the operator
4280 Expression r, exp = this.expressionStack[this.expressionPtr];
4282 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4283 r = this.expressionStack[this.expressionPtr] = new IntLiteralMinValue();
4285 if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4286 r = this.expressionStack[this.expressionPtr] = new LongLiteralMinValue();
4288 r = this.expressionStack[this.expressionPtr] = new UnaryExpression(exp, op);
4292 r = this.expressionStack[this.expressionPtr] = new UnaryExpression(exp, op);
4294 r.sourceStart = this.intStack[this.intPtr--];
4295 r.sourceEnd = exp.sourceEnd;
4297 protected void consumeUnaryExpression(int op, boolean post) {
4298 // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4299 // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4301 // ++ and -- operators
4302 //optimize the push/pop
4304 //intStack has the position of the operator when prefix
4306 Expression leftHandSide = this.expressionStack[this.expressionPtr];
4307 if (leftHandSide instanceof Reference) {
4308 // ++foo()++ is unvalid
4310 this.expressionStack[this.expressionPtr] =
4311 new PostfixExpression(
4315 this.endStatementPosition);
4317 this.expressionStack[this.expressionPtr] =
4318 new PrefixExpression(
4322 this.intStack[this.intPtr--]);
4325 //the ++ or the -- is NOT taken into account if code gen proceeds
4329 problemReporter().invalidUnaryExpression(leftHandSide);
4332 protected void consumeVariableDeclarators() {
4333 // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4334 optimizedConcatNodeLists();
4336 protected void consumeVariableInitializers() {
4337 // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4338 concatExpressionLists();
4341 * Given the current comment stack, answer whether some comment is available in a certain exclusive range
4343 * @param sourceStart int
4344 * @param sourceEnd int
4347 public boolean containsComment(int sourceStart, int sourceEnd) {
4348 int iComment = this.scanner.commentPtr;
4349 for (; iComment >= 0; iComment--) {
4350 int commentStart = this.scanner.commentStarts[iComment];
4351 // ignore comments before start
4352 if (commentStart < sourceStart) continue;
4353 // ignore comments after end
4354 if (commentStart > sourceEnd) continue;
4359 public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
4360 MethodDeclaration m = new MethodDeclaration(compilationResult);
4361 m.sourceStart = c.sourceStart;
4362 m.sourceEnd = c.sourceEnd;
4363 m.bodyStart = c.bodyStart;
4364 m.bodyEnd = c.bodyEnd;
4365 m.declarationSourceEnd = c.declarationSourceEnd;
4366 m.declarationSourceStart = c.declarationSourceStart;
4367 m.selector = c.selector;
4368 m.statements = c.statements;
4369 m.modifiers = c.modifiers;
4370 m.arguments = c.arguments;
4371 m.thrownExceptions = c.thrownExceptions;
4372 m.explicitDeclarations = c.explicitDeclarations;
4373 m.returnType = null;
4376 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4377 return typeRef.copyDims(dim);
4379 protected FieldDeclaration createFieldDeclaration(char[] fieldDeclarationName, int sourceStart, int sourceEnd) {
4380 return new FieldDeclaration(fieldDeclarationName, sourceStart, sourceEnd);
4383 protected LocalDeclaration createLocalDeclaration(char[] localDeclarationName, int sourceStart, int sourceEnd) {
4384 return new LocalDeclaration(localDeclarationName, sourceStart, sourceEnd);
4387 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4389 CompilationUnitDeclaration parsedUnit;
4390 boolean old = this.diet;
4393 parsedUnit = parse(sourceUnit, compilationResult);
4400 protected void dispatchDeclarationInto(int length) {
4401 /* they are length on astStack that should go into
4402 methods fields constructors lists of the typeDecl
4404 Return if there is a constructor declaration in the methods declaration */
4407 // Looks for the size of each array .
4411 int[] flag = new int[length + 1]; //plus one -- see <HERE>
4412 int size1 = 0, size2 = 0, size3 = 0;
4413 for (int i = length - 1; i >= 0; i--) {
4414 ASTNode astNode = this.astStack[this.astPtr--];
4415 if (astNode instanceof AbstractMethodDeclaration) {
4416 //methods and constructors have been regrouped into one single list
4420 if (astNode instanceof TypeDeclaration) {
4432 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4434 typeDecl.fields = new FieldDeclaration[size1];
4436 typeDecl.methods = new AbstractMethodDeclaration[size2];
4438 typeDecl.memberTypes = new TypeDeclaration[size3];
4441 size1 = size2 = size3 = 0;
4442 int flagI = flag[0], start = 0;
4444 for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
4446 if (flagI != flag[end]) //treat the last element as a ended flag.....
4450 size1 += (length2 = end - start);
4453 this.astPtr + start + 1,
4459 size2 += (length2 = end - start);
4462 this.astPtr + start + 1,
4468 size3 += (length2 = end - start);
4471 this.astPtr + start + 1,
4472 typeDecl.memberTypes,
4477 flagI = flag[start = end];
4481 if (typeDecl.memberTypes != null) {
4482 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4483 typeDecl.memberTypes[i].enclosingType = typeDecl;
4487 protected CompilationUnitDeclaration endParse(int act) {
4491 if (this.currentElement != null){
4492 this.currentElement.topElement().updateParseTree();
4493 if (VERBOSE_RECOVERY){
4494 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4495 System.out.println("--------------------------"); //$NON-NLS-1$
4496 System.out.println(this.compilationUnit);
4497 System.out.println("----------------------------------"); //$NON-NLS-1$
4500 if (this.diet & VERBOSE_RECOVERY){
4501 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
4502 System.out.println("--------------------------"); //$NON-NLS-1$
4503 System.out.println(this.compilationUnit);
4504 System.out.println("----------------------------------"); //$NON-NLS-1$
4507 persistLineSeparatorPositions();
4508 for (int i = 0; i < this.scanner.foundTaskCount; i++){
4509 problemReporter().task(
4510 new String(this.scanner.foundTaskTags[i]),
4511 new String(this.scanner.foundTaskMessages[i]),
4512 this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]),
4513 this.scanner.foundTaskPositions[i][0],
4514 this.scanner.foundTaskPositions[i][1]);
4516 return this.compilationUnit;
4519 * Flush comments defined prior to a given positions.
4521 * Note: comments are stacked in syntactical order
4523 * Either answer given <position>, or the end position of a comment line
4524 * immediately following the <position> (same line)
4528 * } // end of method foo
4531 public int flushCommentsDefinedPriorTo(int position) {
4533 int lastCommentIndex = this.scanner.commentPtr;
4534 if (lastCommentIndex < 0) return position; // no comment
4536 // compute the index of the first obsolete comment
4537 int index = lastCommentIndex;
4540 int commentEnd = this.scanner.commentStops[index];
4541 if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
4542 if (commentEnd <= position){
4548 // if the source at <position> is immediately followed by a line comment, then
4549 // flush this comment and shift <position> to the comment end.
4550 if (validCount > 0){
4551 int immediateCommentEnd = -this.scanner.commentStops[index+1]; //non-javadoc comment end positions are negative
4552 if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments
4553 // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
4554 immediateCommentEnd--; // comment end in one char too far
4555 if (this.scanner.getLineNumber(position) == this.scanner.getLineNumber(immediateCommentEnd)){
4556 position = immediateCommentEnd;
4557 validCount--; // flush this comment
4563 if (index < 0) return position; // no obsolete comment
4565 if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
4566 System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
4567 System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);
4569 this.scanner.commentPtr = validCount - 1;
4572 public final int getFirstToken() {
4573 // the first token is a virtual token that
4574 // allows the parser to parse several goals
4575 // even if they aren't LALR(1)....
4576 // Goal ::= '++' CompilationUnit
4577 // Goal ::= '--' MethodBody
4578 // Goal ::= '==' ConstructorBody
4580 // Goal ::= '>>' StaticInitializer
4581 // Goal ::= '>>' Block
4582 // -- error recovery
4583 // Goal ::= '>>>' Headers
4584 // Goal ::= '*' BlockStatements
4585 // Goal ::= '*' MethodPushModifiersHeader
4587 // Goal ::= '&&' FieldDeclaration
4588 // Goal ::= '||' ImportDeclaration
4589 // Goal ::= '?' PackageDeclaration
4590 // Goal ::= '+' TypeDeclaration
4591 // Goal ::= '/' GenericMethodDeclaration
4592 // Goal ::= '&' ClassBodyDeclaration
4594 // Goal ::= '%' Expression
4595 // -- completion parser
4596 // Goal ::= '!' ConstructorBlockStatementsopt
4597 // Goal ::= '~' BlockStatementsopt
4599 return this.firstToken;
4602 * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
4603 * The array is a flattened structure: 2*n entries with consecutives start and end positions.
4605 * If no JavaDoc is available, then null is answered instead of an empty array.
4607 * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
4609 public int[] getJavaDocPositions() {
4611 int javadocCount = 0;
4612 for (int i = 0, max = this.scanner.commentPtr; i <= max; i++){
4613 // javadoc only (non javadoc comment have negative end positions.)
4614 if (this.scanner.commentStops[i] > 0){
4618 if (javadocCount == 0) return null;
4620 int[] positions = new int[2*javadocCount];
4622 for (int i = 0, max = this.scanner.commentPtr; i <= max; i++){
4623 // javadoc only (non javadoc comment have negative end positions.)
4624 if (this.scanner.commentStops[i] > 0){
4625 positions[index++] = this.scanner.commentStarts[i];
4626 positions[index++] = this.scanner.commentStops[i]-1; //stop is one over
4631 public void getMethodBodies(CompilationUnitDeclaration unit) {
4632 //fill the methods bodies in order for the code to be generated
4634 if (unit == null) return;
4636 if (unit.ignoreMethodBodies) {
4637 unit.ignoreFurtherInvestigation = true;
4639 // if initial diet parse did not work, no need to dig into method bodies.
4642 if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
4643 return; //work already done ...
4645 //real parse of the method....
4646 char[] contents = unit.compilationResult.compilationUnit.getContents();
4647 this.scanner.setSource(contents);
4649 // save existing values to restore them at the end of the parsing process
4650 // see bug 47079 for more details
4651 int[] oldLineEnds = this.scanner.lineEnds;
4652 int oldLinePtr = this.scanner.linePtr;
4654 final int[] lineSeparatorPositions = unit.compilationResult.lineSeparatorPositions;
4655 this.scanner.lineEnds = lineSeparatorPositions;
4656 this.scanner.linePtr = lineSeparatorPositions.length - 1;
4658 if (this.javadocParser != null && this.javadocParser.checkDocComment) {
4659 this.javadocParser.scanner.setSource(contents);
4661 if (unit.types != null) {
4662 for (int i = unit.types.length; --i >= 0;)
4663 unit.types[i].parseMethod(this, unit);
4666 // tag unit has having read bodies
4667 unit.bits |= ASTNode.HasAllMethodBodies;
4669 // this is done to prevent any side effects on the compilation unit result
4670 // line separator positions array.
4671 this.scanner.lineEnds = oldLineEnds;
4672 this.scanner.linePtr = oldLinePtr;
4674 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
4675 This variable is a type reference and dim will be its dimensions*/
4679 if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
4680 // single variable reference
4683 new SingleTypeReference(
4684 this.identifierStack[this.identifierPtr],
4685 this.identifierPositionStack[this.identifierPtr--]);
4688 new ArrayTypeReference(
4689 this.identifierStack[this.identifierPtr],
4691 this.identifierPositionStack[this.identifierPtr--]);
4692 ref.sourceEnd = this.endPosition;
4695 if (length < 0) { //flag for precompiled type reference on base types
4696 ref = TypeReference.baseTypeReference(-length, dim);
4697 ref.sourceStart = this.intStack[this.intPtr--];
4699 ref.sourceEnd = this.intStack[this.intPtr--];
4702 ref.sourceEnd = this.endPosition;
4704 } else { //Qualified variable reference
4705 char[][] tokens = new char[length][];
4706 this.identifierPtr -= length;
4707 long[] positions = new long[length];
4708 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4710 this.identifierPositionStack,
4711 this.identifierPtr + 1,
4716 ref = new QualifiedTypeReference(tokens, positions);
4718 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
4719 ref.sourceEnd = this.endPosition;
4725 protected Expression getTypeReference(Expression exp) {
4727 exp.bits &= ~ASTNode.RestrictiveFlagMASK;
4731 protected NameReference getUnspecifiedReference() {
4732 /* build a (unspecified) NameReference which may be qualified*/
4736 if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1)
4737 // single variable reference
4739 new SingleNameReference(
4740 this.identifierStack[this.identifierPtr],
4741 this.identifierPositionStack[this.identifierPtr--]);
4743 //Qualified variable reference
4745 char[][] tokens = new char[length][];
4746 this.identifierPtr -= length;
4747 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4748 long[] positions = new long[length];
4749 System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4751 new QualifiedNameReference(tokens,
4753 (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
4754 (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
4758 protected NameReference getUnspecifiedReferenceOptimized() {
4759 /* build a (unspecified) NameReference which may be qualified
4760 The optimization occurs for qualified reference while we are
4761 certain in this case the last item of the qualified name is
4762 a field access. This optimization is IMPORTANT while it results
4763 that when a NameReference is build, the type checker should always
4764 look for that it is not a type reference */
4768 if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
4769 // single variable reference
4771 new SingleNameReference(
4772 this.identifierStack[this.identifierPtr],
4773 this.identifierPositionStack[this.identifierPtr--]);
4774 ref.bits &= ~ASTNode.RestrictiveFlagMASK;
4775 ref.bits |= LOCAL | FIELD;
4779 //Qualified-variable-reference
4780 //In fact it is variable-reference DOT field-ref , but it would result in a type
4781 //conflict tha can be only reduce by making a superclass (or inetrface ) between
4782 //nameReference and FiledReference or putting FieldReference under NameReference
4783 //or else..........This optimisation is not really relevant so just leave as it is
4785 char[][] tokens = new char[length][];
4786 this.identifierPtr -= length;
4787 System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
4788 long[] positions = new long[length];
4789 System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
4790 ref = new QualifiedNameReference(
4793 (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
4794 (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
4795 ref.bits &= ~ASTNode.RestrictiveFlagMASK;
4796 ref.bits |= LOCAL | FIELD;
4799 public void goForBlockStatementsopt() {
4800 //tells the scanner to go for block statements opt parsing
4802 this.firstToken = TokenNameTWIDDLE;
4803 this.scanner.recordLineSeparator = false;
4805 public void goForBlockStatementsOrCatchHeader() {
4806 //tells the scanner to go for block statements or method headers parsing
4808 this.firstToken = TokenNameMULTIPLY;
4809 this.scanner.recordLineSeparator = false;
4811 public void goForClassBodyDeclarations() {
4812 //tells the scanner to go for any body declarations parsing
4814 this.firstToken = TokenNameAND;
4815 this.scanner.recordLineSeparator = true;
4817 public void goForCompilationUnit(){
4818 //tells the scanner to go for compilation unit parsing
4820 this.firstToken = TokenNamePLUS_PLUS ;
4821 this.scanner.linePtr = -1;
4822 this.scanner.foundTaskCount = 0;
4823 this.scanner.recordLineSeparator = true;
4824 this.scanner.currentLine= null;
4826 public void goForExpression() {
4827 //tells the scanner to go for an expression parsing
4829 this.firstToken = TokenNameREMAINDER;
4830 this.scanner.recordLineSeparator = true; // recovery goals must record line separators
4832 public void goForFieldDeclaration(){
4833 //tells the scanner to go for field declaration parsing
4835 this.firstToken = TokenNameAND_AND ;
4836 this.scanner.recordLineSeparator = true;
4838 public void goForGenericMethodDeclaration(){
4839 //tells the scanner to go for generic method declarations parsing
4841 this.firstToken = TokenNameDIVIDE;
4842 this.scanner.recordLineSeparator = true;
4844 public void goForHeaders(){
4845 //tells the scanner to go for headers only parsing
4847 this.firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
4848 this.scanner.recordLineSeparator = true; // recovery goals must record line separators
4850 public void goForImportDeclaration(){
4851 //tells the scanner to go for import declaration parsing
4853 this.firstToken = TokenNameOR_OR ;
4854 this.scanner.recordLineSeparator = true;
4856 public void goForInitializer(){
4857 //tells the scanner to go for initializer parsing
4859 this.firstToken = TokenNameRIGHT_SHIFT ;
4860 this.scanner.recordLineSeparator = false;
4862 public void goForMethodBody(){
4863 //tells the scanner to go for method body parsing
4865 this.firstToken = TokenNameMINUS_MINUS ;
4866 this.scanner.recordLineSeparator = false;
4868 public void goForPackageDeclaration() {
4869 //tells the scanner to go for package declaration parsing
4871 this.firstToken = TokenNameQUESTION;
4872 this.scanner.recordLineSeparator = true;
4874 public void goForTypeDeclaration() {
4875 //tells the scanner to go for type (interface or class) declaration parsing
4877 this.firstToken = TokenNamePLUS;
4878 this.scanner.recordLineSeparator = true;
4880 protected void ignoreExpressionAssignment() {
4881 // Assignment ::= InvalidArrayInitializerAssignement
4882 // encoded operator would be: this.intStack[this.intPtr]
4884 ArrayInitializer arrayInitializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
4885 this.expressionLengthPtr -- ;
4886 // report a syntax error and abort parsing
4887 problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
4889 protected void ignoreInterfaceDeclaration() {
4890 // BlockStatement ::= InvalidInterfaceDeclaration
4891 //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
4893 // length declarations
4895 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4896 //there are length declarations
4897 //dispatch according to the type of the declarations
4898 dispatchDeclarationInto(length);
4901 flushCommentsDefinedPriorTo(this.endStatementPosition);
4903 // report the problem and continue parsing
4904 TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4905 typeDecl.bodyEnd = this.endStatementPosition;
4906 problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
4908 // mark initializers with local type mark if needed
4909 markInitializersWithLocalType(typeDecl);
4911 // remove the ast node created in interface header
4913 pushOnAstLengthStack(-1);
4916 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
4917 // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
4918 // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
4921 astStack : modifiers arguments throws statements
4922 identifierStack : name
4924 astStack : MethodDeclaration
4928 // pop the position of the { (body of the method) pushed in block decl
4934 this.realBlockPtr--;
4938 if (hasBody && ((length = this.astLengthStack[this.astLengthPtr--]) != 0)) {
4939 this.astPtr -= length;
4941 ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) this.astStack[this.astPtr];
4942 constructorDeclaration.bodyEnd = this.endStatementPosition;
4943 constructorDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
4945 constructorDeclaration.modifiers |= AccSemicolonBody;
4948 protected void ignoreMethodBody() {
4949 // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
4952 astStack : modifiers arguments throws statements
4953 identifierStack : type name
4954 intStack : dim dim dim
4956 astStack : MethodDeclaration
4961 // pop the position of the { (body of the method) pushed in block decl
4963 // retrieve end position of method declarator
4966 this.realBlockPtr--;
4968 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
4969 this.astPtr -= length;
4972 //watch for } that could be given as a unicode ! ( u007D is '}' )
4973 MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
4974 md.bodyEnd = this.endPosition;
4975 md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
4977 // report the problem and continue the parsing - narrowing the problem onto the method
4978 problemReporter().abstractMethodNeedingNoBody(md);
4980 public void initialize() {
4981 //positionning the parser for a new compilation unit
4982 //avoiding stack reallocation and all that....
4984 this.astLengthPtr = -1;
4985 this.expressionPtr = -1;
4986 this.expressionLengthPtr = -1;
4987 this.identifierPtr = -1;
4988 this.identifierLengthPtr = -1;
4990 this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
4991 this.variablesCounter[this.nestedType] = 0;
4992 this.dimensions = 0 ;
4993 this.realBlockPtr = -1;
4994 this.compilationUnit = null;
4995 this.referenceContext = null;
4996 this.endStatementPosition = 0;
4998 //remove objects from stack too, while the same parser/compiler couple is
4999 //re-used between two compilations ....
5001 int astLength = this.astStack.length;
5002 if (this.noAstNodes.length < astLength){
5003 this.noAstNodes = new ASTNode[astLength];
5004 //System.out.println("Resized AST stacks : "+ astLength);
5007 System.arraycopy(this.noAstNodes, 0, this.astStack, 0, astLength);
5009 int expressionLength = this.expressionStack.length;
5010 if (this.noExpressions.length < expressionLength){
5011 this.noExpressions = new Expression[expressionLength];
5012 //System.out.println("Resized EXPR stacks : "+ expressionLength);
5014 System.arraycopy(this.noExpressions, 0, this.expressionStack, 0, expressionLength);
5016 // reset scanner state
5017 this.scanner.commentPtr = -1;
5018 this.scanner.foundTaskCount = 0;
5019 this.scanner.eofPosition = Integer.MAX_VALUE;
5020 this.scanner.wasNonExternalizedStringLiteral = false;
5021 this.scanner.nonNLSStrings = null;
5022 this.scanner.currentLine = null;
5027 this.lastCheckPoint = -1;
5028 this.currentElement = null;
5029 this.restartRecovery = false;
5030 this.hasReportedError = false;
5031 this.recoveredStaticInitializerStart = 0;
5032 this.lastIgnoredToken = -1;
5033 this.lastErrorEndPosition = -1;
5034 this.listLength = 0;
5036 this.rBraceStart = 0;
5038 this.rBraceSuccessorStart = 0;
5040 public void initializeScanner(){
5041 this.scanner = new Scanner(
5043 false /*whitespace*/,
5044 this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /*nls*/,
5045 this.options.sourceLevel /*sourceLevel*/,
5046 this.options.taskTags/*taskTags*/,
5047 this.options.taskPriorites/*taskPriorities*/,
5048 this.options.isTaskCaseSensitive/*taskCaseSensitive*/);
5050 public final static void initTables() throws java.io.IOException {
5052 final String prefix = FILEPREFIX;
5054 lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5055 char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5056 check_table = new short[chars.length];
5057 for (int c = chars.length; c-- > 0;) {
5058 check_table[c] = (short) (chars[c] - 32768);
5060 asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5061 asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5062 nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5063 nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5064 terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5065 non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5066 term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5068 scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5069 scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5070 scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5071 scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5072 scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5073 scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5074 in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5076 rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5077 term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5078 scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5080 name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
5081 readableName = readReadableNameTable(READABLE_NAMES);
5085 public static int in_symbol(int state) {
5086 return in_symb[original_state(state)];
5088 public final void jumpOverMethodBody() {
5089 //on diet parsing.....do not buffer method statements
5091 //the scanner.diet is reinitialized to false
5092 //automatically by the scanner once it has jumped over
5095 if (this.diet && (this.dietInt == 0))
5096 this.scanner.diet = true;
5098 protected void markEnclosingMemberWithLocalType() {
5099 if (this.currentElement != null) return; // this is already done in the recovery code
5100 for (int i = this.astPtr; i >= 0; i--) {
5101 ASTNode node = this.astStack[i];
5102 if (node instanceof AbstractMethodDeclaration
5103 || node instanceof FieldDeclaration
5104 || node instanceof TypeDeclaration) { // mark type for now: all initializers will be marked when added to this type
5105 node.bits |= ASTNode.HasLocalTypeMASK;
5109 // default to reference context (case of parse method body)
5110 if (this.referenceContext instanceof AbstractMethodDeclaration
5111 || this.referenceContext instanceof TypeDeclaration) {
5112 ((ASTNode)this.referenceContext).bits |= ASTNode.HasLocalTypeMASK;
5115 protected void markInitializersWithLocalType(TypeDeclaration type) {
5116 if (type.fields == null || (type.bits & ASTNode.HasLocalTypeMASK) == 0) return;
5117 for (int i = 0, length = type.fields.length; i < length; i++) {
5118 FieldDeclaration field = type.fields[i];
5119 if (field instanceof Initializer) {
5120 field.bits |= ASTNode.HasLocalTypeMASK;
5125 * Move checkpoint location (current implementation is moving it by one token)
5127 * Answers true if successfully moved checkpoint (in other words, it did not attempt to move it
5128 * beyond end of file).
5130 protected boolean moveRecoveryCheckpoint() {
5132 int pos = this.lastCheckPoint;
5133 /* reset scanner, and move checkpoint by one token */
5134 this.scanner.startPosition = pos;
5135 this.scanner.currentPosition = pos;
5136 this.scanner.diet = false; // quit jumping over method bodies
5138 /* if about to restart, then no need to shift token */
5139 if (this.restartRecovery){
5140 this.lastIgnoredToken = -1;
5141 this.scanner.currentLine = null;
5145 /* protect against shifting on an invalid token */
5146 this.lastIgnoredToken = this.nextIgnoredToken;
5147 this.nextIgnoredToken = -1;
5150 this.nextIgnoredToken = this.scanner.getNextToken();
5151 if(this.scanner.currentPosition == this.scanner.startPosition){
5152 this.scanner.currentPosition++; // on fake completion identifier
5153 this.nextIgnoredToken = -1;
5156 } catch(InvalidInputException e){
5157 pos = this.scanner.currentPosition;
5159 } while (this.nextIgnoredToken < 0);
5161 if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
5162 if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
5163 this.scanner.currentLine = null;
5167 this.lastCheckPoint = this.scanner.currentPosition;
5169 /* reset scanner again to previous checkpoint location*/
5170 this.scanner.startPosition = pos;
5171 this.scanner.currentPosition = pos;
5172 this.scanner.commentPtr = -1;
5173 this.scanner.foundTaskCount = 0;
5174 this.scanner.currentLine = null;
5179 The following implementation moves the checkpoint location by one line:
5181 int pos = this.lastCheckPoint;
5182 // reset scanner, and move checkpoint by one token
5183 this.scanner.startPosition = pos;
5184 this.scanner.currentPosition = pos;
5185 this.scanner.diet = false; // quit jumping over method bodies
5187 // if about to restart, then no need to shift token
5188 if (this.restartRecovery){
5189 this.lastIgnoredToken = -1;
5193 // protect against shifting on an invalid token
5194 this.lastIgnoredToken = this.nextIgnoredToken;
5195 this.nextIgnoredToken = -1;
5197 boolean wasTokenizingWhiteSpace = this.scanner.tokenizeWhiteSpace;
5198 this.scanner.tokenizeWhiteSpace = true;
5202 this.nextIgnoredToken = this.scanner.getNextToken();
5203 switch(this.nextIgnoredToken){
5204 case Scanner.TokenNameWHITESPACE :
5205 if(this.scanner.getLineNumber(this.scanner.startPosition)
5206 == this.scanner.getLineNumber(this.scanner.currentPosition)){
5207 this.nextIgnoredToken = -1;
5210 case TokenNameSEMICOLON :
5211 case TokenNameLBRACE :
5212 case TokenNameRBRACE :
5214 case TokenNameIdentifier :
5215 if(this.scanner.currentPosition == this.scanner.startPosition){
5216 this.scanner.currentPosition++; // on fake completion identifier
5219 this.nextIgnoredToken = -1;
5222 break checkpointMove;
5224 } catch(InvalidInputException e){
5225 pos = this.scanner.currentPosition;
5227 } while (this.nextIgnoredToken < 0);
5228 this.scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
5230 if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
5231 if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
5235 this.lastCheckPoint = this.scanner.currentPosition;
5237 // reset scanner again to previous checkpoint location
5238 this.scanner.startPosition = pos;
5239 this.scanner.currentPosition = pos;
5240 this.scanner.commentPtr = -1;
5245 protected MessageSend newMessageSend() {
5246 // '(' ArgumentListopt ')'
5247 // the arguments are on the expression stack
5249 MessageSend m = new MessageSend();
5251 if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
5252 this.expressionPtr -= length;
5254 this.expressionStack,
5255 this.expressionPtr + 1,
5256 m.arguments = new Expression[length],
5262 public static int nasi(int state) {
5263 return nasb[original_state(state)];
5265 public static int ntAction(int state, int sym) {
5266 return base_action[state + sym];
5268 private final void optimizedConcatNodeLists() {
5269 /*back from a recursive loop. Virtualy group the
5270 astNode into an array using astLengthStack*/
5273 * This is a case where you have two sublists into the astStack that you want
5274 * to merge in one list. There is no action required on the astStack. The only
5275 * thing you need to do is merge the two lengths specified on the astStackLength.
5276 * The top two length are for example:
5278 * and you want to result in a list like:
5280 * This means that the p could be equals to 0 in case there is no astNode pushed
5282 * Look at the InterfaceMemberDeclarations for an example.
5283 * This case optimizes the fact that p == 1.
5286 this.astLengthStack[--this.astLengthPtr]++;
5288 protected static int original_state(int state) {
5289 return -base_check(state);
5291 /*main loop of the automat
5292 When a rule is reduced, the method consumeRule(int) is called with the number
5293 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
5294 called in order to remember (when needed) the consumed token */
5295 // (int)asr[asi(act)]
5296 // name[symbol_index[currentKind]]
5297 protected void parse() {
5298 boolean isDietParse = this.diet;
5299 int oldFirstToken = getFirstToken();
5300 this.hasError = false;
5302 this.hasReportedError = false;
5303 int act = START_STATE;
5304 this.stateStackTop = -1;
5305 this.currentToken = getFirstToken();
5306 ProcessTerminals : for (;;) {
5307 int stackLength = this.stack.length;
5308 if (++this.stateStackTop >= stackLength) {
5311 this.stack = new int[stackLength + StackIncrement], 0,
5314 this.stack[this.stateStackTop] = act;
5316 act = tAction(act, this.currentToken);
5318 if (act == ERROR_ACTION || this.restartRecovery) {
5319 int errorPos = this.scanner.currentPosition;
5320 if (!this.hasReportedError){
5321 this.hasError = true;
5323 if (resumeOnSyntaxError()) {
5324 if (act == ERROR_ACTION) this.lastErrorEndPosition = errorPos;
5326 this.stateStackTop = -1;
5327 this.currentToken = getFirstToken();
5328 continue ProcessTerminals;
5331 break ProcessTerminals;
5333 if (act <= NUM_RULES) {
5334 this.stateStackTop--;
5336 } else if (act > ERROR_ACTION) { /* shift-reduce */
5337 consumeToken(this.currentToken);
5338 if (this.currentElement != null) this.recoveryTokenCheck();
5340 this.currentToken = this.scanner.getNextToken();
5341 } catch(InvalidInputException e){
5342 if (!this.hasReportedError){
5343 this.problemReporter().scannerError(this, e.getMessage());
5344 this.hasReportedError = true;
5346 this.lastCheckPoint = this.scanner.currentPosition;
5347 this.restartRecovery = true;
5349 act -= ERROR_ACTION;
5352 if (act < ACCEPT_ACTION) { /* shift */
5353 consumeToken(this.currentToken);
5354 if (this.currentElement != null) this.recoveryTokenCheck();
5356 this.currentToken = this.scanner.getNextToken();
5357 } catch(InvalidInputException e){
5358 if (!this.hasReportedError){
5359 this.problemReporter().scannerError(this, e.getMessage());
5360 this.hasReportedError = true;
5362 this.lastCheckPoint = this.scanner.currentPosition;
5363 this.restartRecovery = true;
5365 continue ProcessTerminals;
5367 break ProcessTerminals;
5369 ProcessNonTerminals : do { /* reduce */
5371 this.stateStackTop -= (rhs[act] - 1);
5372 act = ntAction(this.stack[this.stateStackTop], lhs[act]);
5373 } while (act <= NUM_RULES);
5377 if (this.reportSyntaxErrorIsRequired && this.hasError) {
5378 reportSyntaxErrors(isDietParse, oldFirstToken);
5382 protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) {
5383 if(this.referenceContext instanceof MethodDeclaration) {
5384 MethodDeclaration methodDeclaration = (MethodDeclaration) this.referenceContext;
5385 if(methodDeclaration.errorInSignature){
5389 this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5390 this.scanner.recordLineSeparator = false;
5392 int start = this.scanner.initialPosition;
5393 int end = this.scanner.eofPosition <= Integer.MAX_VALUE ? this.scanner.eofPosition - 1 : this.scanner.eofPosition;
5395 TypeDeclaration[] types = this.compilationUnit.types;
5397 int[][] intervalToSkip = org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types);
5398 DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2]);
5399 diagnoseParser.diagnoseParse();
5401 reportSyntaxErrorsForSkippedMethod(types);
5402 this.scanner.resetTo(start, end);
5404 DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end);
5405 diagnoseParser.diagnoseParse();
5408 private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types){
5410 for (int i = 0; i < types.length; i++) {
5411 TypeDeclaration[] memberTypes = types[i].memberTypes;
5412 if(memberTypes != null) {
5413 reportSyntaxErrorsForSkippedMethod(memberTypes);
5416 AbstractMethodDeclaration[] methods = types[i].methods;
5417 if(methods != null) {
5418 for (int j = 0; j < methods.length; j++) {
5419 AbstractMethodDeclaration method = methods[j];
5420 if(methods[j].errorInSignature) {
5421 DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd);
5422 diagnoseParser.diagnoseParse();
5427 FieldDeclaration[] fields = types[i].fields;
5428 if (fields != null) {
5429 int length = fields.length;
5430 for (int j = 0; j < length; j++) {
5431 if (fields[j] instanceof Initializer) {
5432 Initializer initializer = (Initializer)fields[j];
5433 if(initializer.errorInSignature){
5434 DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd);
5435 diagnoseParser.diagnoseParse();
5443 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
5444 parse(cd, unit, false);
5446 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit, boolean recordLineSeparator) {
5447 //only parse the method body of cd
5448 //fill out its statements
5450 //convert bugs into parse error
5453 goForBlockStatementsopt();
5454 if (recordLineSeparator) {
5455 this.scanner.recordLineSeparator = true;
5457 this.nestedMethod[this.nestedType]++;
5458 pushOnRealBlockStack(0);
5460 this.referenceContext = cd;
5461 this.compilationUnit = unit;
5463 this.scanner.resetTo(cd.bodyStart, cd.bodyEnd);
5466 } catch (AbortCompilation ex) {
5467 this.lastAct = ERROR_ACTION;
5469 this.nestedMethod[this.nestedType]--;
5472 checkNonNLSAfterBodyEnd(cd.declarationSourceEnd);
5474 if (this.lastAct == ERROR_ACTION) {
5480 cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5482 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
5483 this.astPtr -= length;
5484 if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
5485 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
5490 cd.statements = new Statement[length - 1],
5493 cd.constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
5494 } else { //need to add explicitly the super();
5498 cd.statements = new Statement[length],
5501 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
5504 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
5505 if (!containsComment(cd.bodyStart, cd.bodyEnd)) {
5506 cd.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5510 if (cd.constructorCall.sourceEnd == 0) {
5511 cd.constructorCall.sourceEnd = cd.sourceEnd;
5512 cd.constructorCall.sourceStart = cd.sourceStart;
5518 FieldDeclaration field,
5519 TypeDeclaration type,
5520 CompilationUnitDeclaration unit,
5521 char[] initializationSource) {
5522 //only parse the initializationSource of the given field
5524 //convert bugs into parse error
5528 this.nestedMethod[this.nestedType]++;
5530 this.referenceContext = type;
5531 this.compilationUnit = unit;
5533 this.scanner.setSource(initializationSource);
5534 this.scanner.resetTo(0, initializationSource.length-1);
5537 } catch (AbortCompilation ex) {
5538 this.lastAct = ERROR_ACTION;
5540 this.nestedMethod[this.nestedType]--;
5543 if (this.lastAct == ERROR_ACTION) {
5547 field.initialization = this.expressionStack[this.expressionPtr];
5549 // mark field with local type if one was found during parsing
5550 if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
5551 field.bits |= ASTNode.HasLocalTypeMASK;
5557 Initializer initializer,
5558 TypeDeclaration type,
5559 CompilationUnitDeclaration unit) {
5560 //only parse the method body of md
5561 //fill out method statements
5563 //convert bugs into parse error
5566 goForBlockStatementsopt();
5567 this.nestedMethod[this.nestedType]++;
5568 pushOnRealBlockStack(0);
5570 this.referenceContext = type;
5571 this.compilationUnit = unit;
5573 this.scanner.resetTo(initializer.bodyStart, initializer.bodyEnd); // just on the beginning {
5576 } catch (AbortCompilation ex) {
5577 this.lastAct = ERROR_ACTION;
5579 this.nestedMethod[this.nestedType]--;
5582 checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd);
5584 if (this.lastAct == ERROR_ACTION) {
5589 initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5591 if ((length = this.astLengthStack[this.astLengthPtr--]) > 0) {
5592 System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length);
5594 // check whether this block at least contains some comment in it
5595 if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) {
5596 initializer.block.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5600 // mark initializer with local type if one was found during parsing
5601 if ((type.bits & ASTNode.HasLocalTypeMASK) != 0) {
5602 initializer.bits |= ASTNode.HasLocalTypeMASK;
5607 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
5608 //only parse the method body of md
5609 //fill out method statements
5611 //convert bugs into parse error
5613 if (md.isAbstract())
5617 if ((md.modifiers & AccSemicolonBody) != 0)
5621 goForBlockStatementsopt();
5622 this.nestedMethod[this.nestedType]++;
5623 pushOnRealBlockStack(0);
5625 this.referenceContext = md;
5626 this.compilationUnit = unit;
5628 this.scanner.resetTo(md.bodyStart, md.bodyEnd);
5629 // reset the scanner to parser from { down to }
5632 } catch (AbortCompilation ex) {
5633 this.lastAct = ERROR_ACTION;
5635 this.nestedMethod[this.nestedType]--;
5638 checkNonNLSAfterBodyEnd(md.declarationSourceEnd);
5640 if (this.lastAct == ERROR_ACTION) {
5645 md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
5647 if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
5650 (this.astPtr -= length) + 1,
5651 md.statements = new Statement[length],
5655 if (!containsComment(md.bodyStart, md.bodyEnd)) {
5656 md.bits |= ASTNode.UndocumentedEmptyBlockMASK;
5662 public CompilationUnitDeclaration parse(
5663 ICompilationUnit sourceUnit,
5664 CompilationResult compilationResult) {
5665 // parses a compilation unit and manages error handling (even bugs....)
5667 return parse(sourceUnit, compilationResult, -1, -1/*parse without reseting the scanner*/);
5671 public CompilationUnitDeclaration parse(
5672 ICompilationUnit sourceUnit,
5673 CompilationResult compilationResult,
5676 // parses a compilation unit and manages error handling (even bugs....)
5678 CompilationUnitDeclaration unit;
5680 /* automaton initialization */
5682 goForCompilationUnit();
5684 /* scanners initialization */
5685 char[] contents = sourceUnit.getContents();
5686 this.scanner.setSource(contents);
5687 if (end != -1) this.scanner.resetTo(start, end);
5688 if (this.javadocParser != null && this.javadocParser.checkDocComment) {
5689 this.javadocParser.scanner.setSource(contents);
5691 this.javadocParser.scanner.resetTo(start, end);
5695 this.referenceContext =
5696 this.compilationUnit =
5697 new CompilationUnitDeclaration(
5698 this.problemReporter,
5700 this.scanner.source.length);
5704 unit = this.compilationUnit;
5705 this.compilationUnit = null; // reset parser
5706 // tag unit has having read bodies
5707 if (!this.diet) unit.bits |= ASTNode.HasAllMethodBodies;
5711 public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
5712 /* automaton initialization */
5714 goForClassBodyDeclarations();
5715 /* scanner initialization */
5716 this.scanner.setSource(source);
5717 this.scanner.resetTo(offset, offset + length - 1);
5718 if (this.javadocParser != null && this.javadocParser.checkDocComment) {
5719 this.javadocParser.scanner.setSource(source);
5720 this.javadocParser.scanner.resetTo(offset, offset + length - 1);
5723 /* type declaration should be parsed as member type declaration */
5724 this.nestedType = 1;
5727 this.referenceContext = unit;
5728 this.compilationUnit = unit;
5733 } catch (AbortCompilation ex) {
5734 this.lastAct = ERROR_ACTION;
5737 if (this.lastAct == ERROR_ACTION) {
5741 if ((astLength = this.astLengthStack[this.astLengthPtr--]) != 0) {
5742 ASTNode[] result = new ASTNode[astLength];
5743 this.astPtr -= astLength;
5744 System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength);
5749 public Expression parseExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
5753 this.nestedMethod[this.nestedType]++;
5755 this.referenceContext = unit;
5756 this.compilationUnit = unit;
5758 this.scanner.setSource(source);
5759 this.scanner.resetTo(offset, offset + length - 1);
5762 } catch (AbortCompilation ex) {
5763 this.lastAct = ERROR_ACTION;
5765 this.nestedMethod[this.nestedType]--;
5768 if (this.lastAct == ERROR_ACTION) {
5772 return this.expressionStack[this.expressionPtr];
5774 public void persistLineSeparatorPositions() {
5775 if (this.scanner.recordLineSeparator) {
5776 this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5780 * Returns this parser's problem reporter initialized with its reference context.
5781 * Also it is assumed that a problem is going to be reported, so initializes
5782 * the compilation result's line positions.
5784 * @return ProblemReporter
5786 public ProblemReporter problemReporter(){
5787 if (this.scanner.recordLineSeparator) {
5788 this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
5790 this.problemReporter.referenceContext = this.referenceContext;
5791 return this.problemReporter;
5793 protected void pushIdentifier() {
5794 /*push the consumeToken on the identifier stack.
5795 Increase the total number of identifier in the stack.
5796 identifierPtr points on the next top */
5798 int stackLength = this.identifierStack.length;
5799 if (++this.identifierPtr >= stackLength) {
5801 this.identifierStack, 0,
5802 this.identifierStack = new char[stackLength + 20][], 0,
5805 this.identifierPositionStack, 0,
5806 this.identifierPositionStack = new long[stackLength + 20], 0,
5809 this.identifierStack[this.identifierPtr] = this.scanner.getCurrentIdentifierSource();
5810 this.identifierPositionStack[this.identifierPtr] =
5811 (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1);
5813 stackLength = this.identifierLengthStack.length;
5814 if (++this.identifierLengthPtr >= stackLength) {
5816 this.identifierLengthStack, 0,
5817 this.identifierLengthStack = new int[stackLength + 10], 0,
5820 this.identifierLengthStack[this.identifierLengthPtr] = 1;
5822 protected void pushIdentifier(int flag) {
5823 /*push a special flag on the stack :
5824 -zero stands for optional Name
5825 -negative number for direct ref to base types.
5826 identifierLengthPtr points on the top */
5828 int stackLength = this.identifierLengthStack.length;
5829 if (++this.identifierLengthPtr >= stackLength) {
5831 this.identifierLengthStack, 0,
5832 this.identifierLengthStack = new int[stackLength + 10], 0,
5835 this.identifierLengthStack[this.identifierLengthPtr] = flag;
5837 protected void pushOnAstLengthStack(int pos) {
5839 int stackLength = this.astLengthStack.length;
5840 if (++this.astLengthPtr >= stackLength) {
5842 this.astLengthStack, 0,
5843 this.astLengthStack = new int[stackLength + StackIncrement], 0,
5846 this.astLengthStack[this.astLengthPtr] = pos;
5848 protected void pushOnAstStack(ASTNode node) {
5849 /*add a new obj on top of the ast stack
5850 astPtr points on the top*/
5852 int stackLength = this.astStack.length;
5853 if (++this.astPtr >= stackLength) {
5856 this.astStack = new ASTNode[stackLength + AstStackIncrement], 0,
5858 this.astPtr = stackLength;
5860 this.astStack[this.astPtr] = node;
5862 stackLength = this.astLengthStack.length;
5863 if (++this.astLengthPtr >= stackLength) {
5865 this.astLengthStack, 0,
5866 this.astLengthStack = new int[stackLength + AstStackIncrement], 0,
5869 this.astLengthStack[this.astLengthPtr] = 1;
5871 protected void pushOnExpressionStack(Expression expr) {
5873 int stackLength = this.expressionStack.length;
5874 if (++this.expressionPtr >= stackLength) {
5876 this.expressionStack, 0,
5877 this.expressionStack = new Expression[stackLength + ExpressionStackIncrement], 0,
5880 this.expressionStack[this.expressionPtr] = expr;
5882 stackLength = this.expressionLengthStack.length;
5883 if (++this.expressionLengthPtr >= stackLength) {
5885 this.expressionLengthStack, 0,
5886 this.expressionLengthStack = new int[stackLength + ExpressionStackIncrement], 0,
5889 this.expressionLengthStack[this.expressionLengthPtr] = 1;
5891 protected void pushOnExpressionStackLengthStack(int pos) {
5893 int stackLength = this.expressionLengthStack.length;
5894 if (++this.expressionLengthPtr >= stackLength) {
5896 this.expressionLengthStack, 0,
5897 this.expressionLengthStack = new int[stackLength + StackIncrement], 0,
5900 this.expressionLengthStack[this.expressionLengthPtr] = pos;
5902 protected void pushOnIntStack(int pos) {
5904 int stackLength = this.intStack.length;
5905 if (++this.intPtr >= stackLength) {
5908 this.intStack = new int[stackLength + StackIncrement], 0,
5911 this.intStack[this.intPtr] = pos;
5913 protected void pushOnRealBlockStack(int i){
5915 int stackLength = this.realBlockStack.length;
5916 if (++this.realBlockPtr >= stackLength) {
5918 this.realBlockStack, 0,
5919 this.realBlockStack = new int[stackLength + StackIncrement], 0,
5922 this.realBlockStack[this.realBlockPtr] = i;
5924 protected static char[] readTable(String filename) throws java.io.IOException {
5926 //files are located at Parser.class directory
5928 InputStream stream = Parser.class.getResourceAsStream(filename);
5929 if (stream == null) {
5930 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
5932 byte[] bytes = null;
5934 stream = new BufferedInputStream(stream);
5935 bytes = Util.getInputStreamAsByteArray(stream, -1);
5939 } catch (IOException e) {
5944 //minimal integrity check (even size expected)
5945 int length = bytes.length;
5946 if (length % 2 != 0)
5947 throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
5949 // convert bytes into chars
5950 char[] chars = new char[length / 2];
5955 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
5961 protected static byte[] readByteTable(String filename) throws java.io.IOException {
5963 //files are located at Parser.class directory
5965 InputStream stream = Parser.class.getResourceAsStream(filename);
5966 if (stream == null) {
5967 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
5969 byte[] bytes = null;
5971 stream = new BufferedInputStream(stream);
5972 bytes = Util.getInputStreamAsByteArray(stream, -1);
5976 } catch (IOException e) {
5982 protected static String[] readReadableNameTable(String filename) {
5983 String[] result = new String[name.length];
5985 ResourceBundle bundle;
5987 bundle = ResourceBundle.getBundle(filename, Locale.getDefault());
5988 } catch(MissingResourceException e) {
5989 System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
5992 for (int i = 0; i < NT_OFFSET + 1; i++) {
5993 result[i] = name[i];
5995 for (int i = NT_OFFSET; i < name.length; i++) {
5997 String n = bundle.getString(name[i]);
5998 if(n != null && n.length() > 0) {
6001 result[i] = name[i];
6003 } catch(MissingResourceException e) {
6004 result[i] = name[i];
6010 protected static String[] readNameTable(String filename) throws java.io.IOException {
6011 char[] contents = readTable(filename);
6012 char[][] nameAsChar = CharOperation.splitOn('\n', contents);
6014 String[] result = new String[nameAsChar.length + 1];
6016 for (int i = 0; i < nameAsChar.length; i++) {
6017 result[i + 1] = new String(nameAsChar[i]);
6022 public void recoveryExitFromVariable() {
6023 if(this.currentElement != null && this.currentElement.parent != null) {
6024 if(this.currentElement instanceof RecoveredLocalVariable) {
6026 int end = ((RecoveredLocalVariable)this.currentElement).localDeclaration.sourceEnd;
6027 this.currentElement.updateSourceEndIfNecessary(end);
6028 this.currentElement = this.currentElement.parent;
6029 } else if(this.currentElement instanceof RecoveredField
6030 && !(this.currentElement instanceof RecoveredInitializer)) {
6032 int end = ((RecoveredField)this.currentElement).fieldDeclaration.sourceEnd;
6033 this.currentElement.updateSourceEndIfNecessary(end);
6034 this.currentElement = this.currentElement.parent;
6038 /* Token check performed on every token shift once having entered
6041 public void recoveryTokenCheck() {
6042 switch (this.currentToken) {
6043 case TokenNameLBRACE :
6044 RecoveredElement newElement = null;
6045 if(!this.ignoreNextOpeningBrace) {
6046 newElement = this.currentElement.updateOnOpeningBrace(this.scanner.startPosition - 1, this.scanner.currentPosition - 1);
6048 this.lastCheckPoint = this.scanner.currentPosition;
6049 if (newElement != null){ // null means nothing happened
6050 this.restartRecovery = true; // opening brace detected
6051 this.currentElement = newElement;
6055 case TokenNameRBRACE :
6056 this.rBraceStart = this.scanner.startPosition - 1;
6057 this.rBraceEnd = this.scanner.currentPosition - 1;
6058 this.endPosition = this.flushCommentsDefinedPriorTo(this.rBraceEnd);
6060 this.currentElement.updateOnClosingBrace(this.scanner.startPosition, this.rBraceEnd);
6061 this.lastCheckPoint = this.scanner.currentPosition;
6062 if (newElement != this.currentElement){
6063 this.currentElement = newElement;
6066 case TokenNameSEMICOLON :
6067 this.endStatementPosition = this.scanner.currentPosition - 1;
6068 this.endPosition = this.scanner.startPosition - 1;
6071 if (this.rBraceEnd > this.rBraceSuccessorStart && this.scanner.currentPosition != this.scanner.startPosition){
6072 this.rBraceSuccessorStart = this.scanner.startPosition;
6077 this.ignoreNextOpeningBrace = false;
6079 protected void resetModifiers() {
6080 this.modifiers = AccDefault;
6081 this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
6082 this.scanner.commentPtr = -1;
6085 * Reset context so as to resume to regular parse loop
6087 protected void resetStacks() {
6090 this.astLengthPtr = -1;
6091 this.expressionPtr = -1;
6092 this.expressionLengthPtr = -1;
6093 this.identifierPtr = -1;
6094 this.identifierLengthPtr = -1;
6096 this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
6097 this.variablesCounter[this.nestedType] = 0;
6098 this.dimensions = 0 ;
6099 this.realBlockStack[this.realBlockPtr = 0] = 0;
6100 this.recoveredStaticInitializerStart = 0;
6101 this.listLength = 0;
6102 // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=29365
6103 if (this.scanner != null) this.scanner.currentLine = null;
6106 * Reset context so as to resume to regular parse loop
6107 * If unable to reset for resuming, answers false.
6109 * Move checkpoint location, reset internal stacks and
6110 * decide which grammar goal is activated.
6112 protected boolean resumeAfterRecovery() {
6114 // Reset javadoc before restart parsing after recovery
6115 this.javadoc = null;
6117 // reset internal stacks
6120 /* attempt to move checkpoint location */
6121 if (!this.moveRecoveryCheckpoint()) {
6125 // only look for headers
6126 if (this.referenceContext instanceof CompilationUnitDeclaration){
6128 this.diet = true; // passed this point, will not consider method bodies
6131 // does not know how to restart
6135 * Syntax error was detected. Will attempt to perform some recovery action in order
6136 * to resume to the regular parse loop.
6138 protected boolean resumeOnSyntaxError() {
6140 /* request recovery initialization */
6141 if (this.currentElement == null){
6142 this.currentElement =
6143 this.buildInitialRecoveryState(); // build some recovered elements
6145 /* do not investigate deeper in recovery when no recovered element */
6146 if (this.currentElement == null) return false;
6148 /* manual forced recovery restart - after headers */
6149 if (this.restartRecovery){
6150 this.restartRecovery = false;
6152 /* update recovery state with current error state of the parser */
6153 this.updateRecoveryState();
6155 /* attempt to reset state in order to resume to parse loop */
6156 return this.resumeAfterRecovery();
6158 public static int tAction(int state, int sym) {
6159 return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
6161 public String toString() {
6163 String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
6164 for (int i = 0; i <= this.identifierPtr; i++) {
6165 s = s + "\"" + String.valueOf(this.identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
6167 s = s + "}\n"; //$NON-NLS-1$
6169 s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
6170 for (int i = 0; i <= this.identifierLengthPtr; i++) {
6171 s = s + this.identifierLengthStack[i] + ","; //$NON-NLS-1$
6173 s = s + "}\n"; //$NON-NLS-1$
6175 s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
6176 for (int i = 0; i <= this.astLengthPtr; i++) {
6177 s = s + this.astLengthStack[i] + ","; //$NON-NLS-1$
6179 s = s + "}\n"; //$NON-NLS-1$
6180 s = s + "astPtr : int = " + String.valueOf(this.astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
6182 s = s + "intStack : int[] = {"; //$NON-NLS-1$
6183 for (int i = 0; i <= this.intPtr; i++) {
6184 s = s + this.intStack[i] + ","; //$NON-NLS-1$
6186 s = s + "}\n"; //$NON-NLS-1$
6188 s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
6189 for (int i = 0; i <= this.expressionLengthPtr; i++) {
6190 s = s + this.expressionLengthStack[i] + ","; //$NON-NLS-1$
6192 s = s + "}\n"; //$NON-NLS-1$
6194 s = s + "expressionPtr : int = " + String.valueOf(this.expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
6196 s = s + "\n\n\n----------------Scanner--------------\n" + this.scanner.toString(); //$NON-NLS-1$
6201 * Update recovery state based on current parser/scanner state
6203 protected void updateRecoveryState() {
6205 /* expose parser state to recovery state */
6206 this.currentElement.updateFromParserState();
6208 /* check and update recovered state based on current token,
6209 this action is also performed when shifting token after recovery
6212 this.recoveryTokenCheck();
6214 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
6215 //fields is a definition of fields that are grouped together like in
6216 //public int[] a, b[], c
6217 //which results into 3 fields.
6219 FieldDeclaration field;
6220 int endTypeDeclarationPosition =
6221 -1 + this.astStack[this.astPtr - variableDeclaratorsCounter + 1].sourceStart;
6222 for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
6223 //last one is special(see below)
6224 field = (FieldDeclaration) this.astStack[this.astPtr - i - 1];
6225 field.endPart1Position = endTypeDeclarationPosition;
6226 field.endPart2Position = -1 + this.astStack[this.astPtr - i].sourceStart;
6229 (field = (FieldDeclaration) this.astStack[this.astPtr]).endPart1Position =
6230 endTypeDeclarationPosition;
6231 field.endPart2Position = field.declarationSourceEnd;
6234 protected void updateSourcePosition(Expression exp) {
6235 //update the source Position of the expression
6237 //intStack : int int
6241 exp.sourceEnd = this.intStack[this.intPtr--];
6242 exp.sourceStart = this.intStack[this.intPtr--];