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;
91 // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
92 protected int[] variablesCounter;
93 //===DATA===DATA===DATA===DATA===DATA===DATA===//
94 public final static byte rhs[] =
534 public static char asb[] = null;
535 public static char asr[] = null;
536 public static char symbol_index[] = null;
537 private static final String UNEXPECTED_EOF = "Unexpected End Of File"; //$NON-NLS-1$
539 public final static String name[] = { null, "++",
559 ">>>=", //$NON-NLS-1$
587 "$empty", //$NON-NLS-1$
588 "Identifier", //$NON-NLS-1$
589 "abstract", //$NON-NLS-1$
590 "assert", //$NON-NLS-1$
591 "boolean", //$NON-NLS-1$
592 "break", //$NON-NLS-1$
593 "byte", //$NON-NLS-1$
594 "case", //$NON-NLS-1$
595 "catch", //$NON-NLS-1$
596 "char", //$NON-NLS-1$
597 "class", //$NON-NLS-1$
598 "continue", //$NON-NLS-1$
599 "default", //$NON-NLS-1$
601 "double", //$NON-NLS-1$
602 "else", //$NON-NLS-1$
603 "extends", //$NON-NLS-1$
604 "false", //$NON-NLS-1$
605 "final", //$NON-NLS-1$
606 "finally", //$NON-NLS-1$
607 "float", //$NON-NLS-1$
610 "implements", //$NON-NLS-1$
611 "import", //$NON-NLS-1$
612 "instanceof", //$NON-NLS-1$
614 "interface", //$NON-NLS-1$
615 "long", //$NON-NLS-1$
616 "native", //$NON-NLS-1$
618 "null", //$NON-NLS-1$
619 "package", //$NON-NLS-1$
620 "private", //$NON-NLS-1$
621 "protected", //$NON-NLS-1$
622 "public", //$NON-NLS-1$
623 "return", //$NON-NLS-1$
624 "short", //$NON-NLS-1$
625 "static", //$NON-NLS-1$
626 "strictfp", //$NON-NLS-1$
627 "super", //$NON-NLS-1$
628 "switch", //$NON-NLS-1$
629 "synchronized", //$NON-NLS-1$
630 "this", //$NON-NLS-1$
631 "throw", //$NON-NLS-1$
632 "throws", //$NON-NLS-1$
633 "transient", //$NON-NLS-1$
634 "true", //$NON-NLS-1$
636 "void", //$NON-NLS-1$
637 "volatile", //$NON-NLS-1$
638 "while", //$NON-NLS-1$
639 "IntegerLiteral", //$NON-NLS-1$
640 "LongLiteral", //$NON-NLS-1$
641 "FloatingPointLiteral", //$NON-NLS-1$
642 "DoubleLiteral", //$NON-NLS-1$
643 "CharacterLiteral", //$NON-NLS-1$
644 "StringLiteral", //$NON-NLS-1$
645 UNEXPECTED_EOF, "Invalid Character",
647 "Goal", //$NON-NLS-1$
648 "MethodBody", //$NON-NLS-1$
649 "ConstructorBody", //$NON-NLS-1$
650 "StaticInitializer", //$NON-NLS-1$
651 "Initializer", //$NON-NLS-1$
652 "Headers", //$NON-NLS-1$
653 "BlockStatements", //$NON-NLS-1$
654 "MethodPushModifiersHeader", //$NON-NLS-1$
655 "CatchHeader", //$NON-NLS-1$
656 "FieldDeclaration", //$NON-NLS-1$
657 "ImportDeclaration", //$NON-NLS-1$
658 "PackageDeclaration", //$NON-NLS-1$
659 "TypeDeclaration", //$NON-NLS-1$
660 "GenericMethodDeclaration", //$NON-NLS-1$
661 "ClassBodyDeclaration", //$NON-NLS-1$
662 "Expression", //$NON-NLS-1$
663 "Type", //$NON-NLS-1$
664 "PrimitiveType", //$NON-NLS-1$
665 "ReferenceType", //$NON-NLS-1$
666 "ClassOrInterfaceType", //$NON-NLS-1$
667 "ArrayType", //$NON-NLS-1$
668 "Name", //$NON-NLS-1$
669 "Dims", //$NON-NLS-1$
670 "ClassType", //$NON-NLS-1$
671 "SimpleName", //$NON-NLS-1$
672 "Header", //$NON-NLS-1$
673 "ClassHeader", //$NON-NLS-1$
674 "InterfaceHeader", //$NON-NLS-1$
675 "MethodHeader", //$NON-NLS-1$
676 "ConstructorHeader", //$NON-NLS-1$
677 "FormalParameter", //$NON-NLS-1$
678 "ImportDeclarations", //$NON-NLS-1$
679 "TypeDeclarations", //$NON-NLS-1$
680 "PackageDeclarationName", //$NON-NLS-1$
681 "SingleTypeImportDeclarationName", //$NON-NLS-1$
682 "TypeImportOnDemandDeclarationName", //$NON-NLS-1$
683 "Modifiers", //$NON-NLS-1$
684 "Modifier", //$NON-NLS-1$
685 "ClassBody", //$NON-NLS-1$
686 "ClassHeaderName", //$NON-NLS-1$
687 "InterfaceTypeList", //$NON-NLS-1$
688 "InterfaceType", //$NON-NLS-1$
689 "ClassBodyDeclarations", //$NON-NLS-1$
690 "Block", //$NON-NLS-1$
691 "VariableDeclarators", //$NON-NLS-1$
692 "VariableDeclarator", //$NON-NLS-1$
693 "VariableDeclaratorId", //$NON-NLS-1$
694 "VariableInitializer", //$NON-NLS-1$
695 "ArrayInitializer", //$NON-NLS-1$
696 "MethodHeaderName", //$NON-NLS-1$
697 "MethodHeaderParameters", //$NON-NLS-1$
698 "MethodPushModifiersHeaderName", //$NON-NLS-1$
699 "ClassTypeList", //$NON-NLS-1$
700 "ConstructorHeaderName", //$NON-NLS-1$
701 "FormalParameterList", //$NON-NLS-1$
702 "ClassTypeElt", //$NON-NLS-1$
703 "StaticOnly", //$NON-NLS-1$
704 "ExplicitConstructorInvocation", //$NON-NLS-1$
705 "Primary", //$NON-NLS-1$
706 "InterfaceBody", //$NON-NLS-1$
707 "InterfaceHeaderName", //$NON-NLS-1$
708 "InterfaceMemberDeclarations", //$NON-NLS-1$
709 "InterfaceMemberDeclaration", //$NON-NLS-1$
710 "VariableInitializers", //$NON-NLS-1$
711 "BlockStatement", //$NON-NLS-1$
712 "Statement", //$NON-NLS-1$
713 "LocalVariableDeclaration", //$NON-NLS-1$
714 "StatementWithoutTrailingSubstatement", //$NON-NLS-1$
715 "StatementNoShortIf", //$NON-NLS-1$
716 "StatementExpression", //$NON-NLS-1$
717 "PostIncrementExpression", //$NON-NLS-1$
718 "PostDecrementExpression", //$NON-NLS-1$
719 "MethodInvocation", //$NON-NLS-1$
720 "ClassInstanceCreationExpression", //$NON-NLS-1$
721 "SwitchBlock", //$NON-NLS-1$
722 "SwitchBlockStatements", //$NON-NLS-1$
723 "SwitchLabels", //$NON-NLS-1$
724 "SwitchBlockStatement", //$NON-NLS-1$
725 "SwitchLabel", //$NON-NLS-1$
726 "ConstantExpression", //$NON-NLS-1$
727 "StatementExpressionList", //$NON-NLS-1$
728 "OnlySynchronized", //$NON-NLS-1$
729 "Catches", //$NON-NLS-1$
730 "Finally", //$NON-NLS-1$
731 "CatchClause", //$NON-NLS-1$
732 "PushLPAREN", //$NON-NLS-1$
733 "PushRPAREN", //$NON-NLS-1$
734 "PrimaryNoNewArray", //$NON-NLS-1$
735 "FieldAccess", //$NON-NLS-1$
736 "ArrayAccess", //$NON-NLS-1$
737 "ClassInstanceCreationExpressionName", //$NON-NLS-1$
738 "ArgumentList", //$NON-NLS-1$
739 "DimWithOrWithOutExprs", //$NON-NLS-1$
740 "DimWithOrWithOutExpr", //$NON-NLS-1$
741 "DimsLoop", //$NON-NLS-1$
742 "OneDimLoop", //$NON-NLS-1$
743 "PostfixExpression", //$NON-NLS-1$
744 "UnaryExpression", //$NON-NLS-1$
745 "UnaryExpressionNotPlusMinus", //$NON-NLS-1$
746 "MultiplicativeExpression", //$NON-NLS-1$
747 "AdditiveExpression", //$NON-NLS-1$
748 "ShiftExpression", //$NON-NLS-1$
749 "RelationalExpression", //$NON-NLS-1$
750 "EqualityExpression", //$NON-NLS-1$
751 "AndExpression", //$NON-NLS-1$
752 "ExclusiveOrExpression", //$NON-NLS-1$
753 "InclusiveOrExpression", //$NON-NLS-1$
754 "ConditionalAndExpression", //$NON-NLS-1$
755 "ConditionalOrExpression", //$NON-NLS-1$
756 "ConditionalExpression", //$NON-NLS-1$
757 "AssignmentExpression", //$NON-NLS-1$
758 "LeftHandSide", //$NON-NLS-1$
759 "AssignmentOperator" //$NON-NLS-1$
762 public static short check_table[] = null;
763 public static char lhs[] = null;
764 public static char action[] = lhs;
765 private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
770 } catch (java.io.IOException ex) {
771 throw new ExceptionInInitializerError(ex.getMessage());
775 public static final int RoundBracket = 0;
776 public static final int SquareBracket = 1;
777 public static final int CurlyBracket = 2;
778 public static final int BracketKinds = 3;
780 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) {
782 this.problemReporter = problemReporter;
783 this.optimizeStringLiterals = optimizeStringLiterals;
784 this.assertMode = assertMode;
785 this.initializeScanner();
786 astLengthStack = new int[50];
787 expressionLengthStack = new int[30];
788 intStack = new int[50];
789 identifierStack = new char[30][];
790 identifierLengthStack = new int[30];
791 nestedMethod = new int[30];
792 realBlockStack = new int[30];
793 identifierPositionStack = new long[30];
794 variablesCounter = new int[30];
800 protected void adjustInterfaceModifiers() {
801 intStack[intPtr - 1] |= AccInterface;
803 public final void arrayInitializer(int length) {
804 //length is the size of the array Initializer
805 //expressionPtr points on the last elt of the arrayInitializer
806 //i.e. it has not been decremented yet.
808 ArrayInitializer ai = new ArrayInitializer();
810 expressionPtr -= length;
811 System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
813 pushOnExpressionStack(ai);
815 ai.sourceEnd = endStatementPosition;
816 int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart;
818 //does not work with comments(that contain '{') nor '{' describes as a unicode....
819 while (scanner.source[--searchPosition] != '{') {
821 } catch (IndexOutOfBoundsException ex) {
822 //should never occur (except for strange cases like whose describe above)
823 searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1;
825 ai.sourceStart = searchPosition;
827 protected static int asi(int state) {
829 return asb[original_state(state)];
831 protected void blockReal() {
832 // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
833 // increment the amount of declared variables for this block
834 realBlockStack[realBlockPtr]++;
836 private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort)
837 throws java.io.IOException {
839 //transform the String tokens into chars before dumping then into file
843 while (!tokens[i++].equals(tag)) {
846 char[] chars = new char[tokens.length]; //can't be bigger
849 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
850 int c = Integer.parseInt(token);
853 chars[ic++] = (char) c;
857 System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
859 buildFileForTable(filename, chars);
861 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
863 byte[] bytes = new byte[chars.length * 2];
864 for (int i = 0; i < chars.length; i++) {
865 bytes[2 * i] = (byte) (chars[i] >>> 8);
866 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
869 java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
872 System.out.println(filename + " creation complete"); //$NON-NLS-1$
874 public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException {
876 //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
878 //build from the lpg javadcl.java files that represents the parser tables
879 //lhs check_table asb asr symbol_index
881 //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
883 char[] contents = new char[] {
886 contents = Util.getFileCharContent(new File(dataFilename), null);
887 } catch (IOException ex) {
888 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
891 java.util.StringTokenizer st = new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
892 String[] tokens = new String[st.countTokens()];
894 while (st.hasMoreTokens()) {
895 tokens[i++] = st.nextToken();
897 final String prefix = FILEPREFIX;
899 buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
900 buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$
901 buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
902 buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
903 buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
904 System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
907 * Build initial recovery state.
908 * Recovery state is inferred from the current state of the parser (reduced node stack).
910 public RecoveredElement buildInitialRecoveryState() {
912 /* initialize recovery by retrieving available reduced nodes
913 * also rebuild bracket balance
917 RecoveredElement element = null;
918 if (referenceContext instanceof CompilationUnitDeclaration) {
919 element = new RecoveredUnit(compilationUnit, 0, this);
921 /* ignore current stack state, since restarting from the beginnning
922 since could not trust simple brace count */
923 if (true) { // experimenting restart recovery from scratch
924 compilationUnit.currentPackage = null;
925 compilationUnit.imports = null;
926 compilationUnit.types = null;
931 if (compilationUnit.currentPackage != null) {
932 lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd + 1;
934 if (compilationUnit.imports != null) {
935 lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length - 1].declarationSourceEnd + 1;
938 if (referenceContext instanceof AbstractMethodDeclaration) {
939 element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this);
940 lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart;
942 /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
943 if (referenceContext instanceof TypeDeclaration) {
944 TypeDeclaration type = (TypeDeclaration) referenceContext;
945 for (int i = 0; i < type.fields.length; i++) {
946 FieldDeclaration field = type.fields[i];
948 && field.declarationSourceStart <= scanner.initialPosition
949 && scanner.initialPosition <= field.declarationSourceEnd
950 && scanner.eofPosition <= field.declarationSourceEnd + 1) {
951 element = new RecoveredInitializer((Initializer) field, null, 1, this);
952 lastCheckPoint = field.declarationSourceStart;
963 for (int i = 0; i <= astPtr; i++) {
964 AstNode node = astStack[i];
965 if (node instanceof AbstractMethodDeclaration) {
966 AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
967 if (method.declarationSourceEnd == 0) {
968 element = element.add(method, 0);
969 lastCheckPoint = method.bodyStart;
971 element = element.add(method, 0);
972 lastCheckPoint = method.declarationSourceEnd + 1;
976 if (node instanceof Initializer) {
977 Initializer initializer = (Initializer) node;
978 if (initializer.declarationSourceEnd == 0) {
979 element = element.add(initializer, 1);
980 lastCheckPoint = initializer.bodyStart;
982 element = element.add(initializer, 0);
983 lastCheckPoint = initializer.declarationSourceEnd + 1;
987 if (node instanceof FieldDeclaration) {
988 FieldDeclaration field = (FieldDeclaration) node;
989 if (field.declarationSourceEnd == 0) {
990 element = element.add(field, 0);
991 if (field.initialization == null) {
992 lastCheckPoint = field.sourceEnd + 1;
994 lastCheckPoint = field.initialization.sourceEnd + 1;
997 element = element.add(field, 0);
998 lastCheckPoint = field.declarationSourceEnd + 1;
1002 if (node instanceof TypeDeclaration) {
1003 TypeDeclaration type = (TypeDeclaration) node;
1004 if (type.declarationSourceEnd == 0) {
1005 element = element.add(type, 0);
1006 lastCheckPoint = type.bodyStart;
1008 element = element.add(type, 0);
1009 lastCheckPoint = type.declarationSourceEnd + 1;
1013 if (node instanceof ImportReference) {
1014 ImportReference importRef = (ImportReference) node;
1015 element = element.add(importRef, 0);
1016 lastCheckPoint = importRef.declarationSourceEnd + 1;
1021 protected static short check(int i) {
1022 return check_table[i - (NUM_RULES + 1)];
1025 * Reconsider the entire source looking for inconsistencies in {} () []
1027 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
1029 scanner.wasAcr = false;
1030 boolean anomaliesDetected = false;
1032 char[] source = scanner.source;
1033 int[] leftCount = { 0, 0, 0 };
1034 int[] rightCount = { 0, 0, 0 };
1035 int[] depths = { 0, 0, 0 };
1036 int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] };
1037 int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
1038 int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] };
1039 int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] };
1040 scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
1041 while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
1043 // ---------Consume white space and handles startPosition---------
1044 boolean isWhiteSpace;
1046 scanner.startPosition = scanner.currentPosition;
1047 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1048 && (source[scanner.currentPosition] == 'u')) {
1049 isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
1051 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
1052 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
1053 // only record line positions we have not recorded yet
1054 scanner.pushLineSeparator();
1057 isWhiteSpace = Character.isWhitespace(scanner.currentCharacter);
1059 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
1061 // -------consume token until } is found---------
1063 switch (scanner.currentCharacter) {
1066 int index = leftCount[CurlyBracket]++;
1067 if (index == leftPositions[CurlyBracket].length) {
1068 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
1069 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
1071 leftPositions[CurlyBracket][index] = scanner.startPosition;
1072 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
1077 int index = rightCount[CurlyBracket]++;
1078 if (index == rightPositions[CurlyBracket].length) {
1079 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
1080 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
1082 rightPositions[CurlyBracket][index] = scanner.startPosition;
1083 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
1088 int index = leftCount[RoundBracket]++;
1089 if (index == leftPositions[RoundBracket].length) {
1090 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
1091 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
1093 leftPositions[RoundBracket][index] = scanner.startPosition;
1094 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
1099 int index = rightCount[RoundBracket]++;
1100 if (index == rightPositions[RoundBracket].length) {
1101 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
1102 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
1104 rightPositions[RoundBracket][index] = scanner.startPosition;
1105 rightDepths[RoundBracket][index] = --depths[RoundBracket];
1110 int index = leftCount[SquareBracket]++;
1111 if (index == leftPositions[SquareBracket].length) {
1112 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
1113 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
1115 leftPositions[SquareBracket][index] = scanner.startPosition;
1116 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
1121 int index = rightCount[SquareBracket]++;
1122 if (index == rightPositions[SquareBracket].length) {
1124 rightPositions[SquareBracket],
1126 (rightPositions[SquareBracket] = new int[index * 2]),
1129 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
1131 rightPositions[SquareBracket][index] = scanner.startPosition;
1132 rightDepths[SquareBracket][index] = --depths[SquareBracket];
1137 if (scanner.getNextChar('\\')) {
1138 scanner.scanEscapeCharacter();
1139 } else { // consume next character
1140 scanner.unicodeAsBackSlash = false;
1141 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1142 && (source[scanner.currentPosition] == 'u')) {
1143 scanner.getNextUnicodeChar();
1145 if (scanner.withoutUnicodePtr != 0) {
1146 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1150 scanner.getNextChar('\'');
1153 case '"' : // consume next character
1154 scanner.unicodeAsBackSlash = false;
1155 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1156 && (source[scanner.currentPosition] == 'u')) {
1157 scanner.getNextUnicodeChar();
1159 if (scanner.withoutUnicodePtr != 0) {
1160 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1163 while (scanner.currentCharacter != '"') {
1164 if (scanner.currentCharacter == '\r') {
1165 if (source[scanner.currentPosition] == '\n')
1166 scanner.currentPosition++;
1167 break; // the string cannot go further that the line
1169 if (scanner.currentCharacter == '\n') {
1170 break; // the string cannot go further that the line
1172 if (scanner.currentCharacter == '\\') {
1173 scanner.scanEscapeCharacter();
1175 // consume next character
1176 scanner.unicodeAsBackSlash = false;
1177 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1178 && (source[scanner.currentPosition] == 'u')) {
1179 scanner.getNextUnicodeChar();
1181 if (scanner.withoutUnicodePtr != 0) {
1182 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1190 if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment
1192 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1193 && (source[scanner.currentPosition] == 'u')) {
1194 //-------------unicode traitement ------------
1195 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1196 scanner.currentPosition++;
1197 while (source[scanner.currentPosition] == 'u') {
1198 scanner.currentPosition++;
1200 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1202 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1204 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1206 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1207 || c4 < 0) { //error don't care of the value
1208 scanner.currentCharacter = 'A';
1209 } //something different from \n and \r
1211 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1214 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
1216 scanner.startPosition = scanner.currentPosition;
1217 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1218 && (source[scanner.currentPosition] == 'u')) {
1219 //-------------unicode traitement ------------
1220 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1221 scanner.currentPosition++;
1222 while (source[scanner.currentPosition] == 'u') {
1223 scanner.currentPosition++;
1225 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1227 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1229 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1231 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1232 || c4 < 0) { //error don't care of the value
1233 scanner.currentCharacter = 'A';
1234 } //something different from \n and \r
1236 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1240 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
1241 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
1242 // only record line positions we have not recorded yet
1243 scanner.pushLineSeparator();
1248 if (test > 0) { //traditional and annotation comment
1249 boolean star = false;
1250 // consume next character
1251 scanner.unicodeAsBackSlash = false;
1252 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1253 && (source[scanner.currentPosition] == 'u')) {
1254 scanner.getNextUnicodeChar();
1256 if (scanner.withoutUnicodePtr != 0) {
1257 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1260 if (scanner.currentCharacter == '*') {
1264 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1265 && (source[scanner.currentPosition] == 'u')) {
1266 //-------------unicode traitement ------------
1267 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1268 scanner.currentPosition++;
1269 while (source[scanner.currentPosition] == 'u') {
1270 scanner.currentPosition++;
1272 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1274 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1276 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1278 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1279 || c4 < 0) { //error don't care of the value
1280 scanner.currentCharacter = 'A';
1281 } //something different from * and /
1283 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1286 //loop until end of comment */
1287 while ((scanner.currentCharacter != '/') || (!star)) {
1288 star = scanner.currentCharacter == '*';
1290 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1291 && (source[scanner.currentPosition] == 'u')) {
1292 //-------------unicode traitement ------------
1293 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1294 scanner.currentPosition++;
1295 while (source[scanner.currentPosition] == 'u') {
1296 scanner.currentPosition++;
1298 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1300 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1302 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1304 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1305 || c4 < 0) { //error don't care of the value
1306 scanner.currentCharacter = 'A';
1307 } //something different from * and /
1309 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1318 if (Character.isJavaIdentifierStart(scanner.currentCharacter)) {
1319 scanner.scanIdentifierOrKeyword();
1322 if (Character.isDigit(scanner.currentCharacter)) {
1323 scanner.scanNumber(false);
1327 //-----------------end switch while try--------------------
1328 } catch (IndexOutOfBoundsException e) {
1329 break; // read until EOF
1330 } catch (InvalidInputException e) {
1331 return false; // no clue
1334 if (scanner.recordLineSeparator) {
1335 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
1338 // check placement anomalies against other kinds of brackets
1339 for (int kind = 0; kind < BracketKinds; kind++) {
1340 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
1341 int start = leftPositions[kind][leftIndex]; // deepest first
1342 // find matching closing bracket
1343 int depth = leftDepths[kind][leftIndex];
1345 for (int i = 0; i < rightCount[kind]; i++) {
1346 int pos = rightPositions[kind][i];
1347 // want matching bracket further in source with same depth
1348 if ((pos > start) && (depth == rightDepths[kind][i])) {
1353 if (end < 0) { // did not find a good closing match
1354 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
1357 // check if even number of opening/closing other brackets in between this pair of brackets
1359 for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
1360 for (int i = 0; i < leftCount[otherKind]; i++) {
1361 int pos = leftPositions[otherKind][i];
1362 if ((pos > start) && (pos < end))
1365 for (int i = 0; i < rightCount[otherKind]; i++) {
1366 int pos = rightPositions[otherKind][i];
1367 if ((pos > start) && (pos < end))
1371 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
1376 // too many opening brackets ?
1377 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
1378 anomaliesDetected = true;
1379 problemReporter.unmatchedBracket(
1380 leftPositions[kind][leftCount[kind] - i - 1],
1382 compilationUnit.compilationResult);
1384 // too many closing brackets ?
1385 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
1386 anomaliesDetected = true;
1387 problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
1389 if (anomaliesDetected)
1393 return anomaliesDetected;
1394 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
1395 return anomaliesDetected;
1396 } catch (NullPointerException e) { // jdk1.2.2 jit bug
1397 return anomaliesDetected;
1400 public final void checkAndSetModifiers(int flag) {
1401 /*modify the current modifiers buffer.
1402 When the startPosition of the modifiers is 0
1403 it means that the modifier being parsed is the first
1404 of a list of several modifiers. The startPosition
1405 is zeroed when a copy of modifiers-buffer is push
1406 onto the astStack. */
1408 if ((modifiers & flag) != 0) { // duplicate modifier
1409 modifiers |= AccAlternateModifierProblem;
1413 if (modifiersSourceStart < 0)
1414 modifiersSourceStart = scanner.startPosition;
1416 public void checkAnnotation() {
1418 boolean deprecated = false;
1419 boolean checkDeprecated = false;
1420 int lastAnnotationIndex = -1;
1422 //since jdk1.2 look only in the last java doc comment...
1423 found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--) {
1424 //look for @deprecated into the first javadoc comment preceeding the declaration
1425 int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
1426 // javadoc only (non javadoc comment have negative end positions.)
1427 if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
1430 if (scanner.commentStops[lastAnnotationIndex] < 0) {
1433 checkDeprecated = true;
1434 int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
1435 char[] comment = scanner.source;
1437 for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
1438 if ((comment[i] == '@')
1439 && (comment[i + 1] == 'd')
1440 && (comment[i + 2] == 'e')
1441 && (comment[i + 3] == 'p')
1442 && (comment[i + 4] == 'r')
1443 && (comment[i + 5] == 'e')
1444 && (comment[i + 6] == 'c')
1445 && (comment[i + 7] == 'a')
1446 && (comment[i + 8] == 't')
1447 && (comment[i + 9] == 'e')
1448 && (comment[i + 10] == 'd')) {
1449 // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
1450 int nextPos = i + 11;
1452 (comment[nextPos] == ' ')
1453 || (comment[nextPos] == '\t')
1454 || (comment[nextPos] == '\n')
1455 || (comment[nextPos] == '\r')
1456 || (comment[nextPos] == '*');
1463 checkAndSetModifiers(AccDeprecated);
1465 // modify the modifier source start to point at the first comment
1466 if (lastAnnotationIndex >= 0 && checkDeprecated) {
1467 modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex];
1470 protected void classInstanceCreation(boolean alwaysQualified) {
1471 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1473 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1474 // An empty class body produces a 0 on the length stack.....
1476 AllocationExpression alloc;
1478 if (((length = astLengthStack[astLengthPtr--]) == 1) && (astStack[astPtr] == null)) {
1481 if (alwaysQualified) {
1482 alloc = new QualifiedAllocationExpression();
1484 alloc = new AllocationExpression();
1486 alloc.sourceEnd = endPosition; //the position has been stored explicitly
1488 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
1489 expressionPtr -= length;
1490 System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[length], 0, length);
1492 alloc.type = getTypeReference(0);
1493 //the default constructor with the correct number of argument
1494 //will be created and added by the TC (see createsInternalConstructorWithBinding)
1495 alloc.sourceStart = intStack[intPtr--];
1496 pushOnExpressionStack(alloc);
1498 dispatchDeclarationInto(length);
1499 AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr];
1500 anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition;
1501 anonymousTypeDeclaration.bodyEnd = endStatementPosition;
1502 if (anonymousTypeDeclaration.allocation != null) {
1503 anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition;
1508 // mark fields and initializer with local type mark if needed
1509 markFieldsWithLocalType(anonymousTypeDeclaration);
1512 protected final void concatExpressionLists() {
1513 expressionLengthStack[--expressionLengthPtr]++;
1515 private final void concatNodeLists() {
1517 * This is a case where you have two sublists into the astStack that you want
1518 * to merge in one list. There is no action required on the astStack. The only
1519 * thing you need to do is merge the two lengths specified on the astStackLength.
1520 * The top two length are for example:
1522 * and you want to result in a list like:
1524 * This means that the p could be equals to 0 in case there is no astNode pushed
1526 * Look at the InterfaceMemberDeclarations for an example.
1529 astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--];
1531 protected void consumeAllocationHeader() {
1532 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1534 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1535 // An empty class body produces a 0 on the length stack.....
1537 if (currentElement == null) {
1538 return; // should never occur, this consumeRule is only used in recovery mode
1540 if (currentToken == TokenNameLBRACE) {
1541 // beginning of an anonymous type
1542 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
1543 anonymousType.sourceStart = intStack[intPtr--];
1544 anonymousType.sourceEnd = rParenPos; // closing parenthesis
1545 lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition;
1546 currentElement = currentElement.add(anonymousType, 0);
1547 lastIgnoredToken = -1;
1548 currentToken = 0; // opening brace already taken into account
1551 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1552 restartRecovery = true; // request to restart from here on
1554 protected void consumeArgumentList() {
1555 // ArgumentList ::= ArgumentList ',' Expression
1556 concatExpressionLists();
1558 protected void consumeArrayAccess(boolean unspecifiedReference) {
1559 // ArrayAccess ::= Name '[' Expression ']' ==> true
1560 // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
1564 if (unspecifiedReference) {
1565 exp = expressionStack[expressionPtr] = new ArrayReference(getUnspecifiedReferenceOptimized(), expressionStack[expressionPtr]);
1568 expressionLengthPtr--;
1569 exp = expressionStack[expressionPtr] = new ArrayReference(expressionStack[expressionPtr], expressionStack[expressionPtr + 1]);
1571 exp.sourceEnd = endPosition;
1573 protected void consumeArrayCreationExpression() {
1574 // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
1575 // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
1578 ArrayAllocationExpression aae = new ArrayAllocationExpression();
1579 if (expressionLengthStack[expressionLengthPtr] != 0) {
1580 expressionLengthPtr--;
1581 aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--];
1583 expressionLengthPtr--;
1586 aae.type = getTypeReference(0);
1587 length = (expressionLengthStack[expressionLengthPtr--]);
1588 expressionPtr -= length;
1589 System.arraycopy(expressionStack, expressionPtr + 1, aae.dimensions = new Expression[length], 0, length);
1590 aae.sourceStart = intStack[intPtr--];
1591 if (aae.initializer == null) {
1592 aae.sourceEnd = endPosition;
1594 aae.sourceEnd = aae.initializer.sourceEnd;
1596 pushOnExpressionStack(aae);
1598 protected void consumeArrayInitializer() {
1599 // ArrayInitializer ::= '{' VariableInitializers '}'
1600 // ArrayInitializer ::= '{' VariableInitializers , '}'
1602 arrayInitializer(expressionLengthStack[expressionLengthPtr--]);
1605 protected void consumeAssertStatement() {
1606 // AssertStatement ::= 'assert' Expression ':' Expression ';'
1607 expressionLengthPtr -= 2;
1608 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--]));
1611 protected void consumeAssignment() {
1612 // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
1613 //optimize the push/pop
1615 int op = intStack[intPtr--]; //<--the encoded operator
1618 expressionLengthPtr--;
1619 expressionStack[expressionPtr] =
1621 ? new CompoundAssignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op, scanner.startPosition - 1)
1622 : new Assignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], scanner.startPosition - 1);
1624 protected void consumeAssignmentOperator(int pos) {
1625 // AssignmentOperator ::= '='
1626 // AssignmentOperator ::= '*='
1627 // AssignmentOperator ::= '/='
1628 // AssignmentOperator ::= '%='
1629 // AssignmentOperator ::= '+='
1630 // AssignmentOperator ::= '-='
1631 // AssignmentOperator ::= '<<='
1632 // AssignmentOperator ::= '>>='
1633 // AssignmentOperator ::= '>>>='
1634 // AssignmentOperator ::= '&='
1635 // AssignmentOperator ::= '^='
1636 // AssignmentOperator ::= '|='
1639 intStack[++intPtr] = pos;
1640 } catch (IndexOutOfBoundsException e) {
1642 int oldStackLength = intStack.length;
1643 int oldStack[] = intStack;
1644 intStack = new int[oldStackLength + StackIncrement];
1645 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
1646 intStack[intPtr] = pos;
1649 protected void consumeBinaryExpression(int op) {
1650 // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
1651 // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
1652 // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
1653 // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
1654 // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
1655 // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
1656 // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
1657 // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
1658 // RelationalExpression ::= RelationalExpression '<' ShiftExpression
1659 // RelationalExpression ::= RelationalExpression '>' ShiftExpression
1660 // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
1661 // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
1662 // AndExpression ::= AndExpression '&' EqualityExpression
1663 // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
1664 // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
1665 // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
1666 // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
1668 //optimize the push/pop
1671 expressionLengthPtr--;
1673 expressionStack[expressionPtr] = new OR_OR_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1675 if (op == AND_AND) {
1676 expressionStack[expressionPtr] =
1677 new AND_AND_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1679 // look for "string1" + "string2"
1680 if ((op == PLUS) && optimizeStringLiterals) {
1681 Expression expr1, expr2;
1682 expr1 = expressionStack[expressionPtr];
1683 expr2 = expressionStack[expressionPtr + 1];
1684 if (expr1 instanceof StringLiteral) {
1685 if (expr2 instanceof CharLiteral) { // string+char
1686 expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1687 } else if (expr2 instanceof StringLiteral) { //string+string
1688 expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1690 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1693 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1696 expressionStack[expressionPtr] =
1697 new BinaryExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1702 protected void consumeBlock() {
1703 // Block ::= OpenBlock '{' BlockStatementsopt '}'
1704 // simpler action for empty blocks
1707 if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block
1708 pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition));
1709 realBlockPtr--; // still need to pop the block variable counter
1711 Block bk = new Block(realBlockStack[realBlockPtr--]);
1713 System.arraycopy(astStack, astPtr + 1, bk.statements = new Statement[length], 0, length);
1715 bk.sourceStart = intStack[intPtr--];
1716 bk.sourceEnd = endStatementPosition;
1719 protected void consumeBlockStatements() {
1720 // BlockStatements ::= BlockStatements BlockStatement
1723 protected void consumeCaseLabel() {
1724 // SwitchLabel ::= 'case' ConstantExpression ':'
1725 expressionLengthPtr--;
1726 pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--]));
1728 protected void consumeCastExpression() {
1729 // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
1730 // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
1732 //intStack : posOfLeftParen dim posOfRightParen
1734 //optimize the push/pop
1736 Expression exp, cast, castType;
1737 int end = intStack[intPtr--];
1738 expressionStack[expressionPtr] =
1739 cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--]));
1740 castType.sourceEnd = end - 1;
1741 castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1;
1742 cast.sourceEnd = exp.sourceEnd;
1744 protected void consumeCastExpressionLL1() {
1745 //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus
1746 // Expression is used in order to make the grammar LL1
1750 Expression castType, cast, exp;
1752 expressionStack[expressionPtr] =
1754 new CastExpression(exp = expressionStack[expressionPtr + 1], castType = getTypeReference(expressionStack[expressionPtr]));
1755 expressionLengthPtr--;
1756 updateSourcePosition(castType);
1757 cast.sourceStart = castType.sourceStart;
1758 cast.sourceEnd = exp.sourceEnd;
1759 castType.sourceStart++;
1760 castType.sourceEnd--;
1762 protected void consumeCatches() {
1763 // Catches ::= Catches CatchClause
1764 optimizedConcatNodeLists();
1766 protected void consumeCatchHeader() {
1767 // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1769 if (currentElement == null) {
1770 return; // should never occur, this consumeRule is only used in recovery mode
1772 // current element should be a block due to the presence of the opening brace
1773 if (!(currentElement instanceof RecoveredBlock)) {
1776 // exception argument is already on astStack
1777 ((RecoveredBlock) currentElement).attach(new RecoveredLocalVariable((Argument) astStack[astPtr--], currentElement, 0));
1778 // insert catch variable in catch block
1779 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1780 restartRecovery = true; // request to restart from here on
1781 lastIgnoredToken = -1;
1783 protected void consumeClassBodyDeclaration() {
1784 // ClassBodyDeclaration ::= Diet Block
1785 //push an Initializer
1786 //optimize the push/pop
1787 nestedMethod[nestedType]--;
1788 Initializer initializer = new Initializer((Block) astStack[astPtr], 0);
1789 intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1790 realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1791 int javadocCommentStart = intStack[intPtr--];
1792 if (javadocCommentStart != -1) {
1793 initializer.declarationSourceStart = javadocCommentStart;
1795 astStack[astPtr] = initializer;
1796 initializer.sourceEnd = endStatementPosition;
1797 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1799 protected void consumeClassBodyDeclarations() {
1800 // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1803 protected void consumeClassBodyDeclarationsopt() {
1804 // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1807 protected void consumeClassBodyopt() {
1808 // ClassBodyopt ::= $empty
1809 pushOnAstStack(null);
1810 endPosition = scanner.startPosition - 1;
1812 protected void consumeClassDeclaration() {
1813 // ClassDeclaration ::= ClassHeader ClassBody
1816 if ((length = astLengthStack[astLengthPtr--]) != 0) {
1817 //there are length declarations
1818 //dispatch according to the type of the declarations
1819 dispatchDeclarationInto(length);
1822 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1824 // mark fields and initializer with local type mark if needed
1825 markFieldsWithLocalType(typeDecl);
1827 //convert constructor that do not have the type's name into methods
1828 boolean hasConstructor = typeDecl.checkConstructors(this);
1830 //add the default constructor when needed (interface don't have it)
1831 if (!hasConstructor) {
1832 boolean insideFieldInitializer = false;
1834 for (int i = nestedType; i > 0; i--) {
1835 if (variablesCounter[i] > 0) {
1836 insideFieldInitializer = true;
1841 typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true);
1844 //always add <clinit> (will be remove at code gen time if empty)
1845 if (this.scanner.containsAssertKeyword) {
1846 typeDecl.bits |= AstNode.AddAssertionMASK;
1848 typeDecl.addClinit();
1849 typeDecl.bodyEnd = endStatementPosition;
1850 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1852 protected void consumeClassHeader() {
1853 // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1855 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1856 if (currentToken == TokenNameLBRACE) {
1857 typeDecl.bodyStart = scanner.currentPosition;
1859 if (currentElement != null) {
1860 restartRecovery = true; // used to avoid branching back into the regular automaton
1862 // flush the comments related to the class header
1863 scanner.commentPtr = -1;
1865 protected void consumeClassHeaderExtends() {
1866 // ClassHeaderExtends ::= 'extends' ClassType
1867 // There is a class declaration on the top of stack
1868 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1870 typeDecl.superclass = getTypeReference(0);
1871 typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1873 if (currentElement != null) {
1874 lastCheckPoint = typeDecl.bodyStart;
1877 protected void consumeClassHeaderImplements() {
1878 // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1879 int length = astLengthStack[astLengthPtr--];
1882 // There is a class declaration on the top of stack
1883 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1884 System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
1885 typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
1886 listLength = 0; // reset after having read super-interfaces
1888 if (currentElement != null) { // is recovering
1889 lastCheckPoint = typeDecl.bodyStart;
1892 protected void consumeClassHeaderName() {
1893 // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1894 TypeDeclaration typeDecl;
1895 if (nestedMethod[nestedType] == 0) {
1896 if (nestedType != 0) {
1897 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
1899 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1902 // Record that the block has a declaration for local types
1903 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
1904 markCurrentMethodWithLocalType();
1908 //highlight the name of the type
1909 long pos = identifierPositionStack[identifierPtr];
1910 typeDecl.sourceEnd = (int) pos;
1911 typeDecl.sourceStart = (int) (pos >>> 32);
1912 typeDecl.name = identifierStack[identifierPtr--];
1913 identifierLengthPtr--;
1915 //compute the declaration source too
1916 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
1917 // we want to keep the beginning position but get rid of the end position
1918 // it is only used for the ClassLiteralAccess positions.
1919 typeDecl.declarationSourceStart = intStack[intPtr--];
1920 intPtr--; // remove the end position of the class token
1922 typeDecl.modifiersSourceStart = intStack[intPtr--];
1923 typeDecl.modifiers = intStack[intPtr--];
1924 if (typeDecl.modifiersSourceStart >= 0) {
1925 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
1927 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
1928 pushOnAstStack(typeDecl);
1930 listLength = 0; // will be updated when reading super-interfaces
1932 if (currentElement != null) {
1933 lastCheckPoint = typeDecl.bodyStart;
1934 currentElement = currentElement.add(typeDecl, 0);
1935 lastIgnoredToken = -1;
1938 protected void consumeClassInstanceCreationExpression() {
1939 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1940 classInstanceCreation(false);
1942 protected void consumeClassInstanceCreationExpressionName() {
1943 // ClassInstanceCreationExpressionName ::= Name '.'
1944 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1946 protected void consumeClassInstanceCreationExpressionQualified() {
1947 // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1948 // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1950 classInstanceCreation(true); // <-- push the Qualifed....
1952 expressionLengthPtr--;
1953 QualifiedAllocationExpression qae = (QualifiedAllocationExpression) expressionStack[expressionPtr--];
1954 qae.enclosingInstance = expressionStack[expressionPtr];
1955 expressionStack[expressionPtr] = qae;
1956 qae.sourceStart = qae.enclosingInstance.sourceStart;
1958 protected void consumeClassTypeElt() {
1959 // ClassTypeElt ::= ClassType
1960 pushOnAstStack(getTypeReference(0));
1961 /* if incomplete thrown exception list, listLength counter will not have been reset,
1962 indicating that some items are available on the stack */
1965 protected void consumeClassTypeList() {
1966 // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
1967 optimizedConcatNodeLists();
1969 protected void consumeCompilationUnit() {
1970 // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
1971 // do nothing by default
1973 protected void consumeConditionalExpression(int op) {
1974 // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
1975 //optimize the push/pop
1978 expressionLengthPtr -= 2;
1979 expressionStack[expressionPtr] =
1980 new ConditionalExpression(
1981 expressionStack[expressionPtr],
1982 expressionStack[expressionPtr + 1],
1983 expressionStack[expressionPtr + 2]);
1985 protected void consumeConstructorBlockStatements() {
1986 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
1987 concatNodeLists(); // explictly add the first statement into the list of statements
1989 protected void consumeConstructorBody() {
1990 // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
1991 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
1992 nestedMethod[nestedType]--;
1994 protected void consumeConstructorDeclaration() {
1995 // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
1998 astStack : MethodDeclaration statements
1999 identifierStack : name
2001 astStack : MethodDeclaration
2005 //must provide a default constructor call when needed
2009 // pop the position of the { (body of the method) pushed in block decl
2014 ExplicitConstructorCall constructorCall = null;
2015 Statement[] statements = null;
2016 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2018 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) {
2019 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
2020 System.arraycopy(astStack, astPtr + 2, statements = new Statement[length - 1], 0, length - 1);
2021 constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
2022 } else { //need to add explicitly the super();
2023 System.arraycopy(astStack, astPtr + 1, statements = new Statement[length], 0, length);
2024 constructorCall = SuperReference.implicitSuperConstructorCall();
2028 // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
2029 constructorCall = SuperReference.implicitSuperConstructorCall();
2033 // now we know that the top of stack is a constructorDeclaration
2034 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
2035 cd.constructorCall = constructorCall;
2036 cd.statements = statements;
2038 //highlight of the implicit call on the method name
2039 if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
2040 cd.constructorCall.sourceEnd = cd.sourceEnd;
2041 cd.constructorCall.sourceStart = cd.sourceStart;
2044 //watch for } that could be given as a unicode ! ( u007D is '}' )
2045 // store the endPosition (position just before the '}') in case there is
2046 // a trailing comment behind the end of the method
2047 cd.bodyEnd = endPosition;
2048 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2051 protected void consumeInvalidConstructorDeclaration() {
2052 // ConstructorDeclaration ::= ConstructorHeader ';'
2053 // now we know that the top of stack is a constructorDeclaration
2054 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
2056 cd.bodyEnd = endPosition; // position just before the trailing semi-colon
2057 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2058 // report the problem and continue the parsing - narrowing the problem onto the method
2060 protected void consumeConstructorHeader() {
2061 // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
2063 AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
2065 if (currentToken == TokenNameLBRACE) {
2066 method.bodyStart = scanner.currentPosition;
2069 if (currentElement != null) {
2070 restartRecovery = true; // used to avoid branching back into the regular automaton
2073 protected void consumeConstructorHeaderName() {
2075 /* recovering - might be an empty message send */
2076 if (currentElement != null) {
2077 if (lastIgnoredToken == TokenNamenew) { // was an allocation expression
2078 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
2079 restartRecovery = true;
2084 // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
2085 ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
2087 //name -- this is not really revelant but we do .....
2088 cd.selector = identifierStack[identifierPtr];
2089 long selectorSource = identifierPositionStack[identifierPtr--];
2090 identifierLengthPtr--;
2093 cd.declarationSourceStart = intStack[intPtr--];
2094 cd.modifiers = intStack[intPtr--];
2096 //highlight starts at the selector starts
2097 cd.sourceStart = (int) (selectorSource >>> 32);
2099 cd.sourceEnd = lParenPos;
2100 cd.bodyStart = lParenPos + 1;
2101 listLength = 0; // initialize listLength before reading parameters/throws
2104 if (currentElement != null) {
2105 lastCheckPoint = cd.bodyStart;
2106 if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT) || cd.modifiers != 0) {
2107 currentElement = currentElement.add(cd, 0);
2108 lastIgnoredToken = -1;
2112 protected void consumeDefaultLabel() {
2113 // SwitchLabel ::= 'default' ':'
2114 pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--]));
2116 protected void consumeDefaultModifiers() {
2117 checkAnnotation(); // might update modifiers with AccDeprecated
2118 pushOnIntStack(modifiers); // modifiers
2119 pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
2122 protected void consumeDiet() {
2125 pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one
2126 jumpOverMethodBody();
2128 protected void consumeDims() {
2129 // Dims ::= DimsLoop
2130 pushOnIntStack(dimensions);
2133 protected void consumeDimWithOrWithOutExpr() {
2134 // DimWithOrWithOutExpr ::= '[' ']'
2135 pushOnExpressionStack(null);
2137 protected void consumeDimWithOrWithOutExprs() {
2138 // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
2139 concatExpressionLists();
2141 protected void consumeEmptyArgumentListopt() {
2142 // ArgumentListopt ::= $empty
2143 pushOnExpressionStackLengthStack(0);
2145 protected void consumeEmptyArrayInitializer() {
2146 // ArrayInitializer ::= '{' ,opt '}'
2147 arrayInitializer(0);
2149 protected void consumeEmptyArrayInitializeropt() {
2150 // ArrayInitializeropt ::= $empty
2151 pushOnExpressionStackLengthStack(0);
2153 protected void consumeEmptyBlockStatementsopt() {
2154 // BlockStatementsopt ::= $empty
2155 pushOnAstLengthStack(0);
2157 protected void consumeEmptyCatchesopt() {
2158 // Catchesopt ::= $empty
2159 pushOnAstLengthStack(0);
2161 protected void consumeEmptyClassBodyDeclarationsopt() {
2162 // ClassBodyDeclarationsopt ::= $empty
2163 pushOnAstLengthStack(0);
2165 protected void consumeEmptyClassMemberDeclaration() {
2166 // ClassMemberDeclaration ::= ';'
2167 pushOnAstLengthStack(0);
2169 protected void consumeEmptyDimsopt() {
2170 // Dimsopt ::= $empty
2173 protected void consumeEmptyExpression() {
2174 // Expressionopt ::= $empty
2175 pushOnExpressionStackLengthStack(0);
2177 protected void consumeEmptyForInitopt() {
2178 // ForInitopt ::= $empty
2179 pushOnAstLengthStack(0);
2181 protected void consumeEmptyForUpdateopt() {
2182 // ForUpdateopt ::= $empty
2183 pushOnExpressionStackLengthStack(0);
2185 protected void consumeEmptyImportDeclarationsopt() {
2186 // ImportDeclarationsopt ::= $empty
2187 pushOnAstLengthStack(0);
2189 protected void consumeEmptyInterfaceMemberDeclaration() {
2190 // InterfaceMemberDeclaration ::= ';'
2191 pushOnAstLengthStack(0);
2193 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
2194 // InterfaceMemberDeclarationsopt ::= $empty
2195 pushOnAstLengthStack(0);
2197 protected void consumeEmptyStatement() {
2198 // EmptyStatement ::= ';'
2199 if (this.scanner.source[endStatementPosition] == ';') {
2200 pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition));
2202 // we have a Unicode for the ';' (/u003B)
2203 pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition));
2206 protected void consumeEmptySwitchBlock() {
2207 // SwitchBlock ::= '{' '}'
2208 pushOnAstLengthStack(0);
2210 protected void consumeEmptyTypeDeclaration() {
2211 // TypeDeclaration ::= ';'
2212 pushOnAstLengthStack(0);
2214 protected void consumeEmptyTypeDeclarationsopt() {
2215 // TypeDeclarationsopt ::= $empty
2216 pushOnAstLengthStack(0);
2218 protected void consumeEnterAnonymousClassBody() {
2219 // EnterAnonymousClassBody ::= $empty
2220 QualifiedAllocationExpression alloc;
2221 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
2222 alloc = anonymousType.allocation = new QualifiedAllocationExpression(anonymousType);
2223 markCurrentMethodWithLocalType();
2224 pushOnAstStack(anonymousType);
2226 alloc.sourceEnd = rParenPos; //the position has been stored explicitly
2228 if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
2229 expressionPtr -= argumentLength;
2230 System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[argumentLength], 0, argumentLength);
2232 alloc.type = getTypeReference(0);
2234 anonymousType.sourceEnd = alloc.sourceEnd;
2235 //position at the type while it impacts the anonymous declaration
2236 anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
2237 alloc.sourceStart = intStack[intPtr--];
2238 pushOnExpressionStack(alloc);
2240 anonymousType.bodyStart = scanner.currentPosition;
2241 listLength = 0; // will be updated when reading super-interfaces
2243 if (currentElement != null) {
2244 lastCheckPoint = anonymousType.bodyStart;
2245 // the recoveryTokenCheck will deal with the open brace
2246 currentElement = currentElement.add(anonymousType, 0);
2247 currentToken = 0; // opening brace already taken into account
2248 lastIgnoredToken = -1;
2251 protected void consumeEnterCompilationUnit() {
2252 // EnterCompilationUnit ::= $empty
2253 // do nothing by default
2255 protected void consumeEnterVariable() {
2256 // EnterVariable ::= $empty
2257 // do nothing by default
2259 char[] name = identifierStack[identifierPtr];
2260 long namePosition = identifierPositionStack[identifierPtr];
2261 int extendedDimension = intStack[intPtr--];
2262 AbstractVariableDeclaration declaration;
2263 // create the ast node
2264 boolean isLocalDeclaration = nestedMethod[nestedType] != 0;
2265 if (isLocalDeclaration) {
2266 // create the local variable declarations
2267 declaration = this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
2269 // create the field declaration
2270 declaration = this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
2274 identifierLengthPtr--;
2276 int variableIndex = variablesCounter[nestedType];
2278 if (variableIndex == 0) {
2279 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
2280 if (isLocalDeclaration) {
2281 declaration.declarationSourceStart = intStack[intPtr--];
2282 declaration.modifiers = intStack[intPtr--];
2283 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
2284 if (declaration.declarationSourceStart == -1) {
2285 // this is true if there is no modifiers for the local variable declaration
2286 declaration.declarationSourceStart = type.sourceStart;
2288 pushOnAstStack(type);
2290 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
2291 pushOnAstStack(type);
2292 declaration.declarationSourceStart = intStack[intPtr--];
2293 declaration.modifiers = intStack[intPtr--];
2296 type = (TypeReference) astStack[astPtr - variableIndex];
2297 typeDim = type.dimensions();
2298 AbstractVariableDeclaration previousVariable = (AbstractVariableDeclaration) astStack[astPtr];
2299 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
2300 declaration.modifiers = previousVariable.modifiers;
2303 if (extendedDimension == 0) {
2304 declaration.type = type;
2306 int dimension = typeDim + extendedDimension;
2307 //on the identifierLengthStack there is the information about the type....
2309 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2311 int typeSourceStart = type.sourceStart;
2312 int typeSourceEnd = type.sourceEnd;
2313 type = TypeReference.baseTypeReference(-baseType, dimension);
2314 type.sourceStart = typeSourceStart;
2315 type.sourceEnd = typeSourceEnd;
2316 declaration.type = type;
2318 declaration.type = this.copyDims(type, dimension);
2321 variablesCounter[nestedType]++;
2322 pushOnAstStack(declaration);
2324 if (currentElement != null) {
2325 if (!(currentElement instanceof RecoveredType)
2326 && (currentToken == TokenNameDOT //|| declaration.modifiers != 0
2327 || (scanner.getLineNumber(declaration.type.sourceStart) != scanner.getLineNumber((int) (namePosition >>> 32))))) {
2328 lastCheckPoint = (int) (namePosition >>> 32);
2329 restartRecovery = true;
2332 if (isLocalDeclaration) {
2333 LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr];
2334 lastCheckPoint = localDecl.sourceEnd + 1;
2335 currentElement = currentElement.add(localDecl, 0);
2337 FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr];
2338 lastCheckPoint = fieldDecl.sourceEnd + 1;
2339 currentElement = currentElement.add(fieldDecl, 0);
2341 lastIgnoredToken = -1;
2344 protected void consumeEqualityExpression(int op) {
2345 // EqualityExpression ::= EqualityExpression '==' RelationalExpression
2346 // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
2348 //optimize the push/pop
2351 expressionLengthPtr--;
2352 expressionStack[expressionPtr] = new EqualExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
2354 protected void consumeExitVariableWithInitialization() {
2355 // ExitVariableWithInitialization ::= $empty
2356 // do nothing by default
2357 expressionLengthPtr--;
2358 AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr];
2359 variableDecl.initialization = expressionStack[expressionPtr--];
2360 // we need to update the declarationSourceEnd of the local variable declaration to the
2361 // source end position of the initialization expression
2362 variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
2363 variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
2365 protected void consumeExitVariableWithoutInitialization() {
2366 // ExitVariableWithoutInitialization ::= $empty
2367 // do nothing by default
2369 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
2371 /* flag allows to distinguish 3 cases :
2373 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
2374 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
2376 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
2377 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
2379 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
2380 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
2382 int startPosition = intStack[intPtr--];
2383 ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
2385 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
2386 expressionPtr -= length;
2387 System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
2391 ecc.sourceStart = startPosition;
2394 expressionLengthPtr--;
2395 ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart;
2398 ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
2401 pushOnAstStack(ecc);
2402 ecc.sourceEnd = endPosition;
2404 protected void consumeExpressionStatement() {
2405 // ExpressionStatement ::= StatementExpression ';'
2406 expressionLengthPtr--;
2407 pushOnAstStack(expressionStack[expressionPtr--]);
2409 protected void consumeFieldAccess(boolean isSuperAccess) {
2410 // FieldAccess ::= Primary '.' 'Identifier'
2411 // FieldAccess ::= 'super' '.' 'Identifier'
2413 FieldReference fr = new FieldReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
2414 identifierLengthPtr--;
2415 if (isSuperAccess) {
2416 //considerates the fieldReference beginning at the 'super' ....
2417 fr.sourceStart = intStack[intPtr--];
2418 fr.receiver = new SuperReference(fr.sourceStart, endPosition);
2419 pushOnExpressionStack(fr);
2422 if ((fr.receiver = expressionStack[expressionPtr]).isThis()) {
2423 //fieldreference begins at the this
2424 fr.sourceStart = fr.receiver.sourceStart;
2426 expressionStack[expressionPtr] = fr;
2429 protected void consumeFieldDeclaration() {
2430 // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
2431 // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
2435 expressionStack: Expression Expression ...... Expression
2436 identifierStack : type identifier identifier ...... identifier
2437 intStack : typeDim dim dim dim
2439 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2445 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2447 for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2448 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2449 fieldDeclaration.declarationSourceEnd = endStatementPosition;
2450 fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included
2452 updateSourceDeclarationParts(variableDeclaratorsCounter);
2453 int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition);
2454 if (endPos != endStatementPosition) {
2455 for (int i = 0; i < variableDeclaratorsCounter; i++) {
2456 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2457 fieldDeclaration.declarationSourceEnd = endPos;
2460 // update the astStack, astPtr and astLengthStack
2461 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2462 System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
2463 astPtr--; // remove the type reference
2464 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2467 if (currentElement != null) {
2468 lastCheckPoint = endPos + 1;
2469 if (currentElement.parent != null && currentElement instanceof RecoveredField) {
2470 currentElement = currentElement.parent;
2472 restartRecovery = true;
2474 variablesCounter[nestedType] = 0;
2476 protected void consumeForceNoDiet() {
2477 // ForceNoDiet ::= $empty
2480 protected void consumeForInit() {
2481 // ForInit ::= StatementExpressionList
2482 pushOnAstLengthStack(-1);
2484 protected void consumeFormalParameter() {
2485 // FormalParameter ::= Type VariableDeclaratorId ==> false
2486 // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
2489 identifierStack : type identifier
2497 identifierLengthPtr--;
2498 char[] name = identifierStack[identifierPtr];
2499 long namePositions = identifierPositionStack[identifierPtr--];
2500 TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
2501 int modifierPositions = intStack[intPtr--];
2503 Argument arg = new Argument(name, namePositions, type, intStack[intPtr + 1] & ~AccDeprecated); // modifiers
2504 arg.declarationSourceStart = modifierPositions;
2505 pushOnAstStack(arg);
2507 /* if incomplete method header, listLength counter will not have been reset,
2508 indicating that some arguments are available on the stack */
2511 protected void consumeFormalParameterList() {
2512 // FormalParameterList ::= FormalParameterList ',' FormalParameter
2513 optimizedConcatNodeLists();
2515 protected void consumeFormalParameterListopt() {
2516 // FormalParameterListopt ::= $empty
2517 pushOnAstLengthStack(0);
2519 protected void consumeImportDeclarations() {
2520 // ImportDeclarations ::= ImportDeclarations ImportDeclaration
2521 optimizedConcatNodeLists();
2523 protected void consumeImportDeclarationsopt() {
2524 // ImportDeclarationsopt ::= ImportDeclarations
2526 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2528 System.arraycopy(astStack, astPtr + 1, compilationUnit.imports = new ImportReference[length], 0, length);
2531 protected void consumeInstanceOfExpression(int op) {
2532 // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
2533 //optimize the push/pop
2535 //by construction, no base type may be used in getTypeReference
2537 expressionStack[expressionPtr] =
2538 exp = new InstanceOfExpression(expressionStack[expressionPtr], getTypeReference(intStack[intPtr--]), op);
2539 if (exp.sourceEnd == 0) {
2540 //array on base type....
2541 exp.sourceEnd = scanner.startPosition - 1;
2543 //the scanner is on the next token already....
2545 protected void consumeInterfaceDeclaration() {
2546 // see consumeClassDeclaration in case of changes: duplicated code
2547 // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
2549 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2550 //there are length declarations
2551 //dispatch.....according to the type of the declarations
2552 dispatchDeclarationInto(length);
2555 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2557 // mark fields and initializer with local type mark if needed
2558 markFieldsWithLocalType(typeDecl);
2560 //convert constructor that do not have the type's name into methods
2561 typeDecl.checkConstructors(this);
2563 //always add <clinit> (will be remove at code gen time if empty)
2564 if (this.scanner.containsAssertKeyword) {
2565 typeDecl.bits |= AstNode.AddAssertionMASK;
2567 typeDecl.addClinit();
2568 typeDecl.bodyEnd = endStatementPosition;
2569 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2571 protected void consumeInterfaceHeader() {
2572 // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2574 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2575 if (currentToken == TokenNameLBRACE) {
2576 typeDecl.bodyStart = scanner.currentPosition;
2578 if (currentElement != null) {
2579 restartRecovery = true; // used to avoid branching back into the regular automaton
2581 // flush the comments related to the interface header
2582 scanner.commentPtr = -1;
2584 protected void consumeInterfaceHeaderExtends() {
2585 // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2586 int length = astLengthStack[astLengthPtr--];
2589 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2590 System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
2591 typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
2592 listLength = 0; // reset after having read super-interfaces
2594 if (currentElement != null) {
2595 lastCheckPoint = typeDecl.bodyStart;
2598 protected void consumeInterfaceHeaderName() {
2599 // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2600 TypeDeclaration typeDecl;
2601 if (nestedMethod[nestedType] == 0) {
2602 if (nestedType != 0) {
2603 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
2605 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2608 // Record that the block has a declaration for local types
2609 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
2610 markCurrentMethodWithLocalType();
2614 //highlight the name of the type
2615 long pos = identifierPositionStack[identifierPtr];
2616 typeDecl.sourceEnd = (int) pos;
2617 typeDecl.sourceStart = (int) (pos >>> 32);
2618 typeDecl.name = identifierStack[identifierPtr--];
2619 identifierLengthPtr--;
2621 //compute the declaration source too
2622 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2623 // we want to keep the beginning position but get rid of the end position
2624 // it is only used for the ClassLiteralAccess positions.
2625 typeDecl.declarationSourceStart = intStack[intPtr--];
2626 intPtr--; // remove the end position of the class token
2627 typeDecl.modifiersSourceStart = intStack[intPtr--];
2628 typeDecl.modifiers = intStack[intPtr--];
2629 if (typeDecl.modifiersSourceStart >= 0) {
2630 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2632 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2633 pushOnAstStack(typeDecl);
2634 listLength = 0; // will be updated when reading super-interfaces
2636 if (currentElement != null) { // is recovering
2637 lastCheckPoint = typeDecl.bodyStart;
2638 currentElement = currentElement.add(typeDecl, 0);
2639 lastIgnoredToken = -1;
2642 protected void consumeInterfaceMemberDeclarations() {
2643 // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2646 protected void consumeInterfaceMemberDeclarationsopt() {
2647 // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2650 protected void consumeInterfaceType() {
2651 // InterfaceType ::= ClassOrInterfaceType
2652 pushOnAstStack(getTypeReference(0));
2653 /* if incomplete type header, listLength counter will not have been reset,
2654 indicating that some interfaces are available on the stack */
2657 protected void consumeInterfaceTypeList() {
2658 // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2659 optimizedConcatNodeLists();
2661 protected void consumeLeftHandSide() {
2662 // LeftHandSide ::= Name
2664 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2666 protected void consumeLeftParen() {
2667 // PushLPAREN ::= '('
2668 pushOnIntStack(lParenPos);
2670 protected void consumeLocalVariableDeclaration() {
2671 // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2675 expressionStack: Expression Expression ...... Expression
2676 identifierStack : type identifier identifier ...... identifier
2677 intStack : typeDim dim dim dim
2679 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2685 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2687 // update the astStack, astPtr and astLengthStack
2688 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2689 System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
2690 astPtr--; // remove the type reference
2691 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2692 variablesCounter[nestedType] = 0;
2694 protected void consumeLocalVariableDeclarationStatement() {
2695 // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2696 // see blockReal in case of change: duplicated code
2697 // increment the amount of declared variables for this block
2698 realBlockStack[realBlockPtr]++;
2700 protected void consumeMethodBody() {
2701 // MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
2702 nestedMethod[nestedType]--;
2704 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2705 // MethodDeclaration ::= MethodHeader MethodBody
2706 // AbstractMethodDeclaration ::= MethodHeader ';'
2709 astStack : modifiers arguments throws statements
2710 identifierStack : type name
2711 intStack : dim dim dim
2713 astStack : MethodDeclaration
2719 if (isNotAbstract) {
2720 // pop the position of the { (body of the method) pushed in block decl
2724 int explicitDeclarations = 0;
2725 Statement[] statements = null;
2726 if (isNotAbstract) {
2728 explicitDeclarations = realBlockStack[realBlockPtr--];
2729 if ((length = astLengthStack[astLengthPtr--]) != 0)
2730 System.arraycopy(astStack, (astPtr -= length) + 1, statements = new Statement[length], 0, length);
2733 // now we know that we have a method declaration at the top of the ast stack
2734 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2735 md.statements = statements;
2736 md.explicitDeclarations = explicitDeclarations;
2738 // cannot be done in consumeMethodHeader because we have no idea whether or not there
2739 // is a body when we reduce the method header
2740 if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2741 md.modifiers |= AccSemicolonBody;
2743 // store the endPosition (position just before the '}') in case there is
2744 // a trailing comment behind the end of the method
2745 md.bodyEnd = endPosition;
2746 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2748 protected void consumeMethodHeader() {
2749 // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2750 // retrieve end position of method declarator
2751 AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
2753 if (currentToken == TokenNameLBRACE) {
2754 method.bodyStart = scanner.currentPosition;
2757 if (currentElement != null) {
2758 if (currentToken == TokenNameSEMICOLON) {
2759 method.modifiers |= AccSemicolonBody;
2760 method.declarationSourceEnd = scanner.currentPosition - 1;
2761 method.bodyEnd = scanner.currentPosition - 1;
2762 if (currentElement.parent != null) {
2763 currentElement = currentElement.parent;
2766 restartRecovery = true; // used to avoid branching back into the regular automaton
2769 protected void consumeMethodHeaderExtendedDims() {
2770 // MethodHeaderExtendedDims ::= Dimsopt
2771 // now we update the returnType of the method
2772 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2773 int extendedDims = intStack[intPtr--];
2774 if (extendedDims != 0) {
2775 TypeReference returnType = md.returnType;
2776 md.sourceEnd = endPosition;
2777 int dims = returnType.dimensions() + extendedDims;
2779 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2781 int sourceStart = returnType.sourceStart;
2782 int sourceEnd = returnType.sourceEnd;
2783 returnType = TypeReference.baseTypeReference(-baseType, dims);
2784 returnType.sourceStart = sourceStart;
2785 returnType.sourceEnd = sourceEnd;
2786 md.returnType = returnType;
2788 md.returnType = this.copyDims(md.returnType, dims);
2790 if (currentToken == TokenNameLBRACE) {
2791 md.bodyStart = endPosition + 1;
2794 if (currentElement != null) {
2795 lastCheckPoint = md.bodyStart;
2799 protected void consumeMethodHeaderName() {
2800 // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2801 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2804 md.selector = identifierStack[identifierPtr];
2805 long selectorSource = identifierPositionStack[identifierPtr--];
2806 identifierLengthPtr--;
2808 md.returnType = getTypeReference(intStack[intPtr--]);
2810 md.declarationSourceStart = intStack[intPtr--];
2811 md.modifiers = intStack[intPtr--];
2813 //highlight starts at selector start
2814 md.sourceStart = (int) (selectorSource >>> 32);
2816 md.sourceEnd = lParenPos;
2817 md.bodyStart = lParenPos + 1;
2818 listLength = 0; // initialize listLength before reading parameters/throws
2821 if (currentElement != null) {
2822 if (currentElement instanceof RecoveredType //|| md.modifiers != 0
2823 || (scanner.getLineNumber(md.returnType.sourceStart) == scanner.getLineNumber(md.sourceStart))) {
2824 lastCheckPoint = md.bodyStart;
2825 currentElement = currentElement.add(md, 0);
2826 lastIgnoredToken = -1;
2828 lastCheckPoint = md.sourceStart;
2829 restartRecovery = true;
2833 protected void consumeMethodHeaderParameters() {
2834 // MethodHeaderParameters ::= FormalParameterListopt ')'
2835 int length = astLengthStack[astLengthPtr--];
2837 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2838 md.sourceEnd = rParenPos;
2841 System.arraycopy(astStack, astPtr + 1, md.arguments = new Argument[length], 0, length);
2843 md.bodyStart = rParenPos + 1;
2844 listLength = 0; // reset listLength after having read all parameters
2846 if (currentElement != null) {
2847 lastCheckPoint = md.bodyStart;
2848 if (currentElement.parseTree() == md)
2851 // might not have been attached yet - in some constructor scenarii
2852 if (md.isConstructor()) {
2853 if ((length != 0) || (currentToken == TokenNameLBRACE) // || (currentToken == TokenNamethrows)
2855 currentElement = currentElement.add(md, 0);
2856 lastIgnoredToken = -1;
2861 protected void consumeMethodHeaderThrowsClause() {
2862 // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2863 int length = astLengthStack[astLengthPtr--];
2865 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2866 System.arraycopy(astStack, astPtr + 1, md.thrownExceptions = new TypeReference[length], 0, length);
2867 md.sourceEnd = md.thrownExceptions[length - 1].sourceEnd;
2868 md.bodyStart = md.thrownExceptions[length - 1].sourceEnd + 1;
2869 listLength = 0; // reset listLength after having read all thrown exceptions
2871 if (currentElement != null) {
2872 lastCheckPoint = md.bodyStart;
2875 protected void consumeMethodInvocationName() {
2876 // MethodInvocation ::= Name '(' ArgumentListopt ')'
2878 // when the name is only an identifier...we have a message send to "this" (implicit)
2880 MessageSend m = newMessageSend();
2881 m.sourceEnd = rParenPos;
2882 m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2883 m.selector = identifierStack[identifierPtr--];
2884 if (identifierLengthStack[identifierLengthPtr] == 1) {
2885 m.receiver = ThisReference.ThisImplicit;
2886 identifierLengthPtr--;
2888 identifierLengthStack[identifierLengthPtr]--;
2889 m.receiver = getUnspecifiedReference();
2890 m.sourceStart = m.receiver.sourceStart;
2892 pushOnExpressionStack(m);
2894 protected void consumeMethodInvocationPrimary() {
2895 //optimize the push/pop
2896 //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2898 MessageSend m = newMessageSend();
2899 m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2900 m.selector = identifierStack[identifierPtr--];
2901 identifierLengthPtr--;
2902 m.receiver = expressionStack[expressionPtr];
2903 m.sourceStart = m.receiver.sourceStart;
2904 m.sourceEnd = rParenPos;
2905 expressionStack[expressionPtr] = m;
2907 protected void consumeMethodInvocationSuper() {
2908 // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2910 MessageSend m = newMessageSend();
2911 m.sourceStart = intStack[intPtr--];
2912 m.sourceEnd = rParenPos;
2913 m.nameSourcePosition = identifierPositionStack[identifierPtr];
2914 m.selector = identifierStack[identifierPtr--];
2915 identifierLengthPtr--;
2916 m.receiver = new SuperReference(m.sourceStart, endPosition);
2917 pushOnExpressionStack(m);
2919 protected void consumeMethodPushModifiersHeaderName() {
2920 // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
2921 // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
2922 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2925 md.selector = identifierStack[identifierPtr];
2926 long selectorSource = identifierPositionStack[identifierPtr--];
2927 identifierLengthPtr--;
2930 md.declarationSourceStart = intStack[intPtr--];
2931 md.modifiers = intStack[intPtr--];
2934 md.returnType = getTypeReference(intStack[intPtr--]);
2936 //highlight starts at selector start
2937 md.sourceStart = (int) (selectorSource >>> 32);
2939 md.sourceEnd = lParenPos;
2940 md.bodyStart = lParenPos + 1;
2941 listLength = 0; // initialize listLength before reading parameters/throws
2944 if (currentElement != null) {
2945 lastCheckPoint = md.bodyStart;
2946 currentElement = currentElement.add(md, 0);
2947 lastIgnoredToken = -1;
2950 protected void consumeModifiers() {
2951 int savedModifiersSourceStart = modifiersSourceStart;
2952 checkAnnotation(); // might update modifiers with AccDeprecated
2953 pushOnIntStack(modifiers); // modifiers
2954 if (modifiersSourceStart >= savedModifiersSourceStart) {
2955 modifiersSourceStart = savedModifiersSourceStart;
2957 pushOnIntStack(modifiersSourceStart);
2960 protected void consumeNestedMethod() {
2961 // NestedMethod ::= $empty
2962 jumpOverMethodBody();
2963 nestedMethod[nestedType]++;
2966 protected void consumeNestedType() {
2967 // NestedType ::= $empty
2970 nestedMethod[nestedType] = 0;
2971 } catch (IndexOutOfBoundsException e) {
2972 //except in test's cases, it should never raise
2973 int oldL = nestedMethod.length;
2974 System.arraycopy(nestedMethod, 0, (nestedMethod = new int[oldL + 30]), 0, oldL);
2975 nestedMethod[nestedType] = 0;
2976 // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection
2977 System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL);
2979 variablesCounter[nestedType] = 0;
2981 protected void consumeOneDimLoop() {
2982 // OneDimLoop ::= '[' ']'
2985 protected void consumeOnlySynchronized() {
2986 // OnlySynchronized ::= 'synchronized'
2987 pushOnIntStack(this.synchronizedBlockSourceStart);
2990 protected void consumeOpenBlock() {
2991 // OpenBlock ::= $empty
2993 pushOnIntStack(scanner.startPosition);
2995 realBlockStack[++realBlockPtr] = 0;
2996 } catch (IndexOutOfBoundsException e) {
2997 //realBlockPtr is correct
2998 int oldStackLength = realBlockStack.length;
2999 int oldStack[] = realBlockStack;
3000 realBlockStack = new int[oldStackLength + StackIncrement];
3001 System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength);
3002 realBlockStack[realBlockPtr] = 0;
3005 protected void consumePackageDeclaration() {
3006 // PackageDeclaration ::= 'package' Name ';'
3007 /* build an ImportRef build from the last name
3008 stored in the identifier stack. */
3010 ImportReference impt = compilationUnit.currentPackage;
3011 // flush annotations defined prior to import statements
3012 impt.declarationEnd = endStatementPosition;
3013 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
3015 protected void consumePackageDeclarationName() {
3016 // PackageDeclarationName ::= 'package' Name
3017 /* build an ImportRef build from the last name
3018 stored in the identifier stack. */
3020 ImportReference impt;
3022 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
3023 identifierPtr -= length;
3024 long[] positions = new long[length];
3025 System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length);
3026 System.arraycopy(identifierPositionStack, identifierPtr--, positions, 0, length);
3027 compilationUnit.currentPackage = impt = new ImportReference(tokens, positions, true);
3029 if (currentToken == TokenNameSEMICOLON) {
3030 impt.declarationSourceEnd = scanner.currentPosition - 1;
3032 impt.declarationSourceEnd = impt.sourceEnd;
3034 impt.declarationEnd = impt.declarationSourceEnd;
3035 //endPosition is just before the ;
3036 impt.declarationSourceStart = intStack[intPtr--];
3039 if (currentElement != null) {
3040 lastCheckPoint = impt.declarationSourceEnd + 1;
3041 restartRecovery = true; // used to avoid branching back into the regular automaton
3044 protected void consumePostfixExpression() {
3045 // PostfixExpression ::= Name
3046 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
3048 protected void consumePrimaryNoNewArray() {
3049 // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
3050 updateSourcePosition(expressionStack[expressionPtr]);
3052 protected void consumePrimaryNoNewArrayArrayType() {
3053 // PrimaryNoNewArray ::= ArrayType '.' 'class'
3055 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(intStack[intPtr--])));
3057 protected void consumePrimaryNoNewArrayName() {
3058 // PrimaryNoNewArray ::= Name '.' 'class'
3060 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
3062 protected void consumePrimaryNoNewArrayNameSuper() {
3063 // PrimaryNoNewArray ::= Name '.' 'super'
3064 pushOnExpressionStack(new QualifiedSuperReference(getTypeReference(0), intStack[intPtr--], endPosition));
3066 protected void consumePrimaryNoNewArrayNameThis() {
3067 // PrimaryNoNewArray ::= Name '.' 'this'
3068 pushOnExpressionStack(new QualifiedThisReference(getTypeReference(0), intStack[intPtr--], endPosition));
3070 protected void consumePrimaryNoNewArrayPrimitiveType() {
3071 // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
3073 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
3075 protected void consumePrimaryNoNewArrayThis() {
3076 // PrimaryNoNewArray ::= 'this'
3077 pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition));
3079 protected void consumePrimitiveType() {
3080 // Type ::= PrimitiveType
3083 protected void consumePushModifiers() {
3084 if ((modifiers & AccSynchronized) != 0) {
3085 /* remove the starting position of the synchronized keyword
3086 * we don't need it when synchronized is part of the modifiers
3090 pushOnIntStack(modifiers); // modifiers
3091 pushOnIntStack(modifiersSourceStart);
3094 protected void consumePushPosition() {
3095 // for source managment purpose
3096 // PushPosition ::= $empty
3097 pushOnIntStack(endPosition);
3099 protected void consumeQualifiedName() {
3100 // QualifiedName ::= Name '.' SimpleName
3101 /*back from the recursive loop of QualifiedName.
3102 Updates identifier length into the length stack*/
3104 identifierLengthStack[--identifierLengthPtr]++;
3106 protected void consumeReferenceType() {
3107 // ReferenceType ::= ClassOrInterfaceType
3110 protected void consumeRestoreDiet() {
3111 // RestoreDiet ::= $empty
3114 protected void consumeRightParen() {
3115 // PushRPAREN ::= ')'
3116 pushOnIntStack(rParenPos);
3118 // This method is part of an automatic generation : do NOT edit-modify
3119 // This method is part of an automatic generation : do NOT edit-modify
3120 protected void consumeRule(int act) {
3122 case 29 : // System.out.println("Type ::= PrimitiveType");
3123 consumePrimitiveType();
3126 case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
3127 consumeReferenceType();
3130 case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName");
3131 consumeQualifiedName();
3134 case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
3135 consumeCompilationUnit();
3138 case 54 : // System.out.println("EnterCompilationUnit ::=");
3139 consumeEnterCompilationUnit();
3142 case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
3143 consumeCatchHeader();
3146 case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
3147 consumeImportDeclarations();
3150 case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
3151 consumeTypeDeclarations();
3154 case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
3155 consumePackageDeclaration();
3158 case 72 : // System.out.println("PackageDeclarationName ::= package Name");
3159 consumePackageDeclarationName();
3162 case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
3163 consumeSingleTypeImportDeclaration();
3166 case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
3167 consumeSingleTypeImportDeclarationName();
3170 case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
3171 consumeTypeImportOnDemandDeclaration();
3174 case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
3175 consumeTypeImportOnDemandDeclarationName();
3178 case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON");
3179 consumeEmptyTypeDeclaration();
3182 case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
3183 consumeClassDeclaration();
3186 case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
3187 consumeClassHeader();
3190 case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");
3191 consumeClassHeaderName();
3194 case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
3195 consumeClassHeaderExtends();
3198 case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
3199 consumeClassHeaderImplements();
3202 case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
3203 consumeInterfaceTypeList();
3206 case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
3207 consumeInterfaceType();
3210 case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
3211 consumeClassBodyDeclarations();
3214 case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
3215 consumeClassBodyDeclaration();
3218 case 110 : // System.out.println("Diet ::=");
3222 case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block");
3223 consumeClassBodyDeclaration();
3226 case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
3227 consumeEmptyClassMemberDeclaration();
3230 case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
3231 consumeFieldDeclaration();
3234 case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
3235 consumeVariableDeclarators();
3238 case 124 : // System.out.println("EnterVariable ::=");
3239 consumeEnterVariable();
3242 case 125 : // System.out.println("ExitVariableWithInitialization ::=");
3243 consumeExitVariableWithInitialization();
3246 case 126 : // System.out.println("ExitVariableWithoutInitialization ::=");
3247 consumeExitVariableWithoutInitialization();
3250 case 127 : // System.out.println("ForceNoDiet ::=");
3251 consumeForceNoDiet();
3254 case 128 : // System.out.println("RestoreDiet ::=");
3255 consumeRestoreDiet();
3258 case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
3259 // set to true to consume a method with a body
3260 consumeMethodDeclaration(true);
3263 case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
3264 // set to false to consume a method without body
3265 consumeMethodDeclaration(false);
3268 case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
3269 consumeMethodHeader();
3272 case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
3273 consumeMethodHeader();
3276 case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN");
3277 consumeMethodPushModifiersHeaderName();
3280 case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN");
3281 consumeMethodPushModifiersHeaderName();
3284 case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");
3285 consumeMethodHeaderName();
3288 case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
3289 consumeMethodHeaderParameters();
3292 case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
3293 consumeMethodHeaderExtendedDims();
3296 case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
3297 consumeMethodHeaderThrowsClause();
3300 case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
3301 consumeConstructorHeader();
3304 case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
3305 consumeConstructorHeaderName();
3308 case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
3309 consumeFormalParameterList();
3312 case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
3313 // the boolean is used to know if the modifiers should be reset
3314 consumeFormalParameter();
3317 case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
3318 consumeClassTypeList();
3321 case 150 : // System.out.println("ClassTypeElt ::= ClassType");
3322 consumeClassTypeElt();
3325 case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
3326 consumeMethodBody();
3329 case 152 : // System.out.println("NestedMethod ::=");
3330 consumeNestedMethod();
3333 case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block");
3334 consumeStaticInitializer();
3337 case 154 : // System.out.println("StaticOnly ::= static");
3338 consumeStaticOnly();
3341 case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3342 consumeConstructorDeclaration();
3345 case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3346 consumeInvalidConstructorDeclaration();
3349 case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
3350 consumeConstructorBody();
3353 case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
3354 consumeConstructorBlockStatements();
3357 case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
3358 consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.This);
3361 case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
3362 consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.Super);
3365 case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
3366 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
3369 case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
3370 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
3373 case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
3374 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
3377 case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
3378 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
3381 case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
3382 consumeInterfaceDeclaration();
3385 case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
3386 consumeInterfaceHeader();
3389 case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");
3390 consumeInterfaceHeaderName();
3393 case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
3394 consumeInterfaceHeaderExtends();
3397 case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
3398 consumeInterfaceMemberDeclarations();
3401 case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
3402 consumeEmptyInterfaceMemberDeclaration();
3405 case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
3409 case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3410 ignoreInvalidConstructorDeclaration(true);
3413 case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3414 ignoreInvalidConstructorDeclaration(false);
3417 case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
3418 consumeEmptyArrayInitializer();
3421 case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
3422 consumeArrayInitializer();
3425 case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
3426 consumeArrayInitializer();
3429 case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
3430 consumeVariableInitializers();
3433 case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
3437 case 192 : // System.out.println("OpenBlock ::=");
3441 case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
3442 consumeBlockStatements();
3445 case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
3446 ignoreInterfaceDeclaration();
3449 case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
3450 consumeLocalVariableDeclarationStatement();
3453 case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
3454 consumeLocalVariableDeclaration();
3457 case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
3458 consumeLocalVariableDeclaration();
3461 case 202 : // System.out.println("PushModifiers ::=");
3462 consumePushModifiers();
3465 case 226 : // System.out.println("EmptyStatement ::= SEMICOLON");
3466 consumeEmptyStatement();
3469 case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");
3470 consumeStatementLabel();
3473 case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");
3474 consumeStatementLabel();
3477 case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
3478 consumeExpressionStatement();
3481 case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
3482 consumeStatementIfNoElse();
3485 case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
3486 consumeStatementIfWithElse();
3489 case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
3490 consumeStatementIfWithElse();
3493 case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
3494 consumeStatementSwitch();
3497 case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
3498 consumeEmptySwitchBlock();
3501 case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
3502 consumeSwitchBlock();
3505 case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
3506 consumeSwitchBlockStatements();
3509 case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
3510 consumeSwitchBlockStatement();
3513 case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
3514 consumeSwitchLabels();
3517 case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
3521 case 251 : // System.out.println("SwitchLabel ::= default COLON");
3522 consumeDefaultLabel();
3525 case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
3526 consumeStatementWhile();
3529 case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
3530 consumeStatementWhile();
3533 case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
3534 consumeStatementDo();
3537 case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
3538 consumeStatementFor();
3541 case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
3542 consumeStatementFor();
3545 case 257 : // System.out.println("ForInit ::= StatementExpressionList");
3549 case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
3550 consumeStatementExpressionList();
3553 case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
3554 consumeSimpleAssertStatement();
3557 case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
3558 consumeAssertStatement();
3561 case 264 : // System.out.println("BreakStatement ::= break SEMICOLON");
3562 consumeStatementBreak();
3565 case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
3566 consumeStatementBreakWithLabel();
3569 case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
3570 consumeStatementContinue();
3573 case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
3574 consumeStatementContinueWithLabel();
3577 case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
3578 consumeStatementReturn();
3581 case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
3582 consumeStatementThrow();
3586 case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
3587 consumeStatementSynchronized();
3590 case 271 : // System.out.println("OnlySynchronized ::= synchronized");
3591 consumeOnlySynchronized();
3594 case 272 : // System.out.println("TryStatement ::= try Block Catches");
3595 consumeStatementTry(false);
3598 case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
3599 consumeStatementTry(true);
3602 case 275 : // System.out.println("Catches ::= Catches CatchClause");
3606 case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
3607 consumeStatementCatch();
3610 case 278 : // System.out.println("PushLPAREN ::= LPAREN");
3614 case 279 : // System.out.println("PushRPAREN ::= RPAREN");
3615 consumeRightParen();
3618 case 283 : // System.out.println("PrimaryNoNewArray ::= this");
3619 consumePrimaryNoNewArrayThis();
3622 case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
3623 consumePrimaryNoNewArray();
3626 case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
3627 consumePrimaryNoNewArrayNameThis();
3630 case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
3631 consumePrimaryNoNewArrayNameSuper();
3634 case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
3635 consumePrimaryNoNewArrayName();
3638 case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
3639 consumePrimaryNoNewArrayArrayType();
3642 case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
3643 consumePrimaryNoNewArrayPrimitiveType();
3646 case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
3647 consumeAllocationHeader();
3650 case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
3651 consumeClassInstanceCreationExpression();
3654 case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
3655 consumeClassInstanceCreationExpressionQualified();
3658 case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
3659 consumeClassInstanceCreationExpressionQualified();
3662 case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
3663 consumeClassInstanceCreationExpressionName();
3666 case 299 : // System.out.println("ClassBodyopt ::=");
3667 consumeClassBodyopt();
3670 case 301 : // System.out.println("EnterAnonymousClassBody ::=");
3671 consumeEnterAnonymousClassBody();
3674 case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
3675 consumeArgumentList();
3678 case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
3679 consumeArrayCreationExpression();
3682 case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
3683 consumeArrayCreationExpression();
3686 case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
3687 consumeDimWithOrWithOutExprs();
3690 case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
3691 consumeDimWithOrWithOutExpr();
3694 case 310 : // System.out.println("Dims ::= DimsLoop");
3698 case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
3699 consumeOneDimLoop();
3702 case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier");
3703 consumeFieldAccess(false);
3706 case 315 : // System.out.println("FieldAccess ::= super DOT Identifier");
3707 consumeFieldAccess(true);
3710 case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");
3711 consumeMethodInvocationName();
3714 case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN");
3715 consumeMethodInvocationPrimary();
3718 case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN");
3719 consumeMethodInvocationSuper();
3722 case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
3723 consumeArrayAccess(true);
3726 case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
3727 consumeArrayAccess(false);
3730 case 322 : // System.out.println("PostfixExpression ::= Name");
3731 consumePostfixExpression();
3734 case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
3735 consumeUnaryExpression(OperatorExpression.PLUS, true);
3738 case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
3739 consumeUnaryExpression(OperatorExpression.MINUS, true);
3742 case 327 : // System.out.println("PushPosition ::=");
3743 consumePushPosition();
3746 case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
3747 consumeUnaryExpression(OperatorExpression.PLUS);
3750 case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
3751 consumeUnaryExpression(OperatorExpression.MINUS);
3754 case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
3755 consumeUnaryExpression(OperatorExpression.PLUS, false);
3758 case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
3759 consumeUnaryExpression(OperatorExpression.MINUS, false);
3762 case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
3763 consumeUnaryExpression(OperatorExpression.TWIDDLE);
3766 case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
3767 consumeUnaryExpression(OperatorExpression.NOT);
3770 case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
3771 consumeCastExpression();
3774 case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
3775 consumeCastExpression();
3778 case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
3779 consumeCastExpressionLL1();
3782 case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
3783 consumeBinaryExpression(OperatorExpression.MULTIPLY);
3786 case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
3787 consumeBinaryExpression(OperatorExpression.DIVIDE);
3790 case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
3791 consumeBinaryExpression(OperatorExpression.REMAINDER);
3794 case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
3795 consumeBinaryExpression(OperatorExpression.PLUS);
3798 case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
3799 consumeBinaryExpression(OperatorExpression.MINUS);
3802 case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
3803 consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);
3806 case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
3807 consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);
3810 case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
3811 consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);
3814 case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
3815 consumeBinaryExpression(OperatorExpression.LESS);
3818 case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
3819 consumeBinaryExpression(OperatorExpression.GREATER);
3822 case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
3823 consumeBinaryExpression(OperatorExpression.LESS_EQUAL);
3826 case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
3827 consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);
3830 case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
3831 consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);
3834 case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
3835 consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);
3838 case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
3839 consumeEqualityExpression(OperatorExpression.NOT_EQUAL);
3842 case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
3843 consumeBinaryExpression(OperatorExpression.AND);
3846 case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
3847 consumeBinaryExpression(OperatorExpression.XOR);
3850 case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
3851 consumeBinaryExpression(OperatorExpression.OR);
3854 case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
3855 consumeBinaryExpression(OperatorExpression.AND_AND);
3858 case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
3859 consumeBinaryExpression(OperatorExpression.OR_OR);
3862 case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
3863 consumeConditionalExpression(OperatorExpression.QUESTIONCOLON);
3866 case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
3867 consumeAssignment();
3870 case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
3871 ignoreExpressionAssignment();
3874 case 379 : // System.out.println("LeftHandSide ::= Name");
3875 consumeLeftHandSide();
3878 case 382 : // System.out.println("AssignmentOperator ::= EQUAL");
3879 consumeAssignmentOperator(EQUAL);
3882 case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
3883 consumeAssignmentOperator(MULTIPLY);
3886 case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
3887 consumeAssignmentOperator(DIVIDE);
3890 case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
3891 consumeAssignmentOperator(REMAINDER);
3894 case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
3895 consumeAssignmentOperator(PLUS);
3898 case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
3899 consumeAssignmentOperator(MINUS);
3902 case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
3903 consumeAssignmentOperator(LEFT_SHIFT);
3906 case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
3907 consumeAssignmentOperator(RIGHT_SHIFT);
3910 case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
3911 consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
3914 case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
3915 consumeAssignmentOperator(AND);
3918 case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
3919 consumeAssignmentOperator(XOR);
3922 case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
3923 consumeAssignmentOperator(OR);
3926 case 400 : // System.out.println("Expressionopt ::=");
3927 consumeEmptyExpression();
3930 case 404 : // System.out.println("ImportDeclarationsopt ::=");
3931 consumeEmptyImportDeclarationsopt();
3934 case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
3935 consumeImportDeclarationsopt();
3938 case 406 : // System.out.println("TypeDeclarationsopt ::=");
3939 consumeEmptyTypeDeclarationsopt();
3942 case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
3943 consumeTypeDeclarationsopt();
3946 case 408 : // System.out.println("ClassBodyDeclarationsopt ::=");
3947 consumeEmptyClassBodyDeclarationsopt();
3950 case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
3951 consumeClassBodyDeclarationsopt();
3954 case 410 : // System.out.println("Modifiersopt ::=");
3955 consumeDefaultModifiers();
3958 case 411 : // System.out.println("Modifiersopt ::= Modifiers");
3962 case 412 : // System.out.println("BlockStatementsopt ::=");
3963 consumeEmptyBlockStatementsopt();
3966 case 414 : // System.out.println("Dimsopt ::=");
3967 consumeEmptyDimsopt();
3970 case 416 : // System.out.println("ArgumentListopt ::=");
3971 consumeEmptyArgumentListopt();
3974 case 420 : // System.out.println("FormalParameterListopt ::=");
3975 consumeFormalParameterListopt();
3978 case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
3979 consumeEmptyInterfaceMemberDeclarationsopt();
3982 case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
3983 consumeInterfaceMemberDeclarationsopt();
3986 case 426 : // System.out.println("NestedType ::=");
3987 consumeNestedType();
3990 case 427 : // System.out.println("ForInitopt ::=");
3991 consumeEmptyForInitopt();
3994 case 429 : // System.out.println("ForUpdateopt ::=");
3995 consumeEmptyForUpdateopt();
3998 case 433 : // System.out.println("Catchesopt ::=");
3999 consumeEmptyCatchesopt();
4002 case 435 : // System.out.println("ArrayInitializeropt ::=");
4003 consumeEmptyArrayInitializeropt();
4009 protected void consumeSimpleAssertStatement() {
4010 // AssertStatement ::= 'assert' Expression ';'
4011 expressionLengthPtr--;
4012 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4015 protected void consumeSingleTypeImportDeclaration() {
4016 // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
4018 ImportReference impt = (ImportReference) astStack[astPtr];
4019 // flush annotations defined prior to import statements
4020 impt.declarationEnd = endStatementPosition;
4021 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
4024 if (currentElement != null) {
4025 lastCheckPoint = impt.declarationSourceEnd + 1;
4026 currentElement = currentElement.add(impt, 0);
4027 lastIgnoredToken = -1;
4028 restartRecovery = true;
4029 // used to avoid branching back into the regular automaton
4032 protected void consumeSingleTypeImportDeclarationName() {
4033 // SingleTypeImportDeclarationName ::= 'import' Name
4034 /* push an ImportRef build from the last name
4035 stored in the identifier stack. */
4037 ImportReference impt;
4039 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4040 identifierPtr -= length;
4041 long[] positions = new long[length];
4042 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4043 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4044 pushOnAstStack(impt = new ImportReference(tokens, positions, false));
4046 if (currentToken == TokenNameSEMICOLON) {
4047 impt.declarationSourceEnd = scanner.currentPosition - 1;
4049 impt.declarationSourceEnd = impt.sourceEnd;
4051 impt.declarationEnd = impt.declarationSourceEnd;
4052 //endPosition is just before the ;
4053 impt.declarationSourceStart = intStack[intPtr--];
4056 if (currentElement != null) {
4057 lastCheckPoint = impt.declarationSourceEnd + 1;
4058 currentElement = currentElement.add(impt, 0);
4059 lastIgnoredToken = -1;
4060 restartRecovery = true; // used to avoid branching back into the regular automaton
4063 protected void consumeStatementBreak() {
4064 // BreakStatement ::= 'break' ';'
4065 // break pushs a position on intStack in case there is no label
4067 pushOnAstStack(new Break(null, intStack[intPtr--], endPosition));
4069 protected void consumeStatementBreakWithLabel() {
4070 // BreakStatement ::= 'break' Identifier ';'
4071 // break pushs a position on intStack in case there is no label
4073 pushOnAstStack(new Break(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
4074 identifierLengthPtr--;
4076 protected void consumeStatementCatch() {
4077 // CatchClause ::= 'catch' '(' FormalParameter ')' Block
4079 //catch are stored directly into the Try
4080 //has they always comes two by two....
4081 //we remove one entry from the astlengthPtr.
4082 //The construction of the try statement must
4083 //then fetch the catches using 2*i and 2*i + 1
4086 listLength = 0; // reset formalParameter counter (incremented for catch variable)
4088 protected void consumeStatementContinue() {
4089 // ContinueStatement ::= 'continue' ';'
4090 // continue pushs a position on intStack in case there is no label
4092 pushOnAstStack(new Continue(null, intStack[intPtr--], endPosition));
4094 protected void consumeStatementContinueWithLabel() {
4095 // ContinueStatement ::= 'continue' Identifier ';'
4096 // continue pushs a position on intStack in case there is no label
4098 pushOnAstStack(new Continue(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
4099 identifierLengthPtr--;
4101 protected void consumeStatementDo() {
4102 // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
4104 //the 'while' pushes a value on intStack that we need to remove
4107 //optimize the push/pop
4108 Statement action = (Statement) astStack[astPtr];
4109 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4110 expressionLengthPtr--;
4111 astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
4113 expressionLengthPtr--;
4114 astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
4117 protected void consumeStatementExpressionList() {
4118 // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
4119 concatExpressionLists();
4121 protected void consumeStatementFor() {
4122 // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
4123 // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
4126 Expression cond = null;
4127 Statement[] inits, updates;
4129 boolean scope = true;
4132 astLengthPtr--; // we need to consume it
4133 action = (Statement) astStack[astPtr--];
4134 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4138 //updates are on the expresion stack
4139 if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) {
4142 expressionPtr -= length;
4143 System.arraycopy(expressionStack, expressionPtr + 1, updates = new Statement[length], 0, length);
4146 if (expressionLengthStack[expressionLengthPtr--] != 0)
4147 cond = expressionStack[expressionPtr--];
4149 //inits may be on two different stacks
4150 if ((length = astLengthStack[astLengthPtr--]) == 0) {
4154 if (length == -1) { //on expressionStack
4156 length = expressionLengthStack[expressionLengthPtr--];
4157 expressionPtr -= length;
4158 System.arraycopy(expressionStack, expressionPtr + 1, inits = new Statement[length], 0, length);
4159 } else { //on astStack
4161 System.arraycopy(astStack, astPtr + 1, inits = new Statement[length], 0, length);
4164 if (action instanceof Block) {
4165 pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endStatementPosition));
4167 pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endPosition));
4170 protected void consumeStatementIfNoElse() {
4171 // IfThenStatement ::= 'if' '(' Expression ')' Statement
4173 //optimize the push/pop
4174 expressionLengthPtr--;
4175 Statement thenStatement = (Statement) astStack[astPtr];
4176 if (thenStatement instanceof Block) {
4177 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
4178 } else if (thenStatement instanceof EmptyStatement) {
4179 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
4181 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
4184 protected void consumeStatementIfWithElse() {
4185 // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
4186 // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
4188 astLengthPtr--; // optimized {..., Then, Else } ==> {..., If }
4189 expressionLengthPtr--;
4190 //optimize the push/pop
4191 Statement elseStatement = (Statement) astStack[astPtr--];
4192 Statement thenStatement = (Statement) astStack[astPtr];
4193 if (elseStatement instanceof EmptyStatement) {
4194 elseStatement = Block.None;
4196 if (thenStatement instanceof EmptyStatement) {
4197 thenStatement = Block.None;
4199 if (elseStatement instanceof Block) {
4201 new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
4204 new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
4207 protected void consumeStatementLabel() {
4208 // LabeledStatement ::= 'Identifier' ':' Statement
4209 // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
4213 Statement stmt = (Statement) astStack[astPtr];
4214 if (stmt instanceof EmptyStatement) {
4216 new LabeledStatement(
4217 identifierStack[identifierPtr],
4219 (int) (identifierPositionStack[identifierPtr--] >>> 32),
4220 endStatementPosition);
4223 new LabeledStatement(
4224 identifierStack[identifierPtr],
4226 (int) (identifierPositionStack[identifierPtr--] >>> 32),
4227 endStatementPosition);
4229 identifierLengthPtr--;
4231 protected void consumeStatementReturn() {
4232 // ReturnStatement ::= 'return' Expressionopt ';'
4233 // return pushs a position on intStack in case there is no expression
4235 if (expressionLengthStack[expressionLengthPtr--] != 0) {
4236 pushOnAstStack(new ReturnStatement(expressionStack[expressionPtr--], intStack[intPtr--], endPosition));
4238 pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition));
4241 protected void consumeStatementSwitch() {
4242 // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
4244 //OpenBlock just makes the semantic action blockStart()
4245 //the block is inlined but a scope need to be created
4246 //if some declaration occurs.
4249 SwitchStatement s = new SwitchStatement();
4250 expressionLengthPtr--;
4251 s.testExpression = expressionStack[expressionPtr--];
4252 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4254 System.arraycopy(astStack, astPtr + 1, s.statements = new Statement[length], 0, length);
4256 s.explicitDeclarations = realBlockStack[realBlockPtr--];
4258 intPtr--; // because of OpenBlock
4259 s.sourceStart = intStack[intPtr--];
4260 s.sourceEnd = endStatementPosition;
4262 protected void consumeStatementSynchronized() {
4263 // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
4264 //optimize the push/pop
4266 if (astLengthStack[astLengthPtr] == 0) {
4267 astLengthStack[astLengthPtr] = 1;
4268 expressionLengthPtr--;
4269 astStack[++astPtr] =
4270 new SynchronizedStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
4272 expressionLengthPtr--;
4274 new SynchronizedStatement(
4275 expressionStack[expressionPtr--],
4276 (Block) astStack[astPtr],
4278 endStatementPosition);
4282 protected void consumeStatementThrow() {
4283 // ThrowStatement ::= 'throw' Expression ';'
4284 expressionLengthPtr--;
4285 pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4287 protected void consumeStatementTry(boolean withFinally) {
4288 //TryStatement ::= 'try' Block Catches
4289 //TryStatement ::= 'try' Block Catchesopt Finally
4292 TryStatement tryStmt = new TryStatement();
4296 tryStmt.finallyBlock = (Block) astStack[astPtr--];
4298 //catches are handle by two <argument-block> [see statementCatch]
4299 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4301 tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--] };
4302 tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--] };
4304 Block[] bks = (tryStmt.catchBlocks = new Block[length]);
4305 Argument[] args = (tryStmt.catchArguments = new Argument[length]);
4306 while (length-- > 0) {
4307 bks[length] = (Block) astStack[astPtr--];
4308 args[length] = (Argument) astStack[astPtr--];
4314 tryStmt.tryBlock = (Block) astStack[astPtr--];
4317 tryStmt.sourceEnd = endStatementPosition;
4318 tryStmt.sourceStart = intStack[intPtr--];
4319 pushOnAstStack(tryStmt);
4321 protected void consumeStatementWhile() {
4322 // WhileStatement ::= 'while' '(' Expression ')' Statement
4323 // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
4325 Statement action = (Statement) astStack[astPtr];
4326 expressionLengthPtr--;
4327 if (action instanceof Block) {
4328 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endStatementPosition);
4330 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4331 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
4333 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
4337 protected void consumeStaticInitializer() {
4338 // StaticInitializer ::= StaticOnly Block
4339 //push an Initializer
4340 //optimize the push/pop
4341 Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic);
4342 astStack[astPtr] = initializer;
4343 initializer.sourceEnd = endStatementPosition;
4344 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
4345 nestedMethod[nestedType]--;
4346 initializer.declarationSourceStart = intStack[intPtr--];
4349 if (currentElement != null) {
4350 lastCheckPoint = initializer.declarationSourceEnd;
4351 currentElement = currentElement.add(initializer, 0);
4352 lastIgnoredToken = -1;
4355 protected void consumeStaticOnly() {
4356 // StaticOnly ::= 'static'
4357 int savedModifiersSourceStart = modifiersSourceStart;
4358 checkAnnotation(); // might update declaration source start
4359 if (modifiersSourceStart >= savedModifiersSourceStart) {
4360 modifiersSourceStart = savedModifiersSourceStart;
4362 pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
4363 jumpOverMethodBody();
4364 nestedMethod[nestedType]++;
4368 if (currentElement != null) {
4369 recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers
4372 protected void consumeSwitchBlock() {
4373 // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
4376 protected void consumeSwitchBlockStatement() {
4377 // SwitchBlockStatement ::= SwitchLabels BlockStatements
4380 protected void consumeSwitchBlockStatements() {
4381 // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
4384 protected void consumeSwitchLabels() {
4385 // SwitchLabels ::= SwitchLabels SwitchLabel
4386 optimizedConcatNodeLists();
4388 protected void consumeToken(int type) {
4389 /* remember the last consumed value */
4390 /* try to minimize the number of build values */
4391 if (scanner.wasNonExternalizedStringLiteral) {
4392 StringLiteral[] literals = this.scanner.nonNLSStrings;
4393 // could not reproduce, but this is the only NPE
4394 // added preventive null check see PR 9035
4395 if (literals != null) {
4396 for (int i = 0, max = literals.length; i < max; i++) {
4397 problemReporter().nonExternalizedStringLiteral(literals[i]);
4400 scanner.currentLine = null;
4401 scanner.wasNonExternalizedStringLiteral = false;
4403 // clear the commentPtr of the scanner in case we read something different from a modifier
4405 // case TokenNameabstract :
4406 // case TokenNamestrictfp :
4407 // case TokenNamefinal :
4408 // case TokenNamenative :
4409 // case TokenNameprivate :
4410 // case TokenNameprotected :
4411 // case TokenNamepublic :
4412 // case TokenNametransient :
4413 // case TokenNamevolatile :
4414 case TokenNamestatic :
4415 // case TokenNamesynchronized :
4418 scanner.commentPtr = -1;
4420 //System.out.println(scanner.toStringAction(type));
4422 case TokenNameIdentifier :
4424 if (scanner.useAssertAsAnIndentifier) {
4425 long positions = identifierPositionStack[identifierPtr];
4426 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
4428 scanner.commentPtr = -1;
4430 // case TokenNameinterface :
4431 // adjustInterfaceModifiers();
4432 // //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
4433 // pushOnIntStack(scanner.startPosition);
4434 // pushOnIntStack(scanner.currentPosition - 1);
4435 // scanner.commentPtr = -1;
4437 // case TokenNameabstract :
4438 // checkAndSetModifiers(AccAbstract);
4440 // case TokenNamestrictfp :
4441 // checkAndSetModifiers(AccStrictfp);
4443 // case TokenNamefinal :
4444 // checkAndSetModifiers(AccFinal);
4446 // case TokenNamenative :
4447 // checkAndSetModifiers(AccNative);
4449 // case TokenNameprivate :
4450 // checkAndSetModifiers(AccPrivate);
4452 // case TokenNameprotected :
4453 // checkAndSetModifiers(AccProtected);
4455 // case TokenNamepublic :
4456 // checkAndSetModifiers(AccPublic);
4458 // case TokenNametransient :
4459 // checkAndSetModifiers(AccTransient);
4461 // case TokenNamevolatile :
4462 // checkAndSetModifiers(AccVolatile);
4464 case TokenNamestatic :
4465 checkAndSetModifiers(AccStatic);
4467 // case TokenNamesynchronized :
4468 // this.synchronizedBlockSourceStart = scanner.startPosition;
4469 // checkAndSetModifiers(AccSynchronized);
4471 // //==============================
4472 // case TokenNamevoid :
4473 // pushIdentifier(-T_void);
4474 // pushOnIntStack(scanner.currentPosition - 1);
4475 // pushOnIntStack(scanner.startPosition);
4476 // scanner.commentPtr = -1;
4478 // //push a default dimension while void is not part of the primitive
4479 // //declaration baseType and so takes the place of a type without getting into
4480 // //regular type parsing that generates a dimension on intStack
4481 // case TokenNameboolean :
4482 // pushIdentifier(-T_boolean);
4483 // pushOnIntStack(scanner.currentPosition - 1);
4484 // pushOnIntStack(scanner.startPosition);
4485 // scanner.commentPtr = -1;
4487 // case TokenNamebyte :
4488 // pushIdentifier(-T_byte);
4489 // pushOnIntStack(scanner.currentPosition - 1);
4490 // pushOnIntStack(scanner.startPosition);
4491 // scanner.commentPtr = -1;
4493 // case TokenNamechar :
4494 // pushIdentifier(-T_char);
4495 // pushOnIntStack(scanner.currentPosition - 1);
4496 // pushOnIntStack(scanner.startPosition);
4497 // scanner.commentPtr = -1;
4499 // case TokenNamedouble :
4500 // pushIdentifier(-T_double);
4501 // pushOnIntStack(scanner.currentPosition - 1);
4502 // pushOnIntStack(scanner.startPosition);
4503 // scanner.commentPtr = -1;
4505 // case TokenNamefloat :
4506 // pushIdentifier(-T_float);
4507 // pushOnIntStack(scanner.currentPosition - 1);
4508 // pushOnIntStack(scanner.startPosition);
4509 // scanner.commentPtr = -1;
4511 // case TokenNameint :
4512 // pushIdentifier(-T_int);
4513 // pushOnIntStack(scanner.currentPosition - 1);
4514 // pushOnIntStack(scanner.startPosition);
4515 // scanner.commentPtr = -1;
4517 // case TokenNamelong :
4518 // pushIdentifier(-T_long);
4519 // pushOnIntStack(scanner.currentPosition - 1);
4520 // pushOnIntStack(scanner.startPosition);
4521 // scanner.commentPtr = -1;
4523 // case TokenNameshort :
4524 // pushIdentifier(-T_short);
4525 // pushOnIntStack(scanner.currentPosition - 1);
4526 // pushOnIntStack(scanner.startPosition);
4527 // scanner.commentPtr = -1;
4529 //==============================
4530 case TokenNameIntegerLiteral :
4531 pushOnExpressionStack(new IntLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4532 scanner.commentPtr = -1;
4534 case TokenNameLongLiteral :
4535 pushOnExpressionStack(new LongLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4536 scanner.commentPtr = -1;
4538 case TokenNameFloatingPointLiteral :
4539 pushOnExpressionStack(
4540 new FloatLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4541 scanner.commentPtr = -1;
4543 case TokenNameDoubleLiteral :
4544 pushOnExpressionStack(
4545 new DoubleLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4546 scanner.commentPtr = -1;
4548 case TokenNameCharacterLiteral :
4549 pushOnExpressionStack(new CharLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4550 scanner.commentPtr = -1;
4552 case TokenNameStringLiteral :
4553 StringLiteral stringLiteral =
4554 new StringLiteral(scanner.getCurrentTokenSourceString(), scanner.startPosition, scanner.currentPosition - 1);
4555 pushOnExpressionStack(stringLiteral);
4556 scanner.commentPtr = -1;
4558 case TokenNamefalse :
4559 pushOnExpressionStack(new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1));
4560 scanner.commentPtr = -1;
4562 case TokenNametrue :
4563 pushOnExpressionStack(new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1));
4565 case TokenNamenull :
4566 pushOnExpressionStack(new NullLiteral(scanner.startPosition, scanner.currentPosition - 1));
4568 //============================
4569 // case TokenNamesuper :
4570 // case TokenNamethis :
4571 // endPosition = scanner.currentPosition - 1;
4572 // pushOnIntStack(scanner.startPosition);
4574 // case TokenNameassert :
4575 // case TokenNameimport :
4576 // case TokenNamepackage :
4577 // case TokenNamethrow :
4582 case TokenNameswitch :
4583 // case TokenNametry :
4584 case TokenNamewhile :
4585 case TokenNamebreak :
4586 case TokenNamecontinue :
4587 case TokenNamereturn :
4588 case TokenNamecase :
4589 pushOnIntStack(scanner.startPosition);
4591 case TokenNameclass :
4592 pushOnIntStack(scanner.currentPosition - 1);
4593 pushOnIntStack(scanner.startPosition);
4595 case TokenNamedefault :
4596 pushOnIntStack(scanner.startPosition);
4597 pushOnIntStack(scanner.currentPosition - 1);
4599 //let extra semantic action decide when to push
4600 case TokenNameRBRACKET :
4601 case TokenNamePLUS :
4602 case TokenNameMINUS :
4604 case TokenNameTWIDDLE :
4605 endPosition = scanner.startPosition;
4607 case TokenNamePLUS_PLUS :
4608 case TokenNameMINUS_MINUS :
4609 endPosition = scanner.startPosition;
4610 endStatementPosition = scanner.currentPosition - 1;
4612 case TokenNameRBRACE :
4613 case TokenNameSEMICOLON :
4614 endStatementPosition = scanner.currentPosition - 1;
4615 endPosition = scanner.startPosition - 1;
4616 //the item is not part of the potential futur expression/statement
4618 // in order to handle ( expression) ////// (cast)expression///// foo(x)
4619 case TokenNameRPAREN :
4620 rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4622 case TokenNameLPAREN :
4623 lParenPos = scanner.startPosition;
4625 // case TokenNameQUESTION :
4626 // case TokenNameCOMMA :
4627 // case TokenNameCOLON :
4628 // case TokenNameEQUAL :
4629 // case TokenNameLBRACKET :
4630 // case TokenNameDOT :
4631 // case TokenNameERROR :
4632 // case TokenNameEOF :
4633 // case TokenNamecase :
4634 // case TokenNamecatch :
4635 // case TokenNameelse :
4636 // case TokenNameextends :
4637 // case TokenNamefinally :
4638 // case TokenNameimplements :
4639 // case TokenNamethrows :
4640 // case TokenNameinstanceof :
4641 // case TokenNameEQUAL_EQUAL :
4642 // case TokenNameLESS_EQUAL :
4643 // case TokenNameGREATER_EQUAL :
4644 // case TokenNameNOT_EQUAL :
4645 // case TokenNameLEFT_SHIFT :
4646 // case TokenNameRIGHT_SHIFT :
4647 // case TokenNameUNSIGNED_RIGHT_SHIFT :
4648 // case TokenNamePLUS_EQUAL :
4649 // case TokenNameMINUS_EQUAL :
4650 // case TokenNameMULTIPLY_EQUAL :
4651 // case TokenNameDIVIDE_EQUAL :
4652 // case TokenNameAND_EQUAL :
4653 // case TokenNameOR_EQUAL :
4654 // case TokenNameXOR_EQUAL :
4655 // case TokenNameREMAINDER_EQUAL :
4656 // case TokenNameLEFT_SHIFT_EQUAL :
4657 // case TokenNameRIGHT_SHIFT_EQUAL :
4658 // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
4659 // case TokenNameOR_OR :
4660 // case TokenNameAND_AND :
4661 // case TokenNameREMAINDER :
4662 // case TokenNameXOR :
4663 // case TokenNameAND :
4664 // case TokenNameMULTIPLY :
4665 // case TokenNameOR :
4666 // case TokenNameDIVIDE :
4667 // case TokenNameGREATER :
4668 // case TokenNameLESS :
4671 protected void consumeTypeDeclarations() {
4672 // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4675 protected void consumeTypeDeclarationsopt() {
4676 // TypeDeclarationsopt ::= TypeDeclarations
4678 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4680 System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length);
4683 protected void consumeTypeImportOnDemandDeclaration() {
4684 // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4686 ImportReference impt = (ImportReference) astStack[astPtr];
4687 // flush annotations defined prior to import statements
4688 impt.declarationEnd = endStatementPosition;
4689 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
4692 if (currentElement != null) {
4693 lastCheckPoint = impt.declarationSourceEnd + 1;
4694 currentElement = currentElement.add(impt, 0);
4695 restartRecovery = true;
4696 lastIgnoredToken = -1;
4697 // used to avoid branching back into the regular automaton
4700 protected void consumeTypeImportOnDemandDeclarationName() {
4701 // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4702 /* push an ImportRef build from the last name
4703 stored in the identifier stack. */
4705 ImportReference impt;
4707 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4708 identifierPtr -= length;
4709 long[] positions = new long[length];
4710 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4711 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4712 pushOnAstStack(impt = new ImportReference(tokens, positions, true));
4714 if (currentToken == TokenNameSEMICOLON) {
4715 impt.declarationSourceEnd = scanner.currentPosition - 1;
4717 impt.declarationSourceEnd = impt.sourceEnd;
4719 impt.declarationEnd = impt.declarationSourceEnd;
4720 //endPosition is just before the ;
4721 impt.declarationSourceStart = intStack[intPtr--];
4724 if (currentElement != null) {
4725 lastCheckPoint = impt.declarationSourceEnd + 1;
4726 currentElement = currentElement.add(impt, 0);
4727 lastIgnoredToken = -1;
4728 restartRecovery = true; // used to avoid branching back into the regular automaton
4731 protected void consumeUnaryExpression(int op) {
4732 // UnaryExpression ::= '+' PushPosition UnaryExpression
4733 // UnaryExpression ::= '-' PushPosition UnaryExpression
4734 // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4735 // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4737 //optimize the push/pop
4739 //handle manually the -2147483648 while it is not a real
4740 //computation of an - and 2147483648 (notice that 2147483648
4741 //is Integer.MAX_VALUE+1.....)
4742 //Same for -9223372036854775808L ............
4744 //intStack have the position of the operator
4746 Expression r, exp = expressionStack[expressionPtr];
4748 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4749 r = expressionStack[expressionPtr] = new IntLiteralMinValue();
4751 if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4752 r = expressionStack[expressionPtr] = new LongLiteralMinValue();
4754 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4758 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4760 r.sourceStart = intStack[intPtr--];
4761 r.sourceEnd = exp.sourceEnd;
4763 protected void consumeUnaryExpression(int op, boolean post) {
4764 // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4765 // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4767 // ++ and -- operators
4768 //optimize the push/pop
4770 //intStack has the position of the operator when prefix
4772 Expression leftHandSide = expressionStack[expressionPtr];
4773 if (leftHandSide instanceof Reference) {
4774 // ++foo()++ is unvalid
4776 expressionStack[expressionPtr] = new PostfixExpression(leftHandSide, IntLiteral.One, op, endStatementPosition);
4778 expressionStack[expressionPtr] = new PrefixExpression(leftHandSide, IntLiteral.One, op, intStack[intPtr--]);
4781 //the ++ or the -- is NOT taken into account if code gen proceeds
4785 problemReporter().invalidUnaryExpression(leftHandSide);
4788 protected void consumeVariableDeclarators() {
4789 // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4790 optimizedConcatNodeLists();
4792 protected void consumeVariableInitializers() {
4793 // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4794 concatExpressionLists();
4796 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4797 return typeRef.copyDims(dim);
4799 protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4800 return new FieldDeclaration(null, name, sourceStart, sourceEnd);
4803 protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4804 return new LocalDeclaration(null, name, sourceStart, sourceEnd);
4807 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4809 CompilationUnitDeclaration parsedUnit;
4813 parsedUnit = parse(sourceUnit, compilationResult);
4819 protected void dispatchDeclarationInto(int length) {
4820 /* they are length on astStack that should go into
4821 methods fields constructors lists of the typeDecl
4823 Return if there is a constructor declaration in the methods declaration */
4825 // Looks for the size of each array .
4829 int[] flag = new int[length + 1]; //plus one -- see <HERE>
4830 int size1 = 0, size2 = 0, size3 = 0;
4831 for (int i = length - 1; i >= 0; i--) {
4832 AstNode astNode = astStack[astPtr--];
4833 if (astNode instanceof AbstractMethodDeclaration) {
4834 //methods and constructors have been regrouped into one single list
4838 if (astNode instanceof TypeDeclaration) {
4850 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
4852 typeDecl.fields = new FieldDeclaration[size1];
4854 typeDecl.methods = new AbstractMethodDeclaration[size2];
4856 typeDecl.memberTypes = new MemberTypeDeclaration[size3];
4859 size1 = size2 = size3 = 0;
4860 int flagI = flag[0], start = 0;
4862 for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
4864 if (flagI != flag[end]) //treat the last element as a ended flag.....
4868 size1 += (length2 = end - start);
4869 System.arraycopy(astStack, astPtr + start + 1, typeDecl.fields, size1 - length2, length2);
4872 size2 += (length2 = end - start);
4873 System.arraycopy(astStack, astPtr + start + 1, typeDecl.methods, size2 - length2, length2);
4876 size3 += (length2 = end - start);
4877 System.arraycopy(astStack, astPtr + start + 1, typeDecl.memberTypes, size3 - length2, length2);
4880 flagI = flag[start = end];
4884 if (typeDecl.memberTypes != null) {
4885 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4886 typeDecl.memberTypes[i].enclosingType = typeDecl;
4890 protected CompilationUnitDeclaration endParse(int act) {
4894 if (currentElement != null) {
4895 currentElement.topElement().updateParseTree();
4896 if (VERBOSE_RECOVERY) {
4897 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4898 System.out.println("--------------------------"); //$NON-NLS-1$
4899 System.out.println(compilationUnit);
4900 System.out.println("----------------------------------"); //$NON-NLS-1$
4903 if (diet & VERBOSE_RECOVERY) {
4904 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
4905 System.out.println("--------------------------"); //$NON-NLS-1$
4906 System.out.println(compilationUnit);
4907 System.out.println("----------------------------------"); //$NON-NLS-1$
4910 if (scanner.recordLineSeparator) {
4911 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
4913 return compilationUnit;
4916 * Flush annotations defined prior to a given positions.
4918 * Note: annotations are stacked in syntactical order
4920 * Either answer given <position>, or the end position of a comment line
4921 * immediately following the <position> (same line)
4925 * } // end of method foo
4928 public int flushAnnotationsDefinedPriorTo(int position) {
4930 int lastAnnotationIndex = scanner.commentPtr;
4931 if (lastAnnotationIndex < 0)
4932 return position; // no comment
4934 // compute the index of the first obsolete comment
4935 int index = lastAnnotationIndex;
4937 while (index >= 0) {
4938 int commentEnd = scanner.commentStops[index];
4940 commentEnd = -commentEnd; // negative end position for non-javadoc comments
4941 if (commentEnd <= position) {
4947 // if the source at <position> is immediately followed by a line comment, then
4948 // flush this comment and shift <position> to the comment end.
4949 if (validCount > 0) {
4950 int immediateCommentEnd = -scanner.commentStops[index + 1]; //non-javadoc comment end positions are negative
4951 if (immediateCommentEnd > 0) { // only tolerating non-javadoc comments
4952 // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
4953 immediateCommentEnd--; // comment end in one char too far
4954 if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)) {
4955 position = immediateCommentEnd;
4956 validCount--; // flush this comment
4961 // position can be located in the middle of a line break
4962 // this is a bug on Windows platform only.
4963 // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557
4964 char[] source = scanner.source;
4966 if ((position < source.length)
4967 && (source[position] == '\r')
4968 && ((position + 1) < source.length)
4969 && (source[position + 1] == '\n')) {
4973 return position; // no obsolete comment
4975 if (validCount > 0) { // move valid comment infos, overriding obsolete comment infos
4976 System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount);
4977 System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount);
4979 scanner.commentPtr = validCount - 1;
4982 public final int getFirstToken() {
4983 // the first token is a virtual token that
4984 // allows the parser to parse several goals
4985 // even if they aren't LALR(1)....
4986 // Goal ::= '++' CompilationUnit
4987 // Goal ::= '--' MethodBody
4988 // Goal ::= '==' ConstructorBody
4990 // Goal ::= '>>' StaticInitializer
4991 // Goal ::= '>>' Block
4992 // -- error recovery
4993 // Goal ::= '>>>' Headers
4994 // Goal ::= '*' BlockStatements
4995 // Goal ::= '*' MethodPushModifiersHeader
4997 // Goal ::= '&&' FieldDeclaration
4998 // Goal ::= '||' ImportDeclaration
4999 // Goal ::= '?' PackageDeclaration
5000 // Goal ::= '+' TypeDeclaration
5001 // Goal ::= '/' GenericMethodDeclaration
5002 // Goal ::= '&' ClassBodyDeclaration
5004 // Goal ::= '%' Expression
5005 // -- completion parser
5006 // Goal ::= '!' ConstructorBlockStatementsopt
5007 // Goal ::= '~' BlockStatementsopt
5012 * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
5013 * The array is a flattened structure: 2*n entries with consecutives start and end positions.
5015 * If no JavaDoc is available, then null is answered instead of an empty array.
5017 * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
5019 public int[] getJavaDocPositions() {
5021 int javadocCount = 0;
5022 for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
5023 // javadoc only (non javadoc comment have negative end positions.)
5024 if (scanner.commentStops[i] > 0) {
5028 if (javadocCount == 0)
5031 int[] positions = new int[2 * javadocCount];
5033 for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
5034 // javadoc only (non javadoc comment have negative end positions.)
5035 if (scanner.commentStops[i] > 0) {
5036 positions[index++] = scanner.commentStarts[i];
5037 positions[index++] = scanner.commentStops[i] - 1; //stop is one over
5042 protected void getMethodBodies(CompilationUnitDeclaration unit) {
5043 //fill the methods bodies in order for the code to be generated
5048 if (unit.ignoreMethodBodies) {
5049 unit.ignoreFurtherInvestigation = true;
5051 // if initial diet parse did not work, no need to dig into method bodies.
5054 //real parse of the method....
5055 this.scanner.setSource(unit.compilationResult.compilationUnit.getContents());
5056 if (unit.types != null) {
5057 for (int i = unit.types.length; --i >= 0;)
5058 unit.types[i].parseMethod(this, unit);
5061 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
5062 This variable is a type reference and dim will be its dimensions*/
5066 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
5067 // single variable reference
5069 ref = new SingleTypeReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5071 ref = new ArrayTypeReference(identifierStack[identifierPtr], dim, identifierPositionStack[identifierPtr--]);
5072 ref.sourceEnd = endPosition;
5075 if (length < 0) { //flag for precompiled type reference on base types
5076 ref = TypeReference.baseTypeReference(-length, dim);
5077 ref.sourceStart = intStack[intPtr--];
5079 ref.sourceEnd = intStack[intPtr--];
5082 ref.sourceEnd = endPosition;
5084 } else { //Qualified variable reference
5085 char[][] tokens = new char[length][];
5086 identifierPtr -= length;
5087 long[] positions = new long[length];
5088 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5089 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
5091 ref = new QualifiedTypeReference(tokens, positions);
5093 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
5094 ref.sourceEnd = endPosition;
5100 protected Expression getTypeReference(Expression exp) {
5102 exp.bits &= ~AstNode.RestrictiveFlagMASK;
5106 protected NameReference getUnspecifiedReference() {
5107 /* build a (unspecified) NameReference which may be qualified*/
5111 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1)
5112 // single variable reference
5113 ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5115 //Qualified variable reference
5117 char[][] tokens = new char[length][];
5118 identifierPtr -= length;
5119 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5120 ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5121 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5125 protected NameReference getUnspecifiedReferenceOptimized() {
5126 /* build a (unspecified) NameReference which may be qualified
5127 The optimization occurs for qualified reference while we are
5128 certain in this case the last item of the qualified name is
5129 a field access. This optimization is IMPORTANT while it results
5130 that when a NameReference is build, the type checker should always
5131 look for that it is not a type reference */
5135 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
5136 // single variable reference
5137 ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5138 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5139 ref.bits |= LOCAL | FIELD;
5143 //Qualified-variable-reference
5144 //In fact it is variable-reference DOT field-ref , but it would result in a type
5145 //conflict tha can be only reduce by making a superclass (or inetrface ) between
5146 //nameReference and FiledReference or putting FieldReference under NameReference
5147 //or else..........This optimisation is not really relevant so just leave as it is
5149 char[][] tokens = new char[length][];
5150 identifierPtr -= length;
5151 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5152 ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5153 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5154 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5155 ref.bits |= LOCAL | FIELD;
5158 public void goForBlockStatementsOrMethodHeaders() {
5159 //tells the scanner to go for block statements or method headers parsing
5161 firstToken = TokenNameMULTIPLY;
5162 scanner.recordLineSeparator = false;
5164 public void goForClassBodyDeclarations() {
5165 //tells the scanner to go for any body declarations parsing
5167 firstToken = TokenNameAND;
5168 scanner.recordLineSeparator = true;
5170 public void goForCompilationUnit() {
5171 //tells the scanner to go for compilation unit parsing
5173 firstToken = TokenNamePLUS_PLUS;
5174 scanner.linePtr = -1;
5175 scanner.recordLineSeparator = true;
5176 scanner.currentLine = null;
5177 scanner.lines = new ArrayList();
5179 public void goForConstructorBody() {
5180 //tells the scanner to go for compilation unit parsing
5182 firstToken = TokenNameEQUAL_EQUAL;
5183 scanner.recordLineSeparator = false;
5185 public void goForExpression() {
5186 //tells the scanner to go for an expression parsing
5188 firstToken = TokenNameREMAINDER;
5189 scanner.recordLineSeparator = false;
5191 public void goForFieldDeclaration() {
5192 //tells the scanner to go for field declaration parsing
5194 firstToken = TokenNameAND_AND;
5195 scanner.recordLineSeparator = true;
5197 public void goForGenericMethodDeclaration() {
5198 //tells the scanner to go for generic method declarations parsing
5200 firstToken = TokenNameDIVIDE;
5201 scanner.recordLineSeparator = true;
5203 public void goForHeaders() {
5204 //tells the scanner to go for headers only parsing
5206 firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
5207 scanner.recordLineSeparator = true;
5209 public void goForImportDeclaration() {
5210 //tells the scanner to go for import declaration parsing
5212 firstToken = TokenNameOR_OR;
5213 scanner.recordLineSeparator = true;
5215 public void goForInitializer() {
5216 //tells the scanner to go for initializer parsing
5218 firstToken = TokenNameRIGHT_SHIFT;
5219 scanner.recordLineSeparator = false;
5221 public void goForMethodBody() {
5222 //tells the scanner to go for method body parsing
5224 firstToken = TokenNameMINUS_MINUS;
5225 scanner.recordLineSeparator = false;
5227 public void goForPackageDeclaration() {
5228 //tells the scanner to go for package declaration parsing
5230 firstToken = TokenNameQUESTION;
5231 scanner.recordLineSeparator = true;
5233 public void goForTypeDeclaration() {
5234 //tells the scanner to go for type (interface or class) declaration parsing
5236 firstToken = TokenNamePLUS;
5237 scanner.recordLineSeparator = true;
5239 public final static void grammar() {
5242 %options ACTION, AN=JavaAction.java, GP=java,
5243 %options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
5244 %options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME ,
5246 --error recovering options.....
5249 --grammar understanding options
5250 %options first follow
5251 %options TRACE=FULL ,
5254 --Usefull macros helping reading/writing semantic actions
5257 /. case $rule_number : // System.out.println("$rule_text");
5265 -- here it starts really ------------------------------------------
5270 abstract assert boolean break byte case catch char class
5271 continue default do double else extends false final finally float
5272 for if implements import instanceof int
5273 interface long native new null package private
5274 protected public return short static strictfp super switch
5275 synchronized this throw throws transient true try void
5280 FloatingPointLiteral
5293 UNSIGNED_RIGHT_SHIFT
5304 UNSIGNED_RIGHT_SHIFT_EQUAL
5337 '--' ::= MINUS_MINUS
5338 '==' ::= EQUAL_EQUAL
5340 '>=' ::= GREATER_EQUAL
5343 '>>' ::= RIGHT_SHIFT
5344 '>>>' ::= UNSIGNED_RIGHT_SHIFT
5346 '-=' ::= MINUS_EQUAL
5347 '*=' ::= MULTIPLY_EQUAL
5348 '/=' ::= DIVIDE_EQUAL
5352 '%=' ::= REMAINDER_EQUAL
5353 '<<=' ::= LEFT_SHIFT_EQUAL
5354 '>>=' ::= RIGHT_SHIFT_EQUAL
5355 '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
5389 /. // This method is part of an automatic generation : do NOT edit-modify
5390 protected void consumeRule(int act) {
5396 Goal ::= '++' CompilationUnit
5397 Goal ::= '--' MethodBody
5398 Goal ::= '==' ConstructorBody
5400 Goal ::= '>>' StaticInitializer
5401 Goal ::= '>>' Initializer
5403 Goal ::= '>>>' Headers
5404 Goal ::= '*' BlockStatements
5405 Goal ::= '*' MethodPushModifiersHeader
5406 Goal ::= '*' CatchHeader
5408 Goal ::= '&&' FieldDeclaration
5409 Goal ::= '||' ImportDeclaration
5410 Goal ::= '?' PackageDeclaration
5411 Goal ::= '+' TypeDeclaration
5412 Goal ::= '/' GenericMethodDeclaration
5413 Goal ::= '&' ClassBodyDeclaration
5415 Goal ::= '%' Expression
5416 -- completion parser
5417 Goal ::= '!' ConstructorBlockStatementsopt
5418 Goal ::= '~' BlockStatementsopt
5420 Literal -> IntegerLiteral
5421 Literal -> LongLiteral
5422 Literal -> FloatingPointLiteral
5423 Literal -> DoubleLiteral
5424 Literal -> CharacterLiteral
5425 Literal -> StringLiteral
5427 Literal -> BooleanLiteral
5428 BooleanLiteral -> true
5429 BooleanLiteral -> false
5431 -------------------------------------------------------------
5432 -------------------------------------------------------------
5433 --a Type results in both a push of its dimension(s) and its name(s).
5435 Type ::= PrimitiveType
5436 /.$putCase consumePrimitiveType(); $break ./
5437 Type -> ReferenceType
5439 PrimitiveType -> NumericType
5440 NumericType -> IntegralType
5441 NumericType -> FloatingPointType
5443 PrimitiveType -> 'boolean'
5444 PrimitiveType -> 'void'
5445 IntegralType -> 'byte'
5446 IntegralType -> 'short'
5447 IntegralType -> 'int'
5448 IntegralType -> 'long'
5449 IntegralType -> 'char'
5450 FloatingPointType -> 'float'
5451 FloatingPointType -> 'double'
5453 ReferenceType ::= ClassOrInterfaceType
5454 /.$putCase consumeReferenceType(); $break ./
5455 ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0
5457 ClassOrInterfaceType -> Name
5460 -- These rules have been rewritten to avoid some conflicts introduced
5461 -- by adding the 1.1 features
5463 -- ArrayType ::= PrimitiveType '[' ']'
5464 -- ArrayType ::= Name '[' ']'
5465 -- ArrayType ::= ArrayType '[' ']'
5468 ArrayType ::= PrimitiveType Dims
5469 ArrayType ::= Name Dims
5471 ClassType -> ClassOrInterfaceType
5474 --------------------------------------------------------------
5475 --------------------------------------------------------------
5478 Name -> QualifiedName
5480 SimpleName -> 'Identifier'
5482 QualifiedName ::= Name '.' SimpleName
5483 /.$putCase consumeQualifiedName(); $break ./
5485 CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
5486 /.$putCase consumeCompilationUnit(); $break ./
5488 EnterCompilationUnit ::= $empty
5489 /.$putCase consumeEnterCompilationUnit(); $break ./
5492 Headers ::= Headers Header
5494 Header -> ImportDeclaration
5495 Header -> PackageDeclaration
5496 Header -> ClassHeader
5497 Header -> InterfaceHeader
5498 Header -> StaticInitializer
5499 Header -> MethodHeader
5500 Header -> ConstructorHeader
5501 Header -> FieldDeclaration
5502 Header -> AllocationHeader
5504 CatchHeader ::= 'catch' '(' FormalParameter ')' '{'
5505 /.$putCase consumeCatchHeader(); $break ./
5507 ImportDeclarations -> ImportDeclaration
5508 ImportDeclarations ::= ImportDeclarations ImportDeclaration
5509 /.$putCase consumeImportDeclarations(); $break ./
5511 TypeDeclarations -> TypeDeclaration
5512 TypeDeclarations ::= TypeDeclarations TypeDeclaration
5513 /.$putCase consumeTypeDeclarations(); $break ./
5515 PackageDeclaration ::= PackageDeclarationName ';'
5516 /.$putCase consumePackageDeclaration(); $break ./
5518 PackageDeclarationName ::= 'package' Name
5519 /.$putCase consumePackageDeclarationName(); $break ./
5521 ImportDeclaration -> SingleTypeImportDeclaration
5522 ImportDeclaration -> TypeImportOnDemandDeclaration
5524 SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
5525 /.$putCase consumeSingleTypeImportDeclaration(); $break ./
5527 SingleTypeImportDeclarationName ::= 'import' Name
5528 /.$putCase consumeSingleTypeImportDeclarationName(); $break ./
5530 TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
5531 /.$putCase consumeTypeImportOnDemandDeclaration(); $break ./
5533 TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
5534 /.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
5536 TypeDeclaration -> ClassDeclaration
5537 TypeDeclaration -> InterfaceDeclaration
5538 -- this declaration in part of a list od declaration and we will
5539 -- use and optimized list length calculation process
5540 -- thus we decrement the number while it will be incremend.....
5541 TypeDeclaration ::= ';'
5542 /. $putCase consumeEmptyTypeDeclaration(); $break ./
5544 --18.7 Only in the LALR(1) Grammar
5546 Modifiers ::= Modifier
5547 Modifiers ::= Modifiers Modifier
5549 Modifier -> 'public'
5550 Modifier -> 'protected'
5551 Modifier -> 'private'
5552 Modifier -> 'static'
5553 Modifier -> 'abstract'
5555 Modifier -> 'native'
5556 Modifier -> 'synchronized'
5557 Modifier -> 'transient'
5558 Modifier -> 'volatile'
5559 Modifier -> 'strictfp'
5561 --18.8 Productions from 8: Class Declarations
5566 --18.8.1 Productions from 8.1: Class Declarations
5568 ClassDeclaration ::= ClassHeader ClassBody
5569 /.$putCase consumeClassDeclaration(); $break ./
5571 ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
5572 /.$putCase consumeClassHeader(); $break ./
5574 ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
5575 /.$putCase consumeClassHeaderName(); $break ./
5577 ClassHeaderExtends ::= 'extends' ClassType
5578 /.$putCase consumeClassHeaderExtends(); $break ./
5580 ClassHeaderImplements ::= 'implements' InterfaceTypeList
5581 /.$putCase consumeClassHeaderImplements(); $break ./
5583 InterfaceTypeList -> InterfaceType
5584 InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
5585 /.$putCase consumeInterfaceTypeList(); $break ./
5587 InterfaceType ::= ClassOrInterfaceType
5588 /.$putCase consumeInterfaceType(); $break ./
5590 ClassBody ::= '{' ClassBodyDeclarationsopt '}'
5592 ClassBodyDeclarations ::= ClassBodyDeclaration
5593 ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
5594 /.$putCase consumeClassBodyDeclarations(); $break ./
5596 ClassBodyDeclaration -> ClassMemberDeclaration
5597 ClassBodyDeclaration -> StaticInitializer
5598 ClassBodyDeclaration -> ConstructorDeclaration
5600 ClassBodyDeclaration ::= Diet NestedMethod Block
5601 /.$putCase consumeClassBodyDeclaration(); $break ./
5603 /.$putCase consumeDiet(); $break./
5605 Initializer ::= Diet NestedMethod Block
5606 /.$putCase consumeClassBodyDeclaration(); $break ./
5608 ClassMemberDeclaration -> FieldDeclaration
5609 ClassMemberDeclaration -> MethodDeclaration
5611 ClassMemberDeclaration -> ClassDeclaration
5613 ClassMemberDeclaration -> InterfaceDeclaration
5615 -- Empty declarations are not valid Java ClassMemberDeclarations.
5616 -- However, since the current (2/14/97) Java compiler accepts them
5617 -- (in fact, some of the official tests contain this erroneous
5620 GenericMethodDeclaration -> MethodDeclaration
5621 GenericMethodDeclaration -> ConstructorDeclaration
5623 ClassMemberDeclaration ::= ';'
5624 /.$putCase consumeEmptyClassMemberDeclaration(); $break./
5626 --18.8.2 Productions from 8.3: Field Declarations
5627 --VariableModifier ::=
5636 FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
5637 /.$putCase consumeFieldDeclaration(); $break ./
5639 VariableDeclarators -> VariableDeclarator
5640 VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
5641 /.$putCase consumeVariableDeclarators(); $break ./
5643 VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
5645 VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
5647 EnterVariable ::= $empty
5648 /.$putCase consumeEnterVariable(); $break ./
5650 ExitVariableWithInitialization ::= $empty
5651 /.$putCase consumeExitVariableWithInitialization(); $break ./
5653 ExitVariableWithoutInitialization ::= $empty
5654 /.$putCase consumeExitVariableWithoutInitialization(); $break ./
5656 ForceNoDiet ::= $empty
5657 /.$putCase consumeForceNoDiet(); $break ./
5658 RestoreDiet ::= $empty
5659 /.$putCase consumeRestoreDiet(); $break ./
5661 VariableDeclaratorId ::= 'Identifier' Dimsopt
5663 VariableInitializer -> Expression
5664 VariableInitializer -> ArrayInitializer
5666 --18.8.3 Productions from 8.4: Method Declarations
5667 --MethodModifier ::=
5678 MethodDeclaration -> AbstractMethodDeclaration
5679 MethodDeclaration ::= MethodHeader MethodBody
5680 /.$putCase // set to true to consume a method with a body
5681 consumeMethodDeclaration(true); $break ./
5683 AbstractMethodDeclaration ::= MethodHeader ';'
5684 /.$putCase // set to false to consume a method without body
5685 consumeMethodDeclaration(false); $break ./
5687 MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5688 /.$putCase consumeMethodHeader(); $break ./
5690 MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5691 /.$putCase consumeMethodHeader(); $break ./
5693 MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
5694 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5696 MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
5697 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5699 MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
5700 /.$putCase consumeMethodHeaderName(); $break ./
5702 MethodHeaderParameters ::= FormalParameterListopt ')'
5703 /.$putCase consumeMethodHeaderParameters(); $break ./
5705 MethodHeaderExtendedDims ::= Dimsopt
5706 /.$putCase consumeMethodHeaderExtendedDims(); $break ./
5708 MethodHeaderThrowsClause ::= 'throws' ClassTypeList
5709 /.$putCase consumeMethodHeaderThrowsClause(); $break ./
5711 ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
5712 /.$putCase consumeConstructorHeader(); $break ./
5714 ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
5715 /.$putCase consumeConstructorHeaderName(); $break ./
5717 FormalParameterList -> FormalParameter
5718 FormalParameterList ::= FormalParameterList ',' FormalParameter
5719 /.$putCase consumeFormalParameterList(); $break ./
5722 FormalParameter ::= Modifiersopt Type VariableDeclaratorId
5723 /.$putCase // the boolean is used to know if the modifiers should be reset
5724 consumeFormalParameter(); $break ./
5726 ClassTypeList -> ClassTypeElt
5727 ClassTypeList ::= ClassTypeList ',' ClassTypeElt
5728 /.$putCase consumeClassTypeList(); $break ./
5730 ClassTypeElt ::= ClassType
5731 /.$putCase consumeClassTypeElt(); $break ./
5734 MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
5735 /.$putCase consumeMethodBody(); $break ./
5737 NestedMethod ::= $empty
5738 /.$putCase consumeNestedMethod(); $break ./
5740 --18.8.4 Productions from 8.5: Static Initializers
5742 StaticInitializer ::= StaticOnly Block
5743 /.$putCase consumeStaticInitializer(); $break./
5745 StaticOnly ::= 'static'
5746 /.$putCase consumeStaticOnly(); $break ./
5748 --18.8.5 Productions from 8.6: Constructor Declarations
5749 --ConstructorModifier ::=
5755 ConstructorDeclaration ::= ConstructorHeader ConstructorBody
5756 /.$putCase consumeConstructorDeclaration() ; $break ./
5758 -- These rules are added to be able to parse constructors with no body
5759 ConstructorDeclaration ::= ConstructorHeader ';'
5760 /.$putCase consumeInvalidConstructorDeclaration() ; $break ./
5762 -- the rules ExplicitConstructorInvocationopt has been expanded
5763 -- in the rule below in order to make the grammar lalr(1).
5764 -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}'
5765 -- Other inlining has occured into the next rule too....
5767 ConstructorBody ::= NestedMethod '{' ConstructorBlockStatementsopt '}'
5768 /.$putCase consumeConstructorBody(); $break ./
5770 ConstructorBlockStatementsopt -> BlockStatementsopt
5772 ConstructorBlockStatementsopt -> ExplicitConstructorInvocation
5774 ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements
5775 /.$putCase consumeConstructorBlockStatements(); $break ./
5777 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
5778 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./
5780 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
5781 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./
5784 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
5785 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./
5788 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
5789 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./
5792 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
5793 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./
5796 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
5797 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./
5799 --18.9 Productions from 9: Interface Declarations
5801 --18.9.1 Productions from 9.1: Interface Declarations
5802 --InterfaceModifier ::=
5806 InterfaceDeclaration ::= InterfaceHeader InterfaceBody
5807 /.$putCase consumeInterfaceDeclaration(); $break ./
5809 InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
5810 /.$putCase consumeInterfaceHeader(); $break ./
5812 InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
5813 /.$putCase consumeInterfaceHeaderName(); $break ./
5815 -- This rule will be used to accept inner local interface and then report a relevant error message
5816 InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody
5818 InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
5819 /.$putCase consumeInterfaceHeaderExtends(); $break ./
5821 InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}'
5823 InterfaceMemberDeclarations -> InterfaceMemberDeclaration
5824 InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
5825 /.$putCase consumeInterfaceMemberDeclarations(); $break ./
5827 --same as for class members
5828 InterfaceMemberDeclaration ::= ';'
5829 /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./
5831 -- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message
5832 InvalidMethodDeclaration -> MethodHeader MethodBody
5834 InterfaceMemberDeclaration -> ConstantDeclaration
5835 InterfaceMemberDeclaration ::= InvalidMethodDeclaration
5836 /.$putCase ignoreMethodBody(); $break ./
5838 -- These rules are added to be able to parse constructors inside interface and then report a relevent error message
5839 InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody
5840 /.$putCase ignoreInvalidConstructorDeclaration(true); $break ./
5842 InvalidConstructorDeclaration ::= ConstructorHeader ';'
5843 /.$putCase ignoreInvalidConstructorDeclaration(false); $break ./
5845 InterfaceMemberDeclaration -> AbstractMethodDeclaration
5846 InterfaceMemberDeclaration -> InvalidConstructorDeclaration
5849 InterfaceMemberDeclaration -> ClassDeclaration
5851 InterfaceMemberDeclaration -> InterfaceDeclaration
5853 ConstantDeclaration -> FieldDeclaration
5855 ArrayInitializer ::= '{' ,opt '}'
5856 /.$putCase consumeEmptyArrayInitializer(); $break ./
5857 ArrayInitializer ::= '{' VariableInitializers '}'
5858 /.$putCase consumeArrayInitializer(); $break ./
5859 ArrayInitializer ::= '{' VariableInitializers , '}'
5860 /.$putCase consumeArrayInitializer(); $break ./
5862 VariableInitializers ::= VariableInitializer
5863 VariableInitializers ::= VariableInitializers ',' VariableInitializer
5864 /.$putCase consumeVariableInitializers(); $break ./
5866 Block ::= OpenBlock '{' BlockStatementsopt '}'
5867 /.$putCase consumeBlock(); $break ./
5868 OpenBlock ::= $empty
5869 /.$putCase consumeOpenBlock() ; $break ./
5871 BlockStatements -> BlockStatement
5872 BlockStatements ::= BlockStatements BlockStatement
5873 /.$putCase consumeBlockStatements() ; $break ./
5875 BlockStatement -> LocalVariableDeclarationStatement
5876 BlockStatement -> Statement
5878 BlockStatement -> ClassDeclaration
5879 BlockStatement ::= InvalidInterfaceDeclaration
5880 /.$putCase ignoreInterfaceDeclaration(); $break ./
5882 LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
5883 /.$putCase consumeLocalVariableDeclarationStatement(); $break ./
5885 LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
5886 /.$putCase consumeLocalVariableDeclaration(); $break ./
5889 -- The modifiers part of this rule makes the grammar more permissive.
5890 -- The only modifier here is final. We put Modifiers to allow multiple modifiers
5891 -- This will require to check the validity of the modifier
5893 LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators
5894 /.$putCase consumeLocalVariableDeclaration(); $break ./
5896 PushModifiers ::= $empty
5897 /.$putCase consumePushModifiers(); $break ./
5899 Statement -> StatementWithoutTrailingSubstatement
5900 Statement -> LabeledStatement
5901 Statement -> IfThenStatement
5902 Statement -> IfThenElseStatement
5903 Statement -> WhileStatement
5904 Statement -> ForStatement
5906 StatementNoShortIf -> StatementWithoutTrailingSubstatement
5907 StatementNoShortIf -> LabeledStatementNoShortIf
5908 StatementNoShortIf -> IfThenElseStatementNoShortIf
5909 StatementNoShortIf -> WhileStatementNoShortIf
5910 StatementNoShortIf -> ForStatementNoShortIf
5912 StatementWithoutTrailingSubstatement -> AssertStatement
5913 StatementWithoutTrailingSubstatement -> Block
5914 StatementWithoutTrailingSubstatement -> EmptyStatement
5915 StatementWithoutTrailingSubstatement -> ExpressionStatement
5916 StatementWithoutTrailingSubstatement -> SwitchStatement
5917 StatementWithoutTrailingSubstatement -> DoStatement
5918 StatementWithoutTrailingSubstatement -> BreakStatement
5919 StatementWithoutTrailingSubstatement -> ContinueStatement
5920 StatementWithoutTrailingSubstatement -> ReturnStatement
5921 StatementWithoutTrailingSubstatement -> SynchronizedStatement
5922 StatementWithoutTrailingSubstatement -> ThrowStatement
5923 StatementWithoutTrailingSubstatement -> TryStatement
5925 EmptyStatement ::= ';'
5926 /.$putCase consumeEmptyStatement(); $break ./
5928 LabeledStatement ::= 'Identifier' ':' Statement
5929 /.$putCase consumeStatementLabel() ; $break ./
5931 LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
5932 /.$putCase consumeStatementLabel() ; $break ./
5934 ExpressionStatement ::= StatementExpression ';'
5935 /. $putCase consumeExpressionStatement(); $break ./
5937 StatementExpression ::= Assignment
5938 StatementExpression ::= PreIncrementExpression
5939 StatementExpression ::= PreDecrementExpression
5940 StatementExpression ::= PostIncrementExpression
5941 StatementExpression ::= PostDecrementExpression
5942 StatementExpression ::= MethodInvocation
5943 StatementExpression ::= ClassInstanceCreationExpression
5945 IfThenStatement ::= 'if' '(' Expression ')' Statement
5946 /.$putCase consumeStatementIfNoElse(); $break ./
5948 IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
5949 /.$putCase consumeStatementIfWithElse(); $break ./
5951 IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
5952 /.$putCase consumeStatementIfWithElse(); $break ./
5954 SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
5955 /.$putCase consumeStatementSwitch() ; $break ./
5957 SwitchBlock ::= '{' '}'
5958 /.$putCase consumeEmptySwitchBlock() ; $break ./
5960 SwitchBlock ::= '{' SwitchBlockStatements '}'
5961 SwitchBlock ::= '{' SwitchLabels '}'
5962 SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
5963 /.$putCase consumeSwitchBlock() ; $break ./
5965 SwitchBlockStatements -> SwitchBlockStatement
5966 SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
5967 /.$putCase consumeSwitchBlockStatements() ; $break ./
5969 SwitchBlockStatement ::= SwitchLabels BlockStatements
5970 /.$putCase consumeSwitchBlockStatement() ; $break ./
5972 SwitchLabels -> SwitchLabel
5973 SwitchLabels ::= SwitchLabels SwitchLabel
5974 /.$putCase consumeSwitchLabels() ; $break ./
5976 SwitchLabel ::= 'case' ConstantExpression ':'
5977 /. $putCase consumeCaseLabel(); $break ./
5979 SwitchLabel ::= 'default' ':'
5980 /. $putCase consumeDefaultLabel(); $break ./
5982 WhileStatement ::= 'while' '(' Expression ')' Statement
5983 /.$putCase consumeStatementWhile() ; $break ./
5985 WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
5986 /.$putCase consumeStatementWhile() ; $break ./
5988 DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
5989 /.$putCase consumeStatementDo() ; $break ./
5991 ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
5992 /.$putCase consumeStatementFor() ; $break ./
5993 ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
5994 /.$putCase consumeStatementFor() ; $break ./
5996 --the minus one allows to avoid a stack-to-stack transfer
5997 ForInit ::= StatementExpressionList
5998 /.$putCase consumeForInit() ; $break ./
5999 ForInit -> LocalVariableDeclaration
6001 ForUpdate -> StatementExpressionList
6003 StatementExpressionList -> StatementExpression
6004 StatementExpressionList ::= StatementExpressionList ',' StatementExpression
6005 /.$putCase consumeStatementExpressionList() ; $break ./
6008 AssertStatement ::= 'assert' Expression ';'
6009 /.$putCase consumeSimpleAssertStatement() ; $break ./
6011 AssertStatement ::= 'assert' Expression ':' Expression ';'
6012 /.$putCase consumeAssertStatement() ; $break ./
6014 BreakStatement ::= 'break' ';'
6015 /.$putCase consumeStatementBreak() ; $break ./
6017 BreakStatement ::= 'break' Identifier ';'
6018 /.$putCase consumeStatementBreakWithLabel() ; $break ./
6020 ContinueStatement ::= 'continue' ';'
6021 /.$putCase consumeStatementContinue() ; $break ./
6023 ContinueStatement ::= 'continue' Identifier ';'
6024 /.$putCase consumeStatementContinueWithLabel() ; $break ./
6026 ReturnStatement ::= 'return' Expressionopt ';'
6027 /.$putCase consumeStatementReturn() ; $break ./
6029 ThrowStatement ::= 'throw' Expression ';'
6030 /.$putCase consumeStatementThrow();
6033 SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
6034 /.$putCase consumeStatementSynchronized(); $break ./
6035 OnlySynchronized ::= 'synchronized'
6036 /.$putCase consumeOnlySynchronized(); $break ./
6039 TryStatement ::= 'try' Block Catches
6040 /.$putCase consumeStatementTry(false); $break ./
6041 TryStatement ::= 'try' Block Catchesopt Finally
6042 /.$putCase consumeStatementTry(true); $break ./
6044 Catches -> CatchClause
6045 Catches ::= Catches CatchClause
6046 /.$putCase consumeCatches(); $break ./
6048 CatchClause ::= 'catch' '(' FormalParameter ')' Block
6049 /.$putCase consumeStatementCatch() ; $break ./
6051 Finally ::= 'finally' Block
6053 --18.12 Productions from 14: Expressions
6055 --for source positionning purpose
6057 /.$putCase consumeLeftParen(); $break ./
6059 /.$putCase consumeRightParen(); $break ./
6061 Primary -> PrimaryNoNewArray
6062 Primary -> ArrayCreationExpression
6064 PrimaryNoNewArray -> Literal
6065 PrimaryNoNewArray ::= 'this'
6066 /.$putCase consumePrimaryNoNewArrayThis(); $break ./
6068 PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
6069 /.$putCase consumePrimaryNoNewArray(); $break ./
6071 PrimaryNoNewArray -> ClassInstanceCreationExpression
6072 PrimaryNoNewArray -> FieldAccess
6074 PrimaryNoNewArray ::= Name '.' 'this'
6075 /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
6076 PrimaryNoNewArray ::= Name '.' 'super'
6077 /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
6080 --PrimaryNoNewArray ::= Type '.' 'class'
6081 --inline Type in the previous rule in order to make the grammar LL1 instead
6082 -- of LL2. The result is the 3 next rules.
6083 PrimaryNoNewArray ::= Name '.' 'class'
6084 /.$putCase consumePrimaryNoNewArrayName(); $break ./
6086 PrimaryNoNewArray ::= ArrayType '.' 'class'
6087 /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
6089 PrimaryNoNewArray ::= PrimitiveType '.' 'class'
6090 /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
6092 PrimaryNoNewArray -> MethodInvocation
6093 PrimaryNoNewArray -> ArrayAccess
6097 -- In Java 1.0 a ClassBody could not appear at all in a
6098 -- ClassInstanceCreationExpression.
6101 AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
6102 /.$putCase consumeAllocationHeader(); $break ./
6104 ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
6105 /.$putCase consumeClassInstanceCreationExpression(); $break ./
6108 ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
6109 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
6112 ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
6113 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
6115 ClassInstanceCreationExpressionName ::= Name '.'
6116 /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
6118 ClassBodyopt ::= $empty --test made using null as contents
6119 /.$putCase consumeClassBodyopt(); $break ./
6120 ClassBodyopt ::= EnterAnonymousClassBody ClassBody
6122 EnterAnonymousClassBody ::= $empty
6123 /.$putCase consumeEnterAnonymousClassBody(); $break ./
6125 ArgumentList ::= Expression
6126 ArgumentList ::= ArgumentList ',' Expression
6127 /.$putCase consumeArgumentList(); $break ./
6129 --Thess rules are re-written in order to be ll1
6130 --ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer
6131 --ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt
6132 --ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt
6133 --DimExprs ::= DimExpr
6134 --DimExprs ::= DimExprs DimExpr
6136 ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
6137 /.$putCase consumeArrayCreationExpression(); $break ./
6138 ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
6139 /.$putCase consumeArrayCreationExpression(); $break ./
6141 DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
6142 DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
6143 /.$putCase consumeDimWithOrWithOutExprs(); $break ./
6145 DimWithOrWithOutExpr ::= '[' Expression ']'
6146 DimWithOrWithOutExpr ::= '[' ']'
6147 /. $putCase consumeDimWithOrWithOutExpr(); $break ./
6148 -- -----------------------------------------------
6151 /. $putCase consumeDims(); $break ./
6152 DimsLoop -> OneDimLoop
6153 DimsLoop ::= DimsLoop OneDimLoop
6154 OneDimLoop ::= '[' ']'
6155 /. $putCase consumeOneDimLoop(); $break ./
6157 FieldAccess ::= Primary '.' 'Identifier'
6158 /.$putCase consumeFieldAccess(false); $break ./
6160 FieldAccess ::= 'super' '.' 'Identifier'
6161 /.$putCase consumeFieldAccess(true); $break ./
6163 MethodInvocation ::= Name '(' ArgumentListopt ')'
6164 /.$putCase consumeMethodInvocationName(); $break ./
6166 MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
6167 /.$putCase consumeMethodInvocationPrimary(); $break ./
6169 MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
6170 /.$putCase consumeMethodInvocationSuper(); $break ./
6172 ArrayAccess ::= Name '[' Expression ']'
6173 /.$putCase consumeArrayAccess(true); $break ./
6174 ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
6175 /.$putCase consumeArrayAccess(false); $break ./
6177 PostfixExpression -> Primary
6178 PostfixExpression ::= Name
6179 /.$putCase consumePostfixExpression(); $break ./
6180 PostfixExpression -> PostIncrementExpression
6181 PostfixExpression -> PostDecrementExpression
6183 PostIncrementExpression ::= PostfixExpression '++'
6184 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./
6186 PostDecrementExpression ::= PostfixExpression '--'
6187 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./
6189 --for source managment purpose
6190 PushPosition ::= $empty
6191 /.$putCase consumePushPosition(); $break ./
6193 UnaryExpression -> PreIncrementExpression
6194 UnaryExpression -> PreDecrementExpression
6195 UnaryExpression ::= '+' PushPosition UnaryExpression
6196 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./
6197 UnaryExpression ::= '-' PushPosition UnaryExpression
6198 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./
6199 UnaryExpression -> UnaryExpressionNotPlusMinus
6201 PreIncrementExpression ::= '++' PushPosition UnaryExpression
6202 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./
6204 PreDecrementExpression ::= '--' PushPosition UnaryExpression
6205 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./
6207 UnaryExpressionNotPlusMinus -> PostfixExpression
6208 UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
6209 /.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./
6210 UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
6211 /.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./
6212 UnaryExpressionNotPlusMinus -> CastExpression
6214 CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
6215 /.$putCase consumeCastExpression(); $break ./
6216 CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
6217 /.$putCase consumeCastExpression(); $break ./
6218 -- Expression is here only in order to make the grammar LL1
6219 CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus
6220 /.$putCase consumeCastExpressionLL1(); $break ./
6222 MultiplicativeExpression -> UnaryExpression
6223 MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
6224 /.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./
6225 MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
6226 /.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./
6227 MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
6228 /.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./
6230 AdditiveExpression -> MultiplicativeExpression
6231 AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
6232 /.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./
6233 AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
6234 /.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./
6236 ShiftExpression -> AdditiveExpression
6237 ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
6238 /.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./
6239 ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
6240 /.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./
6241 ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
6242 /.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./
6244 RelationalExpression -> ShiftExpression
6245 RelationalExpression ::= RelationalExpression '<' ShiftExpression
6246 /.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./
6247 RelationalExpression ::= RelationalExpression '>' ShiftExpression
6248 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./
6249 RelationalExpression ::= RelationalExpression '<=' ShiftExpression
6250 /.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./
6251 RelationalExpression ::= RelationalExpression '>=' ShiftExpression
6252 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./
6253 RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
6254 /.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./
6256 EqualityExpression -> RelationalExpression
6257 EqualityExpression ::= EqualityExpression '==' RelationalExpression
6258 /.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./
6259 EqualityExpression ::= EqualityExpression '!=' RelationalExpression
6260 /.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./
6262 AndExpression -> EqualityExpression
6263 AndExpression ::= AndExpression '&' EqualityExpression
6264 /.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./
6266 ExclusiveOrExpression -> AndExpression
6267 ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
6268 /.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./
6270 InclusiveOrExpression -> ExclusiveOrExpression
6271 InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
6272 /.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./
6274 ConditionalAndExpression -> InclusiveOrExpression
6275 ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
6276 /.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./
6278 ConditionalOrExpression -> ConditionalAndExpression
6279 ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
6280 /.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./
6282 ConditionalExpression -> ConditionalOrExpression
6283 ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
6284 /.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./
6286 AssignmentExpression -> ConditionalExpression
6287 AssignmentExpression -> Assignment
6289 Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
6290 /.$putCase consumeAssignment(); $break ./
6292 -- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
6293 InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer
6294 Assignment ::= InvalidArrayInitializerAssignement
6295 /.$putcase ignoreExpressionAssignment();$break ./
6297 LeftHandSide ::= Name
6298 /.$putCase consumeLeftHandSide(); $break ./
6299 LeftHandSide -> FieldAccess
6300 LeftHandSide -> ArrayAccess
6302 AssignmentOperator ::= '='
6303 /.$putCase consumeAssignmentOperator(EQUAL); $break ./
6304 AssignmentOperator ::= '*='
6305 /.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
6306 AssignmentOperator ::= '/='
6307 /.$putCase consumeAssignmentOperator(DIVIDE); $break ./
6308 AssignmentOperator ::= '%='
6309 /.$putCase consumeAssignmentOperator(REMAINDER); $break ./
6310 AssignmentOperator ::= '+='
6311 /.$putCase consumeAssignmentOperator(PLUS); $break ./
6312 AssignmentOperator ::= '-='
6313 /.$putCase consumeAssignmentOperator(MINUS); $break ./
6314 AssignmentOperator ::= '<<='
6315 /.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
6316 AssignmentOperator ::= '>>='
6317 /.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
6318 AssignmentOperator ::= '>>>='
6319 /.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
6320 AssignmentOperator ::= '&='
6321 /.$putCase consumeAssignmentOperator(AND); $break ./
6322 AssignmentOperator ::= '^='
6323 /.$putCase consumeAssignmentOperator(XOR); $break ./
6324 AssignmentOperator ::= '|='
6325 /.$putCase consumeAssignmentOperator(OR); $break ./
6327 Expression -> AssignmentExpression
6329 ConstantExpression -> Expression
6331 -- The following rules are for optional nonterminals.
6334 PackageDeclarationopt -> $empty
6335 PackageDeclarationopt -> PackageDeclaration
6337 ClassHeaderExtendsopt ::= $empty
6338 ClassHeaderExtendsopt -> ClassHeaderExtends
6340 Expressionopt ::= $empty
6341 /.$putCase consumeEmptyExpression(); $break ./
6342 Expressionopt -> Expression
6345 ---------------------------------------------------------------------------------------
6347 -- The rules below are for optional terminal symbols. An optional comma,
6348 -- is only used in the context of an array initializer - It is a
6349 -- "syntactic sugar" that otherwise serves no other purpose. By contrast,
6350 -- an optional identifier is used in the definition of a break and
6351 -- continue statement. When the identifier does not appear, a NULL
6352 -- is produced. When the identifier is present, the user should use the
6353 -- corresponding TOKEN(i) method. See break statement as an example.
6355 ---------------------------------------------------------------------------------------
6360 ImportDeclarationsopt ::= $empty
6361 /.$putCase consumeEmptyImportDeclarationsopt(); $break ./
6362 ImportDeclarationsopt ::= ImportDeclarations
6363 /.$putCase consumeImportDeclarationsopt(); $break ./
6366 TypeDeclarationsopt ::= $empty
6367 /.$putCase consumeEmptyTypeDeclarationsopt(); $break ./
6368 TypeDeclarationsopt ::= TypeDeclarations
6369 /.$putCase consumeTypeDeclarationsopt(); $break ./
6371 ClassBodyDeclarationsopt ::= $empty
6372 /.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
6373 ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
6374 /.$putCase consumeClassBodyDeclarationsopt(); $break ./
6376 Modifiersopt ::= $empty
6377 /. $putCase consumeDefaultModifiers(); $break ./
6378 Modifiersopt ::= Modifiers
6379 /.$putCase consumeModifiers(); $break ./
6381 BlockStatementsopt ::= $empty
6382 /.$putCase consumeEmptyBlockStatementsopt(); $break ./
6383 BlockStatementsopt -> BlockStatements
6386 /. $putCase consumeEmptyDimsopt(); $break ./
6389 ArgumentListopt ::= $empty
6390 /. $putCase consumeEmptyArgumentListopt(); $break ./
6391 ArgumentListopt -> ArgumentList
6393 MethodHeaderThrowsClauseopt ::= $empty
6394 MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
6396 FormalParameterListopt ::= $empty
6397 /.$putcase consumeFormalParameterListopt(); $break ./
6398 FormalParameterListopt -> FormalParameterList
6400 ClassHeaderImplementsopt ::= $empty
6401 ClassHeaderImplementsopt -> ClassHeaderImplements
6403 InterfaceMemberDeclarationsopt ::= $empty
6404 /. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
6405 InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
6406 /. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
6408 NestedType ::= $empty
6409 /.$putCase consumeNestedType(); $break./
6411 ForInitopt ::= $empty
6412 /. $putCase consumeEmptyForInitopt(); $break ./
6413 ForInitopt -> ForInit
6415 ForUpdateopt ::= $empty
6416 /. $putCase consumeEmptyForUpdateopt(); $break ./
6417 ForUpdateopt -> ForUpdate
6419 InterfaceHeaderExtendsopt ::= $empty
6420 InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
6422 Catchesopt ::= $empty
6423 /. $putCase consumeEmptyCatchesopt(); $break ./
6424 Catchesopt -> Catches
6426 ArrayInitializeropt ::= $empty
6427 /. $putCase consumeEmptyArrayInitializeropt(); $break ./
6428 ArrayInitializeropt -> ArrayInitializer
6433 ---------------------------------------------------------------------------------------
6437 -- BodyMarker ::= '"class Identifier { ... MethodHeader "'
6442 MINUS_MINUS ::= '--'
6443 EQUAL_EQUAL ::= '=='
6445 GREATER_EQUAL ::= '>='
6448 RIGHT_SHIFT ::= '>>'
6449 UNSIGNED_RIGHT_SHIFT ::= '>>>'
6451 MINUS_EQUAL ::= '-='
6452 MULTIPLY_EQUAL ::= '*='
6453 DIVIDE_EQUAL ::= '/='
6457 REMAINDER_EQUAL ::= '%='
6458 LEFT_SHIFT_EQUAL ::= '<<='
6459 RIGHT_SHIFT_EQUAL ::= '>>='
6460 UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>='
6490 -- need a carriage return after the $end
6493 protected void ignoreExpressionAssignment() {
6494 // Assignment ::= InvalidArrayInitializerAssignement
6495 // encoded operator would be: intStack[intPtr]
6497 ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--];
6498 expressionLengthPtr--;
6499 // report a syntax error and abort parsing
6500 problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
6502 protected void ignoreInterfaceDeclaration() {
6503 // BlockStatement ::= InvalidInterfaceDeclaration
6504 //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
6506 // length declarations
6508 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6509 //there are length declarations
6510 //dispatch according to the type of the declarations
6511 dispatchDeclarationInto(length);
6514 flushAnnotationsDefinedPriorTo(endStatementPosition);
6516 // report the problem and continue parsing
6517 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
6518 typeDecl.bodyEnd = endStatementPosition;
6519 problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
6521 // mark fields and initializer with local type mark if needed
6522 markFieldsWithLocalType(typeDecl);
6524 // remove the ast node created in interface header
6526 // Don't create an astnode for this inner interface, but have to push
6527 // a 0 on the astLengthStack to be consistent with the reduction made
6528 // at the end of the method:
6529 // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit)
6530 pushOnAstLengthStack(0);
6532 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
6533 // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
6534 // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
6537 astStack : modifiers arguments throws statements
6538 identifierStack : name
6540 astStack : MethodDeclaration
6544 //must provide a default constructor call when needed
6547 // pop the position of the { (body of the method) pushed in block decl
6557 if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) {
6561 protected void ignoreMethodBody() {
6562 // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
6565 astStack : modifiers arguments throws statements
6566 identifierStack : type name
6567 intStack : dim dim dim
6569 astStack : MethodDeclaration
6574 // pop the position of the { (body of the method) pushed in block decl
6576 // retrieve end position of method declarator
6581 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6585 //watch for } that could be given as a unicode ! ( u007D is '}' )
6586 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
6587 md.bodyEnd = endPosition;
6588 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
6590 // report the problem and continue the parsing - narrowing the problem onto the method
6591 problemReporter().abstractMethodNeedingNoBody(md);
6593 public void initialize() {
6594 //positionning the parser for a new compilation unit
6595 //avoiding stack reallocation and all that....
6599 expressionLengthPtr = -1;
6601 identifierLengthPtr = -1;
6603 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
6604 variablesCounter[nestedType] = 0;
6607 compilationUnit = null;
6608 referenceContext = null;
6609 endStatementPosition = 0;
6611 //remove objects from stack too, while the same parser/compiler couple is
6612 //re-used between two compilations ....
6614 int astLength = astStack.length;
6615 if (noAstNodes.length < astLength) {
6616 noAstNodes = new AstNode[astLength];
6617 //System.out.println("Resized AST stacks : "+ astLength);
6620 System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
6622 int expressionLength = expressionStack.length;
6623 if (noExpressions.length < expressionLength) {
6624 noExpressions = new Expression[expressionLength];
6625 //System.out.println("Resized EXPR stacks : "+ expressionLength);
6627 System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
6629 // reset scanner state
6630 scanner.commentPtr = -1;
6631 scanner.eofPosition = Integer.MAX_VALUE;
6636 lastCheckPoint = -1;
6637 currentElement = null;
6638 restartRecovery = false;
6639 hasReportedError = false;
6640 recoveredStaticInitializerStart = 0;
6641 lastIgnoredToken = -1;
6642 lastErrorEndPosition = -1;
6645 public void initializeScanner() {
6650 this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore,
6653 public final static void initTables() throws java.io.IOException {
6655 final String prefix = FILEPREFIX;
6657 lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6658 char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6659 check_table = new short[chars.length];
6660 for (int c = chars.length; c-- > 0;) {
6661 check_table[c] = (short) (chars[c] - 32768);
6663 asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6664 asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6665 symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6668 public final void jumpOverMethodBody() {
6669 //on diet parsing.....do not buffer method statements
6671 //the scanner.diet is reinitialized to false
6672 //automatically by the scanner once it has jumped over
6675 if (diet && (dietInt == 0))
6676 scanner.diet = true;
6678 protected void markCurrentMethodWithLocalType() {
6679 if (this.currentElement != null)
6680 return; // this is already done in the recovery code
6681 for (int i = this.astPtr; i >= 0; i--) {
6682 AstNode node = this.astStack[i];
6683 if (node instanceof AbstractMethodDeclaration
6684 || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type
6685 node.bits |= AstNode.HasLocalTypeMASK;
6689 // default to reference context (case of parse method body)
6690 if (this.referenceContext instanceof AbstractMethodDeclaration || this.referenceContext instanceof TypeDeclaration) {
6691 ((AstNode) this.referenceContext).bits |= AstNode.HasLocalTypeMASK;
6694 protected void markFieldsWithLocalType(TypeDeclaration type) {
6695 if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0)
6697 for (int i = 0, length = type.fields.length; i < length; i++) {
6698 type.fields[i].bits |= AstNode.HasLocalTypeMASK;
6702 * Move checkpoint location (current implementation is moving it by one token)
6704 * Answers true if successfully moved checkpoint (i.e. did not attempt to move it
6705 * beyond end of file).
6707 protected boolean moveRecoveryCheckpoint() {
6709 int pos = lastCheckPoint;
6710 /* reset scanner, and move checkpoint by one token */
6711 scanner.startPosition = pos;
6712 scanner.currentPosition = pos;
6713 scanner.diet = false; // quit jumping over method bodies
6715 /* if about to restart, then no need to shift token */
6716 if (restartRecovery) {
6717 lastIgnoredToken = -1;
6721 /* protect against shifting on an invalid token */
6722 lastIgnoredToken = nextIgnoredToken;
6723 nextIgnoredToken = -1;
6726 nextIgnoredToken = scanner.getNextToken();
6727 if (scanner.currentPosition == scanner.startPosition) {
6728 scanner.currentPosition++; // on fake completion identifier
6729 nextIgnoredToken = -1;
6732 } catch (InvalidInputException e) {
6733 pos = scanner.currentPosition;
6735 } while (nextIgnoredToken < 0);
6737 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6738 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6742 lastCheckPoint = scanner.currentPosition;
6744 /* reset scanner again to previous checkpoint location*/
6745 scanner.startPosition = pos;
6746 scanner.currentPosition = pos;
6747 scanner.commentPtr = -1;
6752 The following implementation moves the checkpoint location by one line:
6754 int pos = lastCheckPoint;
6755 // reset scanner, and move checkpoint by one token
6756 scanner.startPosition = pos;
6757 scanner.currentPosition = pos;
6758 scanner.diet = false; // quit jumping over method bodies
6760 // if about to restart, then no need to shift token
6761 if (restartRecovery){
6762 lastIgnoredToken = -1;
6766 // protect against shifting on an invalid token
6767 lastIgnoredToken = nextIgnoredToken;
6768 nextIgnoredToken = -1;
6770 boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace;
6771 scanner.tokenizeWhiteSpace = true;
6775 nextIgnoredToken = scanner.getNextToken();
6776 switch(nextIgnoredToken){
6777 case Scanner.TokenNameWHITESPACE :
6778 if(scanner.getLineNumber(scanner.startPosition)
6779 == scanner.getLineNumber(scanner.currentPosition)){
6780 nextIgnoredToken = -1;
6783 case TokenNameSEMICOLON :
6784 case TokenNameLBRACE :
6785 case TokenNameRBRACE :
6787 case TokenNameIdentifier :
6788 if(scanner.currentPosition == scanner.startPosition){
6789 scanner.currentPosition++; // on fake completion identifier
6792 nextIgnoredToken = -1;
6795 break checkpointMove;
6797 } catch(InvalidInputException e){
6798 pos = scanner.currentPosition;
6800 } while (nextIgnoredToken < 0);
6801 scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
6803 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6804 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6808 lastCheckPoint = scanner.currentPosition;
6810 // reset scanner again to previous checkpoint location
6811 scanner.startPosition = pos;
6812 scanner.currentPosition = pos;
6813 scanner.commentPtr = -1;
6818 protected MessageSend newMessageSend() {
6819 // '(' ArgumentListopt ')'
6820 // the arguments are on the expression stack
6822 MessageSend m = new MessageSend();
6824 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
6825 expressionPtr -= length;
6826 System.arraycopy(expressionStack, expressionPtr + 1, m.arguments = new Expression[length], 0, length);
6830 protected static int ntAction(int state, int sym) {
6831 return action[state + sym];
6833 private final void optimizedConcatNodeLists() {
6834 /*back from a recursive loop. Virtualy group the
6835 astNode into an array using astLengthStack*/
6838 * This is a case where you have two sublists into the astStack that you want
6839 * to merge in one list. There is no action required on the astStack. The only
6840 * thing you need to do is merge the two lengths specified on the astStackLength.
6841 * The top two length are for example:
6843 * and you want to result in a list like:
6845 * This means that the p could be equals to 0 in case there is no astNode pushed
6847 * Look at the InterfaceMemberDeclarations for an example.
6848 * This case optimizes the fact that p == 1.
6851 astLengthStack[--astLengthPtr]++;
6853 protected static int original_state(int state) {
6854 return -check(state);
6856 /*main loop of the automat
6857 When a rule is reduced, the method consumeRule(int) is called with the number
6858 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
6859 called in order to remember (when needed) the consumed token */
6860 // (int)asr[asi(act)]
6861 // name[symbol_index[currentKind]]
6862 protected void parse() {
6864 hasReportedError = false;
6865 int act = START_STATE;
6867 currentToken = getFirstToken();
6868 ProcessTerminals : for (;;) {
6870 stack[++stateStackTop] = act;
6871 } catch (IndexOutOfBoundsException e) {
6872 int oldStackLength = stack.length;
6873 int oldStack[] = stack;
6874 stack = new int[oldStackLength + StackIncrement];
6875 System.arraycopy(oldStack, 0, stack, 0, oldStackLength);
6876 stack[stateStackTop] = act;
6879 act = tAction(act, currentToken);
6881 if (act == ERROR_ACTION || restartRecovery) {
6882 int errorPos = scanner.currentPosition;
6883 if (!hasReportedError) {
6884 this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop);
6885 hasReportedError = true;
6887 if (resumeOnSyntaxError()) {
6888 if (act == ERROR_ACTION)
6889 lastErrorEndPosition = errorPos;
6892 currentToken = getFirstToken();
6893 continue ProcessTerminals;
6897 break ProcessTerminals;
6899 if (act <= NUM_RULES)
6901 else if (act > ERROR_ACTION) { /* shift-reduce */
6902 consumeToken(currentToken);
6903 if (currentElement != null)
6904 this.recoveryTokenCheck();
6906 currentToken = scanner.getNextToken();
6907 } catch (InvalidInputException e) {
6908 if (!hasReportedError) {
6909 this.problemReporter().scannerError(this, e.getMessage());
6910 hasReportedError = true;
6912 lastCheckPoint = scanner.currentPosition;
6913 restartRecovery = true;
6915 act -= ERROR_ACTION;
6916 } else if (act < ACCEPT_ACTION) { /* shift */
6917 consumeToken(currentToken);
6918 if (currentElement != null)
6919 this.recoveryTokenCheck();
6921 currentToken = scanner.getNextToken();
6922 } catch (InvalidInputException e) {
6923 if (!hasReportedError) {
6924 this.problemReporter().scannerError(this, e.getMessage());
6925 hasReportedError = true;
6927 lastCheckPoint = scanner.currentPosition;
6928 restartRecovery = true;
6930 continue ProcessTerminals;
6932 break ProcessTerminals;
6934 ProcessNonTerminals : do { /* reduce */
6936 stateStackTop -= (rhs[act] - 1);
6937 act = ntAction(stack[stateStackTop], lhs[act]);
6938 } while (act <= NUM_RULES);
6944 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
6945 //only parse the method body of cd
6946 //fill out its statements
6948 //convert bugs into parse error
6951 goForConstructorBody();
6952 nestedMethod[nestedType]++;
6954 referenceContext = cd;
6955 compilationUnit = unit;
6957 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
6960 } catch (AbortCompilation ex) {
6961 lastAct = ERROR_ACTION;
6963 nestedMethod[nestedType]--;
6966 if (lastAct == ERROR_ACTION) {
6972 cd.explicitDeclarations = realBlockStack[realBlockPtr--];
6974 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6976 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
6977 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
6979 System.arraycopy(astStack, astPtr + 2, cd.statements = new Statement[length - 1], 0, length - 1);
6980 cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
6981 } else { //need to add explicitly the super();
6982 System.arraycopy(astStack, astPtr + 1, cd.statements = new Statement[length], 0, length);
6983 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6986 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6989 if (cd.constructorCall.sourceEnd == 0) {
6990 cd.constructorCall.sourceEnd = cd.sourceEnd;
6991 cd.constructorCall.sourceStart = cd.sourceStart;
6996 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
6997 //only parse the method body of md
6998 //fill out method statements
7000 //convert bugs into parse error
7004 nestedMethod[nestedType]++;
7006 referenceContext = type;
7007 compilationUnit = unit;
7009 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
7012 } catch (AbortCompilation ex) {
7013 lastAct = ERROR_ACTION;
7015 nestedMethod[nestedType]--;
7018 if (lastAct == ERROR_ACTION) {
7022 ini.block = ((Initializer) astStack[astPtr]).block;
7024 // mark initializer with local type if one was found during parsing
7025 if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
7026 ini.bits |= AstNode.HasLocalTypeMASK;
7031 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
7032 //only parse the method body of md
7033 //fill out method statements
7035 //convert bugs into parse error
7037 if (md.isAbstract())
7041 if ((md.modifiers & AccSemicolonBody) != 0)
7046 nestedMethod[nestedType]++;
7048 referenceContext = md;
7049 compilationUnit = unit;
7051 scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
7052 // reset the scanner to parser from { down to }
7055 } catch (AbortCompilation ex) {
7056 lastAct = ERROR_ACTION;
7058 nestedMethod[nestedType]--;
7061 if (lastAct == ERROR_ACTION) {
7066 md.explicitDeclarations = realBlockStack[realBlockPtr--];
7068 if ((length = astLengthStack[astLengthPtr--]) != 0)
7069 System.arraycopy(astStack, (astPtr -= length) + 1, md.statements = new Statement[length], 0, length);
7073 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
7074 // parses a compilation unit and manages error handling (even bugs....)
7076 CompilationUnitDeclaration unit;
7078 /* automaton initialization */
7080 goForCompilationUnit();
7082 /* scanner initialization */
7083 scanner.setSource(sourceUnit.getContents());
7087 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
7091 unit = compilationUnit;
7092 compilationUnit = null; // reset parser
7098 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
7099 // parses a compilation unit and manages error handling (even bugs....)
7101 CompilationUnitDeclaration unit;
7103 /* automaton initialization */
7105 goForCompilationUnit();
7107 /* scanner initialization */
7108 scanner.setSource(sourceUnit.getContents());
7109 scanner.resetTo(start, end);
7112 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
7116 unit = compilationUnit;
7117 compilationUnit = null; // reset parser
7122 * Returns this parser's problem reporter initialized with its reference context.
7123 * Also it is assumed that a problem is going to be reported, so initializes
7124 * the compilation result's line positions.
7126 public ProblemReporter problemReporter() {
7127 if (scanner.recordLineSeparator) {
7128 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
7130 problemReporter.referenceContext = referenceContext;
7131 return problemReporter;
7133 protected void pushIdentifier() {
7134 /*push the consumeToken on the identifier stack.
7135 Increase the total number of identifier in the stack.
7136 identifierPtr points on the next top */
7139 identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource();
7140 identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7141 } catch (IndexOutOfBoundsException e) {
7142 /*---stack reallaocation (identifierPtr is correct)---*/
7143 int oldStackLength = identifierStack.length;
7144 char[][] oldStack = identifierStack;
7145 identifierStack = new char[oldStackLength + 20][];
7146 System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength);
7147 identifierStack[identifierPtr] = scanner.getCurrentTokenSource();
7148 /*identifier position stack*/
7149 long[] oldPos = identifierPositionStack;
7150 identifierPositionStack = new long[oldStackLength + 20];
7151 System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength);
7152 identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7156 identifierLengthStack[++identifierLengthPtr] = 1;
7157 } catch (IndexOutOfBoundsException e) {
7158 /*---stack reallocation (identifierLengthPtr is correct)---*/
7159 int oldStackLength = identifierLengthStack.length;
7160 int oldStack[] = identifierLengthStack;
7161 identifierLengthStack = new int[oldStackLength + 10];
7162 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7163 identifierLengthStack[identifierLengthPtr] = 1;
7167 protected void pushIdentifier(int flag) {
7168 /*push a special flag on the stack :
7169 -zero stands for optional Name
7170 -negative number for direct ref to base types.
7171 identifierLengthPtr points on the top */
7174 identifierLengthStack[++identifierLengthPtr] = flag;
7175 } catch (IndexOutOfBoundsException e) {
7176 /*---stack reallaocation (identifierLengthPtr is correct)---*/
7177 int oldStackLength = identifierLengthStack.length;
7178 int oldStack[] = identifierLengthStack;
7179 identifierLengthStack = new int[oldStackLength + 10];
7180 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7181 identifierLengthStack[identifierLengthPtr] = flag;
7185 protected void pushOnAstLengthStack(int pos) {
7187 astLengthStack[++astLengthPtr] = pos;
7188 } catch (IndexOutOfBoundsException e) {
7189 int oldStackLength = astLengthStack.length;
7190 int[] oldPos = astLengthStack;
7191 astLengthStack = new int[oldStackLength + StackIncrement];
7192 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7193 astLengthStack[astLengthPtr] = pos;
7196 protected void pushOnAstStack(AstNode node) {
7197 /*add a new obj on top of the ast stack
7198 astPtr points on the top*/
7201 astStack[++astPtr] = node;
7202 } catch (IndexOutOfBoundsException e) {
7203 int oldStackLength = astStack.length;
7204 AstNode[] oldStack = astStack;
7205 astStack = new AstNode[oldStackLength + AstStackIncrement];
7206 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
7207 astPtr = oldStackLength;
7208 astStack[astPtr] = node;
7212 astLengthStack[++astLengthPtr] = 1;
7213 } catch (IndexOutOfBoundsException e) {
7214 int oldStackLength = astLengthStack.length;
7215 int[] oldPos = astLengthStack;
7216 astLengthStack = new int[oldStackLength + AstStackIncrement];
7217 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7218 astLengthStack[astLengthPtr] = 1;
7221 protected void pushOnExpressionStack(Expression expr) {
7224 expressionStack[++expressionPtr] = expr;
7225 } catch (IndexOutOfBoundsException e) {
7226 //expressionPtr is correct
7227 int oldStackLength = expressionStack.length;
7228 Expression[] oldStack = expressionStack;
7229 expressionStack = new Expression[oldStackLength + ExpressionStackIncrement];
7230 System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength);
7231 expressionStack[expressionPtr] = expr;
7235 expressionLengthStack[++expressionLengthPtr] = 1;
7236 } catch (IndexOutOfBoundsException e) {
7237 int oldStackLength = expressionLengthStack.length;
7238 int[] oldPos = expressionLengthStack;
7239 expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement];
7240 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7241 expressionLengthStack[expressionLengthPtr] = 1;
7244 protected void pushOnExpressionStackLengthStack(int pos) {
7246 expressionLengthStack[++expressionLengthPtr] = pos;
7247 } catch (IndexOutOfBoundsException e) {
7248 int oldStackLength = expressionLengthStack.length;
7249 int[] oldPos = expressionLengthStack;
7250 expressionLengthStack = new int[oldStackLength + StackIncrement];
7251 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7252 expressionLengthStack[expressionLengthPtr] = pos;
7255 protected void pushOnIntStack(int pos) {
7258 intStack[++intPtr] = pos;
7259 } catch (IndexOutOfBoundsException e) {
7261 int oldStackLength = intStack.length;
7262 int oldStack[] = intStack;
7263 intStack = new int[oldStackLength + StackIncrement];
7264 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
7265 intStack[intPtr] = pos;
7268 protected static char[] readTable(String filename) throws java.io.IOException {
7270 //files are located at Parser.class directory
7272 InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename));
7273 if (stream == null) {
7274 throw new java.io.IOException(Util.bind("parser.missingFile", filename)); //$NON-NLS-1$
7276 byte[] bytes = null;
7278 bytes = Util.getInputStreamAsByteArray(stream, -1);
7282 } catch (IOException e) {
7286 //minimal integrity check (even size expected)
7287 int length = bytes.length;
7288 if (length % 2 != 0)
7289 throw new java.io.IOException(Util.bind("parser.corruptedFile", filename)); //$NON-NLS-1$
7291 // convert bytes into chars
7292 char[] chars = new char[length / 2];
7297 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
7303 /* Token check performed on every token shift once having entered
7306 public void recoveryTokenCheck() {
7307 switch (currentToken) {
7308 case TokenNameLBRACE :
7310 RecoveredElement newElement = currentElement.updateOnOpeningBrace(scanner.currentPosition - 1);
7311 lastCheckPoint = scanner.currentPosition;
7312 if (newElement != null) { // null means nothing happened
7313 restartRecovery = true; // opening brace detected
7314 currentElement = newElement;
7318 case TokenNameRBRACE :
7320 endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1);
7321 RecoveredElement newElement = currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition - 1);
7322 lastCheckPoint = scanner.currentPosition;
7323 if (newElement != currentElement) {
7324 currentElement = newElement;
7329 protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
7331 /* remember current scanner position */
7332 int startPos = scanner.startPosition;
7333 int currentPos = scanner.currentPosition;
7335 String[] expectings;
7336 String tokenName = name[symbol_index[currentKind]];
7338 //fetch all "accurate" possible terminals that could recover the error
7339 int start, end = start = asi(stack[stateStackTop]);
7340 while (asr[end] != 0)
7342 int length = end - start;
7343 expectings = new String[length];
7345 char[] indexes = new char[length];
7346 System.arraycopy(asr, start, indexes, 0, length);
7347 for (int i = 0; i < length; i++) {
7348 expectings[i] = name[symbol_index[indexes[i]]];
7352 //if the pb is an EOF, try to tell the user that they are some
7353 if (tokenName.equals(UNEXPECTED_EOF)) {
7354 if (!this.checkAndReportBracketAnomalies(problemReporter())) {
7357 tokenSource = this.scanner.getCurrentTokenSource();
7358 } catch (Exception e) {
7359 tokenSource = new char[] {
7362 problemReporter().parseError(
7363 this.scanner.startPosition,
7364 this.scanner.currentPosition - 1,
7369 } else { //the next test is HEAVILY grammar DEPENDENT.
7370 if ((length == 2) && (tokenName.equals(";")) //$NON-NLS-1$
7371 && (expectings[0] == "++") //$NON-NLS-1$
7372 && (expectings[1] == "--") //$NON-NLS-1$
7373 && (expressionPtr > -1)) {
7374 // the ; is not the expected token ==> it ends a statement when an expression is not ended
7375 problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
7379 tokenSource = this.scanner.getCurrentTokenSource();
7380 } catch (Exception e) {
7381 tokenSource = new char[] {
7384 problemReporter().parseError(
7385 this.scanner.startPosition,
7386 this.scanner.currentPosition - 1,
7390 this.checkAndReportBracketAnomalies(problemReporter());
7393 /* reset scanner where it was */
7394 scanner.startPosition = startPos;
7395 scanner.currentPosition = currentPos;
7397 protected void resetModifiers() {
7398 modifiers = AccDefault;
7399 modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
7400 scanner.commentPtr = -1;
7403 * Reset context so as to resume to regular parse loop
7405 protected void resetStacks() {
7410 expressionLengthPtr = -1;
7412 identifierLengthPtr = -1;
7414 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
7415 variablesCounter[nestedType] = 0;
7417 realBlockStack[realBlockPtr = 0] = 0;
7418 recoveredStaticInitializerStart = 0;
7422 * Reset context so as to resume to regular parse loop
7423 * If unable to reset for resuming, answers false.
7425 * Move checkpoint location, reset internal stacks and
7426 * decide which grammar goal is activated.
7428 protected boolean resumeAfterRecovery() {
7430 // reset internal stacks
7433 /* attempt to move checkpoint location */
7434 if (!this.moveRecoveryCheckpoint())
7437 // only look for headers
7438 if (referenceContext instanceof CompilationUnitDeclaration) {
7440 diet = true; // passed this point, will not consider method bodies
7443 // does not know how to restart
7447 * Syntax error was detected. Will attempt to perform some recovery action in order
7448 * to resume to the regular parse loop.
7450 protected boolean resumeOnSyntaxError() {
7452 /* request recovery initialization */
7453 if (currentElement == null) {
7454 currentElement = this.buildInitialRecoveryState(); // build some recovered elements
7456 /* do not investigate deeper in recovery when no recovered element */
7457 if (currentElement == null)
7460 /* manual forced recovery restart - after headers */
7461 if (restartRecovery) {
7462 restartRecovery = false;
7464 /* update recovery state with current error state of the parser */
7465 this.updateRecoveryState();
7467 /* attempt to reset state in order to resume to parse loop */
7468 return this.resumeAfterRecovery();
7470 protected static int tAction(int state, int sym) {
7471 return action[check(state + sym) == sym ? state + sym : state];
7473 public String toString() {
7475 String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
7476 for (int i = 0; i <= identifierPtr; i++) {
7477 s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
7479 s = s + "}\n"; //$NON-NLS-1$
7481 s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
7482 for (int i = 0; i <= identifierLengthPtr; i++) {
7483 s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$
7485 s = s + "}\n"; //$NON-NLS-1$
7487 s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
7488 for (int i = 0; i <= astLengthPtr; i++) {
7489 s = s + astLengthStack[i] + ","; //$NON-NLS-1$
7491 s = s + "}\n"; //$NON-NLS-1$
7492 s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7494 s = s + "intStack : int[] = {"; //$NON-NLS-1$
7495 for (int i = 0; i <= intPtr; i++) {
7496 s = s + intStack[i] + ","; //$NON-NLS-1$
7498 s = s + "}\n"; //$NON-NLS-1$
7500 s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
7501 for (int i = 0; i <= expressionLengthPtr; i++) {
7502 s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$
7504 s = s + "}\n"; //$NON-NLS-1$
7506 s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7508 s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$
7513 * Update recovery state based on current parser/scanner state
7515 protected void updateRecoveryState() {
7517 /* expose parser state to recovery state */
7518 currentElement.updateFromParserState();
7520 /* check and update recovered state based on current token,
7521 this action is also performed when shifting token after recovery
7524 this.recoveryTokenCheck();
7526 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
7527 //fields is a definition of fields that are grouped together like in
7528 //public int[] a, b[], c
7529 //which results into 3 fields.
7531 FieldDeclaration field;
7532 int endTypeDeclarationPosition = -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart;
7533 for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
7534 //last one is special(see below)
7535 field = (FieldDeclaration) astStack[astPtr - i - 1];
7536 field.endPart1Position = endTypeDeclarationPosition;
7537 field.endPart2Position = -1 + astStack[astPtr - i].sourceStart;
7540 (field = (FieldDeclaration) astStack[astPtr]).endPart1Position = endTypeDeclarationPosition;
7541 field.endPart2Position = field.declarationSourceEnd;
7544 protected void updateSourcePosition(Expression exp) {
7545 //update the source Position of the expression
7547 //intStack : int int
7551 exp.sourceEnd = intStack[intPtr--];
7552 exp.sourceStart = intStack[intPtr--];