1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
13 import net.sourceforge.phpdt.core.compiler.*;
14 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
15 import net.sourceforge.phpdt.internal.compiler.*;
16 import net.sourceforge.phpdt.internal.compiler.env.*;
17 import net.sourceforge.phpdt.internal.compiler.impl.*;
18 import net.sourceforge.phpdt.internal.compiler.ast.*;
19 import net.sourceforge.phpdt.internal.compiler.lookup.*;
20 import net.sourceforge.phpdt.internal.compiler.problem.*;
21 import net.sourceforge.phpdt.internal.compiler.util.*;
24 import java.util.ArrayList;
26 public class Parser implements BindingIds, ParserBasicInformation, ITerminalSymbols, CompilerModifiers, OperatorIds, TypeIds {
27 protected ProblemReporter problemReporter;
28 public int firstToken ; // handle for multiple parsing goals
29 public int lastAct ; //handle for multiple parsing goals
30 protected ReferenceContext referenceContext;
31 public int currentToken;
32 private int synchronizedBlockSourceStart;
34 //error recovery management
35 protected int lastCheckPoint;
36 protected RecoveredElement currentElement;
37 public static boolean VERBOSE_RECOVERY = false;
38 protected boolean restartRecovery;
39 protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
40 protected boolean hasReportedError;
41 protected int recoveredStaticInitializerStart;
42 protected int lastIgnoredToken, nextIgnoredToken;
43 protected int lastErrorEndPosition;
46 protected boolean assertMode = false;
48 //internal data for the automat
49 protected final static int StackIncrement = 255;
50 protected int stateStackTop;
51 protected int[] stack = new int[StackIncrement];
53 public Scanner scanner;
55 final static int AstStackIncrement = 100;
57 protected AstNode[] astStack = new AstNode[AstStackIncrement];
58 protected int astLengthPtr;
59 protected int[] astLengthStack;
60 public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
61 AstNode [] noAstNodes = new AstNode[AstStackIncrement];
63 final static int ExpressionStackIncrement = 100;
64 protected int expressionPtr;
65 protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
66 protected int expressionLengthPtr;
67 protected int[] expressionLengthStack;
68 Expression [] noExpressions = new Expression[ExpressionStackIncrement];
70 protected int identifierPtr;
71 protected char[][] identifierStack;
72 protected int identifierLengthPtr;
73 protected int[] identifierLengthStack;
74 protected long[] identifierPositionStack;
75 //positions , dimensions , .... (what ever is int) ..... stack
77 protected int[] intStack;
78 protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
79 protected int endStatementPosition;
80 protected int lParenPos,rParenPos; //accurate only when used !
81 //modifiers dimensions nestedType etc.......
82 protected boolean optimizeStringLiterals =true;
83 protected int modifiers;
84 protected int modifiersSourceStart;
85 protected int nestedType, dimensions;
86 protected int[] nestedMethod; //the ptr is nestedType
87 protected int[] realBlockStack;
88 protected int realBlockPtr;
89 protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
90 protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
91 protected int[] variablesCounter;
92 //===DATA===DATA===DATA===DATA===DATA===DATA===//
93 public final static byte rhs[] = {0,
94 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
95 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
96 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
97 2,2,1,1,1,1,3,4,0,1,2,1,1,1,1,
98 1,1,1,1,1,5,1,2,1,2,2,2,1,1,2,
99 2,2,4,1,1,1,1,2,1,1,1,1,1,1,1,
100 1,1,1,1,2,3,3,2,2,1,3,1,3,1,2,
101 1,1,1,3,0,3,1,1,1,1,1,1,1,4,1,
102 3,3,7,0,0,0,0,0,2,1,1,1,2,2,4,
103 4,5,4,4,2,1,2,3,3,1,3,3,1,3,1,
104 4,0,2,1,2,2,4,1,1,2,5,5,7,7,7,
105 7,2,2,3,2,2,3,1,2,1,2,1,1,2,2,
106 1,1,1,1,1,3,3,4,1,3,4,0,1,2,1,
107 1,1,1,2,3,4,0,1,1,1,1,1,1,1,1,
108 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
109 1,3,3,2,1,1,1,1,1,1,1,5,7,7,6,
110 2,3,3,4,1,2,2,1,2,3,2,5,5,7,9,
111 9,1,1,1,1,3,3,5,2,3,2,3,3,3,5,
112 1,3,4,1,2,5,2,1,1,1,1,1,1,3,1,
113 1,3,3,3,3,3,1,1,5,6,8,7,2,0,2,
114 0,1,3,4,4,1,2,3,2,1,1,2,2,3,3,
115 4,6,6,4,4,1,1,1,1,2,2,0,1,1,3,
116 3,1,3,3,1,3,3,1,5,5,4,1,3,3,3,
117 1,3,3,1,3,3,3,1,3,3,3,3,3,1,3,
118 3,1,3,1,3,1,3,1,3,1,3,1,5,1,1,
119 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,
120 1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,
121 0,1,0,2,0,1,0,1,0,1,0,1,0,1,0,
122 1,0,1,0,2,0,0,1,0,1,0,1,0,1,0,
127 public static char asb[] = null;
128 public static char asr[] = null;
129 public static char symbol_index[] = null;
130 private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
132 public final static String name[] = { null,
180 "$empty",//$NON-NLS-1$
181 "Identifier",//$NON-NLS-1$
182 "abstract",//$NON-NLS-1$
183 "assert",//$NON-NLS-1$
184 "boolean",//$NON-NLS-1$
185 "break",//$NON-NLS-1$
188 "catch",//$NON-NLS-1$
190 "class",//$NON-NLS-1$
191 "continue",//$NON-NLS-1$
192 "default",//$NON-NLS-1$
194 "double",//$NON-NLS-1$
196 "extends",//$NON-NLS-1$
197 "false",//$NON-NLS-1$
198 "final",//$NON-NLS-1$
199 "finally",//$NON-NLS-1$
200 "float",//$NON-NLS-1$
203 "implements",//$NON-NLS-1$
204 "import",//$NON-NLS-1$
205 "instanceof",//$NON-NLS-1$
207 "interface",//$NON-NLS-1$
209 "native",//$NON-NLS-1$
212 "package",//$NON-NLS-1$
213 "private",//$NON-NLS-1$
214 "protected",//$NON-NLS-1$
215 "public",//$NON-NLS-1$
216 "return",//$NON-NLS-1$
217 "short",//$NON-NLS-1$
218 "static",//$NON-NLS-1$
219 "strictfp",//$NON-NLS-1$
220 "super",//$NON-NLS-1$
221 "switch",//$NON-NLS-1$
222 "synchronized",//$NON-NLS-1$
224 "throw",//$NON-NLS-1$
225 "throws",//$NON-NLS-1$
226 "transient",//$NON-NLS-1$
230 "volatile",//$NON-NLS-1$
231 "while",//$NON-NLS-1$
232 "IntegerLiteral",//$NON-NLS-1$
233 "LongLiteral",//$NON-NLS-1$
234 "FloatingPointLiteral",//$NON-NLS-1$
235 "DoubleLiteral",//$NON-NLS-1$
236 "CharacterLiteral",//$NON-NLS-1$
237 "StringLiteral",//$NON-NLS-1$
239 "Invalid Character",//$NON-NLS-1$
241 "MethodBody",//$NON-NLS-1$
242 "ConstructorBody",//$NON-NLS-1$
243 "StaticInitializer",//$NON-NLS-1$
244 "Initializer",//$NON-NLS-1$
245 "Headers",//$NON-NLS-1$
246 "BlockStatements",//$NON-NLS-1$
247 "MethodPushModifiersHeader",//$NON-NLS-1$
248 "CatchHeader",//$NON-NLS-1$
249 "FieldDeclaration",//$NON-NLS-1$
250 "ImportDeclaration",//$NON-NLS-1$
251 "PackageDeclaration",//$NON-NLS-1$
252 "TypeDeclaration",//$NON-NLS-1$
253 "GenericMethodDeclaration",//$NON-NLS-1$
254 "ClassBodyDeclaration",//$NON-NLS-1$
255 "Expression",//$NON-NLS-1$
257 "PrimitiveType",//$NON-NLS-1$
258 "ReferenceType",//$NON-NLS-1$
259 "ClassOrInterfaceType",//$NON-NLS-1$
260 "ArrayType",//$NON-NLS-1$
263 "ClassType",//$NON-NLS-1$
264 "SimpleName",//$NON-NLS-1$
265 "Header",//$NON-NLS-1$
266 "ClassHeader",//$NON-NLS-1$
267 "InterfaceHeader",//$NON-NLS-1$
268 "MethodHeader",//$NON-NLS-1$
269 "ConstructorHeader",//$NON-NLS-1$
270 "FormalParameter",//$NON-NLS-1$
271 "ImportDeclarations",//$NON-NLS-1$
272 "TypeDeclarations",//$NON-NLS-1$
273 "PackageDeclarationName",//$NON-NLS-1$
274 "SingleTypeImportDeclarationName",//$NON-NLS-1$
275 "TypeImportOnDemandDeclarationName",//$NON-NLS-1$
276 "Modifiers",//$NON-NLS-1$
277 "Modifier",//$NON-NLS-1$
278 "ClassBody",//$NON-NLS-1$
279 "ClassHeaderName",//$NON-NLS-1$
280 "InterfaceTypeList",//$NON-NLS-1$
281 "InterfaceType",//$NON-NLS-1$
282 "ClassBodyDeclarations",//$NON-NLS-1$
283 "Block",//$NON-NLS-1$
284 "VariableDeclarators",//$NON-NLS-1$
285 "VariableDeclarator",//$NON-NLS-1$
286 "VariableDeclaratorId",//$NON-NLS-1$
287 "VariableInitializer",//$NON-NLS-1$
288 "ArrayInitializer",//$NON-NLS-1$
289 "MethodHeaderName",//$NON-NLS-1$
290 "MethodHeaderParameters",//$NON-NLS-1$
291 "MethodPushModifiersHeaderName",//$NON-NLS-1$
292 "ClassTypeList",//$NON-NLS-1$
293 "ConstructorHeaderName",//$NON-NLS-1$
294 "FormalParameterList",//$NON-NLS-1$
295 "ClassTypeElt",//$NON-NLS-1$
296 "StaticOnly",//$NON-NLS-1$
297 "ExplicitConstructorInvocation",//$NON-NLS-1$
298 "Primary",//$NON-NLS-1$
299 "InterfaceBody",//$NON-NLS-1$
300 "InterfaceHeaderName",//$NON-NLS-1$
301 "InterfaceMemberDeclarations",//$NON-NLS-1$
302 "InterfaceMemberDeclaration",//$NON-NLS-1$
303 "VariableInitializers",//$NON-NLS-1$
304 "BlockStatement",//$NON-NLS-1$
305 "Statement",//$NON-NLS-1$
306 "LocalVariableDeclaration",//$NON-NLS-1$
307 "StatementWithoutTrailingSubstatement",//$NON-NLS-1$
308 "StatementNoShortIf",//$NON-NLS-1$
309 "StatementExpression",//$NON-NLS-1$
310 "PostIncrementExpression",//$NON-NLS-1$
311 "PostDecrementExpression",//$NON-NLS-1$
312 "MethodInvocation",//$NON-NLS-1$
313 "ClassInstanceCreationExpression",//$NON-NLS-1$
314 "SwitchBlock",//$NON-NLS-1$
315 "SwitchBlockStatements",//$NON-NLS-1$
316 "SwitchLabels",//$NON-NLS-1$
317 "SwitchBlockStatement",//$NON-NLS-1$
318 "SwitchLabel",//$NON-NLS-1$
319 "ConstantExpression",//$NON-NLS-1$
320 "StatementExpressionList",//$NON-NLS-1$
321 "OnlySynchronized",//$NON-NLS-1$
322 "Catches",//$NON-NLS-1$
323 "Finally",//$NON-NLS-1$
324 "CatchClause",//$NON-NLS-1$
325 "PushLPAREN",//$NON-NLS-1$
326 "PushRPAREN",//$NON-NLS-1$
327 "PrimaryNoNewArray",//$NON-NLS-1$
328 "FieldAccess",//$NON-NLS-1$
329 "ArrayAccess",//$NON-NLS-1$
330 "ClassInstanceCreationExpressionName",//$NON-NLS-1$
331 "ArgumentList",//$NON-NLS-1$
332 "DimWithOrWithOutExprs",//$NON-NLS-1$
333 "DimWithOrWithOutExpr",//$NON-NLS-1$
334 "DimsLoop",//$NON-NLS-1$
335 "OneDimLoop",//$NON-NLS-1$
336 "PostfixExpression",//$NON-NLS-1$
337 "UnaryExpression",//$NON-NLS-1$
338 "UnaryExpressionNotPlusMinus",//$NON-NLS-1$
339 "MultiplicativeExpression",//$NON-NLS-1$
340 "AdditiveExpression",//$NON-NLS-1$
341 "ShiftExpression",//$NON-NLS-1$
342 "RelationalExpression",//$NON-NLS-1$
343 "EqualityExpression",//$NON-NLS-1$
344 "AndExpression",//$NON-NLS-1$
345 "ExclusiveOrExpression",//$NON-NLS-1$
346 "InclusiveOrExpression",//$NON-NLS-1$
347 "ConditionalAndExpression",//$NON-NLS-1$
348 "ConditionalOrExpression",//$NON-NLS-1$
349 "ConditionalExpression",//$NON-NLS-1$
350 "AssignmentExpression",//$NON-NLS-1$
351 "LeftHandSide",//$NON-NLS-1$
352 "AssignmentOperator"//$NON-NLS-1$
355 public static short check_table[] = null;
356 public static char lhs[] = null;
357 public static char action[] = lhs;
358 private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
363 } catch(java.io.IOException ex){
364 throw new ExceptionInInitializerError(ex.getMessage());
368 public static final int RoundBracket = 0;
369 public static final int SquareBracket = 1;
370 public static final int CurlyBracket = 2;
371 public static final int BracketKinds = 3;
373 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) {
375 this.problemReporter = problemReporter;
376 this.optimizeStringLiterals = optimizeStringLiterals;
377 this.assertMode = assertMode;
378 this.initializeScanner();
379 astLengthStack = new int[50];
380 expressionLengthStack = new int[30];
381 intStack = new int[50];
382 identifierStack = new char[30][];
383 identifierLengthStack = new int[30];
384 nestedMethod = new int[30];
385 realBlockStack = new int[30];
386 identifierPositionStack = new long[30];
387 variablesCounter = new int[30];
393 protected void adjustInterfaceModifiers() {
394 intStack[intPtr - 1] |= AccInterface;
396 public final void arrayInitializer(int length) {
397 //length is the size of the array Initializer
398 //expressionPtr points on the last elt of the arrayInitializer
399 //i.e. it has not been decremented yet.
401 ArrayInitializer ai = new ArrayInitializer();
403 expressionPtr -= length;
404 System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
406 pushOnExpressionStack(ai);
408 ai.sourceEnd = endStatementPosition;
409 int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart;
411 //does not work with comments(that contain '{') nor '{' describes as a unicode....
412 while (scanner.source[--searchPosition] != '{') {
414 } catch (IndexOutOfBoundsException ex) {
415 //should never occur (except for strange cases like whose describe above)
416 searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1;
418 ai.sourceStart = searchPosition;
420 protected static int asi(int state) {
422 return asb[original_state(state)];
424 protected void blockReal() {
425 // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
426 // increment the amount of declared variables for this block
427 realBlockStack[realBlockPtr]++;
429 private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort) throws java.io.IOException {
431 //transform the String tokens into chars before dumping then into file
435 while (!tokens[i++].equals(tag)) {}
437 char[] chars = new char[tokens.length]; //can't be bigger
440 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
441 int c = Integer.parseInt(token);
444 chars[ic++] = (char) c;
448 System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
450 buildFileForTable(filename, chars);
452 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
454 byte[] bytes = new byte[chars.length * 2];
455 for (int i = 0; i < chars.length; i++) {
456 bytes[2 * i] = (byte) (chars[i] >>> 8);
457 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
460 java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
463 System.out.println(filename + " creation complete"); //$NON-NLS-1$
465 public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException {
467 //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
469 //build from the lpg javadcl.java files that represents the parser tables
470 //lhs check_table asb asr symbol_index
472 //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
474 char[] contents = new char[] {};
476 contents = Util.getFileCharContent(new File(dataFilename), null);
477 } catch (IOException ex) {
478 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
481 java.util.StringTokenizer st =
482 new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
483 String[] tokens = new String[st.countTokens()];
485 while (st.hasMoreTokens()) {
486 tokens[i++] = st.nextToken();
488 final String prefix = FILEPREFIX;
490 buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
491 buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$
492 buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
493 buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
494 buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
495 System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
498 * Build initial recovery state.
499 * Recovery state is inferred from the current state of the parser (reduced node stack).
501 public RecoveredElement buildInitialRecoveryState(){
503 /* initialize recovery by retrieving available reduced nodes
504 * also rebuild bracket balance
508 RecoveredElement element = null;
509 if (referenceContext instanceof CompilationUnitDeclaration){
510 element = new RecoveredUnit(compilationUnit, 0, this);
512 /* ignore current stack state, since restarting from the beginnning
513 since could not trust simple brace count */
514 if (true){ // experimenting restart recovery from scratch
515 compilationUnit.currentPackage = null;
516 compilationUnit.imports = null;
517 compilationUnit.types = null;
522 if (compilationUnit.currentPackage != null){
523 lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd+1;
525 if (compilationUnit.imports != null){
526 lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length -1].declarationSourceEnd+1;
529 if (referenceContext instanceof AbstractMethodDeclaration){
530 element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this);
531 lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart;
533 /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
534 if (referenceContext instanceof TypeDeclaration){
535 TypeDeclaration type = (TypeDeclaration) referenceContext;
536 for (int i = 0; i < type.fields.length; i++){
537 FieldDeclaration field = type.fields[i];
539 && field.declarationSourceStart <= scanner.initialPosition
540 && scanner.initialPosition <= field.declarationSourceEnd
541 && scanner.eofPosition <= field.declarationSourceEnd+1){
542 element = new RecoveredInitializer((Initializer) field, null, 1, this);
543 lastCheckPoint = field.declarationSourceStart;
551 if (element == null) return element;
553 for(int i = 0; i <= astPtr; i++){
554 AstNode node = astStack[i];
555 if (node instanceof AbstractMethodDeclaration){
556 AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
557 if (method.declarationSourceEnd == 0){
558 element = element.add(method, 0);
559 lastCheckPoint = method.bodyStart;
561 element = element.add(method, 0);
562 lastCheckPoint = method.declarationSourceEnd + 1;
566 if (node instanceof Initializer){
567 Initializer initializer = (Initializer) node;
568 if (initializer.declarationSourceEnd == 0){
569 element = element.add(initializer, 1);
570 lastCheckPoint = initializer.bodyStart;
572 element = element.add(initializer, 0);
573 lastCheckPoint = initializer.declarationSourceEnd + 1;
577 if (node instanceof FieldDeclaration){
578 FieldDeclaration field = (FieldDeclaration) node;
579 if (field.declarationSourceEnd == 0){
580 element = element.add(field, 0);
581 if (field.initialization == null){
582 lastCheckPoint = field.sourceEnd + 1;
584 lastCheckPoint = field.initialization.sourceEnd + 1;
587 element = element.add(field, 0);
588 lastCheckPoint = field.declarationSourceEnd + 1;
592 if (node instanceof TypeDeclaration){
593 TypeDeclaration type = (TypeDeclaration) node;
594 if (type.declarationSourceEnd == 0){
595 element = element.add(type, 0);
596 lastCheckPoint = type.bodyStart;
598 element = element.add(type, 0);
599 lastCheckPoint = type.declarationSourceEnd + 1;
603 if (node instanceof ImportReference){
604 ImportReference importRef = (ImportReference) node;
605 element = element.add(importRef, 0);
606 lastCheckPoint = importRef.declarationSourceEnd + 1;
611 protected static short check(int i) {
612 return check_table[i - (NUM_RULES + 1)];
615 * Reconsider the entire source looking for inconsistencies in {} () []
617 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
619 scanner.wasAcr = false;
620 boolean anomaliesDetected = false;
622 char[] source = scanner.source;
623 int[] leftCount = {0, 0, 0};
624 int[] rightCount = {0, 0, 0};
625 int[] depths = {0, 0, 0};
626 int[][] leftPositions = new int[][] {new int[10], new int[10], new int[10]};
627 int[][] leftDepths = new int[][] {new int[10], new int[10], new int[10]};
628 int[][] rightPositions = new int[][] {new int[10], new int[10], new int[10]};
629 int[][] rightDepths = new int[][] {new int[10], new int[10], new int[10]};
630 scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
631 while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
633 // ---------Consume white space and handles startPosition---------
634 boolean isWhiteSpace;
636 scanner.startPosition = scanner.currentPosition;
637 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
638 isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
640 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
641 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
642 // only record line positions we have not recorded yet
643 scanner.pushLineSeparator();
646 isWhiteSpace = Character.isWhitespace(scanner.currentCharacter);
648 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
650 // -------consume token until } is found---------
652 switch (scanner.currentCharacter) {
655 int index = leftCount[CurlyBracket] ++;
656 if (index == leftPositions[CurlyBracket].length) {
657 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
658 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
660 leftPositions[CurlyBracket][index] = scanner.startPosition;
661 leftDepths[CurlyBracket][index] = depths[CurlyBracket] ++;
666 int index = rightCount[CurlyBracket] ++;
667 if (index == rightPositions[CurlyBracket].length) {
668 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
669 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
671 rightPositions[CurlyBracket][index] = scanner.startPosition;
672 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
677 int index = leftCount[RoundBracket] ++;
678 if (index == leftPositions[RoundBracket].length) {
679 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
680 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
682 leftPositions[RoundBracket][index] = scanner.startPosition;
683 leftDepths[RoundBracket][index] = depths[RoundBracket] ++;
688 int index = rightCount[RoundBracket] ++;
689 if (index == rightPositions[RoundBracket].length) {
690 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
691 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
693 rightPositions[RoundBracket][index] = scanner.startPosition;
694 rightDepths[RoundBracket][index] = --depths[RoundBracket];
699 int index = leftCount[SquareBracket] ++;
700 if (index == leftPositions[SquareBracket].length) {
701 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
702 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
704 leftPositions[SquareBracket][index] = scanner.startPosition;
705 leftDepths[SquareBracket][index] = depths[SquareBracket] ++;
710 int index = rightCount[SquareBracket] ++;
711 if (index == rightPositions[SquareBracket].length) {
712 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
713 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
715 rightPositions[SquareBracket][index] = scanner.startPosition;
716 rightDepths[SquareBracket][index] = --depths[SquareBracket];
721 if (scanner.getNextChar('\\')) {
722 scanner.scanEscapeCharacter();
723 } else { // consume next character
724 scanner.unicodeAsBackSlash = false;
725 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
726 scanner.getNextUnicodeChar();
728 if (scanner.withoutUnicodePtr != 0) {
729 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
733 scanner.getNextChar('\'');
736 case '"' : // consume next character
737 scanner.unicodeAsBackSlash = false;
738 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
739 scanner.getNextUnicodeChar();
741 if (scanner.withoutUnicodePtr != 0) {
742 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
745 while (scanner.currentCharacter != '"') {
746 if (scanner.currentCharacter == '\r') {
747 if (source[scanner.currentPosition] == '\n')
748 scanner.currentPosition++;
749 break; // the string cannot go further that the line
751 if (scanner.currentCharacter == '\n') {
752 break; // the string cannot go further that the line
754 if (scanner.currentCharacter == '\\') {
755 scanner.scanEscapeCharacter();
757 // consume next character
758 scanner.unicodeAsBackSlash = false;
759 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
760 scanner.getNextUnicodeChar();
762 if (scanner.withoutUnicodePtr != 0) {
763 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
771 if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment
773 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
774 //-------------unicode traitement ------------
775 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
776 scanner.currentPosition++;
777 while (source[scanner.currentPosition] == 'u') {
778 scanner.currentPosition++;
780 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
781 scanner.currentCharacter = 'A';
782 } //something different from \n and \r
784 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
787 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
789 scanner.startPosition = scanner.currentPosition;
790 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
791 //-------------unicode traitement ------------
792 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
793 scanner.currentPosition++;
794 while (source[scanner.currentPosition] == 'u') {
795 scanner.currentPosition++;
797 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
798 scanner.currentCharacter = 'A';
799 } //something different from \n and \r
801 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
805 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
806 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
807 // only record line positions we have not recorded yet
808 scanner.pushLineSeparator();
813 if (test > 0) { //traditional and annotation comment
814 boolean star = false;
815 // consume next character
816 scanner.unicodeAsBackSlash = false;
817 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
818 scanner.getNextUnicodeChar();
820 if (scanner.withoutUnicodePtr != 0) {
821 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
824 if (scanner.currentCharacter == '*') {
828 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
829 //-------------unicode traitement ------------
830 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
831 scanner.currentPosition++;
832 while (source[scanner.currentPosition] == 'u') {
833 scanner.currentPosition++;
835 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
836 scanner.currentCharacter = 'A';
837 } //something different from * and /
839 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
842 //loop until end of comment */
843 while ((scanner.currentCharacter != '/') || (!star)) {
844 star = scanner.currentCharacter == '*';
846 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
847 //-------------unicode traitement ------------
848 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
849 scanner.currentPosition++;
850 while (source[scanner.currentPosition] == 'u') {
851 scanner.currentPosition++;
853 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
854 scanner.currentCharacter = 'A';
855 } //something different from * and /
857 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
866 if (Character.isJavaIdentifierStart(scanner.currentCharacter)) {
867 scanner.scanIdentifierOrKeyword();
870 if (Character.isDigit(scanner.currentCharacter)) {
871 scanner.scanNumber(false);
875 //-----------------end switch while try--------------------
876 } catch (IndexOutOfBoundsException e) {
877 break; // read until EOF
878 } catch (InvalidInputException e) {
879 return false; // no clue
882 if (scanner.recordLineSeparator) {
883 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
886 // check placement anomalies against other kinds of brackets
887 for (int kind = 0; kind < BracketKinds; kind++) {
888 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
889 int start = leftPositions[kind][leftIndex]; // deepest first
890 // find matching closing bracket
891 int depth = leftDepths[kind][leftIndex];
893 for (int i = 0; i < rightCount[kind]; i++) {
894 int pos = rightPositions[kind][i];
895 // want matching bracket further in source with same depth
896 if ((pos > start) && (depth == rightDepths[kind][i])) {
901 if (end < 0) { // did not find a good closing match
902 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
905 // check if even number of opening/closing other brackets in between this pair of brackets
907 for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
908 for (int i = 0; i < leftCount[otherKind]; i++) {
909 int pos = leftPositions[otherKind][i];
910 if ((pos > start) && (pos < end))
913 for (int i = 0; i < rightCount[otherKind]; i++) {
914 int pos = rightPositions[otherKind][i];
915 if ((pos > start) && (pos < end))
919 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
924 // too many opening brackets ?
925 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
926 anomaliesDetected = true;
927 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, compilationUnit.compilationResult);
929 // too many closing brackets ?
930 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
931 anomaliesDetected = true;
932 problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
934 if (anomaliesDetected) return true;
937 return anomaliesDetected;
938 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
939 return anomaliesDetected;
940 } catch (NullPointerException e) { // jdk1.2.2 jit bug
941 return anomaliesDetected;
944 public final void checkAndSetModifiers(int flag){
945 /*modify the current modifiers buffer.
946 When the startPosition of the modifiers is 0
947 it means that the modifier being parsed is the first
948 of a list of several modifiers. The startPosition
949 is zeroed when a copy of modifiers-buffer is push
950 onto the astStack. */
952 if ((modifiers & flag) != 0){ // duplicate modifier
953 modifiers |= AccAlternateModifierProblem;
957 if (modifiersSourceStart < 0) modifiersSourceStart = scanner.startPosition;
959 public void checkAnnotation() {
961 boolean deprecated = false;
962 boolean checkDeprecated = false;
963 int lastAnnotationIndex = -1;
965 //since jdk1.2 look only in the last java doc comment...
966 found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){
967 //look for @deprecated into the first javadoc comment preceeding the declaration
968 int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
969 // javadoc only (non javadoc comment have negative end positions.)
970 if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
973 if (scanner.commentStops[lastAnnotationIndex] < 0) {
976 checkDeprecated = true;
977 int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
978 char[] comment = scanner.source;
980 for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
981 if ((comment[i] == '@')
982 && (comment[i + 1] == 'd')
983 && (comment[i + 2] == 'e')
984 && (comment[i + 3] == 'p')
985 && (comment[i + 4] == 'r')
986 && (comment[i + 5] == 'e')
987 && (comment[i + 6] == 'c')
988 && (comment[i + 7] == 'a')
989 && (comment[i + 8] == 't')
990 && (comment[i + 9] == 'e')
991 && (comment[i + 10] == 'd')) {
992 // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
994 deprecated = (comment[nextPos] == ' ') || (comment[nextPos] == '\t') || (comment[nextPos] == '\n') || (comment[nextPos] == '\r') || (comment[nextPos] == '*');
1001 checkAndSetModifiers(AccDeprecated);
1003 // modify the modifier source start to point at the first comment
1004 if (lastAnnotationIndex >= 0 && checkDeprecated) {
1005 modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex];
1008 protected void classInstanceCreation(boolean alwaysQualified) {
1009 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1011 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1012 // An empty class body produces a 0 on the length stack.....
1014 AllocationExpression alloc;
1016 if (((length = astLengthStack[astLengthPtr--]) == 1)
1017 && (astStack[astPtr] == null)) {
1020 if (alwaysQualified) {
1021 alloc = new QualifiedAllocationExpression();
1023 alloc = new AllocationExpression();
1025 alloc.sourceEnd = endPosition; //the position has been stored explicitly
1027 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
1028 expressionPtr -= length;
1032 alloc.arguments = new Expression[length],
1036 alloc.type = getTypeReference(0);
1037 //the default constructor with the correct number of argument
1038 //will be created and added by the TC (see createsInternalConstructorWithBinding)
1039 alloc.sourceStart = intStack[intPtr--];
1040 pushOnExpressionStack(alloc);
1042 dispatchDeclarationInto(length);
1043 AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr];
1044 anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition;
1045 anonymousTypeDeclaration.bodyEnd = endStatementPosition;
1046 if (anonymousTypeDeclaration.allocation != null) {
1047 anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition;
1052 // mark fields and initializer with local type mark if needed
1053 markFieldsWithLocalType(anonymousTypeDeclaration);
1056 protected final void concatExpressionLists() {
1057 expressionLengthStack[--expressionLengthPtr]++;
1059 private final void concatNodeLists() {
1061 * This is a case where you have two sublists into the astStack that you want
1062 * to merge in one list. There is no action required on the astStack. The only
1063 * thing you need to do is merge the two lengths specified on the astStackLength.
1064 * The top two length are for example:
1066 * and you want to result in a list like:
1068 * This means that the p could be equals to 0 in case there is no astNode pushed
1070 * Look at the InterfaceMemberDeclarations for an example.
1073 astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--];
1075 protected void consumeAllocationHeader() {
1076 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1078 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1079 // An empty class body produces a 0 on the length stack.....
1081 if (currentElement == null){
1082 return; // should never occur, this consumeRule is only used in recovery mode
1084 if (currentToken == TokenNameLBRACE){
1085 // beginning of an anonymous type
1086 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
1087 anonymousType.sourceStart = intStack[intPtr--];
1088 anonymousType.sourceEnd = rParenPos; // closing parenthesis
1089 lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition;
1090 currentElement = currentElement.add(anonymousType, 0);
1091 lastIgnoredToken = -1;
1092 currentToken = 0; // opening brace already taken into account
1095 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1096 restartRecovery = true; // request to restart from here on
1098 protected void consumeArgumentList() {
1099 // ArgumentList ::= ArgumentList ',' Expression
1100 concatExpressionLists();
1102 protected void consumeArrayAccess(boolean unspecifiedReference) {
1103 // ArrayAccess ::= Name '[' Expression ']' ==> true
1104 // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
1109 if (unspecifiedReference) {
1111 expressionStack[expressionPtr] =
1113 getUnspecifiedReferenceOptimized(),
1114 expressionStack[expressionPtr]);
1117 expressionLengthPtr--;
1119 expressionStack[expressionPtr] =
1121 expressionStack[expressionPtr],
1122 expressionStack[expressionPtr + 1]);
1124 exp.sourceEnd = endPosition;
1126 protected void consumeArrayCreationExpression() {
1127 // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
1128 // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
1131 ArrayAllocationExpression aae = new ArrayAllocationExpression();
1132 if (expressionLengthStack[expressionLengthPtr] != 0) {
1133 expressionLengthPtr -- ;
1134 aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--];
1136 expressionLengthPtr--;
1139 aae.type = getTypeReference(0);
1140 length = (expressionLengthStack[expressionLengthPtr--]);
1141 expressionPtr -= length ;
1145 aae.dimensions = new Expression[length],
1148 aae.sourceStart = intStack[intPtr--];
1149 if (aae.initializer == null) {
1150 aae.sourceEnd = endPosition;
1152 aae.sourceEnd = aae.initializer.sourceEnd ;
1154 pushOnExpressionStack(aae);
1156 protected void consumeArrayInitializer() {
1157 // ArrayInitializer ::= '{' VariableInitializers '}'
1158 // ArrayInitializer ::= '{' VariableInitializers , '}'
1160 arrayInitializer(expressionLengthStack[expressionLengthPtr--]);
1163 protected void consumeAssertStatement() {
1164 // AssertStatement ::= 'assert' Expression ':' Expression ';'
1165 expressionLengthPtr-=2;
1166 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--]));
1169 protected void consumeAssignment() {
1170 // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
1171 //optimize the push/pop
1173 int op = intStack[intPtr--] ; //<--the encoded operator
1175 expressionPtr -- ; expressionLengthPtr -- ;
1176 expressionStack[expressionPtr] =
1178 new CompoundAssignment(
1179 expressionStack[expressionPtr] ,
1180 expressionStack[expressionPtr+1],
1182 scanner.startPosition - 1) :
1184 expressionStack[expressionPtr] ,
1185 expressionStack[expressionPtr+1],
1186 scanner.startPosition - 1);
1188 protected void consumeAssignmentOperator(int pos) {
1189 // AssignmentOperator ::= '='
1190 // AssignmentOperator ::= '*='
1191 // AssignmentOperator ::= '/='
1192 // AssignmentOperator ::= '%='
1193 // AssignmentOperator ::= '+='
1194 // AssignmentOperator ::= '-='
1195 // AssignmentOperator ::= '<<='
1196 // AssignmentOperator ::= '>>='
1197 // AssignmentOperator ::= '>>>='
1198 // AssignmentOperator ::= '&='
1199 // AssignmentOperator ::= '^='
1200 // AssignmentOperator ::= '|='
1203 intStack[++intPtr] = pos;
1204 } catch (IndexOutOfBoundsException e) {
1206 int oldStackLength = intStack.length;
1207 int oldStack[] = intStack;
1208 intStack = new int[oldStackLength + StackIncrement];
1209 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
1210 intStack[intPtr] = pos;
1213 protected void consumeBinaryExpression(int op) {
1214 // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
1215 // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
1216 // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
1217 // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
1218 // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
1219 // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
1220 // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
1221 // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
1222 // RelationalExpression ::= RelationalExpression '<' ShiftExpression
1223 // RelationalExpression ::= RelationalExpression '>' ShiftExpression
1224 // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
1225 // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
1226 // AndExpression ::= AndExpression '&' EqualityExpression
1227 // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
1228 // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
1229 // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
1230 // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
1232 //optimize the push/pop
1235 expressionLengthPtr--;
1237 expressionStack[expressionPtr] =
1238 new OR_OR_Expression(
1239 expressionStack[expressionPtr],
1240 expressionStack[expressionPtr + 1],
1243 if (op == AND_AND) {
1244 expressionStack[expressionPtr] =
1245 new AND_AND_Expression(
1246 expressionStack[expressionPtr],
1247 expressionStack[expressionPtr + 1],
1250 // look for "string1" + "string2"
1251 if ((op == PLUS) && optimizeStringLiterals) {
1252 Expression expr1, expr2;
1253 expr1 = expressionStack[expressionPtr];
1254 expr2 = expressionStack[expressionPtr + 1];
1255 if (expr1 instanceof StringLiteral) {
1256 if (expr2 instanceof CharLiteral) { // string+char
1257 expressionStack[expressionPtr] =
1258 ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1259 } else if (expr2 instanceof StringLiteral) { //string+string
1260 expressionStack[expressionPtr] =
1261 ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1263 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1266 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1269 expressionStack[expressionPtr] =
1270 new BinaryExpression(
1271 expressionStack[expressionPtr],
1272 expressionStack[expressionPtr + 1],
1278 protected void consumeBlock() {
1279 // Block ::= OpenBlock '{' BlockStatementsopt '}'
1280 // simpler action for empty blocks
1283 if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block
1284 pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition));
1285 realBlockPtr--; // still need to pop the block variable counter
1287 Block bk = new Block(realBlockStack[realBlockPtr--]);
1292 bk.statements = new Statement[length],
1296 bk.sourceStart = intStack[intPtr--];
1297 bk.sourceEnd = endStatementPosition;
1300 protected void consumeBlockStatements() {
1301 // BlockStatements ::= BlockStatements BlockStatement
1304 protected void consumeCaseLabel() {
1305 // SwitchLabel ::= 'case' ConstantExpression ':'
1306 expressionLengthPtr--;
1307 pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--]));
1309 protected void consumeCastExpression() {
1310 // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
1311 // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
1313 //intStack : posOfLeftParen dim posOfRightParen
1315 //optimize the push/pop
1317 Expression exp, cast, castType;
1318 int end = intStack[intPtr--];
1319 expressionStack[expressionPtr] = cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--]));
1320 castType.sourceEnd = end - 1;
1321 castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1;
1322 cast.sourceEnd = exp.sourceEnd;
1324 protected void consumeCastExpressionLL1() {
1325 //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus
1326 // Expression is used in order to make the grammar LL1
1330 Expression castType,cast,exp;
1332 expressionStack[expressionPtr] =
1333 cast = new CastExpression( exp=expressionStack[expressionPtr+1] ,
1334 castType = getTypeReference(expressionStack[expressionPtr]));
1335 expressionLengthPtr -- ;
1336 updateSourcePosition(castType);
1337 cast.sourceStart=castType.sourceStart;
1338 cast.sourceEnd=exp.sourceEnd;
1339 castType.sourceStart++;
1340 castType.sourceEnd--;
1342 protected void consumeCatches() {
1343 // Catches ::= Catches CatchClause
1344 optimizedConcatNodeLists();
1346 protected void consumeCatchHeader() {
1347 // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1349 if (currentElement == null){
1350 return; // should never occur, this consumeRule is only used in recovery mode
1352 // current element should be a block due to the presence of the opening brace
1353 if (!(currentElement instanceof RecoveredBlock)){
1356 // exception argument is already on astStack
1357 ((RecoveredBlock)currentElement).attach(
1358 new RecoveredLocalVariable((Argument)astStack[astPtr--], currentElement, 0)); // insert catch variable in catch block
1359 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1360 restartRecovery = true; // request to restart from here on
1361 lastIgnoredToken = -1;
1363 protected void consumeClassBodyDeclaration() {
1364 // ClassBodyDeclaration ::= Diet Block
1365 //push an Initializer
1366 //optimize the push/pop
1367 nestedMethod[nestedType]--;
1368 Initializer initializer = new Initializer((Block) astStack[astPtr], 0);
1369 intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1370 realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1371 int javadocCommentStart = intStack[intPtr--];
1372 if (javadocCommentStart != -1) {
1373 initializer.declarationSourceStart = javadocCommentStart;
1375 astStack[astPtr] = initializer;
1376 initializer.sourceEnd = endStatementPosition;
1377 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1379 protected void consumeClassBodyDeclarations() {
1380 // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1383 protected void consumeClassBodyDeclarationsopt() {
1384 // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1387 protected void consumeClassBodyopt() {
1388 // ClassBodyopt ::= $empty
1389 pushOnAstStack(null);
1390 endPosition = scanner.startPosition - 1;
1392 protected void consumeClassDeclaration() {
1393 // ClassDeclaration ::= ClassHeader ClassBody
1396 if ((length = astLengthStack[astLengthPtr--]) != 0) {
1397 //there are length declarations
1398 //dispatch according to the type of the declarations
1399 dispatchDeclarationInto(length);
1402 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1404 // mark fields and initializer with local type mark if needed
1405 markFieldsWithLocalType(typeDecl);
1407 //convert constructor that do not have the type's name into methods
1408 boolean hasConstructor = typeDecl.checkConstructors(this);
1410 //add the default constructor when needed (interface don't have it)
1411 if (!hasConstructor) {
1412 boolean insideFieldInitializer = false;
1414 for (int i = nestedType; i > 0; i--){
1415 if (variablesCounter[i] > 0) {
1416 insideFieldInitializer = true;
1421 typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true);
1424 //always add <clinit> (will be remove at code gen time if empty)
1425 if (this.scanner.containsAssertKeyword) {
1426 typeDecl.bits |= AstNode.AddAssertionMASK;
1428 typeDecl.addClinit();
1429 typeDecl.bodyEnd = endStatementPosition;
1430 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1432 protected void consumeClassHeader() {
1433 // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1435 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1436 if (currentToken == TokenNameLBRACE) {
1437 typeDecl.bodyStart = scanner.currentPosition;
1439 if (currentElement != null) {
1440 restartRecovery = true; // used to avoid branching back into the regular automaton
1442 // flush the comments related to the class header
1443 scanner.commentPtr = -1;
1445 protected void consumeClassHeaderExtends() {
1446 // ClassHeaderExtends ::= 'extends' ClassType
1447 // There is a class declaration on the top of stack
1448 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1450 typeDecl.superclass = getTypeReference(0);
1451 typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1453 if (currentElement != null){
1454 lastCheckPoint = typeDecl.bodyStart;
1457 protected void consumeClassHeaderImplements() {
1458 // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1459 int length = astLengthStack[astLengthPtr--];
1462 // There is a class declaration on the top of stack
1463 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1467 typeDecl.superInterfaces = new TypeReference[length],
1470 typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
1471 listLength = 0; // reset after having read super-interfaces
1473 if (currentElement != null) { // is recovering
1474 lastCheckPoint = typeDecl.bodyStart;
1477 protected void consumeClassHeaderName() {
1478 // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1479 TypeDeclaration typeDecl;
1480 if (nestedMethod[nestedType] == 0) {
1481 if (nestedType != 0) {
1482 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
1484 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1487 // Record that the block has a declaration for local types
1488 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
1489 markCurrentMethodWithLocalType();
1493 //highlight the name of the type
1494 long pos = identifierPositionStack[identifierPtr];
1495 typeDecl.sourceEnd = (int) pos;
1496 typeDecl.sourceStart = (int) (pos >>> 32);
1497 typeDecl.name = identifierStack[identifierPtr--];
1498 identifierLengthPtr--;
1500 //compute the declaration source too
1501 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
1502 // we want to keep the beginning position but get rid of the end position
1503 // it is only used for the ClassLiteralAccess positions.
1504 typeDecl.declarationSourceStart = intStack[intPtr--];
1505 intPtr--; // remove the end position of the class token
1507 typeDecl.modifiersSourceStart = intStack[intPtr--];
1508 typeDecl.modifiers = intStack[intPtr--];
1509 if (typeDecl.modifiersSourceStart >= 0) {
1510 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
1512 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
1513 pushOnAstStack(typeDecl);
1515 listLength = 0; // will be updated when reading super-interfaces
1517 if (currentElement != null){
1518 lastCheckPoint = typeDecl.bodyStart;
1519 currentElement = currentElement.add(typeDecl, 0);
1520 lastIgnoredToken = -1;
1523 protected void consumeClassInstanceCreationExpression() {
1524 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1525 classInstanceCreation(false);
1527 protected void consumeClassInstanceCreationExpressionName() {
1528 // ClassInstanceCreationExpressionName ::= Name '.'
1529 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1531 protected void consumeClassInstanceCreationExpressionQualified() {
1532 // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1533 // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1535 classInstanceCreation(true); // <-- push the Qualifed....
1537 expressionLengthPtr--;
1538 QualifiedAllocationExpression qae =
1539 (QualifiedAllocationExpression) expressionStack[expressionPtr--];
1540 qae.enclosingInstance = expressionStack[expressionPtr];
1541 expressionStack[expressionPtr] = qae;
1542 qae.sourceStart = qae.enclosingInstance.sourceStart;
1544 protected void consumeClassTypeElt() {
1545 // ClassTypeElt ::= ClassType
1546 pushOnAstStack(getTypeReference(0));
1547 /* if incomplete thrown exception list, listLength counter will not have been reset,
1548 indicating that some items are available on the stack */
1551 protected void consumeClassTypeList() {
1552 // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
1553 optimizedConcatNodeLists();
1555 protected void consumeCompilationUnit() {
1556 // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
1557 // do nothing by default
1559 protected void consumeConditionalExpression(int op) {
1560 // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
1561 //optimize the push/pop
1564 expressionLengthPtr -= 2;
1565 expressionStack[expressionPtr] =
1566 new ConditionalExpression(
1567 expressionStack[expressionPtr],
1568 expressionStack[expressionPtr + 1],
1569 expressionStack[expressionPtr + 2]);
1571 protected void consumeConstructorBlockStatements() {
1572 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
1573 concatNodeLists(); // explictly add the first statement into the list of statements
1575 protected void consumeConstructorBody() {
1576 // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
1577 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
1578 nestedMethod[nestedType] --;
1580 protected void consumeConstructorDeclaration() {
1581 // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
1584 astStack : MethodDeclaration statements
1585 identifierStack : name
1587 astStack : MethodDeclaration
1591 //must provide a default constructor call when needed
1595 // pop the position of the { (body of the method) pushed in block decl
1600 ExplicitConstructorCall constructorCall = null;
1601 Statement[] statements = null;
1602 if ((length = astLengthStack[astLengthPtr--]) != 0) {
1604 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) {
1605 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
1609 statements = new Statement[length - 1],
1612 constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
1613 } else { //need to add explicitly the super();
1617 statements = new Statement[length],
1620 constructorCall = SuperReference.implicitSuperConstructorCall();
1624 // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
1625 constructorCall = SuperReference.implicitSuperConstructorCall();
1629 // now we know that the top of stack is a constructorDeclaration
1630 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
1631 cd.constructorCall = constructorCall;
1632 cd.statements = statements;
1634 //highlight of the implicit call on the method name
1635 if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
1636 cd.constructorCall.sourceEnd = cd.sourceEnd;
1637 cd.constructorCall.sourceStart = cd.sourceStart;
1640 //watch for } that could be given as a unicode ! ( u007D is '}' )
1641 // store the endPosition (position just before the '}') in case there is
1642 // a trailing comment behind the end of the method
1643 cd.bodyEnd = endPosition;
1644 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1647 protected void consumeInvalidConstructorDeclaration() {
1648 // ConstructorDeclaration ::= ConstructorHeader ';'
1649 // now we know that the top of stack is a constructorDeclaration
1650 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
1652 cd.bodyEnd = endPosition; // position just before the trailing semi-colon
1653 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1654 // report the problem and continue the parsing - narrowing the problem onto the method
1656 protected void consumeConstructorHeader() {
1657 // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
1659 AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr];
1661 if (currentToken == TokenNameLBRACE){
1662 method.bodyStart = scanner.currentPosition;
1665 if (currentElement != null){
1666 restartRecovery = true; // used to avoid branching back into the regular automaton
1669 protected void consumeConstructorHeaderName() {
1671 /* recovering - might be an empty message send */
1672 if (currentElement != null){
1673 if (lastIgnoredToken == TokenNamenew){ // was an allocation expression
1674 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1675 restartRecovery = true;
1680 // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
1681 ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
1683 //name -- this is not really revelant but we do .....
1684 cd.selector = identifierStack[identifierPtr];
1685 long selectorSource = identifierPositionStack[identifierPtr--];
1686 identifierLengthPtr--;
1689 cd.declarationSourceStart = intStack[intPtr--];
1690 cd.modifiers = intStack[intPtr--];
1692 //highlight starts at the selector starts
1693 cd.sourceStart = (int) (selectorSource >>> 32);
1695 cd.sourceEnd = lParenPos;
1696 cd.bodyStart = lParenPos+1;
1697 listLength = 0; // initialize listLength before reading parameters/throws
1700 if (currentElement != null){
1701 lastCheckPoint = cd.bodyStart;
1702 if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT)
1703 || cd.modifiers != 0){
1704 currentElement = currentElement.add(cd, 0);
1705 lastIgnoredToken = -1;
1709 protected void consumeDefaultLabel() {
1710 // SwitchLabel ::= 'default' ':'
1711 pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--]));
1713 protected void consumeDefaultModifiers() {
1714 checkAnnotation(); // might update modifiers with AccDeprecated
1715 pushOnIntStack(modifiers); // modifiers
1717 modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
1720 protected void consumeDiet() {
1723 pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one
1724 jumpOverMethodBody();
1726 protected void consumeDims() {
1727 // Dims ::= DimsLoop
1728 pushOnIntStack(dimensions);
1731 protected void consumeDimWithOrWithOutExpr() {
1732 // DimWithOrWithOutExpr ::= '[' ']'
1733 pushOnExpressionStack(null);
1735 protected void consumeDimWithOrWithOutExprs() {
1736 // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
1737 concatExpressionLists();
1739 protected void consumeEmptyArgumentListopt() {
1740 // ArgumentListopt ::= $empty
1741 pushOnExpressionStackLengthStack(0);
1743 protected void consumeEmptyArrayInitializer() {
1744 // ArrayInitializer ::= '{' ,opt '}'
1745 arrayInitializer(0);
1747 protected void consumeEmptyArrayInitializeropt() {
1748 // ArrayInitializeropt ::= $empty
1749 pushOnExpressionStackLengthStack(0);
1751 protected void consumeEmptyBlockStatementsopt() {
1752 // BlockStatementsopt ::= $empty
1753 pushOnAstLengthStack(0);
1755 protected void consumeEmptyCatchesopt() {
1756 // Catchesopt ::= $empty
1757 pushOnAstLengthStack(0);
1759 protected void consumeEmptyClassBodyDeclarationsopt() {
1760 // ClassBodyDeclarationsopt ::= $empty
1761 pushOnAstLengthStack(0);
1763 protected void consumeEmptyClassMemberDeclaration() {
1764 // ClassMemberDeclaration ::= ';'
1765 pushOnAstLengthStack(0);
1767 protected void consumeEmptyDimsopt() {
1768 // Dimsopt ::= $empty
1771 protected void consumeEmptyExpression() {
1772 // Expressionopt ::= $empty
1773 pushOnExpressionStackLengthStack(0);
1775 protected void consumeEmptyForInitopt() {
1776 // ForInitopt ::= $empty
1777 pushOnAstLengthStack(0);
1779 protected void consumeEmptyForUpdateopt() {
1780 // ForUpdateopt ::= $empty
1781 pushOnExpressionStackLengthStack(0);
1783 protected void consumeEmptyImportDeclarationsopt() {
1784 // ImportDeclarationsopt ::= $empty
1785 pushOnAstLengthStack(0);
1787 protected void consumeEmptyInterfaceMemberDeclaration() {
1788 // InterfaceMemberDeclaration ::= ';'
1789 pushOnAstLengthStack(0);
1791 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
1792 // InterfaceMemberDeclarationsopt ::= $empty
1793 pushOnAstLengthStack(0);
1795 protected void consumeEmptyStatement() {
1796 // EmptyStatement ::= ';'
1797 if (this.scanner.source[endStatementPosition] == ';') {
1798 pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition));
1800 // we have a Unicode for the ';' (/u003B)
1801 pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition));
1804 protected void consumeEmptySwitchBlock() {
1805 // SwitchBlock ::= '{' '}'
1806 pushOnAstLengthStack(0);
1808 protected void consumeEmptyTypeDeclaration() {
1809 // TypeDeclaration ::= ';'
1810 pushOnAstLengthStack(0);
1812 protected void consumeEmptyTypeDeclarationsopt() {
1813 // TypeDeclarationsopt ::= $empty
1814 pushOnAstLengthStack(0);
1816 protected void consumeEnterAnonymousClassBody() {
1817 // EnterAnonymousClassBody ::= $empty
1818 QualifiedAllocationExpression alloc;
1819 AnonymousLocalTypeDeclaration anonymousType =
1820 new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
1822 anonymousType.allocation = new QualifiedAllocationExpression(anonymousType);
1823 markCurrentMethodWithLocalType();
1824 pushOnAstStack(anonymousType);
1826 alloc.sourceEnd = rParenPos; //the position has been stored explicitly
1828 if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
1829 expressionPtr -= argumentLength;
1833 alloc.arguments = new Expression[argumentLength],
1837 alloc.type = getTypeReference(0);
1839 anonymousType.sourceEnd = alloc.sourceEnd;
1840 //position at the type while it impacts the anonymous declaration
1841 anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
1842 alloc.sourceStart = intStack[intPtr--];
1843 pushOnExpressionStack(alloc);
1845 anonymousType.bodyStart = scanner.currentPosition;
1846 listLength = 0; // will be updated when reading super-interfaces
1848 if (currentElement != null){
1849 lastCheckPoint = anonymousType.bodyStart;
1850 // the recoveryTokenCheck will deal with the open brace
1851 currentElement = currentElement.add(anonymousType, 0);
1852 currentToken = 0; // opening brace already taken into account
1853 lastIgnoredToken = -1;
1856 protected void consumeEnterCompilationUnit() {
1857 // EnterCompilationUnit ::= $empty
1858 // do nothing by default
1860 protected void consumeEnterVariable() {
1861 // EnterVariable ::= $empty
1862 // do nothing by default
1864 char[] name = identifierStack[identifierPtr];
1865 long namePosition = identifierPositionStack[identifierPtr];
1866 int extendedDimension = intStack[intPtr--];
1867 AbstractVariableDeclaration declaration;
1868 // create the ast node
1869 boolean isLocalDeclaration = nestedMethod[nestedType] != 0;
1870 if (isLocalDeclaration) {
1871 // create the local variable declarations
1873 this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
1875 // create the field declaration
1877 this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
1881 identifierLengthPtr--;
1883 int variableIndex = variablesCounter[nestedType];
1885 if (variableIndex == 0) {
1886 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
1887 if (isLocalDeclaration) {
1888 declaration.declarationSourceStart = intStack[intPtr--];
1889 declaration.modifiers = intStack[intPtr--];
1890 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
1891 if (declaration.declarationSourceStart == -1) {
1892 // this is true if there is no modifiers for the local variable declaration
1893 declaration.declarationSourceStart = type.sourceStart;
1895 pushOnAstStack(type);
1897 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
1898 pushOnAstStack(type);
1899 declaration.declarationSourceStart = intStack[intPtr--];
1900 declaration.modifiers = intStack[intPtr--];
1903 type = (TypeReference) astStack[astPtr - variableIndex];
1904 typeDim = type.dimensions();
1905 AbstractVariableDeclaration previousVariable =
1906 (AbstractVariableDeclaration) astStack[astPtr];
1907 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
1908 declaration.modifiers = previousVariable.modifiers;
1911 if (extendedDimension == 0) {
1912 declaration.type = type;
1914 int dimension = typeDim + extendedDimension;
1915 //on the identifierLengthStack there is the information about the type....
1917 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
1919 int typeSourceStart = type.sourceStart;
1920 int typeSourceEnd = type.sourceEnd;
1921 type = TypeReference.baseTypeReference(-baseType, dimension);
1922 type.sourceStart = typeSourceStart;
1923 type.sourceEnd = typeSourceEnd;
1924 declaration.type = type;
1926 declaration.type = this.copyDims(type, dimension);
1929 variablesCounter[nestedType]++;
1930 pushOnAstStack(declaration);
1932 if (currentElement != null) {
1933 if (!(currentElement instanceof RecoveredType)
1934 && (currentToken == TokenNameDOT
1935 //|| declaration.modifiers != 0
1936 || (scanner.getLineNumber(declaration.type.sourceStart)
1937 != scanner.getLineNumber((int) (namePosition >>> 32))))){
1938 lastCheckPoint = (int) (namePosition >>> 32);
1939 restartRecovery = true;
1942 if (isLocalDeclaration){
1943 LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr];
1944 lastCheckPoint = localDecl.sourceEnd + 1;
1945 currentElement = currentElement.add(localDecl, 0);
1947 FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr];
1948 lastCheckPoint = fieldDecl.sourceEnd + 1;
1949 currentElement = currentElement.add(fieldDecl, 0);
1951 lastIgnoredToken = -1;
1954 protected void consumeEqualityExpression(int op) {
1955 // EqualityExpression ::= EqualityExpression '==' RelationalExpression
1956 // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
1958 //optimize the push/pop
1961 expressionLengthPtr--;
1962 expressionStack[expressionPtr] =
1963 new EqualExpression(
1964 expressionStack[expressionPtr],
1965 expressionStack[expressionPtr + 1],
1968 protected void consumeExitVariableWithInitialization() {
1969 // ExitVariableWithInitialization ::= $empty
1970 // do nothing by default
1971 expressionLengthPtr--;
1972 AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr];
1973 variableDecl.initialization = expressionStack[expressionPtr--];
1974 // we need to update the declarationSourceEnd of the local variable declaration to the
1975 // source end position of the initialization expression
1976 variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
1977 variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
1979 protected void consumeExitVariableWithoutInitialization() {
1980 // ExitVariableWithoutInitialization ::= $empty
1981 // do nothing by default
1983 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
1985 /* flag allows to distinguish 3 cases :
1987 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
1988 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
1990 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
1991 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
1993 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
1994 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
1996 int startPosition = intStack[intPtr--];
1997 ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
1999 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
2000 expressionPtr -= length;
2001 System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
2005 ecc.sourceStart = startPosition;
2008 expressionLengthPtr--;
2009 ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart;
2012 ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
2015 pushOnAstStack(ecc);
2016 ecc.sourceEnd = endPosition;
2018 protected void consumeExpressionStatement() {
2019 // ExpressionStatement ::= StatementExpression ';'
2020 expressionLengthPtr--;
2021 pushOnAstStack(expressionStack[expressionPtr--]);
2023 protected void consumeFieldAccess(boolean isSuperAccess) {
2024 // FieldAccess ::= Primary '.' 'Identifier'
2025 // FieldAccess ::= 'super' '.' 'Identifier'
2029 identifierStack[identifierPtr],
2030 identifierPositionStack[identifierPtr--]);
2031 identifierLengthPtr--;
2032 if (isSuperAccess) {
2033 //considerates the fieldReference beginning at the 'super' ....
2034 fr.sourceStart = intStack[intPtr--];
2035 fr.receiver = new SuperReference(fr.sourceStart, endPosition);
2036 pushOnExpressionStack(fr);
2039 if ((fr.receiver = expressionStack[expressionPtr]).isThis()) {
2040 //fieldreference begins at the this
2041 fr.sourceStart = fr.receiver.sourceStart;
2043 expressionStack[expressionPtr] = fr;
2046 protected void consumeFieldDeclaration() {
2047 // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
2048 // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
2052 expressionStack: Expression Expression ...... Expression
2053 identifierStack : type identifier identifier ...... identifier
2054 intStack : typeDim dim dim dim
2056 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2062 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2064 for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2065 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2066 fieldDeclaration.declarationSourceEnd = endStatementPosition;
2067 fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included
2069 updateSourceDeclarationParts(variableDeclaratorsCounter);
2070 int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition);
2071 if (endPos != endStatementPosition) {
2072 for (int i = 0; i < variableDeclaratorsCounter; i++) {
2073 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2074 fieldDeclaration.declarationSourceEnd = endPos;
2077 // update the astStack, astPtr and astLengthStack
2078 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2084 variableDeclaratorsCounter);
2085 astPtr--; // remove the type reference
2086 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2089 if (currentElement != null) {
2090 lastCheckPoint = endPos + 1;
2091 if (currentElement.parent != null && currentElement instanceof RecoveredField){
2092 currentElement = currentElement.parent;
2094 restartRecovery = true;
2096 variablesCounter[nestedType] = 0;
2098 protected void consumeForceNoDiet() {
2099 // ForceNoDiet ::= $empty
2102 protected void consumeForInit() {
2103 // ForInit ::= StatementExpressionList
2104 pushOnAstLengthStack(-1);
2106 protected void consumeFormalParameter() {
2107 // FormalParameter ::= Type VariableDeclaratorId ==> false
2108 // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
2111 identifierStack : type identifier
2119 identifierLengthPtr--;
2120 char[] name = identifierStack[identifierPtr];
2121 long namePositions = identifierPositionStack[identifierPtr--];
2122 TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
2123 int modifierPositions = intStack[intPtr--];
2130 intStack[intPtr + 1] & ~AccDeprecated); // modifiers
2131 arg.declarationSourceStart = modifierPositions;
2132 pushOnAstStack(arg);
2134 /* if incomplete method header, listLength counter will not have been reset,
2135 indicating that some arguments are available on the stack */
2138 protected void consumeFormalParameterList() {
2139 // FormalParameterList ::= FormalParameterList ',' FormalParameter
2140 optimizedConcatNodeLists();
2142 protected void consumeFormalParameterListopt() {
2143 // FormalParameterListopt ::= $empty
2144 pushOnAstLengthStack(0);
2146 protected void consumeImportDeclarations() {
2147 // ImportDeclarations ::= ImportDeclarations ImportDeclaration
2148 optimizedConcatNodeLists();
2150 protected void consumeImportDeclarationsopt() {
2151 // ImportDeclarationsopt ::= ImportDeclarations
2153 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2158 compilationUnit.imports = new ImportReference[length],
2163 protected void consumeInstanceOfExpression(int op) {
2164 // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
2165 //optimize the push/pop
2167 //by construction, no base type may be used in getTypeReference
2169 expressionStack[expressionPtr] = exp =
2170 new InstanceOfExpression(
2171 expressionStack[expressionPtr],
2172 getTypeReference(intStack[intPtr--]),
2174 if (exp.sourceEnd == 0) {
2175 //array on base type....
2176 exp.sourceEnd = scanner.startPosition - 1;
2178 //the scanner is on the next token already....
2180 protected void consumeInterfaceDeclaration() {
2181 // see consumeClassDeclaration in case of changes: duplicated code
2182 // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
2184 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2185 //there are length declarations
2186 //dispatch.....according to the type of the declarations
2187 dispatchDeclarationInto(length);
2190 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2192 // mark fields and initializer with local type mark if needed
2193 markFieldsWithLocalType(typeDecl);
2195 //convert constructor that do not have the type's name into methods
2196 typeDecl.checkConstructors(this);
2198 //always add <clinit> (will be remove at code gen time if empty)
2199 if (this.scanner.containsAssertKeyword) {
2200 typeDecl.bits |= AstNode.AddAssertionMASK;
2202 typeDecl.addClinit();
2203 typeDecl.bodyEnd = endStatementPosition;
2204 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2206 protected void consumeInterfaceHeader() {
2207 // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2209 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2210 if (currentToken == TokenNameLBRACE){
2211 typeDecl.bodyStart = scanner.currentPosition;
2213 if (currentElement != null){
2214 restartRecovery = true; // used to avoid branching back into the regular automaton
2216 // flush the comments related to the interface header
2217 scanner.commentPtr = -1;
2219 protected void consumeInterfaceHeaderExtends() {
2220 // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2221 int length = astLengthStack[astLengthPtr--];
2224 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2228 typeDecl.superInterfaces = new TypeReference[length],
2231 typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
2232 listLength = 0; // reset after having read super-interfaces
2234 if (currentElement != null) {
2235 lastCheckPoint = typeDecl.bodyStart;
2238 protected void consumeInterfaceHeaderName() {
2239 // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2240 TypeDeclaration typeDecl;
2241 if (nestedMethod[nestedType] == 0) {
2242 if (nestedType != 0) {
2243 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
2245 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2248 // Record that the block has a declaration for local types
2249 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
2250 markCurrentMethodWithLocalType();
2254 //highlight the name of the type
2255 long pos = identifierPositionStack[identifierPtr];
2256 typeDecl.sourceEnd = (int) pos;
2257 typeDecl.sourceStart = (int) (pos >>> 32);
2258 typeDecl.name = identifierStack[identifierPtr--];
2259 identifierLengthPtr--;
2261 //compute the declaration source too
2262 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2263 // we want to keep the beginning position but get rid of the end position
2264 // it is only used for the ClassLiteralAccess positions.
2265 typeDecl.declarationSourceStart = intStack[intPtr--];
2266 intPtr--; // remove the end position of the class token
2267 typeDecl.modifiersSourceStart = intStack[intPtr--];
2268 typeDecl.modifiers = intStack[intPtr--];
2269 if (typeDecl.modifiersSourceStart >= 0) {
2270 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2272 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2273 pushOnAstStack(typeDecl);
2274 listLength = 0; // will be updated when reading super-interfaces
2276 if (currentElement != null){ // is recovering
2277 lastCheckPoint = typeDecl.bodyStart;
2278 currentElement = currentElement.add(typeDecl, 0);
2279 lastIgnoredToken = -1;
2282 protected void consumeInterfaceMemberDeclarations() {
2283 // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2286 protected void consumeInterfaceMemberDeclarationsopt() {
2287 // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2290 protected void consumeInterfaceType() {
2291 // InterfaceType ::= ClassOrInterfaceType
2292 pushOnAstStack(getTypeReference(0));
2293 /* if incomplete type header, listLength counter will not have been reset,
2294 indicating that some interfaces are available on the stack */
2297 protected void consumeInterfaceTypeList() {
2298 // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2299 optimizedConcatNodeLists();
2301 protected void consumeLeftHandSide() {
2302 // LeftHandSide ::= Name
2304 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2306 protected void consumeLeftParen() {
2307 // PushLPAREN ::= '('
2308 pushOnIntStack(lParenPos);
2310 protected void consumeLocalVariableDeclaration() {
2311 // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2315 expressionStack: Expression Expression ...... Expression
2316 identifierStack : type identifier identifier ...... identifier
2317 intStack : typeDim dim dim dim
2319 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2325 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2327 // update the astStack, astPtr and astLengthStack
2328 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2334 variableDeclaratorsCounter);
2335 astPtr--; // remove the type reference
2336 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2337 variablesCounter[nestedType] = 0;
2339 protected void consumeLocalVariableDeclarationStatement() {
2340 // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2341 // see blockReal in case of change: duplicated code
2342 // increment the amount of declared variables for this block
2343 realBlockStack[realBlockPtr]++;
2345 protected void consumeMethodBody() {
2346 // MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
2347 nestedMethod[nestedType] --;
2349 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2350 // MethodDeclaration ::= MethodHeader MethodBody
2351 // AbstractMethodDeclaration ::= MethodHeader ';'
2354 astStack : modifiers arguments throws statements
2355 identifierStack : type name
2356 intStack : dim dim dim
2358 astStack : MethodDeclaration
2364 if (isNotAbstract) {
2365 // pop the position of the { (body of the method) pushed in block decl
2369 int explicitDeclarations = 0;
2370 Statement[] statements = null;
2371 if (isNotAbstract) {
2373 explicitDeclarations = realBlockStack[realBlockPtr--];
2374 if ((length = astLengthStack[astLengthPtr--]) != 0)
2377 (astPtr -= length) + 1,
2378 statements = new Statement[length],
2383 // now we know that we have a method declaration at the top of the ast stack
2384 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2385 md.statements = statements;
2386 md.explicitDeclarations = explicitDeclarations;
2388 // cannot be done in consumeMethodHeader because we have no idea whether or not there
2389 // is a body when we reduce the method header
2390 if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2391 md.modifiers |= AccSemicolonBody;
2393 // store the endPosition (position just before the '}') in case there is
2394 // a trailing comment behind the end of the method
2395 md.bodyEnd = endPosition;
2396 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2398 protected void consumeMethodHeader() {
2399 // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2400 // retrieve end position of method declarator
2401 AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr];
2403 if (currentToken == TokenNameLBRACE){
2404 method.bodyStart = scanner.currentPosition;
2407 if (currentElement != null){
2408 if (currentToken == TokenNameSEMICOLON){
2409 method.modifiers |= AccSemicolonBody;
2410 method.declarationSourceEnd = scanner.currentPosition-1;
2411 method.bodyEnd = scanner.currentPosition-1;
2412 if (currentElement.parent != null){
2413 currentElement = currentElement.parent;
2416 restartRecovery = true; // used to avoid branching back into the regular automaton
2419 protected void consumeMethodHeaderExtendedDims() {
2420 // MethodHeaderExtendedDims ::= Dimsopt
2421 // now we update the returnType of the method
2422 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2423 int extendedDims = intStack[intPtr--];
2424 if (extendedDims != 0) {
2425 TypeReference returnType = md.returnType;
2426 md.sourceEnd = endPosition;
2427 int dims = returnType.dimensions() + extendedDims;
2429 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2431 int sourceStart = returnType.sourceStart;
2432 int sourceEnd = returnType.sourceEnd;
2433 returnType = TypeReference.baseTypeReference(-baseType, dims);
2434 returnType.sourceStart = sourceStart;
2435 returnType.sourceEnd = sourceEnd;
2436 md.returnType = returnType;
2438 md.returnType = this.copyDims(md.returnType, dims);
2440 if (currentToken == TokenNameLBRACE){
2441 md.bodyStart = endPosition + 1;
2444 if (currentElement != null){
2445 lastCheckPoint = md.bodyStart;
2449 protected void consumeMethodHeaderName() {
2450 // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2451 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2454 md.selector = identifierStack[identifierPtr];
2455 long selectorSource = identifierPositionStack[identifierPtr--];
2456 identifierLengthPtr--;
2458 md.returnType = getTypeReference(intStack[intPtr--]);
2460 md.declarationSourceStart = intStack[intPtr--];
2461 md.modifiers = intStack[intPtr--];
2463 //highlight starts at selector start
2464 md.sourceStart = (int) (selectorSource >>> 32);
2466 md.sourceEnd = lParenPos;
2467 md.bodyStart = lParenPos+1;
2468 listLength = 0; // initialize listLength before reading parameters/throws
2471 if (currentElement != null){
2472 if (currentElement instanceof RecoveredType
2473 //|| md.modifiers != 0
2474 || (scanner.getLineNumber(md.returnType.sourceStart)
2475 == scanner.getLineNumber(md.sourceStart))){
2476 lastCheckPoint = md.bodyStart;
2477 currentElement = currentElement.add(md, 0);
2478 lastIgnoredToken = -1;
2480 lastCheckPoint = md.sourceStart;
2481 restartRecovery = true;
2485 protected void consumeMethodHeaderParameters() {
2486 // MethodHeaderParameters ::= FormalParameterListopt ')'
2487 int length = astLengthStack[astLengthPtr--];
2489 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2490 md.sourceEnd = rParenPos;
2496 md.arguments = new Argument[length],
2500 md.bodyStart = rParenPos+1;
2501 listLength = 0; // reset listLength after having read all parameters
2503 if (currentElement != null){
2504 lastCheckPoint = md.bodyStart;
2505 if (currentElement.parseTree() == md) return;
2507 // might not have been attached yet - in some constructor scenarii
2508 if (md.isConstructor()){
2510 || (currentToken == TokenNameLBRACE)
2511 // || (currentToken == TokenNamethrows)
2513 currentElement = currentElement.add(md, 0);
2514 lastIgnoredToken = -1;
2519 protected void consumeMethodHeaderThrowsClause() {
2520 // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2521 int length = astLengthStack[astLengthPtr--];
2523 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2527 md.thrownExceptions = new TypeReference[length],
2530 md.sourceEnd = md.thrownExceptions[length-1].sourceEnd;
2531 md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1;
2532 listLength = 0; // reset listLength after having read all thrown exceptions
2534 if (currentElement != null){
2535 lastCheckPoint = md.bodyStart;
2538 protected void consumeMethodInvocationName() {
2539 // MethodInvocation ::= Name '(' ArgumentListopt ')'
2541 // when the name is only an identifier...we have a message send to "this" (implicit)
2543 MessageSend m = newMessageSend();
2544 m.sourceEnd = rParenPos;
2546 (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2547 m.selector = identifierStack[identifierPtr--];
2548 if (identifierLengthStack[identifierLengthPtr] == 1) {
2549 m.receiver = ThisReference.ThisImplicit;
2550 identifierLengthPtr--;
2552 identifierLengthStack[identifierLengthPtr]--;
2553 m.receiver = getUnspecifiedReference();
2554 m.sourceStart = m.receiver.sourceStart;
2556 pushOnExpressionStack(m);
2558 protected void consumeMethodInvocationPrimary() {
2559 //optimize the push/pop
2560 //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2562 MessageSend m = newMessageSend();
2564 (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2565 m.selector = identifierStack[identifierPtr--];
2566 identifierLengthPtr--;
2567 m.receiver = expressionStack[expressionPtr];
2568 m.sourceStart = m.receiver.sourceStart;
2569 m.sourceEnd = rParenPos;
2570 expressionStack[expressionPtr] = m;
2572 protected void consumeMethodInvocationSuper() {
2573 // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2575 MessageSend m = newMessageSend();
2576 m.sourceStart = intStack[intPtr--];
2577 m.sourceEnd = rParenPos;
2578 m.nameSourcePosition = identifierPositionStack[identifierPtr];
2579 m.selector = identifierStack[identifierPtr--];
2580 identifierLengthPtr--;
2581 m.receiver = new SuperReference(m.sourceStart, endPosition);
2582 pushOnExpressionStack(m);
2584 protected void consumeMethodPushModifiersHeaderName() {
2585 // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
2586 // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
2587 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2590 md.selector = identifierStack[identifierPtr];
2591 long selectorSource = identifierPositionStack[identifierPtr--];
2592 identifierLengthPtr--;
2595 md.declarationSourceStart = intStack[intPtr--];
2596 md.modifiers = intStack[intPtr--];
2599 md.returnType = getTypeReference(intStack[intPtr--]);
2601 //highlight starts at selector start
2602 md.sourceStart = (int) (selectorSource >>> 32);
2604 md.sourceEnd = lParenPos;
2605 md.bodyStart = lParenPos + 1;
2606 listLength = 0; // initialize listLength before reading parameters/throws
2609 if (currentElement != null) {
2610 lastCheckPoint = md.bodyStart;
2611 currentElement = currentElement.add(md, 0);
2612 lastIgnoredToken = -1;
2615 protected void consumeModifiers() {
2616 int savedModifiersSourceStart = modifiersSourceStart;
2617 checkAnnotation(); // might update modifiers with AccDeprecated
2618 pushOnIntStack(modifiers); // modifiers
2619 if (modifiersSourceStart >= savedModifiersSourceStart) {
2620 modifiersSourceStart = savedModifiersSourceStart;
2622 pushOnIntStack(modifiersSourceStart);
2625 protected void consumeNestedMethod() {
2626 // NestedMethod ::= $empty
2627 jumpOverMethodBody();
2628 nestedMethod[nestedType] ++;
2631 protected void consumeNestedType() {
2632 // NestedType ::= $empty
2635 nestedMethod[nestedType] = 0;
2636 } catch (IndexOutOfBoundsException e) {
2637 //except in test's cases, it should never raise
2638 int oldL = nestedMethod.length;
2639 System.arraycopy(nestedMethod , 0, (nestedMethod = new int[oldL + 30]), 0, oldL);
2640 nestedMethod[nestedType] = 0;
2641 // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection
2642 System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL);
2644 variablesCounter[nestedType] = 0;
2646 protected void consumeOneDimLoop() {
2647 // OneDimLoop ::= '[' ']'
2650 protected void consumeOnlySynchronized() {
2651 // OnlySynchronized ::= 'synchronized'
2652 pushOnIntStack(this.synchronizedBlockSourceStart);
2655 protected void consumeOpenBlock() {
2656 // OpenBlock ::= $empty
2658 pushOnIntStack(scanner.startPosition);
2660 realBlockStack[++realBlockPtr] = 0;
2661 } catch (IndexOutOfBoundsException e) {
2662 //realBlockPtr is correct
2663 int oldStackLength = realBlockStack.length;
2664 int oldStack[] = realBlockStack;
2665 realBlockStack = new int[oldStackLength + StackIncrement];
2666 System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength);
2667 realBlockStack[realBlockPtr] = 0;
2670 protected void consumePackageDeclaration() {
2671 // PackageDeclaration ::= 'package' Name ';'
2672 /* build an ImportRef build from the last name
2673 stored in the identifier stack. */
2675 ImportReference impt = compilationUnit.currentPackage;
2676 // flush annotations defined prior to import statements
2677 impt.declarationEnd = endStatementPosition;
2678 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
2680 protected void consumePackageDeclarationName() {
2681 // PackageDeclarationName ::= 'package' Name
2682 /* build an ImportRef build from the last name
2683 stored in the identifier stack. */
2685 ImportReference impt;
2688 new char[length = identifierLengthStack[identifierLengthPtr--]][];
2689 identifierPtr -= length;
2690 long[] positions = new long[length];
2691 System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length);
2693 identifierPositionStack,
2698 compilationUnit.currentPackage =
2699 impt = new ImportReference(tokens, positions, true);
2701 if (currentToken == TokenNameSEMICOLON){
2702 impt.declarationSourceEnd = scanner.currentPosition - 1;
2704 impt.declarationSourceEnd = impt.sourceEnd;
2706 impt.declarationEnd = impt.declarationSourceEnd;
2707 //endPosition is just before the ;
2708 impt.declarationSourceStart = intStack[intPtr--];
2711 if (currentElement != null){
2712 lastCheckPoint = impt.declarationSourceEnd+1;
2713 restartRecovery = true; // used to avoid branching back into the regular automaton
2716 protected void consumePostfixExpression() {
2717 // PostfixExpression ::= Name
2718 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2720 protected void consumePrimaryNoNewArray() {
2721 // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
2722 updateSourcePosition(expressionStack[expressionPtr]);
2724 protected void consumePrimaryNoNewArrayArrayType() {
2725 // PrimaryNoNewArray ::= ArrayType '.' 'class'
2727 pushOnExpressionStack(
2728 new ClassLiteralAccess(intStack[intPtr--],
2729 getTypeReference(intStack[intPtr--])));
2731 protected void consumePrimaryNoNewArrayName() {
2732 // PrimaryNoNewArray ::= Name '.' 'class'
2734 pushOnExpressionStack(
2735 new ClassLiteralAccess(intStack[intPtr--],
2736 getTypeReference(0)));
2738 protected void consumePrimaryNoNewArrayNameSuper() {
2739 // PrimaryNoNewArray ::= Name '.' 'super'
2740 pushOnExpressionStack(
2741 new QualifiedSuperReference(
2742 getTypeReference(0),
2746 protected void consumePrimaryNoNewArrayNameThis() {
2747 // PrimaryNoNewArray ::= Name '.' 'this'
2748 pushOnExpressionStack(
2749 new QualifiedThisReference(
2750 getTypeReference(0),
2754 protected void consumePrimaryNoNewArrayPrimitiveType() {
2755 // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
2757 pushOnExpressionStack(
2758 new ClassLiteralAccess(intStack[intPtr--],
2759 getTypeReference(0)));
2761 protected void consumePrimaryNoNewArrayThis() {
2762 // PrimaryNoNewArray ::= 'this'
2763 pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition));
2765 protected void consumePrimitiveType() {
2766 // Type ::= PrimitiveType
2769 protected void consumePushModifiers() {
2770 if ((modifiers & AccSynchronized) != 0) {
2771 /* remove the starting position of the synchronized keyword
2772 * we don't need it when synchronized is part of the modifiers
2776 pushOnIntStack(modifiers); // modifiers
2777 pushOnIntStack(modifiersSourceStart);
2780 protected void consumePushPosition() {
2781 // for source managment purpose
2782 // PushPosition ::= $empty
2783 pushOnIntStack(endPosition);
2785 protected void consumeQualifiedName() {
2786 // QualifiedName ::= Name '.' SimpleName
2787 /*back from the recursive loop of QualifiedName.
2788 Updates identifier length into the length stack*/
2790 identifierLengthStack[--identifierLengthPtr]++;
2792 protected void consumeReferenceType() {
2793 // ReferenceType ::= ClassOrInterfaceType
2796 protected void consumeRestoreDiet() {
2797 // RestoreDiet ::= $empty
2800 protected void consumeRightParen() {
2801 // PushRPAREN ::= ')'
2802 pushOnIntStack(rParenPos);
2804 // This method is part of an automatic generation : do NOT edit-modify
2805 // This method is part of an automatic generation : do NOT edit-modify
2806 protected void consumeRule(int act) {
2808 case 29 : // System.out.println("Type ::= PrimitiveType");
2809 consumePrimitiveType();
2812 case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
2813 consumeReferenceType();
2816 case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName");
2817 consumeQualifiedName();
2820 case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
2821 consumeCompilationUnit();
2824 case 54 : // System.out.println("EnterCompilationUnit ::=");
2825 consumeEnterCompilationUnit();
2828 case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
2829 consumeCatchHeader();
2832 case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
2833 consumeImportDeclarations();
2836 case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
2837 consumeTypeDeclarations();
2840 case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
2841 consumePackageDeclaration();
2844 case 72 : // System.out.println("PackageDeclarationName ::= package Name");
2845 consumePackageDeclarationName();
2848 case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
2849 consumeSingleTypeImportDeclaration();
2852 case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
2853 consumeSingleTypeImportDeclarationName();
2856 case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
2857 consumeTypeImportOnDemandDeclaration();
2860 case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
2861 consumeTypeImportOnDemandDeclarationName();
2864 case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON");
2865 consumeEmptyTypeDeclaration();
2868 case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
2869 consumeClassDeclaration();
2872 case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
2873 consumeClassHeader();
2876 case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");
2877 consumeClassHeaderName();
2880 case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
2881 consumeClassHeaderExtends();
2884 case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
2885 consumeClassHeaderImplements();
2888 case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
2889 consumeInterfaceTypeList();
2892 case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
2893 consumeInterfaceType();
2896 case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
2897 consumeClassBodyDeclarations();
2900 case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
2901 consumeClassBodyDeclaration();
2904 case 110 : // System.out.println("Diet ::=");
2908 case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block");
2909 consumeClassBodyDeclaration();
2912 case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
2913 consumeEmptyClassMemberDeclaration();
2916 case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
2917 consumeFieldDeclaration();
2920 case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
2921 consumeVariableDeclarators();
2924 case 124 : // System.out.println("EnterVariable ::=");
2925 consumeEnterVariable();
2928 case 125 : // System.out.println("ExitVariableWithInitialization ::=");
2929 consumeExitVariableWithInitialization();
2932 case 126 : // System.out.println("ExitVariableWithoutInitialization ::=");
2933 consumeExitVariableWithoutInitialization();
2936 case 127 : // System.out.println("ForceNoDiet ::=");
2937 consumeForceNoDiet();
2940 case 128 : // System.out.println("RestoreDiet ::=");
2941 consumeRestoreDiet();
2944 case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
2945 // set to true to consume a method with a body
2946 consumeMethodDeclaration(true);
2949 case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
2950 // set to false to consume a method without body
2951 consumeMethodDeclaration(false);
2954 case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
2955 consumeMethodHeader();
2958 case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
2959 consumeMethodHeader();
2962 case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN");
2963 consumeMethodPushModifiersHeaderName();
2966 case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN");
2967 consumeMethodPushModifiersHeaderName();
2970 case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");
2971 consumeMethodHeaderName();
2974 case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
2975 consumeMethodHeaderParameters();
2978 case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
2979 consumeMethodHeaderExtendedDims();
2982 case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
2983 consumeMethodHeaderThrowsClause();
2986 case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
2987 consumeConstructorHeader();
2990 case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
2991 consumeConstructorHeaderName();
2994 case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
2995 consumeFormalParameterList();
2998 case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
2999 // the boolean is used to know if the modifiers should be reset
3000 consumeFormalParameter();
3003 case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
3004 consumeClassTypeList();
3007 case 150 : // System.out.println("ClassTypeElt ::= ClassType");
3008 consumeClassTypeElt();
3011 case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
3012 consumeMethodBody();
3015 case 152 : // System.out.println("NestedMethod ::=");
3016 consumeNestedMethod();
3019 case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block");
3020 consumeStaticInitializer();
3023 case 154 : // System.out.println("StaticOnly ::= static");
3024 consumeStaticOnly();
3027 case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3028 consumeConstructorDeclaration() ;
3031 case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3032 consumeInvalidConstructorDeclaration() ;
3035 case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
3036 consumeConstructorBody();
3039 case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
3040 consumeConstructorBlockStatements();
3043 case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
3044 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This);
3047 case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
3048 consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super);
3051 case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
3052 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
3055 case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
3056 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
3059 case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
3060 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
3063 case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
3064 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
3067 case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
3068 consumeInterfaceDeclaration();
3071 case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
3072 consumeInterfaceHeader();
3075 case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");
3076 consumeInterfaceHeaderName();
3079 case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
3080 consumeInterfaceHeaderExtends();
3083 case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
3084 consumeInterfaceMemberDeclarations();
3087 case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
3088 consumeEmptyInterfaceMemberDeclaration();
3091 case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
3095 case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3096 ignoreInvalidConstructorDeclaration(true);
3099 case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3100 ignoreInvalidConstructorDeclaration(false);
3103 case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
3104 consumeEmptyArrayInitializer();
3107 case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
3108 consumeArrayInitializer();
3111 case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
3112 consumeArrayInitializer();
3115 case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
3116 consumeVariableInitializers();
3119 case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
3123 case 192 : // System.out.println("OpenBlock ::=");
3124 consumeOpenBlock() ;
3127 case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
3128 consumeBlockStatements() ;
3131 case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
3132 ignoreInterfaceDeclaration();
3135 case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
3136 consumeLocalVariableDeclarationStatement();
3139 case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
3140 consumeLocalVariableDeclaration();
3143 case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
3144 consumeLocalVariableDeclaration();
3147 case 202 : // System.out.println("PushModifiers ::=");
3148 consumePushModifiers();
3151 case 226 : // System.out.println("EmptyStatement ::= SEMICOLON");
3152 consumeEmptyStatement();
3155 case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");
3156 consumeStatementLabel() ;
3159 case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");
3160 consumeStatementLabel() ;
3163 case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
3164 consumeExpressionStatement();
3167 case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
3168 consumeStatementIfNoElse();
3171 case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
3172 consumeStatementIfWithElse();
3175 case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
3176 consumeStatementIfWithElse();
3179 case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
3180 consumeStatementSwitch() ;
3183 case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
3184 consumeEmptySwitchBlock() ;
3187 case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
3188 consumeSwitchBlock() ;
3191 case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
3192 consumeSwitchBlockStatements() ;
3195 case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
3196 consumeSwitchBlockStatement() ;
3199 case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
3200 consumeSwitchLabels() ;
3203 case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
3207 case 251 : // System.out.println("SwitchLabel ::= default COLON");
3208 consumeDefaultLabel();
3211 case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
3212 consumeStatementWhile() ;
3215 case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
3216 consumeStatementWhile() ;
3219 case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
3220 consumeStatementDo() ;
3223 case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
3224 consumeStatementFor() ;
3227 case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
3228 consumeStatementFor() ;
3231 case 257 : // System.out.println("ForInit ::= StatementExpressionList");
3235 case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
3236 consumeStatementExpressionList() ;
3239 case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
3240 consumeSimpleAssertStatement() ;
3243 case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
3244 consumeAssertStatement() ;
3247 case 264 : // System.out.println("BreakStatement ::= break SEMICOLON");
3248 consumeStatementBreak() ;
3251 case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
3252 consumeStatementBreakWithLabel() ;
3255 case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
3256 consumeStatementContinue() ;
3259 case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
3260 consumeStatementContinueWithLabel() ;
3263 case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
3264 consumeStatementReturn() ;
3267 case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
3268 consumeStatementThrow();
3272 case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
3273 consumeStatementSynchronized();
3276 case 271 : // System.out.println("OnlySynchronized ::= synchronized");
3277 consumeOnlySynchronized();
3280 case 272 : // System.out.println("TryStatement ::= try Block Catches");
3281 consumeStatementTry(false);
3284 case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
3285 consumeStatementTry(true);
3288 case 275 : // System.out.println("Catches ::= Catches CatchClause");
3292 case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
3293 consumeStatementCatch() ;
3296 case 278 : // System.out.println("PushLPAREN ::= LPAREN");
3300 case 279 : // System.out.println("PushRPAREN ::= RPAREN");
3301 consumeRightParen();
3304 case 283 : // System.out.println("PrimaryNoNewArray ::= this");
3305 consumePrimaryNoNewArrayThis();
3308 case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
3309 consumePrimaryNoNewArray();
3312 case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
3313 consumePrimaryNoNewArrayNameThis();
3316 case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
3317 consumePrimaryNoNewArrayNameSuper();
3320 case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
3321 consumePrimaryNoNewArrayName();
3324 case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
3325 consumePrimaryNoNewArrayArrayType();
3328 case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
3329 consumePrimaryNoNewArrayPrimitiveType();
3332 case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
3333 consumeAllocationHeader();
3336 case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
3337 consumeClassInstanceCreationExpression();
3340 case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
3341 consumeClassInstanceCreationExpressionQualified() ;
3344 case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
3345 consumeClassInstanceCreationExpressionQualified() ;
3348 case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
3349 consumeClassInstanceCreationExpressionName() ;
3352 case 299 : // System.out.println("ClassBodyopt ::=");
3353 consumeClassBodyopt();
3356 case 301 : // System.out.println("EnterAnonymousClassBody ::=");
3357 consumeEnterAnonymousClassBody();
3360 case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
3361 consumeArgumentList();
3364 case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
3365 consumeArrayCreationExpression();
3368 case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
3369 consumeArrayCreationExpression();
3372 case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
3373 consumeDimWithOrWithOutExprs();
3376 case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
3377 consumeDimWithOrWithOutExpr();
3380 case 310 : // System.out.println("Dims ::= DimsLoop");
3384 case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
3385 consumeOneDimLoop();
3388 case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier");
3389 consumeFieldAccess(false);
3392 case 315 : // System.out.println("FieldAccess ::= super DOT Identifier");
3393 consumeFieldAccess(true);
3396 case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");
3397 consumeMethodInvocationName();
3400 case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN");
3401 consumeMethodInvocationPrimary();
3404 case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN");
3405 consumeMethodInvocationSuper();
3408 case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
3409 consumeArrayAccess(true);
3412 case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
3413 consumeArrayAccess(false);
3416 case 322 : // System.out.println("PostfixExpression ::= Name");
3417 consumePostfixExpression();
3420 case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
3421 consumeUnaryExpression(OperatorExpression.PLUS,true);
3424 case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
3425 consumeUnaryExpression(OperatorExpression.MINUS,true);
3428 case 327 : // System.out.println("PushPosition ::=");
3429 consumePushPosition();
3432 case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
3433 consumeUnaryExpression(OperatorExpression.PLUS);
3436 case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
3437 consumeUnaryExpression(OperatorExpression.MINUS);
3440 case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
3441 consumeUnaryExpression(OperatorExpression.PLUS,false);
3444 case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
3445 consumeUnaryExpression(OperatorExpression.MINUS,false);
3448 case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
3449 consumeUnaryExpression(OperatorExpression.TWIDDLE);
3452 case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
3453 consumeUnaryExpression(OperatorExpression.NOT);
3456 case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
3457 consumeCastExpression();
3460 case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
3461 consumeCastExpression();
3464 case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
3465 consumeCastExpressionLL1();
3468 case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
3469 consumeBinaryExpression(OperatorExpression.MULTIPLY);
3472 case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
3473 consumeBinaryExpression(OperatorExpression.DIVIDE);
3476 case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
3477 consumeBinaryExpression(OperatorExpression.REMAINDER);
3480 case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
3481 consumeBinaryExpression(OperatorExpression.PLUS);
3484 case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
3485 consumeBinaryExpression(OperatorExpression.MINUS);
3488 case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
3489 consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);
3492 case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
3493 consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);
3496 case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
3497 consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);
3500 case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
3501 consumeBinaryExpression(OperatorExpression.LESS);
3504 case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
3505 consumeBinaryExpression(OperatorExpression.GREATER);
3508 case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
3509 consumeBinaryExpression(OperatorExpression.LESS_EQUAL);
3512 case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
3513 consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);
3516 case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
3517 consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);
3520 case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
3521 consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);
3524 case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
3525 consumeEqualityExpression(OperatorExpression.NOT_EQUAL);
3528 case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
3529 consumeBinaryExpression(OperatorExpression.AND);
3532 case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
3533 consumeBinaryExpression(OperatorExpression.XOR);
3536 case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
3537 consumeBinaryExpression(OperatorExpression.OR);
3540 case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
3541 consumeBinaryExpression(OperatorExpression.AND_AND);
3544 case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
3545 consumeBinaryExpression(OperatorExpression.OR_OR);
3548 case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
3549 consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ;
3552 case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
3553 consumeAssignment();
3556 case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
3557 ignoreExpressionAssignment();
3560 case 379 : // System.out.println("LeftHandSide ::= Name");
3561 consumeLeftHandSide();
3564 case 382 : // System.out.println("AssignmentOperator ::= EQUAL");
3565 consumeAssignmentOperator(EQUAL);
3568 case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
3569 consumeAssignmentOperator(MULTIPLY);
3572 case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
3573 consumeAssignmentOperator(DIVIDE);
3576 case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
3577 consumeAssignmentOperator(REMAINDER);
3580 case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
3581 consumeAssignmentOperator(PLUS);
3584 case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
3585 consumeAssignmentOperator(MINUS);
3588 case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
3589 consumeAssignmentOperator(LEFT_SHIFT);
3592 case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
3593 consumeAssignmentOperator(RIGHT_SHIFT);
3596 case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
3597 consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
3600 case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
3601 consumeAssignmentOperator(AND);
3604 case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
3605 consumeAssignmentOperator(XOR);
3608 case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
3609 consumeAssignmentOperator(OR);
3612 case 400 : // System.out.println("Expressionopt ::=");
3613 consumeEmptyExpression();
3616 case 404 : // System.out.println("ImportDeclarationsopt ::=");
3617 consumeEmptyImportDeclarationsopt();
3620 case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
3621 consumeImportDeclarationsopt();
3624 case 406 : // System.out.println("TypeDeclarationsopt ::=");
3625 consumeEmptyTypeDeclarationsopt();
3628 case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
3629 consumeTypeDeclarationsopt();
3632 case 408 : // System.out.println("ClassBodyDeclarationsopt ::=");
3633 consumeEmptyClassBodyDeclarationsopt();
3636 case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
3637 consumeClassBodyDeclarationsopt();
3640 case 410 : // System.out.println("Modifiersopt ::=");
3641 consumeDefaultModifiers();
3644 case 411 : // System.out.println("Modifiersopt ::= Modifiers");
3648 case 412 : // System.out.println("BlockStatementsopt ::=");
3649 consumeEmptyBlockStatementsopt();
3652 case 414 : // System.out.println("Dimsopt ::=");
3653 consumeEmptyDimsopt();
3656 case 416 : // System.out.println("ArgumentListopt ::=");
3657 consumeEmptyArgumentListopt();
3660 case 420 : // System.out.println("FormalParameterListopt ::=");
3661 consumeFormalParameterListopt();
3664 case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
3665 consumeEmptyInterfaceMemberDeclarationsopt();
3668 case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
3669 consumeInterfaceMemberDeclarationsopt();
3672 case 426 : // System.out.println("NestedType ::=");
3673 consumeNestedType();
3676 case 427 : // System.out.println("ForInitopt ::=");
3677 consumeEmptyForInitopt();
3680 case 429 : // System.out.println("ForUpdateopt ::=");
3681 consumeEmptyForUpdateopt();
3684 case 433 : // System.out.println("Catchesopt ::=");
3685 consumeEmptyCatchesopt();
3688 case 435 : // System.out.println("ArrayInitializeropt ::=");
3689 consumeEmptyArrayInitializeropt();
3696 protected void consumeSimpleAssertStatement() {
3697 // AssertStatement ::= 'assert' Expression ';'
3698 expressionLengthPtr--;
3699 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
3702 protected void consumeSingleTypeImportDeclaration() {
3703 // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
3705 ImportReference impt = (ImportReference) astStack[astPtr];
3706 // flush annotations defined prior to import statements
3707 impt.declarationEnd = endStatementPosition;
3708 impt.declarationSourceEnd =
3709 this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
3712 if (currentElement != null) {
3713 lastCheckPoint = impt.declarationSourceEnd + 1;
3714 currentElement = currentElement.add(impt, 0);
3715 lastIgnoredToken = -1;
3716 restartRecovery = true;
3717 // used to avoid branching back into the regular automaton
3720 protected void consumeSingleTypeImportDeclarationName() {
3721 // SingleTypeImportDeclarationName ::= 'import' Name
3722 /* push an ImportRef build from the last name
3723 stored in the identifier stack. */
3725 ImportReference impt;
3727 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
3728 identifierPtr -= length;
3729 long[] positions = new long[length];
3730 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
3731 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
3732 pushOnAstStack(impt = new ImportReference(tokens, positions, false));
3734 if (currentToken == TokenNameSEMICOLON){
3735 impt.declarationSourceEnd = scanner.currentPosition - 1;
3737 impt.declarationSourceEnd = impt.sourceEnd;
3739 impt.declarationEnd = impt.declarationSourceEnd;
3740 //endPosition is just before the ;
3741 impt.declarationSourceStart = intStack[intPtr--];
3744 if (currentElement != null){
3745 lastCheckPoint = impt.declarationSourceEnd+1;
3746 currentElement = currentElement.add(impt, 0);
3747 lastIgnoredToken = -1;
3748 restartRecovery = true; // used to avoid branching back into the regular automaton
3751 protected void consumeStatementBreak() {
3752 // BreakStatement ::= 'break' ';'
3753 // break pushs a position on intStack in case there is no label
3755 pushOnAstStack(new Break(null, intStack[intPtr--], endPosition));
3757 protected void consumeStatementBreakWithLabel() {
3758 // BreakStatement ::= 'break' Identifier ';'
3759 // break pushs a position on intStack in case there is no label
3763 identifierStack[identifierPtr--],
3766 identifierLengthPtr--;
3768 protected void consumeStatementCatch() {
3769 // CatchClause ::= 'catch' '(' FormalParameter ')' Block
3771 //catch are stored directly into the Try
3772 //has they always comes two by two....
3773 //we remove one entry from the astlengthPtr.
3774 //The construction of the try statement must
3775 //then fetch the catches using 2*i and 2*i + 1
3778 listLength = 0; // reset formalParameter counter (incremented for catch variable)
3780 protected void consumeStatementContinue() {
3781 // ContinueStatement ::= 'continue' ';'
3782 // continue pushs a position on intStack in case there is no label
3790 protected void consumeStatementContinueWithLabel() {
3791 // ContinueStatement ::= 'continue' Identifier ';'
3792 // continue pushs a position on intStack in case there is no label
3796 identifierStack[identifierPtr--],
3799 identifierLengthPtr--;
3801 protected void consumeStatementDo() {
3802 // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
3804 //the 'while' pushes a value on intStack that we need to remove
3807 //optimize the push/pop
3808 Statement action = (Statement) astStack[astPtr];
3809 if (action instanceof EmptyStatement
3810 && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
3811 expressionLengthPtr--;
3814 expressionStack[expressionPtr--],
3819 expressionLengthPtr--;
3822 expressionStack[expressionPtr--],
3828 protected void consumeStatementExpressionList() {
3829 // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
3830 concatExpressionLists();
3832 protected void consumeStatementFor() {
3833 // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
3834 // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
3837 Expression cond = null;
3838 Statement[] inits, updates;
3840 boolean scope = true;
3843 astLengthPtr--; // we need to consume it
3844 action = (Statement) astStack[astPtr--];
3845 if (action instanceof EmptyStatement
3846 && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
3850 //updates are on the expresion stack
3851 if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) {
3854 expressionPtr -= length;
3858 updates = new Statement[length],
3863 if (expressionLengthStack[expressionLengthPtr--] != 0)
3864 cond = expressionStack[expressionPtr--];
3866 //inits may be on two different stacks
3867 if ((length = astLengthStack[astLengthPtr--]) == 0) {
3871 if (length == -1) { //on expressionStack
3873 length = expressionLengthStack[expressionLengthPtr--];
3874 expressionPtr -= length;
3878 inits = new Statement[length],
3881 } else { //on astStack
3886 inits = new Statement[length],
3891 if (action instanceof Block) {
3900 endStatementPosition));
3913 protected void consumeStatementIfNoElse() {
3914 // IfThenStatement ::= 'if' '(' Expression ')' Statement
3916 //optimize the push/pop
3917 expressionLengthPtr--;
3918 Statement thenStatement = (Statement) astStack[astPtr];
3919 if (thenStatement instanceof Block) {
3922 expressionStack[expressionPtr--],
3925 endStatementPosition);
3926 } else if (thenStatement instanceof EmptyStatement) {
3929 expressionStack[expressionPtr--],
3932 endStatementPosition);
3936 expressionStack[expressionPtr--],
3939 endStatementPosition);
3942 protected void consumeStatementIfWithElse() {
3943 // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
3944 // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
3946 astLengthPtr--; // optimized {..., Then, Else } ==> {..., If }
3947 expressionLengthPtr--;
3948 //optimize the push/pop
3949 Statement elseStatement = (Statement) astStack[astPtr--];
3950 Statement thenStatement = (Statement) astStack[astPtr];
3951 if (elseStatement instanceof EmptyStatement) {
3952 elseStatement = Block.None;
3954 if (thenStatement instanceof EmptyStatement) {
3955 thenStatement = Block.None;
3957 if (elseStatement instanceof Block) {
3960 expressionStack[expressionPtr--],
3964 endStatementPosition);
3968 expressionStack[expressionPtr--],
3972 endStatementPosition);
3975 protected void consumeStatementLabel() {
3976 // LabeledStatement ::= 'Identifier' ':' Statement
3977 // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
3981 Statement stmt = (Statement) astStack[astPtr];
3982 if (stmt instanceof EmptyStatement) {
3984 new LabeledStatement(
3985 identifierStack[identifierPtr],
3987 (int) (identifierPositionStack[identifierPtr--] >>> 32),
3988 endStatementPosition);
3991 new LabeledStatement(
3992 identifierStack[identifierPtr],
3994 (int) (identifierPositionStack[identifierPtr--] >>> 32),
3995 endStatementPosition);
3997 identifierLengthPtr--;
3999 protected void consumeStatementReturn() {
4000 // ReturnStatement ::= 'return' Expressionopt ';'
4001 // return pushs a position on intStack in case there is no expression
4003 if (expressionLengthStack[expressionLengthPtr--] != 0) {
4005 new ReturnStatement(
4006 expressionStack[expressionPtr--],
4011 pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition));
4014 protected void consumeStatementSwitch() {
4015 // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
4017 //OpenBlock just makes the semantic action blockStart()
4018 //the block is inlined but a scope need to be created
4019 //if some declaration occurs.
4022 SwitchStatement s = new SwitchStatement();
4023 expressionLengthPtr--;
4024 s.testExpression = expressionStack[expressionPtr--];
4025 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4030 s.statements = new Statement[length],
4034 s.explicitDeclarations = realBlockStack[realBlockPtr--];
4036 intPtr--; // because of OpenBlock
4037 s.sourceStart = intStack[intPtr--];
4038 s.sourceEnd = endStatementPosition;
4040 protected void consumeStatementSynchronized() {
4041 // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
4042 //optimize the push/pop
4044 if (astLengthStack[astLengthPtr] == 0) {
4045 astLengthStack[astLengthPtr] = 1;
4046 expressionLengthPtr--;
4047 astStack[++astPtr] =
4048 new SynchronizedStatement(
4049 expressionStack[expressionPtr--],
4052 endStatementPosition);
4054 expressionLengthPtr--;
4056 new SynchronizedStatement(
4057 expressionStack[expressionPtr--],
4058 (Block) astStack[astPtr],
4060 endStatementPosition);
4064 protected void consumeStatementThrow() {
4065 // ThrowStatement ::= 'throw' Expression ';'
4066 expressionLengthPtr--;
4067 pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4069 protected void consumeStatementTry(boolean withFinally) {
4070 //TryStatement ::= 'try' Block Catches
4071 //TryStatement ::= 'try' Block Catchesopt Finally
4074 TryStatement tryStmt = new TryStatement();
4078 tryStmt.finallyBlock = (Block) astStack[astPtr--];
4080 //catches are handle by two <argument-block> [see statementCatch]
4081 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4083 tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--]};
4084 tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--]};
4086 Block[] bks = (tryStmt.catchBlocks = new Block[length]);
4087 Argument[] args = (tryStmt.catchArguments = new Argument[length]);
4088 while (length-- > 0) {
4089 bks[length] = (Block) astStack[astPtr--];
4090 args[length] = (Argument) astStack[astPtr--];
4096 tryStmt.tryBlock = (Block) astStack[astPtr--];
4099 tryStmt.sourceEnd = endStatementPosition;
4100 tryStmt.sourceStart = intStack[intPtr--];
4101 pushOnAstStack(tryStmt);
4103 protected void consumeStatementWhile() {
4104 // WhileStatement ::= 'while' '(' Expression ')' Statement
4105 // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
4107 Statement action = (Statement) astStack[astPtr];
4108 expressionLengthPtr--;
4109 if (action instanceof Block) {
4112 expressionStack[expressionPtr--],
4115 endStatementPosition);
4117 if (action instanceof EmptyStatement
4118 && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4121 expressionStack[expressionPtr--],
4128 expressionStack[expressionPtr--],
4135 protected void consumeStaticInitializer() {
4136 // StaticInitializer ::= StaticOnly Block
4137 //push an Initializer
4138 //optimize the push/pop
4139 Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic);
4140 astStack[astPtr] = initializer;
4141 initializer.sourceEnd = endStatementPosition;
4142 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
4143 nestedMethod[nestedType] --;
4144 initializer.declarationSourceStart = intStack[intPtr--];
4147 if (currentElement != null){
4148 lastCheckPoint = initializer.declarationSourceEnd;
4149 currentElement = currentElement.add(initializer, 0);
4150 lastIgnoredToken = -1;
4153 protected void consumeStaticOnly() {
4154 // StaticOnly ::= 'static'
4155 int savedModifiersSourceStart = modifiersSourceStart;
4156 checkAnnotation(); // might update declaration source start
4157 if (modifiersSourceStart >= savedModifiersSourceStart) {
4158 modifiersSourceStart = savedModifiersSourceStart;
4161 modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
4162 jumpOverMethodBody();
4163 nestedMethod[nestedType]++;
4167 if (currentElement != null){
4168 recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers
4171 protected void consumeSwitchBlock() {
4172 // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
4175 protected void consumeSwitchBlockStatement() {
4176 // SwitchBlockStatement ::= SwitchLabels BlockStatements
4179 protected void consumeSwitchBlockStatements() {
4180 // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
4183 protected void consumeSwitchLabels() {
4184 // SwitchLabels ::= SwitchLabels SwitchLabel
4185 optimizedConcatNodeLists();
4187 protected void consumeToken(int type) {
4188 /* remember the last consumed value */
4189 /* try to minimize the number of build values */
4190 if (scanner.wasNonExternalizedStringLiteral) {
4191 StringLiteral[] literals = this.scanner.nonNLSStrings;
4192 // could not reproduce, but this is the only NPE
4193 // added preventive null check see PR 9035
4194 if (literals != null) {
4195 for (int i = 0, max = literals.length; i < max; i++) {
4196 problemReporter().nonExternalizedStringLiteral(literals[i]);
4199 scanner.currentLine = null;
4200 scanner.wasNonExternalizedStringLiteral = false;
4202 // clear the commentPtr of the scanner in case we read something different from a modifier
4204 // case TokenNameabstract :
4205 // case TokenNamestrictfp :
4206 // case TokenNamefinal :
4207 // case TokenNamenative :
4208 // case TokenNameprivate :
4209 // case TokenNameprotected :
4210 // case TokenNamepublic :
4211 // case TokenNametransient :
4212 // case TokenNamevolatile :
4213 case TokenNamestatic :
4214 // case TokenNamesynchronized :
4217 scanner.commentPtr = -1;
4219 //System.out.println(scanner.toStringAction(type));
4221 case TokenNameIdentifier :
4223 if (scanner.useAssertAsAnIndentifier) {
4224 long positions = identifierPositionStack[identifierPtr];
4225 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
4227 scanner.commentPtr = -1;
4229 // case TokenNameinterface :
4230 // adjustInterfaceModifiers();
4231 // //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
4232 // pushOnIntStack(scanner.startPosition);
4233 // pushOnIntStack(scanner.currentPosition - 1);
4234 // scanner.commentPtr = -1;
4236 // case TokenNameabstract :
4237 // checkAndSetModifiers(AccAbstract);
4239 // case TokenNamestrictfp :
4240 // checkAndSetModifiers(AccStrictfp);
4242 // case TokenNamefinal :
4243 // checkAndSetModifiers(AccFinal);
4245 // case TokenNamenative :
4246 // checkAndSetModifiers(AccNative);
4248 // case TokenNameprivate :
4249 // checkAndSetModifiers(AccPrivate);
4251 // case TokenNameprotected :
4252 // checkAndSetModifiers(AccProtected);
4254 // case TokenNamepublic :
4255 // checkAndSetModifiers(AccPublic);
4257 // case TokenNametransient :
4258 // checkAndSetModifiers(AccTransient);
4260 // case TokenNamevolatile :
4261 // checkAndSetModifiers(AccVolatile);
4263 case TokenNamestatic :
4264 checkAndSetModifiers(AccStatic);
4266 // case TokenNamesynchronized :
4267 // this.synchronizedBlockSourceStart = scanner.startPosition;
4268 // checkAndSetModifiers(AccSynchronized);
4270 // //==============================
4271 // case TokenNamevoid :
4272 // pushIdentifier(-T_void);
4273 // pushOnIntStack(scanner.currentPosition - 1);
4274 // pushOnIntStack(scanner.startPosition);
4275 // scanner.commentPtr = -1;
4277 // //push a default dimension while void is not part of the primitive
4278 // //declaration baseType and so takes the place of a type without getting into
4279 // //regular type parsing that generates a dimension on intStack
4280 // case TokenNameboolean :
4281 // pushIdentifier(-T_boolean);
4282 // pushOnIntStack(scanner.currentPosition - 1);
4283 // pushOnIntStack(scanner.startPosition);
4284 // scanner.commentPtr = -1;
4286 // case TokenNamebyte :
4287 // pushIdentifier(-T_byte);
4288 // pushOnIntStack(scanner.currentPosition - 1);
4289 // pushOnIntStack(scanner.startPosition);
4290 // scanner.commentPtr = -1;
4292 // case TokenNamechar :
4293 // pushIdentifier(-T_char);
4294 // pushOnIntStack(scanner.currentPosition - 1);
4295 // pushOnIntStack(scanner.startPosition);
4296 // scanner.commentPtr = -1;
4298 // case TokenNamedouble :
4299 // pushIdentifier(-T_double);
4300 // pushOnIntStack(scanner.currentPosition - 1);
4301 // pushOnIntStack(scanner.startPosition);
4302 // scanner.commentPtr = -1;
4304 // case TokenNamefloat :
4305 // pushIdentifier(-T_float);
4306 // pushOnIntStack(scanner.currentPosition - 1);
4307 // pushOnIntStack(scanner.startPosition);
4308 // scanner.commentPtr = -1;
4310 // case TokenNameint :
4311 // pushIdentifier(-T_int);
4312 // pushOnIntStack(scanner.currentPosition - 1);
4313 // pushOnIntStack(scanner.startPosition);
4314 // scanner.commentPtr = -1;
4316 // case TokenNamelong :
4317 // pushIdentifier(-T_long);
4318 // pushOnIntStack(scanner.currentPosition - 1);
4319 // pushOnIntStack(scanner.startPosition);
4320 // scanner.commentPtr = -1;
4322 // case TokenNameshort :
4323 // pushIdentifier(-T_short);
4324 // pushOnIntStack(scanner.currentPosition - 1);
4325 // pushOnIntStack(scanner.startPosition);
4326 // scanner.commentPtr = -1;
4328 //==============================
4329 case TokenNameIntegerLiteral :
4330 pushOnExpressionStack(
4332 scanner.getCurrentTokenSource(),
4333 scanner.startPosition,
4334 scanner.currentPosition - 1));
4335 scanner.commentPtr = -1;
4337 case TokenNameLongLiteral :
4338 pushOnExpressionStack(
4340 scanner.getCurrentTokenSource(),
4341 scanner.startPosition,
4342 scanner.currentPosition - 1));
4343 scanner.commentPtr = -1;
4345 case TokenNameFloatingPointLiteral :
4346 pushOnExpressionStack(
4348 scanner.getCurrentTokenSource(),
4349 scanner.startPosition,
4350 scanner.currentPosition - 1));
4351 scanner.commentPtr = -1;
4353 case TokenNameDoubleLiteral :
4354 pushOnExpressionStack(
4356 scanner.getCurrentTokenSource(),
4357 scanner.startPosition,
4358 scanner.currentPosition - 1));
4359 scanner.commentPtr = -1;
4361 case TokenNameCharacterLiteral :
4362 pushOnExpressionStack(
4364 scanner.getCurrentTokenSource(),
4365 scanner.startPosition,
4366 scanner.currentPosition - 1));
4367 scanner.commentPtr = -1;
4369 case TokenNameStringLiteral :
4370 StringLiteral stringLiteral = new StringLiteral(
4371 scanner.getCurrentTokenSourceString(),
4372 scanner.startPosition,
4373 scanner.currentPosition - 1);
4374 pushOnExpressionStack(stringLiteral);
4375 scanner.commentPtr = -1;
4377 case TokenNamefalse :
4378 pushOnExpressionStack(
4379 new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1));
4380 scanner.commentPtr = -1;
4382 case TokenNametrue :
4383 pushOnExpressionStack(
4384 new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1));
4386 case TokenNamenull :
4387 pushOnExpressionStack(
4388 new NullLiteral(scanner.startPosition, scanner.currentPosition - 1));
4390 //============================
4391 // case TokenNamesuper :
4392 // case TokenNamethis :
4393 // endPosition = scanner.currentPosition - 1;
4394 // pushOnIntStack(scanner.startPosition);
4396 // case TokenNameassert :
4397 // case TokenNameimport :
4398 // case TokenNamepackage :
4399 // case TokenNamethrow :
4404 case TokenNameswitch :
4405 // case TokenNametry :
4406 case TokenNamewhile :
4407 case TokenNamebreak :
4408 case TokenNamecontinue :
4409 case TokenNamereturn :
4410 case TokenNamecase :
4411 pushOnIntStack(scanner.startPosition);
4413 case TokenNameclass :
4414 pushOnIntStack(scanner.currentPosition - 1);
4415 pushOnIntStack(scanner.startPosition);
4417 case TokenNamedefault :
4418 pushOnIntStack(scanner.startPosition);
4419 pushOnIntStack(scanner.currentPosition - 1);
4421 //let extra semantic action decide when to push
4422 case TokenNameRBRACKET :
4423 case TokenNamePLUS :
4424 case TokenNameMINUS :
4426 case TokenNameTWIDDLE :
4427 endPosition = scanner.startPosition;
4429 case TokenNamePLUS_PLUS :
4430 case TokenNameMINUS_MINUS :
4431 endPosition = scanner.startPosition;
4432 endStatementPosition = scanner.currentPosition - 1;
4434 case TokenNameRBRACE:
4435 case TokenNameSEMICOLON :
4436 endStatementPosition = scanner.currentPosition - 1;
4437 endPosition = scanner.startPosition - 1;
4438 //the item is not part of the potential futur expression/statement
4440 // in order to handle ( expression) ////// (cast)expression///// foo(x)
4441 case TokenNameRPAREN :
4442 rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4444 case TokenNameLPAREN :
4445 lParenPos = scanner.startPosition;
4447 // case TokenNameQUESTION :
4448 // case TokenNameCOMMA :
4449 // case TokenNameCOLON :
4450 // case TokenNameEQUAL :
4451 // case TokenNameLBRACKET :
4452 // case TokenNameDOT :
4453 // case TokenNameERROR :
4454 // case TokenNameEOF :
4455 // case TokenNamecase :
4456 // case TokenNamecatch :
4457 // case TokenNameelse :
4458 // case TokenNameextends :
4459 // case TokenNamefinally :
4460 // case TokenNameimplements :
4461 // case TokenNamethrows :
4462 // case TokenNameinstanceof :
4463 // case TokenNameEQUAL_EQUAL :
4464 // case TokenNameLESS_EQUAL :
4465 // case TokenNameGREATER_EQUAL :
4466 // case TokenNameNOT_EQUAL :
4467 // case TokenNameLEFT_SHIFT :
4468 // case TokenNameRIGHT_SHIFT :
4469 // case TokenNameUNSIGNED_RIGHT_SHIFT :
4470 // case TokenNamePLUS_EQUAL :
4471 // case TokenNameMINUS_EQUAL :
4472 // case TokenNameMULTIPLY_EQUAL :
4473 // case TokenNameDIVIDE_EQUAL :
4474 // case TokenNameAND_EQUAL :
4475 // case TokenNameOR_EQUAL :
4476 // case TokenNameXOR_EQUAL :
4477 // case TokenNameREMAINDER_EQUAL :
4478 // case TokenNameLEFT_SHIFT_EQUAL :
4479 // case TokenNameRIGHT_SHIFT_EQUAL :
4480 // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
4481 // case TokenNameOR_OR :
4482 // case TokenNameAND_AND :
4483 // case TokenNameREMAINDER :
4484 // case TokenNameXOR :
4485 // case TokenNameAND :
4486 // case TokenNameMULTIPLY :
4487 // case TokenNameOR :
4488 // case TokenNameDIVIDE :
4489 // case TokenNameGREATER :
4490 // case TokenNameLESS :
4493 protected void consumeTypeDeclarations() {
4494 // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4497 protected void consumeTypeDeclarationsopt() {
4498 // TypeDeclarationsopt ::= TypeDeclarations
4500 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4502 System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length);
4505 protected void consumeTypeImportOnDemandDeclaration() {
4506 // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4508 ImportReference impt = (ImportReference) astStack[astPtr];
4509 // flush annotations defined prior to import statements
4510 impt.declarationEnd = endStatementPosition;
4511 impt.declarationSourceEnd =
4512 this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
4515 if (currentElement != null) {
4516 lastCheckPoint = impt.declarationSourceEnd + 1;
4517 currentElement = currentElement.add(impt, 0);
4518 restartRecovery = true;
4519 lastIgnoredToken = -1;
4520 // used to avoid branching back into the regular automaton
4523 protected void consumeTypeImportOnDemandDeclarationName() {
4524 // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4525 /* push an ImportRef build from the last name
4526 stored in the identifier stack. */
4528 ImportReference impt;
4530 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4531 identifierPtr -= length;
4532 long[] positions = new long[length];
4533 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4534 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4535 pushOnAstStack(impt = new ImportReference(tokens, positions, true));
4537 if (currentToken == TokenNameSEMICOLON){
4538 impt.declarationSourceEnd = scanner.currentPosition - 1;
4540 impt.declarationSourceEnd = impt.sourceEnd;
4542 impt.declarationEnd = impt.declarationSourceEnd;
4543 //endPosition is just before the ;
4544 impt.declarationSourceStart = intStack[intPtr--];
4547 if (currentElement != null){
4548 lastCheckPoint = impt.declarationSourceEnd+1;
4549 currentElement = currentElement.add(impt, 0);
4550 lastIgnoredToken = -1;
4551 restartRecovery = true; // used to avoid branching back into the regular automaton
4554 protected void consumeUnaryExpression(int op) {
4555 // UnaryExpression ::= '+' PushPosition UnaryExpression
4556 // UnaryExpression ::= '-' PushPosition UnaryExpression
4557 // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4558 // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4560 //optimize the push/pop
4562 //handle manually the -2147483648 while it is not a real
4563 //computation of an - and 2147483648 (notice that 2147483648
4564 //is Integer.MAX_VALUE+1.....)
4565 //Same for -9223372036854775808L ............
4567 //intStack have the position of the operator
4569 Expression r, exp = expressionStack[expressionPtr];
4571 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4572 r = expressionStack[expressionPtr] = new IntLiteralMinValue();
4574 if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4575 r = expressionStack[expressionPtr] = new LongLiteralMinValue();
4577 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4581 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4583 r.sourceStart = intStack[intPtr--];
4584 r.sourceEnd = exp.sourceEnd;
4586 protected void consumeUnaryExpression(int op, boolean post) {
4587 // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4588 // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4590 // ++ and -- operators
4591 //optimize the push/pop
4593 //intStack has the position of the operator when prefix
4595 Expression leftHandSide = expressionStack[expressionPtr];
4596 if (leftHandSide instanceof Reference) {
4597 // ++foo()++ is unvalid
4599 expressionStack[expressionPtr] =
4600 new PostfixExpression(
4604 endStatementPosition);
4606 expressionStack[expressionPtr] =
4607 new PrefixExpression(
4611 intStack[intPtr--]);
4614 //the ++ or the -- is NOT taken into account if code gen proceeds
4618 problemReporter().invalidUnaryExpression(leftHandSide);
4621 protected void consumeVariableDeclarators() {
4622 // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4623 optimizedConcatNodeLists();
4625 protected void consumeVariableInitializers() {
4626 // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4627 concatExpressionLists();
4629 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4630 return typeRef.copyDims(dim);
4632 protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4633 return new FieldDeclaration(null, name, sourceStart, sourceEnd);
4636 protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4637 return new LocalDeclaration(null, name, sourceStart, sourceEnd);
4640 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4642 CompilationUnitDeclaration parsedUnit;
4646 parsedUnit = parse(sourceUnit, compilationResult);
4653 protected void dispatchDeclarationInto(int length) {
4654 /* they are length on astStack that should go into
4655 methods fields constructors lists of the typeDecl
4657 Return if there is a constructor declaration in the methods declaration */
4660 // Looks for the size of each array .
4664 int[] flag = new int[length + 1]; //plus one -- see <HERE>
4665 int size1 = 0, size2 = 0, size3 = 0;
4666 for (int i = length - 1; i >= 0; i--) {
4667 AstNode astNode = astStack[astPtr--];
4668 if (astNode instanceof AbstractMethodDeclaration) {
4669 //methods and constructors have been regrouped into one single list
4673 if (astNode instanceof TypeDeclaration) {
4685 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
4687 typeDecl.fields = new FieldDeclaration[size1];
4689 typeDecl.methods = new AbstractMethodDeclaration[size2];
4691 typeDecl.memberTypes = new MemberTypeDeclaration[size3];
4694 size1 = size2 = size3 = 0;
4695 int flagI = flag[0], start = 0;
4697 for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
4699 if (flagI != flag[end]) //treat the last element as a ended flag.....
4703 size1 += (length2 = end - start);
4712 size2 += (length2 = end - start);
4721 size3 += (length2 = end - start);
4725 typeDecl.memberTypes,
4730 flagI = flag[start = end];
4734 if (typeDecl.memberTypes != null) {
4735 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4736 typeDecl.memberTypes[i].enclosingType = typeDecl;
4740 protected CompilationUnitDeclaration endParse(int act) {
4744 if (currentElement != null){
4745 currentElement.topElement().updateParseTree();
4746 if (VERBOSE_RECOVERY){
4747 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4748 System.out.println("--------------------------"); //$NON-NLS-1$
4749 System.out.println(compilationUnit);
4750 System.out.println("----------------------------------"); //$NON-NLS-1$
4753 if (diet & VERBOSE_RECOVERY){
4754 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
4755 System.out.println("--------------------------"); //$NON-NLS-1$
4756 System.out.println(compilationUnit);
4757 System.out.println("----------------------------------"); //$NON-NLS-1$
4760 if (scanner.recordLineSeparator) {
4761 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
4763 return compilationUnit;
4766 * Flush annotations defined prior to a given positions.
4768 * Note: annotations are stacked in syntactical order
4770 * Either answer given <position>, or the end position of a comment line
4771 * immediately following the <position> (same line)
4775 * } // end of method foo
4778 public int flushAnnotationsDefinedPriorTo(int position) {
4780 int lastAnnotationIndex = scanner.commentPtr;
4781 if (lastAnnotationIndex < 0) return position; // no comment
4783 // compute the index of the first obsolete comment
4784 int index = lastAnnotationIndex;
4787 int commentEnd = scanner.commentStops[index];
4788 if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
4789 if (commentEnd <= position){
4795 // if the source at <position> is immediately followed by a line comment, then
4796 // flush this comment and shift <position> to the comment end.
4797 if (validCount > 0){
4798 int immediateCommentEnd = -scanner.commentStops[index+1]; //non-javadoc comment end positions are negative
4799 if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments
4800 // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
4801 immediateCommentEnd--; // comment end in one char too far
4802 if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)){
4803 position = immediateCommentEnd;
4804 validCount--; // flush this comment
4809 // position can be located in the middle of a line break
4810 // this is a bug on Windows platform only.
4811 // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557
4812 char[] source = scanner.source;
4814 if ((position < source.length)
4815 && (source[position] == '\r')
4816 && ((position + 1) < source.length)
4817 && (source[position + 1] == '\n')) {
4820 if (index < 0) return position; // no obsolete comment
4822 if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
4823 System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount);
4824 System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount);
4826 scanner.commentPtr = validCount - 1;
4829 public final int getFirstToken() {
4830 // the first token is a virtual token that
4831 // allows the parser to parse several goals
4832 // even if they aren't LALR(1)....
4833 // Goal ::= '++' CompilationUnit
4834 // Goal ::= '--' MethodBody
4835 // Goal ::= '==' ConstructorBody
4837 // Goal ::= '>>' StaticInitializer
4838 // Goal ::= '>>' Block
4839 // -- error recovery
4840 // Goal ::= '>>>' Headers
4841 // Goal ::= '*' BlockStatements
4842 // Goal ::= '*' MethodPushModifiersHeader
4844 // Goal ::= '&&' FieldDeclaration
4845 // Goal ::= '||' ImportDeclaration
4846 // Goal ::= '?' PackageDeclaration
4847 // Goal ::= '+' TypeDeclaration
4848 // Goal ::= '/' GenericMethodDeclaration
4849 // Goal ::= '&' ClassBodyDeclaration
4851 // Goal ::= '%' Expression
4852 // -- completion parser
4853 // Goal ::= '!' ConstructorBlockStatementsopt
4854 // Goal ::= '~' BlockStatementsopt
4859 * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
4860 * The array is a flattened structure: 2*n entries with consecutives start and end positions.
4862 * If no JavaDoc is available, then null is answered instead of an empty array.
4864 * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
4866 public int[] getJavaDocPositions() {
4868 int javadocCount = 0;
4869 for (int i = 0, max = scanner.commentPtr; i <= max; i++){
4870 // javadoc only (non javadoc comment have negative end positions.)
4871 if (scanner.commentStops[i] > 0){
4875 if (javadocCount == 0) return null;
4877 int[] positions = new int[2*javadocCount];
4879 for (int i = 0, max = scanner.commentPtr; i <= max; i++){
4880 // javadoc only (non javadoc comment have negative end positions.)
4881 if (scanner.commentStops[i] > 0){
4882 positions[index++] = scanner.commentStarts[i];
4883 positions[index++] = scanner.commentStops[i]-1; //stop is one over
4888 protected void getMethodBodies(CompilationUnitDeclaration unit) {
4889 //fill the methods bodies in order for the code to be generated
4891 if (unit == null) return;
4893 if (unit.ignoreMethodBodies) {
4894 unit.ignoreFurtherInvestigation = true;
4896 // if initial diet parse did not work, no need to dig into method bodies.
4899 //real parse of the method....
4900 this.scanner.setSource(
4901 unit.compilationResult.compilationUnit.getContents());
4902 if (unit.types != null) {
4903 for (int i = unit.types.length; --i >= 0;)
4904 unit.types[i].parseMethod(this, unit);
4907 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
4908 This variable is a type reference and dim will be its dimensions*/
4912 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
4913 // single variable reference
4916 new SingleTypeReference(
4917 identifierStack[identifierPtr],
4918 identifierPositionStack[identifierPtr--]);
4921 new ArrayTypeReference(
4922 identifierStack[identifierPtr],
4924 identifierPositionStack[identifierPtr--]);
4925 ref.sourceEnd = endPosition;
4928 if (length < 0) { //flag for precompiled type reference on base types
4929 ref = TypeReference.baseTypeReference(-length, dim);
4930 ref.sourceStart = intStack[intPtr--];
4932 ref.sourceEnd = intStack[intPtr--];
4935 ref.sourceEnd = endPosition;
4937 } else { //Qualified variable reference
4938 char[][] tokens = new char[length][];
4939 identifierPtr -= length;
4940 long[] positions = new long[length];
4941 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4943 identifierPositionStack,
4949 ref = new QualifiedTypeReference(tokens, positions);
4951 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
4952 ref.sourceEnd = endPosition;
4958 protected Expression getTypeReference(Expression exp) {
4960 exp.bits &= ~AstNode.RestrictiveFlagMASK;
4964 protected NameReference getUnspecifiedReference() {
4965 /* build a (unspecified) NameReference which may be qualified*/
4969 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1)
4970 // single variable reference
4972 new SingleNameReference(
4973 identifierStack[identifierPtr],
4974 identifierPositionStack[identifierPtr--]);
4976 //Qualified variable reference
4978 char[][] tokens = new char[length][];
4979 identifierPtr -= length;
4980 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4982 new QualifiedNameReference(tokens,
4983 (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
4984 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
4988 protected NameReference getUnspecifiedReferenceOptimized() {
4989 /* build a (unspecified) NameReference which may be qualified
4990 The optimization occurs for qualified reference while we are
4991 certain in this case the last item of the qualified name is
4992 a field access. This optimization is IMPORTANT while it results
4993 that when a NameReference is build, the type checker should always
4994 look for that it is not a type reference */
4998 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
4999 // single variable reference
5001 new SingleNameReference(
5002 identifierStack[identifierPtr],
5003 identifierPositionStack[identifierPtr--]);
5004 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5005 ref.bits |= LOCAL | FIELD;
5009 //Qualified-variable-reference
5010 //In fact it is variable-reference DOT field-ref , but it would result in a type
5011 //conflict tha can be only reduce by making a superclass (or inetrface ) between
5012 //nameReference and FiledReference or putting FieldReference under NameReference
5013 //or else..........This optimisation is not really relevant so just leave as it is
5015 char[][] tokens = new char[length][];
5016 identifierPtr -= length;
5017 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5018 ref = new QualifiedNameReference(
5020 (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5021 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5022 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5023 ref.bits |= LOCAL | FIELD;
5026 public void goForBlockStatementsOrMethodHeaders() {
5027 //tells the scanner to go for block statements or method headers parsing
5029 firstToken = TokenNameMULTIPLY;
5030 scanner.recordLineSeparator = false;
5032 public void goForClassBodyDeclarations() {
5033 //tells the scanner to go for any body declarations parsing
5035 firstToken = TokenNameAND;
5036 scanner.recordLineSeparator = true;
5038 public void goForCompilationUnit(){
5039 //tells the scanner to go for compilation unit parsing
5041 firstToken = TokenNamePLUS_PLUS ;
5042 scanner.linePtr = -1;
5043 scanner.recordLineSeparator = true;
5044 scanner.currentLine= null;
5045 scanner.lines= new ArrayList();
5047 public void goForConstructorBody(){
5048 //tells the scanner to go for compilation unit parsing
5050 firstToken = TokenNameEQUAL_EQUAL ;
5051 scanner.recordLineSeparator = false;
5053 public void goForExpression() {
5054 //tells the scanner to go for an expression parsing
5056 firstToken = TokenNameREMAINDER;
5057 scanner.recordLineSeparator = false;
5059 public void goForFieldDeclaration(){
5060 //tells the scanner to go for field declaration parsing
5062 firstToken = TokenNameAND_AND ;
5063 scanner.recordLineSeparator = true;
5065 public void goForGenericMethodDeclaration(){
5066 //tells the scanner to go for generic method declarations parsing
5068 firstToken = TokenNameDIVIDE;
5069 scanner.recordLineSeparator = true;
5071 public void goForHeaders(){
5072 //tells the scanner to go for headers only parsing
5074 firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
5075 scanner.recordLineSeparator = true;
5077 public void goForImportDeclaration(){
5078 //tells the scanner to go for import declaration parsing
5080 firstToken = TokenNameOR_OR ;
5081 scanner.recordLineSeparator = true;
5083 public void goForInitializer(){
5084 //tells the scanner to go for initializer parsing
5086 firstToken = TokenNameRIGHT_SHIFT ;
5087 scanner.recordLineSeparator = false;
5089 public void goForMethodBody(){
5090 //tells the scanner to go for method body parsing
5092 firstToken = TokenNameMINUS_MINUS ;
5093 scanner.recordLineSeparator = false;
5095 public void goForPackageDeclaration() {
5096 //tells the scanner to go for package declaration parsing
5098 firstToken = TokenNameQUESTION;
5099 scanner.recordLineSeparator = true;
5101 public void goForTypeDeclaration() {
5102 //tells the scanner to go for type (interface or class) declaration parsing
5104 firstToken = TokenNamePLUS;
5105 scanner.recordLineSeparator = true;
5107 public final static void grammar(){
5110 %options ACTION, AN=JavaAction.java, GP=java,
5111 %options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
5112 %options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME ,
5114 --error recovering options.....
5117 --grammar understanding options
5118 %options first follow
5119 %options TRACE=FULL ,
5122 --Usefull macros helping reading/writing semantic actions
5125 /. case $rule_number : // System.out.println("$rule_text");
5133 -- here it starts really ------------------------------------------
5138 abstract assert boolean break byte case catch char class
5139 continue default do double else extends false final finally float
5140 for if implements import instanceof int
5141 interface long native new null package private
5142 protected public return short static strictfp super switch
5143 synchronized this throw throws transient true try void
5148 FloatingPointLiteral
5161 UNSIGNED_RIGHT_SHIFT
5172 UNSIGNED_RIGHT_SHIFT_EQUAL
5205 '--' ::= MINUS_MINUS
5206 '==' ::= EQUAL_EQUAL
5208 '>=' ::= GREATER_EQUAL
5211 '>>' ::= RIGHT_SHIFT
5212 '>>>' ::= UNSIGNED_RIGHT_SHIFT
5214 '-=' ::= MINUS_EQUAL
5215 '*=' ::= MULTIPLY_EQUAL
5216 '/=' ::= DIVIDE_EQUAL
5220 '%=' ::= REMAINDER_EQUAL
5221 '<<=' ::= LEFT_SHIFT_EQUAL
5222 '>>=' ::= RIGHT_SHIFT_EQUAL
5223 '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
5257 /. // This method is part of an automatic generation : do NOT edit-modify
5258 protected void consumeRule(int act) {
5264 Goal ::= '++' CompilationUnit
5265 Goal ::= '--' MethodBody
5266 Goal ::= '==' ConstructorBody
5268 Goal ::= '>>' StaticInitializer
5269 Goal ::= '>>' Initializer
5271 Goal ::= '>>>' Headers
5272 Goal ::= '*' BlockStatements
5273 Goal ::= '*' MethodPushModifiersHeader
5274 Goal ::= '*' CatchHeader
5276 Goal ::= '&&' FieldDeclaration
5277 Goal ::= '||' ImportDeclaration
5278 Goal ::= '?' PackageDeclaration
5279 Goal ::= '+' TypeDeclaration
5280 Goal ::= '/' GenericMethodDeclaration
5281 Goal ::= '&' ClassBodyDeclaration
5283 Goal ::= '%' Expression
5284 -- completion parser
5285 Goal ::= '!' ConstructorBlockStatementsopt
5286 Goal ::= '~' BlockStatementsopt
5288 Literal -> IntegerLiteral
5289 Literal -> LongLiteral
5290 Literal -> FloatingPointLiteral
5291 Literal -> DoubleLiteral
5292 Literal -> CharacterLiteral
5293 Literal -> StringLiteral
5295 Literal -> BooleanLiteral
5296 BooleanLiteral -> true
5297 BooleanLiteral -> false
5299 -------------------------------------------------------------
5300 -------------------------------------------------------------
5301 --a Type results in both a push of its dimension(s) and its name(s).
5303 Type ::= PrimitiveType
5304 /.$putCase consumePrimitiveType(); $break ./
5305 Type -> ReferenceType
5307 PrimitiveType -> NumericType
5308 NumericType -> IntegralType
5309 NumericType -> FloatingPointType
5311 PrimitiveType -> 'boolean'
5312 PrimitiveType -> 'void'
5313 IntegralType -> 'byte'
5314 IntegralType -> 'short'
5315 IntegralType -> 'int'
5316 IntegralType -> 'long'
5317 IntegralType -> 'char'
5318 FloatingPointType -> 'float'
5319 FloatingPointType -> 'double'
5321 ReferenceType ::= ClassOrInterfaceType
5322 /.$putCase consumeReferenceType(); $break ./
5323 ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0
5325 ClassOrInterfaceType -> Name
5328 -- These rules have been rewritten to avoid some conflicts introduced
5329 -- by adding the 1.1 features
5331 -- ArrayType ::= PrimitiveType '[' ']'
5332 -- ArrayType ::= Name '[' ']'
5333 -- ArrayType ::= ArrayType '[' ']'
5336 ArrayType ::= PrimitiveType Dims
5337 ArrayType ::= Name Dims
5339 ClassType -> ClassOrInterfaceType
5342 --------------------------------------------------------------
5343 --------------------------------------------------------------
5346 Name -> QualifiedName
5348 SimpleName -> 'Identifier'
5350 QualifiedName ::= Name '.' SimpleName
5351 /.$putCase consumeQualifiedName(); $break ./
5353 CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
5354 /.$putCase consumeCompilationUnit(); $break ./
5356 EnterCompilationUnit ::= $empty
5357 /.$putCase consumeEnterCompilationUnit(); $break ./
5360 Headers ::= Headers Header
5362 Header -> ImportDeclaration
5363 Header -> PackageDeclaration
5364 Header -> ClassHeader
5365 Header -> InterfaceHeader
5366 Header -> StaticInitializer
5367 Header -> MethodHeader
5368 Header -> ConstructorHeader
5369 Header -> FieldDeclaration
5370 Header -> AllocationHeader
5372 CatchHeader ::= 'catch' '(' FormalParameter ')' '{'
5373 /.$putCase consumeCatchHeader(); $break ./
5375 ImportDeclarations -> ImportDeclaration
5376 ImportDeclarations ::= ImportDeclarations ImportDeclaration
5377 /.$putCase consumeImportDeclarations(); $break ./
5379 TypeDeclarations -> TypeDeclaration
5380 TypeDeclarations ::= TypeDeclarations TypeDeclaration
5381 /.$putCase consumeTypeDeclarations(); $break ./
5383 PackageDeclaration ::= PackageDeclarationName ';'
5384 /.$putCase consumePackageDeclaration(); $break ./
5386 PackageDeclarationName ::= 'package' Name
5387 /.$putCase consumePackageDeclarationName(); $break ./
5389 ImportDeclaration -> SingleTypeImportDeclaration
5390 ImportDeclaration -> TypeImportOnDemandDeclaration
5392 SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
5393 /.$putCase consumeSingleTypeImportDeclaration(); $break ./
5395 SingleTypeImportDeclarationName ::= 'import' Name
5396 /.$putCase consumeSingleTypeImportDeclarationName(); $break ./
5398 TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
5399 /.$putCase consumeTypeImportOnDemandDeclaration(); $break ./
5401 TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
5402 /.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
5404 TypeDeclaration -> ClassDeclaration
5405 TypeDeclaration -> InterfaceDeclaration
5406 -- this declaration in part of a list od declaration and we will
5407 -- use and optimized list length calculation process
5408 -- thus we decrement the number while it will be incremend.....
5409 TypeDeclaration ::= ';'
5410 /. $putCase consumeEmptyTypeDeclaration(); $break ./
5412 --18.7 Only in the LALR(1) Grammar
5414 Modifiers ::= Modifier
5415 Modifiers ::= Modifiers Modifier
5417 Modifier -> 'public'
5418 Modifier -> 'protected'
5419 Modifier -> 'private'
5420 Modifier -> 'static'
5421 Modifier -> 'abstract'
5423 Modifier -> 'native'
5424 Modifier -> 'synchronized'
5425 Modifier -> 'transient'
5426 Modifier -> 'volatile'
5427 Modifier -> 'strictfp'
5429 --18.8 Productions from 8: Class Declarations
5434 --18.8.1 Productions from 8.1: Class Declarations
5436 ClassDeclaration ::= ClassHeader ClassBody
5437 /.$putCase consumeClassDeclaration(); $break ./
5439 ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
5440 /.$putCase consumeClassHeader(); $break ./
5442 ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
5443 /.$putCase consumeClassHeaderName(); $break ./
5445 ClassHeaderExtends ::= 'extends' ClassType
5446 /.$putCase consumeClassHeaderExtends(); $break ./
5448 ClassHeaderImplements ::= 'implements' InterfaceTypeList
5449 /.$putCase consumeClassHeaderImplements(); $break ./
5451 InterfaceTypeList -> InterfaceType
5452 InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
5453 /.$putCase consumeInterfaceTypeList(); $break ./
5455 InterfaceType ::= ClassOrInterfaceType
5456 /.$putCase consumeInterfaceType(); $break ./
5458 ClassBody ::= '{' ClassBodyDeclarationsopt '}'
5460 ClassBodyDeclarations ::= ClassBodyDeclaration
5461 ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
5462 /.$putCase consumeClassBodyDeclarations(); $break ./
5464 ClassBodyDeclaration -> ClassMemberDeclaration
5465 ClassBodyDeclaration -> StaticInitializer
5466 ClassBodyDeclaration -> ConstructorDeclaration
5468 ClassBodyDeclaration ::= Diet NestedMethod Block
5469 /.$putCase consumeClassBodyDeclaration(); $break ./
5471 /.$putCase consumeDiet(); $break./
5473 Initializer ::= Diet NestedMethod Block
5474 /.$putCase consumeClassBodyDeclaration(); $break ./
5476 ClassMemberDeclaration -> FieldDeclaration
5477 ClassMemberDeclaration -> MethodDeclaration
5479 ClassMemberDeclaration -> ClassDeclaration
5481 ClassMemberDeclaration -> InterfaceDeclaration
5483 -- Empty declarations are not valid Java ClassMemberDeclarations.
5484 -- However, since the current (2/14/97) Java compiler accepts them
5485 -- (in fact, some of the official tests contain this erroneous
5488 GenericMethodDeclaration -> MethodDeclaration
5489 GenericMethodDeclaration -> ConstructorDeclaration
5491 ClassMemberDeclaration ::= ';'
5492 /.$putCase consumeEmptyClassMemberDeclaration(); $break./
5494 --18.8.2 Productions from 8.3: Field Declarations
5495 --VariableModifier ::=
5504 FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
5505 /.$putCase consumeFieldDeclaration(); $break ./
5507 VariableDeclarators -> VariableDeclarator
5508 VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
5509 /.$putCase consumeVariableDeclarators(); $break ./
5511 VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
5513 VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
5515 EnterVariable ::= $empty
5516 /.$putCase consumeEnterVariable(); $break ./
5518 ExitVariableWithInitialization ::= $empty
5519 /.$putCase consumeExitVariableWithInitialization(); $break ./
5521 ExitVariableWithoutInitialization ::= $empty
5522 /.$putCase consumeExitVariableWithoutInitialization(); $break ./
5524 ForceNoDiet ::= $empty
5525 /.$putCase consumeForceNoDiet(); $break ./
5526 RestoreDiet ::= $empty
5527 /.$putCase consumeRestoreDiet(); $break ./
5529 VariableDeclaratorId ::= 'Identifier' Dimsopt
5531 VariableInitializer -> Expression
5532 VariableInitializer -> ArrayInitializer
5534 --18.8.3 Productions from 8.4: Method Declarations
5535 --MethodModifier ::=
5546 MethodDeclaration -> AbstractMethodDeclaration
5547 MethodDeclaration ::= MethodHeader MethodBody
5548 /.$putCase // set to true to consume a method with a body
5549 consumeMethodDeclaration(true); $break ./
5551 AbstractMethodDeclaration ::= MethodHeader ';'
5552 /.$putCase // set to false to consume a method without body
5553 consumeMethodDeclaration(false); $break ./
5555 MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5556 /.$putCase consumeMethodHeader(); $break ./
5558 MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5559 /.$putCase consumeMethodHeader(); $break ./
5561 MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
5562 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5564 MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
5565 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5567 MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
5568 /.$putCase consumeMethodHeaderName(); $break ./
5570 MethodHeaderParameters ::= FormalParameterListopt ')'
5571 /.$putCase consumeMethodHeaderParameters(); $break ./
5573 MethodHeaderExtendedDims ::= Dimsopt
5574 /.$putCase consumeMethodHeaderExtendedDims(); $break ./
5576 MethodHeaderThrowsClause ::= 'throws' ClassTypeList
5577 /.$putCase consumeMethodHeaderThrowsClause(); $break ./
5579 ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
5580 /.$putCase consumeConstructorHeader(); $break ./
5582 ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
5583 /.$putCase consumeConstructorHeaderName(); $break ./
5585 FormalParameterList -> FormalParameter
5586 FormalParameterList ::= FormalParameterList ',' FormalParameter
5587 /.$putCase consumeFormalParameterList(); $break ./
5590 FormalParameter ::= Modifiersopt Type VariableDeclaratorId
5591 /.$putCase // the boolean is used to know if the modifiers should be reset
5592 consumeFormalParameter(); $break ./
5594 ClassTypeList -> ClassTypeElt
5595 ClassTypeList ::= ClassTypeList ',' ClassTypeElt
5596 /.$putCase consumeClassTypeList(); $break ./
5598 ClassTypeElt ::= ClassType
5599 /.$putCase consumeClassTypeElt(); $break ./
5602 MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
5603 /.$putCase consumeMethodBody(); $break ./
5605 NestedMethod ::= $empty
5606 /.$putCase consumeNestedMethod(); $break ./
5608 --18.8.4 Productions from 8.5: Static Initializers
5610 StaticInitializer ::= StaticOnly Block
5611 /.$putCase consumeStaticInitializer(); $break./
5613 StaticOnly ::= 'static'
5614 /.$putCase consumeStaticOnly(); $break ./
5616 --18.8.5 Productions from 8.6: Constructor Declarations
5617 --ConstructorModifier ::=
5623 ConstructorDeclaration ::= ConstructorHeader ConstructorBody
5624 /.$putCase consumeConstructorDeclaration() ; $break ./
5626 -- These rules are added to be able to parse constructors with no body
5627 ConstructorDeclaration ::= ConstructorHeader ';'
5628 /.$putCase consumeInvalidConstructorDeclaration() ; $break ./
5630 -- the rules ExplicitConstructorInvocationopt has been expanded
5631 -- in the rule below in order to make the grammar lalr(1).
5632 -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}'
5633 -- Other inlining has occured into the next rule too....
5635 ConstructorBody ::= NestedMethod '{' ConstructorBlockStatementsopt '}'
5636 /.$putCase consumeConstructorBody(); $break ./
5638 ConstructorBlockStatementsopt -> BlockStatementsopt
5640 ConstructorBlockStatementsopt -> ExplicitConstructorInvocation
5642 ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements
5643 /.$putCase consumeConstructorBlockStatements(); $break ./
5645 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
5646 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./
5648 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
5649 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./
5652 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
5653 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./
5656 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
5657 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./
5660 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
5661 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./
5664 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
5665 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./
5667 --18.9 Productions from 9: Interface Declarations
5669 --18.9.1 Productions from 9.1: Interface Declarations
5670 --InterfaceModifier ::=
5674 InterfaceDeclaration ::= InterfaceHeader InterfaceBody
5675 /.$putCase consumeInterfaceDeclaration(); $break ./
5677 InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
5678 /.$putCase consumeInterfaceHeader(); $break ./
5680 InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
5681 /.$putCase consumeInterfaceHeaderName(); $break ./
5683 -- This rule will be used to accept inner local interface and then report a relevant error message
5684 InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody
5686 InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
5687 /.$putCase consumeInterfaceHeaderExtends(); $break ./
5689 InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}'
5691 InterfaceMemberDeclarations -> InterfaceMemberDeclaration
5692 InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
5693 /.$putCase consumeInterfaceMemberDeclarations(); $break ./
5695 --same as for class members
5696 InterfaceMemberDeclaration ::= ';'
5697 /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./
5699 -- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message
5700 InvalidMethodDeclaration -> MethodHeader MethodBody
5702 InterfaceMemberDeclaration -> ConstantDeclaration
5703 InterfaceMemberDeclaration ::= InvalidMethodDeclaration
5704 /.$putCase ignoreMethodBody(); $break ./
5706 -- These rules are added to be able to parse constructors inside interface and then report a relevent error message
5707 InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody
5708 /.$putCase ignoreInvalidConstructorDeclaration(true); $break ./
5710 InvalidConstructorDeclaration ::= ConstructorHeader ';'
5711 /.$putCase ignoreInvalidConstructorDeclaration(false); $break ./
5713 InterfaceMemberDeclaration -> AbstractMethodDeclaration
5714 InterfaceMemberDeclaration -> InvalidConstructorDeclaration
5717 InterfaceMemberDeclaration -> ClassDeclaration
5719 InterfaceMemberDeclaration -> InterfaceDeclaration
5721 ConstantDeclaration -> FieldDeclaration
5723 ArrayInitializer ::= '{' ,opt '}'
5724 /.$putCase consumeEmptyArrayInitializer(); $break ./
5725 ArrayInitializer ::= '{' VariableInitializers '}'
5726 /.$putCase consumeArrayInitializer(); $break ./
5727 ArrayInitializer ::= '{' VariableInitializers , '}'
5728 /.$putCase consumeArrayInitializer(); $break ./
5730 VariableInitializers ::= VariableInitializer
5731 VariableInitializers ::= VariableInitializers ',' VariableInitializer
5732 /.$putCase consumeVariableInitializers(); $break ./
5734 Block ::= OpenBlock '{' BlockStatementsopt '}'
5735 /.$putCase consumeBlock(); $break ./
5736 OpenBlock ::= $empty
5737 /.$putCase consumeOpenBlock() ; $break ./
5739 BlockStatements -> BlockStatement
5740 BlockStatements ::= BlockStatements BlockStatement
5741 /.$putCase consumeBlockStatements() ; $break ./
5743 BlockStatement -> LocalVariableDeclarationStatement
5744 BlockStatement -> Statement
5746 BlockStatement -> ClassDeclaration
5747 BlockStatement ::= InvalidInterfaceDeclaration
5748 /.$putCase ignoreInterfaceDeclaration(); $break ./
5750 LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
5751 /.$putCase consumeLocalVariableDeclarationStatement(); $break ./
5753 LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
5754 /.$putCase consumeLocalVariableDeclaration(); $break ./
5757 -- The modifiers part of this rule makes the grammar more permissive.
5758 -- The only modifier here is final. We put Modifiers to allow multiple modifiers
5759 -- This will require to check the validity of the modifier
5761 LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators
5762 /.$putCase consumeLocalVariableDeclaration(); $break ./
5764 PushModifiers ::= $empty
5765 /.$putCase consumePushModifiers(); $break ./
5767 Statement -> StatementWithoutTrailingSubstatement
5768 Statement -> LabeledStatement
5769 Statement -> IfThenStatement
5770 Statement -> IfThenElseStatement
5771 Statement -> WhileStatement
5772 Statement -> ForStatement
5774 StatementNoShortIf -> StatementWithoutTrailingSubstatement
5775 StatementNoShortIf -> LabeledStatementNoShortIf
5776 StatementNoShortIf -> IfThenElseStatementNoShortIf
5777 StatementNoShortIf -> WhileStatementNoShortIf
5778 StatementNoShortIf -> ForStatementNoShortIf
5780 StatementWithoutTrailingSubstatement -> AssertStatement
5781 StatementWithoutTrailingSubstatement -> Block
5782 StatementWithoutTrailingSubstatement -> EmptyStatement
5783 StatementWithoutTrailingSubstatement -> ExpressionStatement
5784 StatementWithoutTrailingSubstatement -> SwitchStatement
5785 StatementWithoutTrailingSubstatement -> DoStatement
5786 StatementWithoutTrailingSubstatement -> BreakStatement
5787 StatementWithoutTrailingSubstatement -> ContinueStatement
5788 StatementWithoutTrailingSubstatement -> ReturnStatement
5789 StatementWithoutTrailingSubstatement -> SynchronizedStatement
5790 StatementWithoutTrailingSubstatement -> ThrowStatement
5791 StatementWithoutTrailingSubstatement -> TryStatement
5793 EmptyStatement ::= ';'
5794 /.$putCase consumeEmptyStatement(); $break ./
5796 LabeledStatement ::= 'Identifier' ':' Statement
5797 /.$putCase consumeStatementLabel() ; $break ./
5799 LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
5800 /.$putCase consumeStatementLabel() ; $break ./
5802 ExpressionStatement ::= StatementExpression ';'
5803 /. $putCase consumeExpressionStatement(); $break ./
5805 StatementExpression ::= Assignment
5806 StatementExpression ::= PreIncrementExpression
5807 StatementExpression ::= PreDecrementExpression
5808 StatementExpression ::= PostIncrementExpression
5809 StatementExpression ::= PostDecrementExpression
5810 StatementExpression ::= MethodInvocation
5811 StatementExpression ::= ClassInstanceCreationExpression
5813 IfThenStatement ::= 'if' '(' Expression ')' Statement
5814 /.$putCase consumeStatementIfNoElse(); $break ./
5816 IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
5817 /.$putCase consumeStatementIfWithElse(); $break ./
5819 IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
5820 /.$putCase consumeStatementIfWithElse(); $break ./
5822 SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
5823 /.$putCase consumeStatementSwitch() ; $break ./
5825 SwitchBlock ::= '{' '}'
5826 /.$putCase consumeEmptySwitchBlock() ; $break ./
5828 SwitchBlock ::= '{' SwitchBlockStatements '}'
5829 SwitchBlock ::= '{' SwitchLabels '}'
5830 SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
5831 /.$putCase consumeSwitchBlock() ; $break ./
5833 SwitchBlockStatements -> SwitchBlockStatement
5834 SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
5835 /.$putCase consumeSwitchBlockStatements() ; $break ./
5837 SwitchBlockStatement ::= SwitchLabels BlockStatements
5838 /.$putCase consumeSwitchBlockStatement() ; $break ./
5840 SwitchLabels -> SwitchLabel
5841 SwitchLabels ::= SwitchLabels SwitchLabel
5842 /.$putCase consumeSwitchLabels() ; $break ./
5844 SwitchLabel ::= 'case' ConstantExpression ':'
5845 /. $putCase consumeCaseLabel(); $break ./
5847 SwitchLabel ::= 'default' ':'
5848 /. $putCase consumeDefaultLabel(); $break ./
5850 WhileStatement ::= 'while' '(' Expression ')' Statement
5851 /.$putCase consumeStatementWhile() ; $break ./
5853 WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
5854 /.$putCase consumeStatementWhile() ; $break ./
5856 DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
5857 /.$putCase consumeStatementDo() ; $break ./
5859 ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
5860 /.$putCase consumeStatementFor() ; $break ./
5861 ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
5862 /.$putCase consumeStatementFor() ; $break ./
5864 --the minus one allows to avoid a stack-to-stack transfer
5865 ForInit ::= StatementExpressionList
5866 /.$putCase consumeForInit() ; $break ./
5867 ForInit -> LocalVariableDeclaration
5869 ForUpdate -> StatementExpressionList
5871 StatementExpressionList -> StatementExpression
5872 StatementExpressionList ::= StatementExpressionList ',' StatementExpression
5873 /.$putCase consumeStatementExpressionList() ; $break ./
5876 AssertStatement ::= 'assert' Expression ';'
5877 /.$putCase consumeSimpleAssertStatement() ; $break ./
5879 AssertStatement ::= 'assert' Expression ':' Expression ';'
5880 /.$putCase consumeAssertStatement() ; $break ./
5882 BreakStatement ::= 'break' ';'
5883 /.$putCase consumeStatementBreak() ; $break ./
5885 BreakStatement ::= 'break' Identifier ';'
5886 /.$putCase consumeStatementBreakWithLabel() ; $break ./
5888 ContinueStatement ::= 'continue' ';'
5889 /.$putCase consumeStatementContinue() ; $break ./
5891 ContinueStatement ::= 'continue' Identifier ';'
5892 /.$putCase consumeStatementContinueWithLabel() ; $break ./
5894 ReturnStatement ::= 'return' Expressionopt ';'
5895 /.$putCase consumeStatementReturn() ; $break ./
5897 ThrowStatement ::= 'throw' Expression ';'
5898 /.$putCase consumeStatementThrow();
5901 SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
5902 /.$putCase consumeStatementSynchronized(); $break ./
5903 OnlySynchronized ::= 'synchronized'
5904 /.$putCase consumeOnlySynchronized(); $break ./
5907 TryStatement ::= 'try' Block Catches
5908 /.$putCase consumeStatementTry(false); $break ./
5909 TryStatement ::= 'try' Block Catchesopt Finally
5910 /.$putCase consumeStatementTry(true); $break ./
5912 Catches -> CatchClause
5913 Catches ::= Catches CatchClause
5914 /.$putCase consumeCatches(); $break ./
5916 CatchClause ::= 'catch' '(' FormalParameter ')' Block
5917 /.$putCase consumeStatementCatch() ; $break ./
5919 Finally ::= 'finally' Block
5921 --18.12 Productions from 14: Expressions
5923 --for source positionning purpose
5925 /.$putCase consumeLeftParen(); $break ./
5927 /.$putCase consumeRightParen(); $break ./
5929 Primary -> PrimaryNoNewArray
5930 Primary -> ArrayCreationExpression
5932 PrimaryNoNewArray -> Literal
5933 PrimaryNoNewArray ::= 'this'
5934 /.$putCase consumePrimaryNoNewArrayThis(); $break ./
5936 PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
5937 /.$putCase consumePrimaryNoNewArray(); $break ./
5939 PrimaryNoNewArray -> ClassInstanceCreationExpression
5940 PrimaryNoNewArray -> FieldAccess
5942 PrimaryNoNewArray ::= Name '.' 'this'
5943 /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
5944 PrimaryNoNewArray ::= Name '.' 'super'
5945 /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
5948 --PrimaryNoNewArray ::= Type '.' 'class'
5949 --inline Type in the previous rule in order to make the grammar LL1 instead
5950 -- of LL2. The result is the 3 next rules.
5951 PrimaryNoNewArray ::= Name '.' 'class'
5952 /.$putCase consumePrimaryNoNewArrayName(); $break ./
5954 PrimaryNoNewArray ::= ArrayType '.' 'class'
5955 /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
5957 PrimaryNoNewArray ::= PrimitiveType '.' 'class'
5958 /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
5960 PrimaryNoNewArray -> MethodInvocation
5961 PrimaryNoNewArray -> ArrayAccess
5965 -- In Java 1.0 a ClassBody could not appear at all in a
5966 -- ClassInstanceCreationExpression.
5969 AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
5970 /.$putCase consumeAllocationHeader(); $break ./
5972 ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
5973 /.$putCase consumeClassInstanceCreationExpression(); $break ./
5976 ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
5977 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
5980 ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
5981 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
5983 ClassInstanceCreationExpressionName ::= Name '.'
5984 /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
5986 ClassBodyopt ::= $empty --test made using null as contents
5987 /.$putCase consumeClassBodyopt(); $break ./
5988 ClassBodyopt ::= EnterAnonymousClassBody ClassBody
5990 EnterAnonymousClassBody ::= $empty
5991 /.$putCase consumeEnterAnonymousClassBody(); $break ./
5993 ArgumentList ::= Expression
5994 ArgumentList ::= ArgumentList ',' Expression
5995 /.$putCase consumeArgumentList(); $break ./
5997 --Thess rules are re-written in order to be ll1
5998 --ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer
5999 --ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt
6000 --ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt
6001 --DimExprs ::= DimExpr
6002 --DimExprs ::= DimExprs DimExpr
6004 ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
6005 /.$putCase consumeArrayCreationExpression(); $break ./
6006 ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
6007 /.$putCase consumeArrayCreationExpression(); $break ./
6009 DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
6010 DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
6011 /.$putCase consumeDimWithOrWithOutExprs(); $break ./
6013 DimWithOrWithOutExpr ::= '[' Expression ']'
6014 DimWithOrWithOutExpr ::= '[' ']'
6015 /. $putCase consumeDimWithOrWithOutExpr(); $break ./
6016 -- -----------------------------------------------
6019 /. $putCase consumeDims(); $break ./
6020 DimsLoop -> OneDimLoop
6021 DimsLoop ::= DimsLoop OneDimLoop
6022 OneDimLoop ::= '[' ']'
6023 /. $putCase consumeOneDimLoop(); $break ./
6025 FieldAccess ::= Primary '.' 'Identifier'
6026 /.$putCase consumeFieldAccess(false); $break ./
6028 FieldAccess ::= 'super' '.' 'Identifier'
6029 /.$putCase consumeFieldAccess(true); $break ./
6031 MethodInvocation ::= Name '(' ArgumentListopt ')'
6032 /.$putCase consumeMethodInvocationName(); $break ./
6034 MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
6035 /.$putCase consumeMethodInvocationPrimary(); $break ./
6037 MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
6038 /.$putCase consumeMethodInvocationSuper(); $break ./
6040 ArrayAccess ::= Name '[' Expression ']'
6041 /.$putCase consumeArrayAccess(true); $break ./
6042 ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
6043 /.$putCase consumeArrayAccess(false); $break ./
6045 PostfixExpression -> Primary
6046 PostfixExpression ::= Name
6047 /.$putCase consumePostfixExpression(); $break ./
6048 PostfixExpression -> PostIncrementExpression
6049 PostfixExpression -> PostDecrementExpression
6051 PostIncrementExpression ::= PostfixExpression '++'
6052 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./
6054 PostDecrementExpression ::= PostfixExpression '--'
6055 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./
6057 --for source managment purpose
6058 PushPosition ::= $empty
6059 /.$putCase consumePushPosition(); $break ./
6061 UnaryExpression -> PreIncrementExpression
6062 UnaryExpression -> PreDecrementExpression
6063 UnaryExpression ::= '+' PushPosition UnaryExpression
6064 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./
6065 UnaryExpression ::= '-' PushPosition UnaryExpression
6066 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./
6067 UnaryExpression -> UnaryExpressionNotPlusMinus
6069 PreIncrementExpression ::= '++' PushPosition UnaryExpression
6070 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./
6072 PreDecrementExpression ::= '--' PushPosition UnaryExpression
6073 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./
6075 UnaryExpressionNotPlusMinus -> PostfixExpression
6076 UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
6077 /.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./
6078 UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
6079 /.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./
6080 UnaryExpressionNotPlusMinus -> CastExpression
6082 CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
6083 /.$putCase consumeCastExpression(); $break ./
6084 CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
6085 /.$putCase consumeCastExpression(); $break ./
6086 -- Expression is here only in order to make the grammar LL1
6087 CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus
6088 /.$putCase consumeCastExpressionLL1(); $break ./
6090 MultiplicativeExpression -> UnaryExpression
6091 MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
6092 /.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./
6093 MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
6094 /.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./
6095 MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
6096 /.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./
6098 AdditiveExpression -> MultiplicativeExpression
6099 AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
6100 /.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./
6101 AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
6102 /.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./
6104 ShiftExpression -> AdditiveExpression
6105 ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
6106 /.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./
6107 ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
6108 /.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./
6109 ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
6110 /.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./
6112 RelationalExpression -> ShiftExpression
6113 RelationalExpression ::= RelationalExpression '<' ShiftExpression
6114 /.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./
6115 RelationalExpression ::= RelationalExpression '>' ShiftExpression
6116 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./
6117 RelationalExpression ::= RelationalExpression '<=' ShiftExpression
6118 /.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./
6119 RelationalExpression ::= RelationalExpression '>=' ShiftExpression
6120 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./
6121 RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
6122 /.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./
6124 EqualityExpression -> RelationalExpression
6125 EqualityExpression ::= EqualityExpression '==' RelationalExpression
6126 /.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./
6127 EqualityExpression ::= EqualityExpression '!=' RelationalExpression
6128 /.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./
6130 AndExpression -> EqualityExpression
6131 AndExpression ::= AndExpression '&' EqualityExpression
6132 /.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./
6134 ExclusiveOrExpression -> AndExpression
6135 ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
6136 /.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./
6138 InclusiveOrExpression -> ExclusiveOrExpression
6139 InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
6140 /.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./
6142 ConditionalAndExpression -> InclusiveOrExpression
6143 ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
6144 /.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./
6146 ConditionalOrExpression -> ConditionalAndExpression
6147 ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
6148 /.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./
6150 ConditionalExpression -> ConditionalOrExpression
6151 ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
6152 /.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./
6154 AssignmentExpression -> ConditionalExpression
6155 AssignmentExpression -> Assignment
6157 Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
6158 /.$putCase consumeAssignment(); $break ./
6160 -- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
6161 InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer
6162 Assignment ::= InvalidArrayInitializerAssignement
6163 /.$putcase ignoreExpressionAssignment();$break ./
6165 LeftHandSide ::= Name
6166 /.$putCase consumeLeftHandSide(); $break ./
6167 LeftHandSide -> FieldAccess
6168 LeftHandSide -> ArrayAccess
6170 AssignmentOperator ::= '='
6171 /.$putCase consumeAssignmentOperator(EQUAL); $break ./
6172 AssignmentOperator ::= '*='
6173 /.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
6174 AssignmentOperator ::= '/='
6175 /.$putCase consumeAssignmentOperator(DIVIDE); $break ./
6176 AssignmentOperator ::= '%='
6177 /.$putCase consumeAssignmentOperator(REMAINDER); $break ./
6178 AssignmentOperator ::= '+='
6179 /.$putCase consumeAssignmentOperator(PLUS); $break ./
6180 AssignmentOperator ::= '-='
6181 /.$putCase consumeAssignmentOperator(MINUS); $break ./
6182 AssignmentOperator ::= '<<='
6183 /.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
6184 AssignmentOperator ::= '>>='
6185 /.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
6186 AssignmentOperator ::= '>>>='
6187 /.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
6188 AssignmentOperator ::= '&='
6189 /.$putCase consumeAssignmentOperator(AND); $break ./
6190 AssignmentOperator ::= '^='
6191 /.$putCase consumeAssignmentOperator(XOR); $break ./
6192 AssignmentOperator ::= '|='
6193 /.$putCase consumeAssignmentOperator(OR); $break ./
6195 Expression -> AssignmentExpression
6197 ConstantExpression -> Expression
6199 -- The following rules are for optional nonterminals.
6202 PackageDeclarationopt -> $empty
6203 PackageDeclarationopt -> PackageDeclaration
6205 ClassHeaderExtendsopt ::= $empty
6206 ClassHeaderExtendsopt -> ClassHeaderExtends
6208 Expressionopt ::= $empty
6209 /.$putCase consumeEmptyExpression(); $break ./
6210 Expressionopt -> Expression
6213 ---------------------------------------------------------------------------------------
6215 -- The rules below are for optional terminal symbols. An optional comma,
6216 -- is only used in the context of an array initializer - It is a
6217 -- "syntactic sugar" that otherwise serves no other purpose. By contrast,
6218 -- an optional identifier is used in the definition of a break and
6219 -- continue statement. When the identifier does not appear, a NULL
6220 -- is produced. When the identifier is present, the user should use the
6221 -- corresponding TOKEN(i) method. See break statement as an example.
6223 ---------------------------------------------------------------------------------------
6228 ImportDeclarationsopt ::= $empty
6229 /.$putCase consumeEmptyImportDeclarationsopt(); $break ./
6230 ImportDeclarationsopt ::= ImportDeclarations
6231 /.$putCase consumeImportDeclarationsopt(); $break ./
6234 TypeDeclarationsopt ::= $empty
6235 /.$putCase consumeEmptyTypeDeclarationsopt(); $break ./
6236 TypeDeclarationsopt ::= TypeDeclarations
6237 /.$putCase consumeTypeDeclarationsopt(); $break ./
6239 ClassBodyDeclarationsopt ::= $empty
6240 /.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
6241 ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
6242 /.$putCase consumeClassBodyDeclarationsopt(); $break ./
6244 Modifiersopt ::= $empty
6245 /. $putCase consumeDefaultModifiers(); $break ./
6246 Modifiersopt ::= Modifiers
6247 /.$putCase consumeModifiers(); $break ./
6249 BlockStatementsopt ::= $empty
6250 /.$putCase consumeEmptyBlockStatementsopt(); $break ./
6251 BlockStatementsopt -> BlockStatements
6254 /. $putCase consumeEmptyDimsopt(); $break ./
6257 ArgumentListopt ::= $empty
6258 /. $putCase consumeEmptyArgumentListopt(); $break ./
6259 ArgumentListopt -> ArgumentList
6261 MethodHeaderThrowsClauseopt ::= $empty
6262 MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
6264 FormalParameterListopt ::= $empty
6265 /.$putcase consumeFormalParameterListopt(); $break ./
6266 FormalParameterListopt -> FormalParameterList
6268 ClassHeaderImplementsopt ::= $empty
6269 ClassHeaderImplementsopt -> ClassHeaderImplements
6271 InterfaceMemberDeclarationsopt ::= $empty
6272 /. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
6273 InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
6274 /. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
6276 NestedType ::= $empty
6277 /.$putCase consumeNestedType(); $break./
6279 ForInitopt ::= $empty
6280 /. $putCase consumeEmptyForInitopt(); $break ./
6281 ForInitopt -> ForInit
6283 ForUpdateopt ::= $empty
6284 /. $putCase consumeEmptyForUpdateopt(); $break ./
6285 ForUpdateopt -> ForUpdate
6287 InterfaceHeaderExtendsopt ::= $empty
6288 InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
6290 Catchesopt ::= $empty
6291 /. $putCase consumeEmptyCatchesopt(); $break ./
6292 Catchesopt -> Catches
6294 ArrayInitializeropt ::= $empty
6295 /. $putCase consumeEmptyArrayInitializeropt(); $break ./
6296 ArrayInitializeropt -> ArrayInitializer
6301 ---------------------------------------------------------------------------------------
6305 -- BodyMarker ::= '"class Identifier { ... MethodHeader "'
6310 MINUS_MINUS ::= '--'
6311 EQUAL_EQUAL ::= '=='
6313 GREATER_EQUAL ::= '>='
6316 RIGHT_SHIFT ::= '>>'
6317 UNSIGNED_RIGHT_SHIFT ::= '>>>'
6319 MINUS_EQUAL ::= '-='
6320 MULTIPLY_EQUAL ::= '*='
6321 DIVIDE_EQUAL ::= '/='
6325 REMAINDER_EQUAL ::= '%='
6326 LEFT_SHIFT_EQUAL ::= '<<='
6327 RIGHT_SHIFT_EQUAL ::= '>>='
6328 UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>='
6358 -- need a carriage return after the $end
6361 protected void ignoreExpressionAssignment() {
6362 // Assignment ::= InvalidArrayInitializerAssignement
6363 // encoded operator would be: intStack[intPtr]
6365 ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--];
6366 expressionLengthPtr -- ;
6367 // report a syntax error and abort parsing
6368 problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
6370 protected void ignoreInterfaceDeclaration() {
6371 // BlockStatement ::= InvalidInterfaceDeclaration
6372 //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
6374 // length declarations
6376 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6377 //there are length declarations
6378 //dispatch according to the type of the declarations
6379 dispatchDeclarationInto(length);
6382 flushAnnotationsDefinedPriorTo(endStatementPosition);
6384 // report the problem and continue parsing
6385 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
6386 typeDecl.bodyEnd = endStatementPosition;
6387 problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
6389 // mark fields and initializer with local type mark if needed
6390 markFieldsWithLocalType(typeDecl);
6392 // remove the ast node created in interface header
6394 // Don't create an astnode for this inner interface, but have to push
6395 // a 0 on the astLengthStack to be consistent with the reduction made
6396 // at the end of the method:
6397 // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit)
6398 pushOnAstLengthStack(0);
6400 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
6401 // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
6402 // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
6405 astStack : modifiers arguments throws statements
6406 identifierStack : name
6408 astStack : MethodDeclaration
6412 //must provide a default constructor call when needed
6415 // pop the position of the { (body of the method) pushed in block decl
6425 if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) {
6429 protected void ignoreMethodBody() {
6430 // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
6433 astStack : modifiers arguments throws statements
6434 identifierStack : type name
6435 intStack : dim dim dim
6437 astStack : MethodDeclaration
6442 // pop the position of the { (body of the method) pushed in block decl
6444 // retrieve end position of method declarator
6449 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6453 //watch for } that could be given as a unicode ! ( u007D is '}' )
6454 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
6455 md.bodyEnd = endPosition;
6456 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
6458 // report the problem and continue the parsing - narrowing the problem onto the method
6459 problemReporter().abstractMethodNeedingNoBody(md);
6461 public void initialize() {
6462 //positionning the parser for a new compilation unit
6463 //avoiding stack reallocation and all that....
6467 expressionLengthPtr = -1;
6469 identifierLengthPtr = -1;
6471 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
6472 variablesCounter[nestedType] = 0;
6475 compilationUnit = null;
6476 referenceContext = null;
6477 endStatementPosition = 0;
6479 //remove objects from stack too, while the same parser/compiler couple is
6480 //re-used between two compilations ....
6482 int astLength = astStack.length;
6483 if (noAstNodes.length < astLength){
6484 noAstNodes = new AstNode[astLength];
6485 //System.out.println("Resized AST stacks : "+ astLength);
6488 System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
6490 int expressionLength = expressionStack.length;
6491 if (noExpressions.length < expressionLength){
6492 noExpressions = new Expression[expressionLength];
6493 //System.out.println("Resized EXPR stacks : "+ expressionLength);
6495 System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
6497 // reset scanner state
6498 scanner.commentPtr = -1;
6499 scanner.eofPosition = Integer.MAX_VALUE;
6504 lastCheckPoint = -1;
6505 currentElement = null;
6506 restartRecovery = false;
6507 hasReportedError = false;
6508 recoveredStaticInitializerStart = 0;
6509 lastIgnoredToken = -1;
6510 lastErrorEndPosition = -1;
6513 public void initializeScanner(){
6514 this.scanner = new Scanner(false, false, this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore , this.assertMode);
6516 public final static void initTables() throws java.io.IOException {
6518 final String prefix = FILEPREFIX;
6520 lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6521 char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6522 check_table = new short[chars.length];
6523 for (int c = chars.length; c-- > 0;) {
6524 check_table[c] = (short) (chars[c] - 32768);
6526 asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6527 asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6528 symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6531 public final void jumpOverMethodBody() {
6532 //on diet parsing.....do not buffer method statements
6534 //the scanner.diet is reinitialized to false
6535 //automatically by the scanner once it has jumped over
6538 if (diet && (dietInt == 0))
6539 scanner.diet = true;
6541 protected void markCurrentMethodWithLocalType() {
6542 if (this.currentElement != null) return; // this is already done in the recovery code
6543 for (int i = this.astPtr; i >= 0; i--) {
6544 AstNode node = this.astStack[i];
6545 if (node instanceof AbstractMethodDeclaration
6546 || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type
6547 node.bits |= AstNode.HasLocalTypeMASK;
6551 // default to reference context (case of parse method body)
6552 if (this.referenceContext instanceof AbstractMethodDeclaration
6553 || this.referenceContext instanceof TypeDeclaration) {
6554 ((AstNode)this.referenceContext).bits |= AstNode.HasLocalTypeMASK;
6557 protected void markFieldsWithLocalType(TypeDeclaration type) {
6558 if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0) return;
6559 for (int i = 0, length = type.fields.length; i < length; i++) {
6560 type.fields[i].bits |= AstNode.HasLocalTypeMASK;
6564 * Move checkpoint location (current implementation is moving it by one token)
6566 * Answers true if successfully moved checkpoint (i.e. did not attempt to move it
6567 * beyond end of file).
6569 protected boolean moveRecoveryCheckpoint() {
6571 int pos = lastCheckPoint;
6572 /* reset scanner, and move checkpoint by one token */
6573 scanner.startPosition = pos;
6574 scanner.currentPosition = pos;
6575 scanner.diet = false; // quit jumping over method bodies
6577 /* if about to restart, then no need to shift token */
6578 if (restartRecovery){
6579 lastIgnoredToken = -1;
6583 /* protect against shifting on an invalid token */
6584 lastIgnoredToken = nextIgnoredToken;
6585 nextIgnoredToken = -1;
6588 nextIgnoredToken = scanner.getNextToken();
6589 if(scanner.currentPosition == scanner.startPosition){
6590 scanner.currentPosition++; // on fake completion identifier
6591 nextIgnoredToken = -1;
6594 } catch(InvalidInputException e){
6595 pos = scanner.currentPosition;
6597 } while (nextIgnoredToken < 0);
6599 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6600 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6604 lastCheckPoint = scanner.currentPosition;
6606 /* reset scanner again to previous checkpoint location*/
6607 scanner.startPosition = pos;
6608 scanner.currentPosition = pos;
6609 scanner.commentPtr = -1;
6614 The following implementation moves the checkpoint location by one line:
6616 int pos = lastCheckPoint;
6617 // reset scanner, and move checkpoint by one token
6618 scanner.startPosition = pos;
6619 scanner.currentPosition = pos;
6620 scanner.diet = false; // quit jumping over method bodies
6622 // if about to restart, then no need to shift token
6623 if (restartRecovery){
6624 lastIgnoredToken = -1;
6628 // protect against shifting on an invalid token
6629 lastIgnoredToken = nextIgnoredToken;
6630 nextIgnoredToken = -1;
6632 boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace;
6633 scanner.tokenizeWhiteSpace = true;
6637 nextIgnoredToken = scanner.getNextToken();
6638 switch(nextIgnoredToken){
6639 case Scanner.TokenNameWHITESPACE :
6640 if(scanner.getLineNumber(scanner.startPosition)
6641 == scanner.getLineNumber(scanner.currentPosition)){
6642 nextIgnoredToken = -1;
6645 case TokenNameSEMICOLON :
6646 case TokenNameLBRACE :
6647 case TokenNameRBRACE :
6649 case TokenNameIdentifier :
6650 if(scanner.currentPosition == scanner.startPosition){
6651 scanner.currentPosition++; // on fake completion identifier
6654 nextIgnoredToken = -1;
6657 break checkpointMove;
6659 } catch(InvalidInputException e){
6660 pos = scanner.currentPosition;
6662 } while (nextIgnoredToken < 0);
6663 scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
6665 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6666 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6670 lastCheckPoint = scanner.currentPosition;
6672 // reset scanner again to previous checkpoint location
6673 scanner.startPosition = pos;
6674 scanner.currentPosition = pos;
6675 scanner.commentPtr = -1;
6680 protected MessageSend newMessageSend() {
6681 // '(' ArgumentListopt ')'
6682 // the arguments are on the expression stack
6684 MessageSend m = new MessageSend();
6686 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
6687 expressionPtr -= length;
6691 m.arguments = new Expression[length],
6697 protected static int ntAction(int state, int sym) {
6698 return action[state + sym];
6700 private final void optimizedConcatNodeLists() {
6701 /*back from a recursive loop. Virtualy group the
6702 astNode into an array using astLengthStack*/
6705 * This is a case where you have two sublists into the astStack that you want
6706 * to merge in one list. There is no action required on the astStack. The only
6707 * thing you need to do is merge the two lengths specified on the astStackLength.
6708 * The top two length are for example:
6710 * and you want to result in a list like:
6712 * This means that the p could be equals to 0 in case there is no astNode pushed
6714 * Look at the InterfaceMemberDeclarations for an example.
6715 * This case optimizes the fact that p == 1.
6718 astLengthStack[--astLengthPtr]++;
6720 protected static int original_state(int state) {
6721 return -check(state);
6723 /*main loop of the automat
6724 When a rule is reduced, the method consumeRule(int) is called with the number
6725 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
6726 called in order to remember (when needed) the consumed token */
6727 // (int)asr[asi(act)]
6728 // name[symbol_index[currentKind]]
6729 protected void parse() {
6731 hasReportedError = false;
6732 int act = START_STATE;
6734 currentToken = getFirstToken();
6735 ProcessTerminals : for (;;) {
6737 stack[++stateStackTop] = act;
6738 } catch (IndexOutOfBoundsException e) {
6739 int oldStackLength = stack.length;
6740 int oldStack[] = stack;
6741 stack = new int[oldStackLength + StackIncrement];
6742 System.arraycopy(oldStack, 0, stack, 0, oldStackLength);
6743 stack[stateStackTop] = act;
6746 act = tAction(act, currentToken);
6748 if (act == ERROR_ACTION || restartRecovery) {
6749 int errorPos = scanner.currentPosition;
6750 if (!hasReportedError){
6751 this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop);
6752 hasReportedError = true;
6754 if (resumeOnSyntaxError()) {
6755 if (act == ERROR_ACTION) lastErrorEndPosition = errorPos;
6758 currentToken = getFirstToken();
6759 continue ProcessTerminals;
6762 } break ProcessTerminals;
6764 if (act <= NUM_RULES)
6767 if (act > ERROR_ACTION) { /* shift-reduce */
6768 consumeToken(currentToken);
6769 if (currentElement != null) this.recoveryTokenCheck();
6771 currentToken = scanner.getNextToken();
6772 } catch(InvalidInputException e){
6773 if (!hasReportedError){
6774 this.problemReporter().scannerError(this, e.getMessage());
6775 hasReportedError = true;
6777 lastCheckPoint = scanner.currentPosition;
6778 restartRecovery = true;
6780 act -= ERROR_ACTION;
6782 if (act < ACCEPT_ACTION) { /* shift */
6783 consumeToken(currentToken);
6784 if (currentElement != null) this.recoveryTokenCheck();
6786 currentToken = scanner.getNextToken();
6787 } catch(InvalidInputException e){
6788 if (!hasReportedError){
6789 this.problemReporter().scannerError(this, e.getMessage());
6790 hasReportedError = true;
6792 lastCheckPoint = scanner.currentPosition;
6793 restartRecovery = true;
6795 continue ProcessTerminals;
6797 break ProcessTerminals;
6799 ProcessNonTerminals : do { /* reduce */
6801 stateStackTop -= (rhs[act] - 1);
6802 act = ntAction(stack[stateStackTop], lhs[act]);
6803 } while (act <= NUM_RULES);
6809 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
6810 //only parse the method body of cd
6811 //fill out its statements
6813 //convert bugs into parse error
6816 goForConstructorBody();
6817 nestedMethod[nestedType]++;
6819 referenceContext = cd;
6820 compilationUnit = unit;
6822 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
6825 } catch (AbortCompilation ex) {
6826 lastAct = ERROR_ACTION;
6828 nestedMethod[nestedType]--;
6831 if (lastAct == ERROR_ACTION) {
6837 cd.explicitDeclarations = realBlockStack[realBlockPtr--];
6839 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6841 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
6842 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
6847 cd.statements = new Statement[length - 1],
6850 cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
6851 } else { //need to add explicitly the super();
6855 cd.statements = new Statement[length],
6858 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6861 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6864 if (cd.constructorCall.sourceEnd == 0) {
6865 cd.constructorCall.sourceEnd = cd.sourceEnd;
6866 cd.constructorCall.sourceStart = cd.sourceStart;
6873 TypeDeclaration type,
6874 CompilationUnitDeclaration unit) {
6875 //only parse the method body of md
6876 //fill out method statements
6878 //convert bugs into parse error
6882 nestedMethod[nestedType]++;
6884 referenceContext = type;
6885 compilationUnit = unit;
6887 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
6890 } catch (AbortCompilation ex) {
6891 lastAct = ERROR_ACTION;
6893 nestedMethod[nestedType]--;
6896 if (lastAct == ERROR_ACTION) {
6900 ini.block = ((Initializer) astStack[astPtr]).block;
6902 // mark initializer with local type if one was found during parsing
6903 if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
6904 ini.bits |= AstNode.HasLocalTypeMASK;
6909 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
6910 //only parse the method body of md
6911 //fill out method statements
6913 //convert bugs into parse error
6915 if (md.isAbstract())
6919 if ((md.modifiers & AccSemicolonBody) != 0)
6924 nestedMethod[nestedType]++;
6926 referenceContext = md;
6927 compilationUnit = unit;
6929 scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
6930 // reset the scanner to parser from { down to }
6933 } catch (AbortCompilation ex) {
6934 lastAct = ERROR_ACTION;
6936 nestedMethod[nestedType]--;
6939 if (lastAct == ERROR_ACTION) {
6944 md.explicitDeclarations = realBlockStack[realBlockPtr--];
6946 if ((length = astLengthStack[astLengthPtr--]) != 0)
6949 (astPtr -= length) + 1,
6950 md.statements = new Statement[length],
6956 public CompilationUnitDeclaration parse(
6957 ICompilationUnit sourceUnit,
6958 CompilationResult compilationResult) {
6959 // parses a compilation unit and manages error handling (even bugs....)
6961 CompilationUnitDeclaration unit;
6963 /* automaton initialization */
6965 goForCompilationUnit();
6967 /* scanner initialization */
6968 scanner.setSource(sourceUnit.getContents());
6973 new CompilationUnitDeclaration(
6976 scanner.source.length);
6980 unit = compilationUnit;
6981 compilationUnit = null; // reset parser
6987 public CompilationUnitDeclaration parse(
6988 ICompilationUnit sourceUnit,
6989 CompilationResult compilationResult,
6992 // parses a compilation unit and manages error handling (even bugs....)
6994 CompilationUnitDeclaration unit;
6996 /* automaton initialization */
6998 goForCompilationUnit();
7000 /* scanner initialization */
7001 scanner.setSource(sourceUnit.getContents());
7002 scanner.resetTo(start, end);
7006 new CompilationUnitDeclaration(
7009 scanner.source.length);
7013 unit = compilationUnit;
7014 compilationUnit = null; // reset parser
7019 * Returns this parser's problem reporter initialized with its reference context.
7020 * Also it is assumed that a problem is going to be reported, so initializes
7021 * the compilation result's line positions.
7023 public ProblemReporter problemReporter(){
7024 if (scanner.recordLineSeparator) {
7025 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
7027 problemReporter.referenceContext = referenceContext;
7028 return problemReporter;
7030 protected void pushIdentifier() {
7031 /*push the consumeToken on the identifier stack.
7032 Increase the total number of identifier in the stack.
7033 identifierPtr points on the next top */
7036 identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource();
7037 identifierPositionStack[identifierPtr] =
7038 (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7039 } catch (IndexOutOfBoundsException e) {
7040 /*---stack reallaocation (identifierPtr is correct)---*/
7041 int oldStackLength = identifierStack.length;
7042 char[][] oldStack = identifierStack;
7043 identifierStack = new char[oldStackLength + 20][];
7044 System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength);
7045 identifierStack[identifierPtr] = scanner.getCurrentTokenSource();
7046 /*identifier position stack*/
7047 long[] oldPos = identifierPositionStack;
7048 identifierPositionStack = new long[oldStackLength + 20];
7049 System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength);
7050 identifierPositionStack[identifierPtr] =
7051 (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7055 identifierLengthStack[++identifierLengthPtr] = 1;
7056 } catch (IndexOutOfBoundsException e) {
7057 /*---stack reallocation (identifierLengthPtr is correct)---*/
7058 int oldStackLength = identifierLengthStack.length;
7059 int oldStack[] = identifierLengthStack;
7060 identifierLengthStack = new int[oldStackLength + 10];
7061 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7062 identifierLengthStack[identifierLengthPtr] = 1;
7066 protected void pushIdentifier(int flag) {
7067 /*push a special flag on the stack :
7068 -zero stands for optional Name
7069 -negative number for direct ref to base types.
7070 identifierLengthPtr points on the top */
7073 identifierLengthStack[++identifierLengthPtr] = flag;
7074 } catch (IndexOutOfBoundsException e) {
7075 /*---stack reallaocation (identifierLengthPtr is correct)---*/
7076 int oldStackLength = identifierLengthStack.length;
7077 int oldStack[] = identifierLengthStack;
7078 identifierLengthStack = new int[oldStackLength + 10];
7079 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7080 identifierLengthStack[identifierLengthPtr] = flag;
7084 protected void pushOnAstLengthStack(int pos) {
7086 astLengthStack[++astLengthPtr] = pos;
7087 } catch (IndexOutOfBoundsException e) {
7088 int oldStackLength = astLengthStack.length;
7089 int[] oldPos = astLengthStack;
7090 astLengthStack = new int[oldStackLength + StackIncrement];
7091 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7092 astLengthStack[astLengthPtr] = pos;
7095 protected void pushOnAstStack(AstNode node) {
7096 /*add a new obj on top of the ast stack
7097 astPtr points on the top*/
7100 astStack[++astPtr] = node;
7101 } catch (IndexOutOfBoundsException e) {
7102 int oldStackLength = astStack.length;
7103 AstNode[] oldStack = astStack;
7104 astStack = new AstNode[oldStackLength + AstStackIncrement];
7105 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
7106 astPtr = oldStackLength;
7107 astStack[astPtr] = node;
7111 astLengthStack[++astLengthPtr] = 1;
7112 } catch (IndexOutOfBoundsException e) {
7113 int oldStackLength = astLengthStack.length;
7114 int[] oldPos = astLengthStack;
7115 astLengthStack = new int[oldStackLength + AstStackIncrement];
7116 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7117 astLengthStack[astLengthPtr] = 1;
7120 protected void pushOnExpressionStack(Expression expr) {
7123 expressionStack[++expressionPtr] = expr;
7124 } catch (IndexOutOfBoundsException e) {
7125 //expressionPtr is correct
7126 int oldStackLength = expressionStack.length;
7127 Expression[] oldStack = expressionStack;
7128 expressionStack = new Expression[oldStackLength + ExpressionStackIncrement];
7129 System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength);
7130 expressionStack[expressionPtr] = expr;
7134 expressionLengthStack[++expressionLengthPtr] = 1;
7135 } catch (IndexOutOfBoundsException e) {
7136 int oldStackLength = expressionLengthStack.length;
7137 int[] oldPos = expressionLengthStack;
7138 expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement];
7139 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7140 expressionLengthStack[expressionLengthPtr] = 1;
7143 protected void pushOnExpressionStackLengthStack(int pos) {
7145 expressionLengthStack[++expressionLengthPtr] = pos;
7146 } catch (IndexOutOfBoundsException e) {
7147 int oldStackLength = expressionLengthStack.length;
7148 int[] oldPos = expressionLengthStack;
7149 expressionLengthStack = new int[oldStackLength + StackIncrement];
7150 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7151 expressionLengthStack[expressionLengthPtr] = pos;
7154 protected void pushOnIntStack(int pos) {
7157 intStack[++intPtr] = pos;
7158 } catch (IndexOutOfBoundsException e) {
7160 int oldStackLength = intStack.length;
7161 int oldStack[] = intStack;
7162 intStack = new int[oldStackLength + StackIncrement];
7163 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
7164 intStack[intPtr] = pos;
7167 protected static char[] readTable(String filename) throws java.io.IOException {
7169 //files are located at Parser.class directory
7171 InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename));
7172 if (stream == null) {
7173 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
7175 byte[] bytes = null;
7177 bytes = Util.getInputStreamAsByteArray(stream, -1);
7181 } catch (IOException e) {
7185 //minimal integrity check (even size expected)
7186 int length = bytes.length;
7187 if (length % 2 != 0)
7188 throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
7190 // convert bytes into chars
7191 char[] chars = new char[length / 2];
7196 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
7202 /* Token check performed on every token shift once having entered
7205 public void recoveryTokenCheck() {
7206 switch (currentToken) {
7207 case TokenNameLBRACE : {
7208 RecoveredElement newElement =
7209 currentElement.updateOnOpeningBrace(scanner.currentPosition - 1);
7210 lastCheckPoint = scanner.currentPosition;
7211 if (newElement != null){ // null means nothing happened
7212 restartRecovery = true; // opening brace detected
7213 currentElement = newElement;
7217 case TokenNameRBRACE : {
7218 endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1);
7219 RecoveredElement newElement =
7220 currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition -1);
7221 lastCheckPoint = scanner.currentPosition;
7222 if (newElement != currentElement){
7223 currentElement = newElement;
7228 protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
7230 /* remember current scanner position */
7231 int startPos = scanner.startPosition;
7232 int currentPos = scanner.currentPosition;
7234 String[] expectings;
7235 String tokenName = name[symbol_index[currentKind]];
7237 //fetch all "accurate" possible terminals that could recover the error
7238 int start, end = start = asi(stack[stateStackTop]);
7239 while (asr[end] != 0)
7241 int length = end - start;
7242 expectings = new String[length];
7244 char[] indexes = new char[length];
7245 System.arraycopy(asr, start, indexes, 0, length);
7246 for (int i = 0; i < length; i++) {
7247 expectings[i] = name[symbol_index[indexes[i]]];
7251 //if the pb is an EOF, try to tell the user that they are some
7252 if (tokenName.equals(UNEXPECTED_EOF)) {
7253 if (!this.checkAndReportBracketAnomalies(problemReporter())) {
7256 tokenSource = this.scanner.getCurrentTokenSource();
7257 } catch (Exception e) {
7258 tokenSource = new char[] {};
7260 problemReporter().parseError(
7261 this.scanner.startPosition,
7262 this.scanner.currentPosition - 1,
7267 } else { //the next test is HEAVILY grammar DEPENDENT.
7269 && (tokenName.equals(";")) //$NON-NLS-1$
7270 && (expectings[0] == "++") //$NON-NLS-1$
7271 && (expectings[1] == "--") //$NON-NLS-1$
7272 && (expressionPtr > -1)) {
7273 // the ; is not the expected token ==> it ends a statement when an expression is not ended
7274 problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
7278 tokenSource = this.scanner.getCurrentTokenSource();
7279 } catch (Exception e) {
7280 tokenSource = new char[] {};
7282 problemReporter().parseError(
7283 this.scanner.startPosition,
7284 this.scanner.currentPosition - 1,
7288 this.checkAndReportBracketAnomalies(problemReporter());
7291 /* reset scanner where it was */
7292 scanner.startPosition = startPos;
7293 scanner.currentPosition = currentPos;
7295 protected void resetModifiers() {
7296 modifiers = AccDefault;
7297 modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
7298 scanner.commentPtr = -1;
7301 * Reset context so as to resume to regular parse loop
7303 protected void resetStacks() {
7308 expressionLengthPtr = -1;
7310 identifierLengthPtr = -1;
7312 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
7313 variablesCounter[nestedType] = 0;
7315 realBlockStack[realBlockPtr = 0] = 0;
7316 recoveredStaticInitializerStart = 0;
7320 * Reset context so as to resume to regular parse loop
7321 * If unable to reset for resuming, answers false.
7323 * Move checkpoint location, reset internal stacks and
7324 * decide which grammar goal is activated.
7326 protected boolean resumeAfterRecovery() {
7328 // reset internal stacks
7331 /* attempt to move checkpoint location */
7332 if (!this.moveRecoveryCheckpoint()) return false;
7334 // only look for headers
7335 if (referenceContext instanceof CompilationUnitDeclaration){
7337 diet = true; // passed this point, will not consider method bodies
7340 // does not know how to restart
7344 * Syntax error was detected. Will attempt to perform some recovery action in order
7345 * to resume to the regular parse loop.
7347 protected boolean resumeOnSyntaxError() {
7349 /* request recovery initialization */
7350 if (currentElement == null){
7352 this.buildInitialRecoveryState(); // build some recovered elements
7354 /* do not investigate deeper in recovery when no recovered element */
7355 if (currentElement == null) return false;
7357 /* manual forced recovery restart - after headers */
7358 if (restartRecovery){
7359 restartRecovery = false;
7361 /* update recovery state with current error state of the parser */
7362 this.updateRecoveryState();
7364 /* attempt to reset state in order to resume to parse loop */
7365 return this.resumeAfterRecovery();
7367 protected static int tAction(int state, int sym) {
7368 return action[check(state + sym) == sym ? state + sym : state];
7370 public String toString() {
7372 String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
7373 for (int i = 0; i <= identifierPtr; i++) {
7374 s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
7376 s = s + "}\n"; //$NON-NLS-1$
7378 s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
7379 for (int i = 0; i <= identifierLengthPtr; i++) {
7380 s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$
7382 s = s + "}\n"; //$NON-NLS-1$
7384 s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
7385 for (int i = 0; i <= astLengthPtr; i++) {
7386 s = s + astLengthStack[i] + ","; //$NON-NLS-1$
7388 s = s + "}\n"; //$NON-NLS-1$
7389 s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7391 s = s + "intStack : int[] = {"; //$NON-NLS-1$
7392 for (int i = 0; i <= intPtr; i++) {
7393 s = s + intStack[i] + ","; //$NON-NLS-1$
7395 s = s + "}\n"; //$NON-NLS-1$
7397 s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
7398 for (int i = 0; i <= expressionLengthPtr; i++) {
7399 s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$
7401 s = s + "}\n"; //$NON-NLS-1$
7403 s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7405 s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$
7410 * Update recovery state based on current parser/scanner state
7412 protected void updateRecoveryState() {
7414 /* expose parser state to recovery state */
7415 currentElement.updateFromParserState();
7417 /* check and update recovered state based on current token,
7418 this action is also performed when shifting token after recovery
7421 this.recoveryTokenCheck();
7423 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
7424 //fields is a definition of fields that are grouped together like in
7425 //public int[] a, b[], c
7426 //which results into 3 fields.
7428 FieldDeclaration field;
7429 int endTypeDeclarationPosition =
7430 -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart;
7431 for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
7432 //last one is special(see below)
7433 field = (FieldDeclaration) astStack[astPtr - i - 1];
7434 field.endPart1Position = endTypeDeclarationPosition;
7435 field.endPart2Position = -1 + astStack[astPtr - i].sourceStart;
7438 (field = (FieldDeclaration) astStack[astPtr]).endPart1Position =
7439 endTypeDeclarationPosition;
7440 field.endPart2Position = field.declarationSourceEnd;
7443 protected void updateSourcePosition(Expression exp) {
7444 //update the source Position of the expression
7446 //intStack : int int
7450 exp.sourceEnd = intStack[intPtr--];
7451 exp.sourceStart = intStack[intPtr--];