/******************************************************************************* * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196 *******************************************************************************/ package org.eclipse.jdt.internal.compiler.parser; import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ArrayReference; import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference; import org.eclipse.jdt.internal.compiler.ast.AssertStatement; import org.eclipse.jdt.internal.compiler.ast.Assignment; import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; import org.eclipse.jdt.internal.compiler.ast.Block; import org.eclipse.jdt.internal.compiler.ast.BreakStatement; import org.eclipse.jdt.internal.compiler.ast.CaseStatement; import org.eclipse.jdt.internal.compiler.ast.CastExpression; import org.eclipse.jdt.internal.compiler.ast.CharLiteral; import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment; import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; import org.eclipse.jdt.internal.compiler.ast.ContinueStatement; import org.eclipse.jdt.internal.compiler.ast.DoStatement; import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral; import org.eclipse.jdt.internal.compiler.ast.EmptyStatement; import org.eclipse.jdt.internal.compiler.ast.EqualExpression; import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FalseLiteral; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.FloatLiteral; import org.eclipse.jdt.internal.compiler.ast.ForStatement; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.Initializer; import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression; import org.eclipse.jdt.internal.compiler.ast.IntLiteral; import org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue; import org.eclipse.jdt.internal.compiler.ast.Javadoc; import org.eclipse.jdt.internal.compiler.ast.LabeledStatement; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.LongLiteral; import org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue; import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.PostfixExpression; import org.eclipse.jdt.internal.compiler.ast.PrefixExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.Reference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.SuperReference; import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; import org.eclipse.jdt.internal.compiler.ast.TrueLiteral; import org.eclipse.jdt.internal.compiler.ast.TryStatement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.ast.UnaryExpression; import org.eclipse.jdt.internal.compiler.ast.WhileStatement; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.compiler.util.Messages; import org.eclipse.jdt.internal.compiler.util.Util; public class Parser implements ParserBasicInformation, TerminalTokens, OperatorIds, TypeIds { protected static final int THIS_CALL= ExplicitConstructorCall.This; protected static final int SUPER_CALL= ExplicitConstructorCall.Super; public static final char[] FALL_THROUGH_TAG= "$FALL-THROUGH$".toCharArray(); //$NON-NLS-1$ public static char asb[]= null; public static char asr[]= null; //ast stack protected final static int AstStackIncrement= 100; public static char base_action[]= null; public static final int BracketKinds= 3; public static short check_table[]= null; public static final int CurlyBracket= 2; private static final boolean DEBUG= false; private static final boolean DEBUG_AUTOMATON= false; private static final String EOF_TOKEN= "$eof"; //$NON-NLS-1$ private static final String ERROR_TOKEN= "$error"; //$NON-NLS-1$ //expression stack protected final static int ExpressionStackIncrement= 100; protected final static int GenericsStackIncrement= 10; private final static String FILEPREFIX= "parser"; //$NON-NLS-1$ public static char in_symb[]= null; private static final String INVALID_CHARACTER= "Invalid Character"; //$NON-NLS-1$ public static char lhs[]= null; public static String name[]= null; public static char nasb[]= null; public static char nasr[]= null; public static char non_terminal_index[]= null; private final static String READABLE_NAMES_FILE= "readableNames"; //$NON-NLS-1$ private final static String READABLE_NAMES_FILE_NAME= "org.eclipse.jdt.internal.compiler.parser." + READABLE_NAMES_FILE; //$NON-NLS-1$ public static String readableName[]= null; public static byte rhs[]= null; public static int[] reverse_index= null; public static char[] recovery_templates_index= null; public static char[] recovery_templates= null; public static char[] statements_recovery_filter= null; public static long rules_compliance[]= null; public static final int RoundBracket= 0; public static byte scope_la[]= null; public static char scope_lhs[]= null; public static char scope_prefix[]= null; public static char scope_rhs[]= null; public static char scope_state[]= null; public static char scope_state_set[]= null; public static char scope_suffix[]= null; public static final int SquareBracket= 1; //internal data for the automat protected final static int StackIncrement= 255; public static char term_action[]= null; public static byte term_check[]= null; public static char terminal_index[]= null; private static final String UNEXPECTED_EOF= "Unexpected End Of File"; //$NON-NLS-1$ public static boolean VERBOSE_RECOVERY= false; static { try { initTables(); } catch (java.io.IOException ex) { throw new ExceptionInInitializerError(ex.getMessage()); } } public static int asi(int state) { return asb[original_state(state)]; } public final static short base_check(int i) { return check_table[i - (NUM_RULES + 1)]; } private final static void buildFile(String filename, List listToDump) { BufferedWriter writer= null; try { writer= new BufferedWriter(new FileWriter(filename)); for (Iterator iterator= listToDump.iterator(); iterator.hasNext();) { writer.write(String.valueOf(iterator.next())); } writer.flush(); } catch (IOException e) { // ignore } finally { if (writer != null) { try { writer.close(); } catch (IOException e1) { // ignore } } } System.out.println(filename + " creation complete"); //$NON-NLS-1$ } private static void buildFileForCompliance( String file, int length, String[] tokens) { byte[] result= new byte[length * 8]; for (int i= 0; i < tokens.length; i= i + 3) { if ("2".equals(tokens[i])) { //$NON-NLS-1$ int index= Integer.parseInt(tokens[i + 1]); String token= tokens[i + 2].trim(); long compliance= 0; if ("1.4".equals(token)) { //$NON-NLS-1$ compliance= ClassFileConstants.JDK1_4; } else if ("1.5".equals(token)) { //$NON-NLS-1$ compliance= ClassFileConstants.JDK1_5; } else if ("recovery".equals(token)) { //$NON-NLS-1$ compliance= ClassFileConstants.JDK_DEFERRED; } int j= index * 8; result[j]= (byte)(compliance >>> 56); result[j + 1]= (byte)(compliance >>> 48); result[j + 2]= (byte)(compliance >>> 40); result[j + 3]= (byte)(compliance >>> 32); result[j + 4]= (byte)(compliance >>> 24); result[j + 5]= (byte)(compliance >>> 16); result[j + 6]= (byte)(compliance >>> 8); result[j + 7]= (byte)(compliance); } } buildFileForTable(file, result); } private final static String[] buildFileForName(String filename, String contents) { String[] result= new String[contents.length()]; result[0]= null; int resultCount= 1; StringBuffer buffer= new StringBuffer(); int start= contents.indexOf("name[]"); //$NON-NLS-1$ start= contents.indexOf('\"', start); int end= contents.indexOf("};", start); //$NON-NLS-1$ contents= contents.substring(start, end); boolean addLineSeparator= false; int tokenStart= -1; StringBuffer currentToken= new StringBuffer(); for (int i= 0; i < contents.length(); i++) { char c= contents.charAt(i); if (c == '\"') { if (tokenStart == -1) { tokenStart= i + 1; } else { if (addLineSeparator) { buffer.append('\n'); result[resultCount++]= currentToken.toString(); currentToken= new StringBuffer(); } String token= contents.substring(tokenStart, i); if (token.equals(ERROR_TOKEN)) { token= INVALID_CHARACTER; } else if (token.equals(EOF_TOKEN)) { token= UNEXPECTED_EOF; } buffer.append(token); currentToken.append(token); addLineSeparator= true; tokenStart= -1; } } if (tokenStart == -1 && c == '+') { addLineSeparator= false; } } if (currentToken.length() > 0) { result[resultCount++]= currentToken.toString(); } buildFileForTable(filename, buffer.toString().toCharArray()); System.arraycopy(result, 0, result= new String[resultCount], 0, resultCount); return result; } private static void buildFileForReadableName( String file, char[] newLhs, char[] newNonTerminalIndex, String[] newName, String[] tokens) { ArrayList entries= new ArrayList(); boolean[] alreadyAdded= new boolean[newName.length]; for (int i= 0; i < tokens.length; i= i + 3) { if ("1".equals(tokens[i])) { //$NON-NLS-1$ int index= newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i + 1])]]; StringBuffer buffer= new StringBuffer(); if (!alreadyAdded[index]) { alreadyAdded[index]= true; buffer.append(newName[index]); buffer.append('='); buffer.append(tokens[i + 2].trim()); buffer.append('\n'); entries.add(String.valueOf(buffer)); } } } int i= 1; while (!INVALID_CHARACTER.equals(newName[i])) i++; i++; for (; i < alreadyAdded.length; i++) { if (!alreadyAdded[i]) { System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$ } } Collections.sort(entries); buildFile(file, entries); } private final static void buildFileForTable(String filename, byte[] bytes) { java.io.FileOutputStream stream= null; try { stream= new java.io.FileOutputStream(filename); stream.write(bytes); } catch (IOException e) { // ignore } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // ignore } } } System.out.println(filename + " creation complete"); //$NON-NLS-1$ } private final static void buildFileForTable(String filename, char[] chars) { byte[] bytes= new byte[chars.length * 2]; for (int i= 0; i < chars.length; i++) { bytes[2 * i]= (byte)(chars[i] >>> 8); bytes[2 * i + 1]= (byte)(chars[i] & 0xFF); } java.io.FileOutputStream stream= null; try { stream= new java.io.FileOutputStream(filename); stream.write(bytes); } catch (IOException e) { // ignore } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // ignore } } } System.out.println(filename + " creation complete"); //$NON-NLS-1$ } private final static byte[] buildFileOfByteFor(String filename, String tag, String[] tokens) { //transform the String tokens into chars before dumping then into file int i= 0; //read upto the tag while (!tokens[i++].equals(tag)) {/*empty*/ } //read upto the } byte[] bytes= new byte[tokens.length]; //can't be bigger int ic= 0; String token; while (!(token= tokens[i++]).equals("}")) { //$NON-NLS-1$ int c= Integer.parseInt(token); bytes[ic++]= (byte)c; } //resize System.arraycopy(bytes, 0, bytes= new byte[ic], 0, ic); buildFileForTable(filename, bytes); return bytes; } private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) { //transform the String tokens into chars before dumping then into file int i= 0; //read upto the tag while (!tokens[i++].equals(tag)) {/*empty*/ } //read upto the } char[] chars= new char[tokens.length]; //can't be bigger int ic= 0; String token; while (!(token= tokens[i++]).equals("}")) { //$NON-NLS-1$ int c= Integer.parseInt(token); chars[ic++]= (char)c; } //resize System.arraycopy(chars, 0, chars= new char[ic], 0, ic); buildFileForTable(filename, chars); return chars; } private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) { //transform the String tokens into chars before dumping then into file int i= 0; //read upto the tag while (!tokens[i++].equals(tag)) {/*empty*/ } //read upto the } char[] chars= new char[tokens.length]; //can't be bigger int ic= 0; String token; while (!(token= tokens[i++]).equals("}")) { //$NON-NLS-1$ int c= Integer.parseInt(token); chars[ic++]= (char)(c + 32768); } //resize System.arraycopy(chars, 0, chars= new char[ic], 0, ic); buildFileForTable(filename, chars); } private static void buildFilesForRecoveryTemplates( String indexFilename, String templatesFilename, char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName, char[] newLhs, String[] tokens) { int[] newReverse= computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName); char[] newRecoveyTemplatesIndex= new char[newNonTerminalIndex.length]; char[] newRecoveyTemplates= new char[newNonTerminalIndex.length]; int newRecoveyTemplatesPtr= 0; for (int i= 0; i < tokens.length; i= i + 3) { if ("3".equals(tokens[i])) { //$NON-NLS-1$ int length= newRecoveyTemplates.length; if (length == newRecoveyTemplatesPtr + 1) { System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates= new char[length * 2], 0, length); } newRecoveyTemplates[newRecoveyTemplatesPtr++]= 0; int index= newLhs[Integer.parseInt(tokens[i + 1])]; newRecoveyTemplatesIndex[index]= (char)newRecoveyTemplatesPtr; String token= tokens[i + 2].trim(); java.util.StringTokenizer st= new java.util.StringTokenizer(token, " "); //$NON-NLS-1$ String[] terminalNames= new String[st.countTokens()]; int t= 0; while (st.hasMoreTokens()) { terminalNames[t++]= st.nextToken(); } for (int j= 0; j < terminalNames.length; j++) { int symbol= getSymbol(terminalNames[j], newName, newReverse); if (symbol > -1) { length= newRecoveyTemplates.length; if (length == newRecoveyTemplatesPtr + 1) { System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates= new char[length * 2], 0, length); } newRecoveyTemplates[newRecoveyTemplatesPtr++]= (char)symbol; } } } } newRecoveyTemplates[newRecoveyTemplatesPtr++]= 0; System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates= new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr); buildFileForTable(indexFilename, newRecoveyTemplatesIndex); buildFileForTable(templatesFilename, newRecoveyTemplates); } private static void buildFilesForStatementsRecoveryFilter( String filename, char[] newNonTerminalIndex, char[] newLhs, String[] tokens) { char[] newStatementsRecoveryFilter= new char[newNonTerminalIndex.length]; for (int i= 0; i < tokens.length; i= i + 3) { if ("4".equals(tokens[i])) { //$NON-NLS-1$ int index= newLhs[Integer.parseInt(tokens[i + 1])]; newStatementsRecoveryFilter[index]= 1; } } buildFileForTable(filename, newStatementsRecoveryFilter); } public final static void buildFilesFromLPG(String dataFilename, String dataFilename2) { //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES //build from the lpg javadcl.java files that represents the parser tables //lhs check_table asb asr symbol_index //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")] char[] contents= CharOperation.NO_CHAR; try { contents= Util.getFileCharContent(new File(dataFilename), null); } catch (IOException ex) { System.out.println(Messages.parser_incorrectPath); return; } java.util.StringTokenizer st= new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$ String[] tokens= new String[st.countTokens()]; int j= 0; while (st.hasMoreTokens()) { tokens[j++]= st.nextToken(); } final String prefix= FILEPREFIX; int i= 0; char[] newLhs= buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$ buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$ char[] newTerminalIndex= buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$ char[] newNonTerminalIndex= buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$ buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$ byte[] newRhs= buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$ buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$ String[] newName= buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$ contents= CharOperation.NO_CHAR; try { contents= Util.getFileCharContent(new File(dataFilename2), null); } catch (IOException ex) { System.out.println(Messages.parser_incorrectPath); return; } st= new java.util.StringTokenizer(new String(contents), "\t\n\r#"); //$NON-NLS-1$ tokens= new String[st.countTokens()]; j= 0; while (st.hasMoreTokens()) { tokens[j++]= st.nextToken(); } buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$ buildFileForReadableName(READABLE_NAMES_FILE + ".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$ buildFilesForRecoveryTemplates( prefix + (++i) + ".rsc", //$NON-NLS-1$ prefix + (++i) + ".rsc", //$NON-NLS-1$ newTerminalIndex, newNonTerminalIndex, newName, newLhs, tokens); buildFilesForStatementsRecoveryFilter( prefix + (++i) + ".rsc", //$NON-NLS-1$ newNonTerminalIndex, newLhs, tokens); System.out.println(Messages.parser_moveFiles); } protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName) { int[] newReverseTable= new int[newName.length]; for (int j= 0; j < newName.length; j++) { found: { for (int k= 0; k < newTerminalIndex.length; k++) { if (newTerminalIndex[k] == j) { newReverseTable[j]= k; break found; } } for (int k= 0; k < newNonTerminalIndex.length; k++) { if (newNonTerminalIndex[k] == j) { newReverseTable[j]= -k; break found; } } } } return newReverseTable; } private static int getSymbol(String terminalName, String[] newName, int[] newReverse) { for (int j= 0; j < newName.length; j++) { if (terminalName.equals(newName[j])) { return newReverse[j]; } } return -1; } public static int in_symbol(int state) { return in_symb[original_state(state)]; } public final static void initTables() throws java.io.IOException { final String prefix= FILEPREFIX; int i= 0; lhs= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ char[] chars= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ check_table= new short[chars.length]; for (int c= chars.length; c-- > 0;) { check_table[c]= (short)(chars[c] - 32768); } asb= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ asr= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ nasb= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ nasr= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ terminal_index= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ non_terminal_index= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ term_action= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_prefix= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_suffix= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_lhs= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_state_set= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_rhs= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_state= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ in_symb= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ rhs= readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ term_check= readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ scope_la= readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ name= readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ rules_compliance= readLongTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ readableName= readReadableNameTable(READABLE_NAMES_FILE_NAME); reverse_index= computeReverseTable(terminal_index, non_terminal_index, name); recovery_templates_index= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ recovery_templates= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ statements_recovery_filter= readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ base_action= lhs; } public static int nasi(int state) { return nasb[original_state(state)]; } public static int ntAction(int state, int sym) { return base_action[state + sym]; } protected static int original_state(int state) { return -base_check(state); } protected static byte[] readByteTable(String filename) throws java.io.IOException { //files are located at Parser.class directory InputStream stream= Parser.class.getResourceAsStream(filename); if (stream == null) { throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); } byte[] bytes= null; try { stream= new BufferedInputStream(stream); bytes= Util.getInputStreamAsByteArray(stream, -1); } finally { try { stream.close(); } catch (IOException e) { // ignore } } return bytes; } protected static long[] readLongTable(String filename) throws java.io.IOException { //files are located at Parser.class directory InputStream stream= Parser.class.getResourceAsStream(filename); if (stream == null) { throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); } byte[] bytes= null; try { stream= new BufferedInputStream(stream); bytes= Util.getInputStreamAsByteArray(stream, -1); } finally { try { stream.close(); } catch (IOException e) { // ignore } } //minimal integrity check (even size expected) int length= bytes.length; if (length % 8 != 0) throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename)); // convert bytes into longs long[] longs= new long[length / 8]; int i= 0; int longIndex= 0; while (true) { longs[longIndex++]= (((long)(bytes[i++] & 0xFF)) << 56) + (((long)(bytes[i++] & 0xFF)) << 48) + (((long)(bytes[i++] & 0xFF)) << 40) + (((long)(bytes[i++] & 0xFF)) << 32) + (((long)(bytes[i++] & 0xFF)) << 24) + (((long)(bytes[i++] & 0xFF)) << 16) + (((long)(bytes[i++] & 0xFF)) << 8) + (bytes[i++] & 0xFF); if (i == length) break; } return longs; } protected static String[] readNameTable(String filename) throws java.io.IOException { char[] contents= readTable(filename); char[][] nameAsChar= CharOperation.splitOn('\n', contents); String[] result= new String[nameAsChar.length + 1]; result[0]= null; for (int i= 0; i < nameAsChar.length; i++) { result[i + 1]= new String(nameAsChar[i]); } return result; } protected static String[] readReadableNameTable(String filename) { String[] result= new String[name.length]; ResourceBundle bundle; try { bundle= ResourceBundle.getBundle(filename, Locale.getDefault()); } catch (MissingResourceException e) { System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$ throw e; } for (int i= 0; i < NT_OFFSET + 1; i++) { result[i]= name[i]; } for (int i= NT_OFFSET; i < name.length; i++) { try { String n= bundle.getString(name[i]); if (n != null && n.length() > 0) { result[i]= n; } else { result[i]= name[i]; } } catch (MissingResourceException e) { result[i]= name[i]; } } return result; } protected static char[] readTable(String filename) throws java.io.IOException { //files are located at Parser.class directory InputStream stream= Parser.class.getResourceAsStream(filename); if (stream == null) { throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); } byte[] bytes= null; try { stream= new BufferedInputStream(stream); bytes= Util.getInputStreamAsByteArray(stream, -1); } finally { try { stream.close(); } catch (IOException e) { // ignore } } //minimal integrity check (even size expected) int length= bytes.length; if ((length & 1) != 0) throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename)); // convert bytes into chars char[] chars= new char[length / 2]; int i= 0; int charIndex= 0; while (true) { chars[charIndex++]= (char)(((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF)); if (i == length) break; } return chars; } public static int tAction(int state, int sym) { return term_action[term_check[base_action[state] + sym] == sym ? base_action[state] + sym : base_action[state]]; } protected int astLengthPtr; protected int[] astLengthStack; protected int astPtr; protected ASTNode[] astStack= new ASTNode[AstStackIncrement]; public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/ protected RecoveredElement currentElement; public int currentToken; protected boolean diet= false; //tells the scanner to jump over some parts of the code/expressions like method bodies protected int dietInt= 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...] protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one) protected int endStatementPosition; protected int expressionLengthPtr; protected int[] expressionLengthStack; protected int expressionPtr; protected Expression[] expressionStack= new Expression[ExpressionStackIncrement]; public int firstToken; // handle for multiple parsing goals // generics management protected int genericsIdentifiersLengthPtr; protected int[] genericsIdentifiersLengthStack= new int[GenericsStackIncrement]; protected int genericsLengthPtr; protected int[] genericsLengthStack= new int[GenericsStackIncrement]; protected int genericsPtr; protected ASTNode[] genericsStack= new ASTNode[GenericsStackIncrement]; protected boolean hasError; protected boolean hasReportedError; //identifiers stacks protected int identifierLengthPtr; protected int[] identifierLengthStack; protected long[] identifierPositionStack; protected int identifierPtr; protected char[][] identifierStack; protected boolean ignoreNextOpeningBrace; //positions , dimensions , .... (int stacks) protected int intPtr; protected int[] intStack; public int lastAct; //handle for multiple parsing goals //error recovery management protected int lastCheckPoint; protected int lastErrorEndPosition; protected int lastErrorEndPositionBeforeRecovery= -1; protected int lastIgnoredToken, nextIgnoredToken; protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters) protected int listTypeParameterLength; // for recovering some incomplete list (type parameters) protected int lParenPos, rParenPos; //accurate only when used ! protected int modifiers; protected int modifiersSourceStart; protected int[] nestedMethod; //the ptr is nestedType protected int nestedType, dimensions; ASTNode[] noAstNodes= new ASTNode[AstStackIncrement]; Expression[] noExpressions= new Expression[ExpressionStackIncrement]; //modifiers dimensions nestedType etc....... protected boolean optimizeStringLiterals= true; protected CompilerOptions options; protected ProblemReporter problemReporter; protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used ! protected int realBlockPtr; protected int[] realBlockStack; protected int recoveredStaticInitializerStart; public ReferenceContext referenceContext; public boolean reportOnlyOneSyntaxError= false; public boolean reportSyntaxErrorIsRequired= true; protected boolean restartRecovery; protected boolean annotationRecoveryActivated= true; protected int lastPosistion; // statement recovery public boolean methodRecoveryActivated= false; protected boolean statementRecoveryActivated= false; protected TypeDeclaration[] recoveredTypes; protected int recoveredTypePtr; protected int nextTypeStart; protected TypeDeclaration pendingRecoveredType; public RecoveryScanner recoveryScanner; //scanner token public Scanner scanner; protected int[] stack= new int[StackIncrement]; protected int stateStackTop; protected int synchronizedBlockSourceStart; protected int[] variablesCounter; protected boolean checkExternalizeStrings; protected boolean recordStringLiterals; // javadoc public Javadoc javadoc; public JavadocParser javadocParser; // used for recovery protected int lastJavadocEnd; public org.eclipse.jdt.internal.compiler.ReadManager readManager; public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { this.problemReporter= problemReporter; this.options= problemReporter.options; this.optimizeStringLiterals= optimizeStringLiterals; initializeScanner(); this.astLengthStack= new int[50]; this.expressionLengthStack= new int[30]; this.intStack= new int[50]; this.identifierStack= new char[30][]; this.identifierLengthStack= new int[30]; this.nestedMethod= new int[30]; this.realBlockStack= new int[30]; this.identifierPositionStack= new long[30]; this.variablesCounter= new int[30]; // javadoc support this.javadocParser= createJavadocParser(); } protected void annotationRecoveryCheckPoint(int start, int end) { if (this.lastCheckPoint < end) { this.lastCheckPoint= end + 1; } } public void arrayInitializer(int length) { //length is the size of the array Initializer //expressionPtr points on the last elt of the arrayInitializer, // in other words, it has not been decremented yet. ArrayInitializer ai= new ArrayInitializer(); if (length != 0) { this.expressionPtr-= length; System.arraycopy(this.expressionStack, this.expressionPtr + 1, ai.expressions= new Expression[length], 0, length); } pushOnExpressionStack(ai); //positionning ai.sourceEnd= this.endStatementPosition; ai.sourceStart= this.intStack[this.intPtr--]; } protected void blockReal() { // See consumeLocalVariableDeclarationStatement in case of change: duplicated code // increment the amount of declared variables for this block this.realBlockStack[this.realBlockPtr]++; } /* * Build initial recovery state. * Recovery state is inferred from the current state of the parser (reduced node stack). */ public RecoveredElement buildInitialRecoveryState() { /* initialize recovery by retrieving available reduced nodes * also rebuild bracket balance */ this.lastCheckPoint= 0; this.lastErrorEndPositionBeforeRecovery= this.scanner.currentPosition; RecoveredElement element= null; if (this.referenceContext instanceof CompilationUnitDeclaration) { element= new RecoveredUnit(this.compilationUnit, 0, this); /* ignore current stack state, since restarting from the beginnning since could not trust simple brace count */ // restart recovery from scratch this.compilationUnit.currentPackage= null; this.compilationUnit.imports= null; this.compilationUnit.types= null; this.currentToken= 0; this.listLength= 0; this.listTypeParameterLength= 0; this.endPosition= 0; this.endStatementPosition= 0; return element; } else { if (this.referenceContext instanceof AbstractMethodDeclaration) { element= new RecoveredMethod((AbstractMethodDeclaration)this.referenceContext, null, 0, this); this.lastCheckPoint= ((AbstractMethodDeclaration)this.referenceContext).bodyStart; if (this.statementRecoveryActivated) { element= element.add(new Block(0), 0); } } else { /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */ if (this.referenceContext instanceof TypeDeclaration) { TypeDeclaration type= (TypeDeclaration)this.referenceContext; for (int i= 0; i < type.fields.length; i++) { FieldDeclaration field= type.fields[i]; if (field != null && field.getKind() == AbstractVariableDeclaration.INITIALIZER && ((Initializer)field).block != null && field.declarationSourceStart <= this.scanner.initialPosition && this.scanner.initialPosition <= field.declarationSourceEnd && this.scanner.eofPosition <= field.declarationSourceEnd + 1) { element= new RecoveredInitializer(field, null, 1, this); this.lastCheckPoint= field.declarationSourceStart; break; } } } } } if (element == null) return element; for (int i= 0; i <= this.astPtr; i++) { ASTNode node= this.astStack[i]; if (node instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration method= (AbstractMethodDeclaration)node; if (method.declarationSourceEnd == 0) { element= element.add(method, 0); this.lastCheckPoint= method.bodyStart; } else { element= element.add(method, 0); this.lastCheckPoint= method.declarationSourceEnd + 1; } continue; } if (node instanceof Initializer) { Initializer initializer= (Initializer)node; // ignore initializer with no block if (initializer.block == null) continue; if (initializer.declarationSourceEnd == 0) { element= element.add(initializer, 1); this.lastCheckPoint= initializer.sourceStart; } else { element= element.add(initializer, 0); this.lastCheckPoint= initializer.declarationSourceEnd + 1; } continue; } if (node instanceof FieldDeclaration) { FieldDeclaration field= (FieldDeclaration)node; if (field.declarationSourceEnd == 0) { element= element.add(field, 0); if (field.initialization == null) { this.lastCheckPoint= field.sourceEnd + 1; } else { this.lastCheckPoint= field.initialization.sourceEnd + 1; } } else { element= element.add(field, 0); this.lastCheckPoint= field.declarationSourceEnd + 1; } continue; } if (node instanceof TypeDeclaration) { TypeDeclaration type= (TypeDeclaration)node; if (type.declarationSourceEnd == 0) { element= element.add(type, 0); this.lastCheckPoint= type.bodyStart; } else { element= element.add(type, 0); this.lastCheckPoint= type.declarationSourceEnd + 1; } continue; } if (node instanceof ImportReference) { ImportReference importRef= (ImportReference)node; element= element.add(importRef, 0); this.lastCheckPoint= importRef.declarationSourceEnd + 1; } if (this.statementRecoveryActivated) { if (node instanceof Block) { Block block= (Block)node; element= element.add(block, 0); this.lastCheckPoint= block.sourceEnd + 1; } else if (node instanceof LocalDeclaration) { LocalDeclaration statement= (LocalDeclaration)node; element= element.add(statement, 0); this.lastCheckPoint= statement.sourceEnd + 1; } else if (node instanceof Expression) { if (node instanceof Assignment || node instanceof PrefixExpression || node instanceof PostfixExpression || node instanceof MessageSend || node instanceof AllocationExpression) { // recover only specific expressions Expression statement= (Expression)node; element= element.add(statement, 0); if (statement.statementEnd != -1) { this.lastCheckPoint= statement.statementEnd + 1; } else { this.lastCheckPoint= statement.sourceEnd + 1; } } } else if (node instanceof Statement) { Statement statement= (Statement)node; element= element.add(statement, 0); this.lastCheckPoint= statement.sourceEnd + 1; } } } if (this.statementRecoveryActivated) { if (this.pendingRecoveredType != null && this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) { // Add the pending type to the AST if this type isn't already added in the AST. element= element.add(this.pendingRecoveredType, 0); this.lastCheckPoint= this.pendingRecoveredType.declarationSourceEnd + 1; this.pendingRecoveredType= null; } } return element; } protected void checkAndSetModifiers(int flag) { /*modify the current modifiers buffer. When the startPosition of the modifiers is 0 it means that the modifier being parsed is the first of a list of several modifiers. The startPosition is zeroed when a copy of modifiers-buffer is push onto the this.astStack. */ if ((this.modifiers & flag) != 0) { // duplicate modifier this.modifiers|= ExtraCompilerModifiers.AccAlternateModifierProblem; } this.modifiers|= flag; if (this.modifiersSourceStart < 0) this.modifiersSourceStart= this.scanner.startPosition; if (this.currentElement != null && this.annotationRecoveryActivated) { this.currentElement.addModifier(flag, this.modifiersSourceStart); } } public void checkComment() { // discard obsolete comments while inside methods or fields initializer (see bug 74369) if (!(this.diet && this.dietInt == 0) && this.scanner.commentPtr >= 0) { flushCommentsDefinedPriorTo(this.endStatementPosition); } int lastComment= this.scanner.commentPtr; if (this.modifiersSourceStart >= 0) { // eliminate comments located after modifierSourceStart if positionned while (lastComment >= 0) { int commentSourceStart= this.scanner.commentStarts[lastComment]; if (commentSourceStart < 0) commentSourceStart= -commentSourceStart; if (commentSourceStart <= this.modifiersSourceStart) break; lastComment--; } } if (lastComment >= 0) { // consider all remaining leading comments to be part of current declaration this.modifiersSourceStart= this.scanner.commentStarts[0]; if (this.modifiersSourceStart < 0) this.modifiersSourceStart= -this.modifiersSourceStart; // check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored) while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions if (lastComment >= 0 && this.javadocParser != null) { int commentEnd= this.scanner.commentStops[lastComment] - 1; //stop is one over, // do not report problem before last parsed comment while recovering code... if (this.javadocParser.shouldReportProblems) { this.javadocParser.reportProblems= this.currentElement == null || commentEnd > this.lastJavadocEnd; } else { this.javadocParser.reportProblems= false; } if (this.javadocParser.checkDeprecation(lastComment)) { checkAndSetModifiers(ClassFileConstants.AccDeprecated); } this.javadoc= this.javadocParser.docComment; // null if check javadoc is not activated if (this.currentElement == null) this.lastJavadocEnd= commentEnd; } } } protected void checkNonNLSAfterBodyEnd(int declarationEnd) { if (this.scanner.currentPosition - 1 <= declarationEnd) { this.scanner.eofPosition= declarationEnd < Integer.MAX_VALUE ? declarationEnd + 1 : declarationEnd; try { while (this.scanner.getNextToken() != TokenNameEOF) {/*empty*/ } } catch (InvalidInputException e) { // Nothing to do } } } protected void classInstanceCreation(boolean isQualified) { // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt // ClassBodyopt produces a null item on the astStak if it produces NO class body // An empty class body produces a 0 on the length stack..... AllocationExpression alloc; int length; if (((length= this.astLengthStack[this.astLengthPtr--]) == 1) && (this.astStack[this.astPtr] == null)) { //NO ClassBody this.astPtr--; if (isQualified) { alloc= new QualifiedAllocationExpression(); } else { alloc= new AllocationExpression(); } alloc.sourceEnd= this.endPosition; //the position has been stored explicitly if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, alloc.arguments= new Expression[length], 0, length); } alloc.type= getTypeReference(0); //the default constructor with the correct number of argument //will be created and added by the TC (see createsInternalConstructorWithBinding) alloc.sourceStart= this.intStack[this.intPtr--]; pushOnExpressionStack(alloc); } else { dispatchDeclarationInto(length); TypeDeclaration anonymousTypeDeclaration= (TypeDeclaration)this.astStack[this.astPtr]; anonymousTypeDeclaration.declarationSourceEnd= this.endStatementPosition; anonymousTypeDeclaration.bodyEnd= this.endStatementPosition; if (anonymousTypeDeclaration.allocation != null) { anonymousTypeDeclaration.allocation.sourceEnd= this.endStatementPosition; } if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) { anonymousTypeDeclaration.bits|= ASTNode.UndocumentedEmptyBlock; } this.astPtr--; this.astLengthPtr--; } } protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim) { int nameSize= this.identifierLengthStack[this.identifierLengthPtr]; int tokensSize= nameSize; if (rightSide instanceof ParameterizedSingleTypeReference) { tokensSize++; } else if (rightSide instanceof SingleTypeReference) { tokensSize++; } else if (rightSide instanceof ParameterizedQualifiedTypeReference) { tokensSize+= ((QualifiedTypeReference)rightSide).tokens.length; } else if (rightSide instanceof QualifiedTypeReference) { tokensSize+= ((QualifiedTypeReference)rightSide).tokens.length; } TypeReference[][] typeArguments= new TypeReference[tokensSize][]; char[][] tokens= new char[tokensSize][]; long[] positions= new long[tokensSize]; if (rightSide instanceof ParameterizedSingleTypeReference) { ParameterizedSingleTypeReference singleParameterizedTypeReference= (ParameterizedSingleTypeReference)rightSide; tokens[nameSize]= singleParameterizedTypeReference.token; positions[nameSize]= (((long)singleParameterizedTypeReference.sourceStart) << 32) + singleParameterizedTypeReference.sourceEnd; typeArguments[nameSize]= singleParameterizedTypeReference.typeArguments; } else if (rightSide instanceof SingleTypeReference) { SingleTypeReference singleTypeReference= (SingleTypeReference)rightSide; tokens[nameSize]= singleTypeReference.token; positions[nameSize]= (((long)singleTypeReference.sourceStart) << 32) + singleTypeReference.sourceEnd; } else if (rightSide instanceof ParameterizedQualifiedTypeReference) { ParameterizedQualifiedTypeReference parameterizedTypeReference= (ParameterizedQualifiedTypeReference)rightSide; TypeReference[][] rightSideTypeArguments= parameterizedTypeReference.typeArguments; System.arraycopy(rightSideTypeArguments, 0, typeArguments, nameSize, rightSideTypeArguments.length); char[][] rightSideTokens= parameterizedTypeReference.tokens; System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length); long[] rightSidePositions= parameterizedTypeReference.sourcePositions; System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length); } else if (rightSide instanceof QualifiedTypeReference) { QualifiedTypeReference qualifiedTypeReference= (QualifiedTypeReference)rightSide; char[][] rightSideTokens= qualifiedTypeReference.tokens; System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length); long[] rightSidePositions= qualifiedTypeReference.sourcePositions; System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length); } int currentTypeArgumentsLength= this.genericsLengthStack[this.genericsLengthPtr--]; TypeReference[] currentTypeArguments= new TypeReference[currentTypeArgumentsLength]; this.genericsPtr-= currentTypeArgumentsLength; System.arraycopy(this.genericsStack, this.genericsPtr + 1, currentTypeArguments, 0, currentTypeArgumentsLength); if (nameSize == 1) { tokens[0]= this.identifierStack[this.identifierPtr]; positions[0]= this.identifierPositionStack[this.identifierPtr--]; typeArguments[0]= currentTypeArguments; } else { this.identifierPtr-= nameSize; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, nameSize); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, nameSize); typeArguments[nameSize - 1]= currentTypeArguments; } this.identifierLengthPtr--; return new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, positions); } protected void concatExpressionLists() { this.expressionLengthStack[--this.expressionLengthPtr]++; } protected void concatGenericsLists() { this.genericsLengthStack[this.genericsLengthPtr - 1]+= this.genericsLengthStack[this.genericsLengthPtr--]; } protected void concatNodeLists() { /* * This is a case where you have two sublists into the this.astStack that you want * to merge in one list. There is no action required on the this.astStack. The only * thing you need to do is merge the two lengths specified on the astStackLength. * The top two length are for example: * ... p n * and you want to result in a list like: * ... n+p * This means that the p could be equals to 0 in case there is no astNode pushed * on the this.astStack. * Look at the InterfaceMemberDeclarations for an example. */ this.astLengthStack[this.astLengthPtr - 1]+= this.astLengthStack[this.astLengthPtr--]; } protected void consumeAdditionalBound() { pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--])); } protected void consumeAdditionalBound1() { // nothing to be done. // The reference type1 is consumed by consumeReferenceType1 method. } protected void consumeAdditionalBoundList() { concatGenericsLists(); } protected void consumeAdditionalBoundList1() { concatGenericsLists(); } protected void consumeAllocationHeader() { // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt // ClassBodyopt produces a null item on the astStak if it produces NO class body // An empty class body produces a 0 on the length stack..... if (this.currentElement == null) { return; // should never occur, this consumeRule is only used in recovery mode } if (this.currentToken == TokenNameLBRACE) { // beginning of an anonymous type TypeDeclaration anonymousType= new TypeDeclaration(this.compilationUnit.compilationResult); anonymousType.name= CharOperation.NO_CHAR; anonymousType.bits|= (ASTNode.IsAnonymousType | ASTNode.IsLocalType); anonymousType.sourceStart= this.intStack[this.intPtr--]; anonymousType.declarationSourceStart= anonymousType.sourceStart; anonymousType.sourceEnd= this.rParenPos; // closing parenthesis QualifiedAllocationExpression alloc= new QualifiedAllocationExpression(anonymousType); alloc.type= getTypeReference(0); alloc.sourceStart= anonymousType.sourceStart; alloc.sourceEnd= anonymousType.sourceEnd; this.lastCheckPoint= anonymousType.bodyStart= this.scanner.currentPosition; this.currentElement= this.currentElement.add(anonymousType, 0); this.lastIgnoredToken= -1; this.currentToken= 0; // opening brace already taken into account return; } this.lastCheckPoint= this.scanner.startPosition; // force to restart at this exact position this.restartRecovery= true; // request to restart from here on } protected void consumeAnnotationAsModifier() { Expression expression= this.expressionStack[this.expressionPtr]; int sourceStart= expression.sourceStart; if (this.modifiersSourceStart < 0) { this.modifiersSourceStart= sourceStart; } } protected void consumeAnnotationName() { if (this.currentElement != null) { int start= this.intStack[this.intPtr]; int end= (int)(this.identifierPositionStack[this.identifierPtr] & 0x00000000FFFFFFFFL); annotationRecoveryCheckPoint(start, end); if (this.annotationRecoveryActivated) { this.currentElement= this.currentElement.addAnnotationName(this.identifierPtr, this.identifierLengthPtr, start, 0); } } this.recordStringLiterals= false; } protected void consumeAnnotationTypeDeclaration() { int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch according to the type of the declarations dispatchDeclarationInto(length); } TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods typeDecl.checkConstructors(this); //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { typeDecl.bits|= ASTNode.ContainsAssertion; } typeDecl.addClinit(); typeDecl.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) { typeDecl.bits|= ASTNode.UndocumentedEmptyBlock; } typeDecl.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeAnnotationTypeDeclarationHeader() { TypeDeclaration annotationTypeDeclaration= (TypeDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { annotationTypeDeclaration.bodyStart= this.scanner.currentPosition; } if (this.currentElement != null) { this.restartRecovery= true; // used to avoid branching back into the regular automaton } // flush the comments related to the annotation type header this.scanner.commentPtr= -1; } protected void consumeAnnotationTypeDeclarationHeaderName() { // consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier // consumeAnnotationTypeDeclarationHeader ::= '@' PushModifiers interface Identifier TypeDeclaration annotationTypeDeclaration= new TypeDeclaration(this.compilationUnit.compilationResult); if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { annotationTypeDeclaration.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types annotationTypeDeclaration.bits|= ASTNode.IsLocalType; markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; annotationTypeDeclaration.sourceEnd= (int)pos; annotationTypeDeclaration.sourceStart= (int)(pos >>> 32); annotationTypeDeclaration.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. this.intPtr--; // remove the start position of the interface token this.intPtr--; // remove the end position of the interface token annotationTypeDeclaration.modifiersSourceStart= this.intStack[this.intPtr--]; annotationTypeDeclaration.modifiers= this.intStack[this.intPtr--] | ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface; if (annotationTypeDeclaration.modifiersSourceStart >= 0) { annotationTypeDeclaration.declarationSourceStart= annotationTypeDeclaration.modifiersSourceStart; this.intPtr--; // remove the position of the '@' token as we have modifiers } else { int atPosition= this.intStack[this.intPtr--]; // remove the position of the '@' token as we don't have modifiers annotationTypeDeclaration.declarationSourceStart= atPosition; } // Store secondary info if ((annotationTypeDeclaration.bits & ASTNode.IsMemberType) == 0 && (annotationTypeDeclaration.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(annotationTypeDeclaration.name, this.compilationUnit.getMainTypeName())) { annotationTypeDeclaration.bits|= ASTNode.IsSecondaryType; } } // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, annotationTypeDeclaration.annotations= new Annotation[length], 0, length); } annotationTypeDeclaration.bodyStart= annotationTypeDeclaration.sourceEnd + 1; // javadoc annotationTypeDeclaration.javadoc= this.javadoc; this.javadoc= null; pushOnAstStack(annotationTypeDeclaration); if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration); } // recovery if (this.currentElement != null) { this.lastCheckPoint= annotationTypeDeclaration.bodyStart; this.currentElement= this.currentElement.add(annotationTypeDeclaration, 0); this.lastIgnoredToken= -1; } } protected void consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() { // consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier TypeParameters // consumeAnnotationTypeDeclarationHeader ::= '@' PushModifiers interface Identifier TypeParameters TypeDeclaration annotationTypeDeclaration= new TypeDeclaration(this.compilationUnit.compilationResult); // consume type parameters int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, annotationTypeDeclaration.typeParameters= new TypeParameter[length], 0, length); problemReporter().invalidUsageOfTypeParametersForAnnotationDeclaration(annotationTypeDeclaration); annotationTypeDeclaration.bodyStart= annotationTypeDeclaration.typeParameters[length - 1].declarationSourceEnd + 1; // annotationTypeDeclaration.typeParameters = null; this.listTypeParameterLength= 0; if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { annotationTypeDeclaration.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types annotationTypeDeclaration.bits|= ASTNode.IsLocalType; markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; annotationTypeDeclaration.sourceEnd= (int)pos; annotationTypeDeclaration.sourceStart= (int)(pos >>> 32); annotationTypeDeclaration.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. this.intPtr--; // remove the start position of the interface token this.intPtr--; // remove the end position of the interface token annotationTypeDeclaration.modifiersSourceStart= this.intStack[this.intPtr--]; annotationTypeDeclaration.modifiers= this.intStack[this.intPtr--] | ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface; if (annotationTypeDeclaration.modifiersSourceStart >= 0) { annotationTypeDeclaration.declarationSourceStart= annotationTypeDeclaration.modifiersSourceStart; this.intPtr--; // remove the position of the '@' token as we have modifiers } else { int atPosition= this.intStack[this.intPtr--]; // remove the position of the '@' token as we don't have modifiers annotationTypeDeclaration.declarationSourceStart= atPosition; } // Store secondary info if ((annotationTypeDeclaration.bits & ASTNode.IsMemberType) == 0 && (annotationTypeDeclaration.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(annotationTypeDeclaration.name, this.compilationUnit.getMainTypeName())) { annotationTypeDeclaration.bits|= ASTNode.IsSecondaryType; } } // consume annotations if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, annotationTypeDeclaration.annotations= new Annotation[length], 0, length); } // javadoc annotationTypeDeclaration.javadoc= this.javadoc; this.javadoc= null; pushOnAstStack(annotationTypeDeclaration); if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration); } // recovery if (this.currentElement != null) { this.lastCheckPoint= annotationTypeDeclaration.bodyStart; this.currentElement= this.currentElement.add(annotationTypeDeclaration, 0); this.lastIgnoredToken= -1; } } protected void consumeAnnotationTypeMemberDeclaration() { // AnnotationTypeMemberDeclaration ::= AnnotationTypeMemberDeclarationHeader AnnotationTypeMemberHeaderExtendedDims DefaultValueopt ';' AnnotationMethodDeclaration annotationTypeMemberDeclaration= (AnnotationMethodDeclaration)this.astStack[this.astPtr]; annotationTypeMemberDeclaration.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; // store the this.endPosition (position just before the '}') in case there is // a trailing comment behind the end of the method int declarationEndPosition= flushCommentsDefinedPriorTo(this.endStatementPosition); annotationTypeMemberDeclaration.bodyStart= this.endStatementPosition; annotationTypeMemberDeclaration.bodyEnd= declarationEndPosition; annotationTypeMemberDeclaration.declarationSourceEnd= declarationEndPosition; } protected void consumeAnnotationTypeMemberDeclarations() { // AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration concatNodeLists(); } protected void consumeAnnotationTypeMemberDeclarationsopt() { this.nestedType--; } protected void consumeArgumentList() { // ArgumentList ::= ArgumentList ',' Expression concatExpressionLists(); } protected void consumeArguments() { // Arguments ::= '(' ArgumentListopt ')' // nothing to do, the expression stack is already updated pushOnIntStack(this.rParenPos); } protected void consumeArrayAccess(boolean unspecifiedReference) { // ArrayAccess ::= Name '[' Expression ']' ==> true // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false //optimize push/pop Expression exp; if (unspecifiedReference) { exp= this.expressionStack[this.expressionPtr]= new ArrayReference( getUnspecifiedReferenceOptimized(), this.expressionStack[this.expressionPtr]); } else { this.expressionPtr--; this.expressionLengthPtr--; exp= this.expressionStack[this.expressionPtr]= new ArrayReference( this.expressionStack[this.expressionPtr], this.expressionStack[this.expressionPtr + 1]); } exp.sourceEnd= this.endStatementPosition; } protected void consumeArrayCreationExpressionWithInitializer() { // ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer // ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer int length; ArrayAllocationExpression arrayAllocation= new ArrayAllocationExpression(); this.expressionLengthPtr--; arrayAllocation.initializer= (ArrayInitializer)this.expressionStack[this.expressionPtr--]; arrayAllocation.type= getTypeReference(0); arrayAllocation.type.bits|= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage length= (this.expressionLengthStack[this.expressionLengthPtr--]); this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, arrayAllocation.dimensions= new Expression[length], 0, length); arrayAllocation.sourceStart= this.intStack[this.intPtr--]; if (arrayAllocation.initializer == null) { arrayAllocation.sourceEnd= this.endStatementPosition; } else { arrayAllocation.sourceEnd= arrayAllocation.initializer.sourceEnd; } pushOnExpressionStack(arrayAllocation); } protected void consumeArrayCreationExpressionWithoutInitializer() { // ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs // ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs int length; ArrayAllocationExpression arrayAllocation= new ArrayAllocationExpression(); arrayAllocation.type= getTypeReference(0); arrayAllocation.type.bits|= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage length= (this.expressionLengthStack[this.expressionLengthPtr--]); this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, arrayAllocation.dimensions= new Expression[length], 0, length); arrayAllocation.sourceStart= this.intStack[this.intPtr--]; if (arrayAllocation.initializer == null) { arrayAllocation.sourceEnd= this.endStatementPosition; } else { arrayAllocation.sourceEnd= arrayAllocation.initializer.sourceEnd; } pushOnExpressionStack(arrayAllocation); } protected void consumeArrayCreationHeader() { // nothing to do } protected void consumeArrayInitializer() { // ArrayInitializer ::= '{' VariableInitializers '}' // ArrayInitializer ::= '{' VariableInitializers , '}' arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]); } protected void consumeArrayTypeWithTypeArgumentsName() { this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr]+= this.identifierLengthStack[this.identifierLengthPtr]; pushOnGenericsLengthStack(0); // handle type arguments } protected void consumeAssertStatement() { // AssertStatement ::= 'assert' Expression ':' Expression ';' this.expressionLengthPtr-= 2; pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--])); } protected void consumeAssignment() { // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression //optimize the push/pop int op= this.intStack[this.intPtr--]; //<--the encoded operator this.expressionPtr--; this.expressionLengthPtr--; Expression expression= this.expressionStack[this.expressionPtr + 1]; this.expressionStack[this.expressionPtr]= (op != EQUAL) ? new CompoundAssignment( this.expressionStack[this.expressionPtr], expression, op, expression.sourceEnd) : new Assignment( this.expressionStack[this.expressionPtr], expression, expression.sourceEnd); if (this.pendingRecoveredType != null) { // Used only in statements recovery. // This is not a real assignment but a placeholder for an existing anonymous type. // The assignment must be replace by the anonymous type. if (this.pendingRecoveredType.allocation != null && this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) { this.expressionStack[this.expressionPtr]= this.pendingRecoveredType.allocation; this.pendingRecoveredType= null; return; } this.pendingRecoveredType= null; } } protected void consumeAssignmentOperator(int pos) { // AssignmentOperator ::= '=' // AssignmentOperator ::= '*=' // AssignmentOperator ::= '/=' // AssignmentOperator ::= '%=' // AssignmentOperator ::= '+=' // AssignmentOperator ::= '-=' // AssignmentOperator ::= '<<=' // AssignmentOperator ::= '>>=' // AssignmentOperator ::= '>>>=' // AssignmentOperator ::= '&=' // AssignmentOperator ::= '^=' // AssignmentOperator ::= '|=' pushOnIntStack(pos); } protected void consumeBinaryExpression(int op) { // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression // RelationalExpression ::= RelationalExpression '<' ShiftExpression // RelationalExpression ::= RelationalExpression '>' ShiftExpression // RelationalExpression ::= RelationalExpression '<=' ShiftExpression // RelationalExpression ::= RelationalExpression '>=' ShiftExpression // AndExpression ::= AndExpression '&' EqualityExpression // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression //optimize the push/pop this.expressionPtr--; this.expressionLengthPtr--; Expression expr1= this.expressionStack[this.expressionPtr]; Expression expr2= this.expressionStack[this.expressionPtr + 1]; switch (op) { case OR_OR: this.expressionStack[this.expressionPtr]= new OR_OR_Expression( expr1, expr2, op); break; case AND_AND: this.expressionStack[this.expressionPtr]= new AND_AND_Expression( expr1, expr2, op); break; case PLUS: // look for "string1" + "string2" if (this.optimizeStringLiterals) { if (expr1 instanceof StringLiteral) { if (((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { if (expr2 instanceof CharLiteral) { // string+char this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendWith((CharLiteral)expr2); } else if (expr2 instanceof StringLiteral) { //string+string this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendWith((StringLiteral)expr2); } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else if (expr1 instanceof CombinedBinaryExpression) { CombinedBinaryExpression cursor; // left branch is comprised of PLUS BEs // cursor is shifted upwards, while needed BEs are added // on demand; past the arityMax-th // consecutive BE, a CBE is inserted that holds a // full-fledged references table if ((cursor= (CombinedBinaryExpression)expr1).arity < cursor.arityMax) { cursor.left= new BinaryExpression(cursor); cursor.arity++; } else { cursor.left= new CombinedBinaryExpression(cursor); cursor.arity= 0; cursor.tuneArityMax(); } cursor.right= expr2; cursor.sourceEnd= expr2.sourceEnd; this.expressionStack[this.expressionPtr]= cursor; // BE_INSTRUMENTATION: neutralized in the released code // cursor.depthTracker = ((BinaryExpression)cursor.left). // depthTracker + 1; } else if (expr1 instanceof BinaryExpression && // single out the a + b case, which is a BE // instead of a CBE (slightly more than a half of // strings concatenation are one-deep binary // expressions) ((expr1.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) { this.expressionStack[this.expressionPtr]= new CombinedBinaryExpression(expr1, expr2, PLUS, 1); } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else if (expr1 instanceof StringLiteral) { if (expr2 instanceof StringLiteral && ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { // string + string this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendsWith((StringLiteral)expr2); } else { // single out the a + b case this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else if (expr1 instanceof CombinedBinaryExpression) { CombinedBinaryExpression cursor; // shift cursor; create BE/CBE as needed if ((cursor= (CombinedBinaryExpression)expr1).arity < cursor.arityMax) { cursor.left= new BinaryExpression(cursor); // clear the bits on cursor cursor.bits&= ~ASTNode.ParenthesizedMASK; cursor.arity++; } else { cursor.left= new CombinedBinaryExpression(cursor); // clear the bits on cursor cursor.bits&= ~ASTNode.ParenthesizedMASK; cursor.arity= 0; cursor.tuneArityMax(); } cursor.right= expr2; cursor.sourceEnd= expr2.sourceEnd; // BE_INSTRUMENTATION: neutralized in the released code // cursor.depthTracker = ((BinaryExpression)cursor.left). // depthTracker + 1; this.expressionStack[this.expressionPtr]= cursor; } else if (expr1 instanceof BinaryExpression && ((expr1.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) { // single out the a + b case this.expressionStack[this.expressionPtr]= new CombinedBinaryExpression(expr1, expr2, PLUS, 1); } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } break; case LESS: this.intPtr--; this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); break; default: this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); } } /** * @param op binary operator */ protected void consumeBinaryExpressionWithName(int op) { pushOnExpressionStack(getUnspecifiedReferenceOptimized()); this.expressionPtr--; this.expressionLengthPtr--; /* if (op == OR_OR) { this.expressionStack[this.expressionPtr] = new OR_OR_Expression( this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr], op); } else { if (op == AND_AND) { this.expressionStack[this.expressionPtr] = new AND_AND_Expression( this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr], op); } else { // look for "string1" + "string2" if ((op == PLUS) && this.optimizeStringLiterals) { Expression expr1, expr2; expr1 = this.expressionStack[this.expressionPtr + 1]; expr2 = this.expressionStack[this.expressionPtr]; if (expr1 instanceof StringLiteral) { if (expr2 instanceof CharLiteral) { // string+char this.expressionStack[this.expressionPtr] = ((StringLiteral) expr1).extendWith((CharLiteral) expr2); } else if (expr2 instanceof StringLiteral) { //string+string this.expressionStack[this.expressionPtr] = ((StringLiteral) expr1).extendWith((StringLiteral) expr2); } else { this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS); } } else { this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS); } } else { this.expressionStack[this.expressionPtr] = new BinaryExpression( this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr], op); } } } */ Expression expr1= this.expressionStack[this.expressionPtr + 1]; Expression expr2= this.expressionStack[this.expressionPtr]; // Note: we do not attempt to promote BinaryExpression-s to // IndexedBinaryExpression-s here since expr1 always holds a name switch (op) { case OR_OR: this.expressionStack[this.expressionPtr]= new OR_OR_Expression( expr1, expr2, op); break; case AND_AND: this.expressionStack[this.expressionPtr]= new AND_AND_Expression( expr1, expr2, op); break; case PLUS: // look for "string1" + "string2" if (this.optimizeStringLiterals) { if (expr1 instanceof StringLiteral && ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { if (expr2 instanceof CharLiteral) { // string+char this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendWith((CharLiteral)expr2); } else if (expr2 instanceof StringLiteral) { //string+string this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendWith((StringLiteral)expr2); } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else { this.expressionStack[this.expressionPtr]= new BinaryExpression(expr1, expr2, PLUS); } } else if (expr1 instanceof StringLiteral) { if (expr2 instanceof StringLiteral && ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { // string + string this.expressionStack[this.expressionPtr]= ((StringLiteral)expr1).extendsWith((StringLiteral)expr2); } else { this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); } } else { this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); } break; case LESS: this.intPtr--; this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); break; default: this.expressionStack[this.expressionPtr]= new BinaryExpression( expr1, expr2, op); } } protected void consumeBlock() { // Block ::= OpenBlock '{' BlockStatementsopt '}' // simpler action for empty blocks int statementsLength= this.astLengthStack[this.astLengthPtr--]; Block block; if (statementsLength == 0) { // empty block block= new Block(0); block.sourceStart= this.intStack[this.intPtr--]; block.sourceEnd= this.endStatementPosition; // check whether this block at least contains some comment in it if (!containsComment(block.sourceStart, block.sourceEnd)) { block.bits|= ASTNode.UndocumentedEmptyBlock; } this.realBlockPtr--; // still need to pop the block variable counter } else { block= new Block(this.realBlockStack[this.realBlockPtr--]); this.astPtr-= statementsLength; System.arraycopy( this.astStack, this.astPtr + 1, block.statements= new Statement[statementsLength], 0, statementsLength); block.sourceStart= this.intStack[this.intPtr--]; block.sourceEnd= this.endStatementPosition; } pushOnAstStack(block); } protected void consumeBlockStatements() { // BlockStatements ::= BlockStatements BlockStatement concatNodeLists(); } protected void consumeCaseLabel() { // SwitchLabel ::= 'case' ConstantExpression ':' this.expressionLengthPtr--; Expression expression= this.expressionStack[this.expressionPtr--]; CaseStatement caseStatement= new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); // Look for $fall-through$ tag in leading comment for case statement if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) { caseStatement.bits|= ASTNode.DocumentedFallthrough; } pushOnAstStack(caseStatement); } protected void consumeCastExpressionLL1() { //CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus // Expression is used in order to make the grammar LL1 //optimize push/pop Expression cast, exp; this.expressionPtr--; this.expressionStack[this.expressionPtr]= cast= new CastExpression( exp= this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr]); this.expressionLengthPtr--; updateSourcePosition(cast); cast.sourceEnd= exp.sourceEnd; } protected void consumeCastExpressionWithGenericsArray() { // CastExpression ::= PushLPAREN Name TypeArguments Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus Expression exp, cast, castType; int end= this.intStack[this.intPtr--]; int dim= this.intStack[this.intPtr--]; pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); this.expressionStack[this.expressionPtr]= cast= new CastExpression(exp= this.expressionStack[this.expressionPtr], castType= getTypeReference(dim)); this.intPtr--; castType.sourceEnd= end - 1; castType.sourceStart= (cast.sourceStart= this.intStack[this.intPtr--]) + 1; cast.sourceEnd= exp.sourceEnd; } protected void consumeCastExpressionWithNameArray() { // CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus Expression exp, cast, castType; int end= this.intStack[this.intPtr--]; // handle type arguments pushOnGenericsLengthStack(0); pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); this.expressionStack[this.expressionPtr]= cast= new CastExpression(exp= this.expressionStack[this.expressionPtr], castType= getTypeReference(this.intStack[this.intPtr--])); castType.sourceEnd= end - 1; castType.sourceStart= (cast.sourceStart= this.intStack[this.intPtr--]) + 1; cast.sourceEnd= exp.sourceEnd; } protected void consumeCastExpressionWithPrimitiveType() { // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression //this.intStack : posOfLeftParen dim posOfRightParen //optimize the push/pop Expression exp, cast, castType; int end= this.intStack[this.intPtr--]; this.expressionStack[this.expressionPtr]= cast= new CastExpression(exp= this.expressionStack[this.expressionPtr], castType= getTypeReference(this.intStack[this.intPtr--])); castType.sourceEnd= end - 1; castType.sourceStart= (cast.sourceStart= this.intStack[this.intPtr--]) + 1; cast.sourceEnd= exp.sourceEnd; } protected void consumeCastExpressionWithQualifiedGenericsArray() { // CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus Expression exp, cast, castType; int end= this.intStack[this.intPtr--]; int dim= this.intStack[this.intPtr--]; TypeReference rightSide= getTypeReference(0); ParameterizedQualifiedTypeReference qualifiedParameterizedTypeReference= computeQualifiedGenericsFromRightSide(rightSide, dim); this.intPtr--; this.expressionStack[this.expressionPtr]= cast= new CastExpression(exp= this.expressionStack[this.expressionPtr], castType= qualifiedParameterizedTypeReference); castType.sourceEnd= end - 1; castType.sourceStart= (cast.sourceStart= this.intStack[this.intPtr--]) + 1; cast.sourceEnd= exp.sourceEnd; } protected void consumeCatches() { // Catches ::= Catches CatchClause optimizedConcatNodeLists(); } protected void consumeCatchHeader() { // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{' if (this.currentElement == null) { return; // should never occur, this consumeRule is only used in recovery mode } // current element should be a block due to the presence of the opening brace if (!(this.currentElement instanceof RecoveredBlock)) { if (!(this.currentElement instanceof RecoveredMethod)) { return; } RecoveredMethod rMethod= (RecoveredMethod)this.currentElement; if (!(rMethod.methodBody == null && rMethod.bracketBalance > 0)) { return; } } Argument arg= (Argument)this.astStack[this.astPtr--]; // convert argument to local variable LocalDeclaration localDeclaration= new LocalDeclaration(arg.name, arg.sourceStart, arg.sourceEnd); localDeclaration.type= arg.type; localDeclaration.declarationSourceStart= arg.declarationSourceStart; localDeclaration.declarationSourceEnd= arg.declarationSourceEnd; this.currentElement= this.currentElement.add(localDeclaration, 0); this.lastCheckPoint= this.scanner.startPosition; // force to restart at this exact position this.restartRecovery= true; // request to restart from here on this.lastIgnoredToken= -1; } protected void consumeClassBodyDeclaration() { // ClassBodyDeclaration ::= Diet NestedMethod CreateInitializer Block //push an Initializer //optimize the push/pop this.nestedMethod[this.nestedType]--; Block block= (Block)this.astStack[this.astPtr--]; this.astLengthPtr--; if (this.diet) block.bits&= ~ASTNode.UndocumentedEmptyBlock; // clear bit since was diet Initializer initializer= (Initializer)this.astStack[this.astPtr]; initializer.declarationSourceStart= initializer.sourceStart= block.sourceStart; initializer.block= block; this.intPtr--; // pop sourcestart left on the stack by consumeNestedMethod. initializer.bodyStart= this.intStack[this.intPtr--]; this.realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod int javadocCommentStart= this.intStack[this.intPtr--]; if (javadocCommentStart != -1) { initializer.declarationSourceStart= javadocCommentStart; initializer.javadoc= this.javadoc; this.javadoc= null; } initializer.bodyEnd= this.endPosition; initializer.sourceEnd= this.endStatementPosition; initializer.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeClassBodyDeclarations() { // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration concatNodeLists(); } protected void consumeClassBodyDeclarationsopt() { // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations this.nestedType--; } protected void consumeClassBodyopt() { // ClassBodyopt ::= $empty pushOnAstStack(null); this.endPosition= this.rParenPos; } protected void consumeClassDeclaration() { // ClassDeclaration ::= ClassHeader ClassBody int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch according to the type of the declarations dispatchDeclarationInto(length); } TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods boolean hasConstructor= typeDecl.checkConstructors(this); //add the default constructor when needed (interface don't have it) if (!hasConstructor) { switch (TypeDeclaration.kind(typeDecl.modifiers)) { case TypeDeclaration.CLASS_DECL: case TypeDeclaration.ENUM_DECL: boolean insideFieldInitializer= false; if (this.diet) { for (int i= this.nestedType; i > 0; i--) { if (this.variablesCounter[i] > 0) { insideFieldInitializer= true; break; } } } typeDecl.createDefaultConstructor(!this.diet || insideFieldInitializer, true); } } //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { typeDecl.bits|= ASTNode.ContainsAssertion; } typeDecl.addClinit(); typeDecl.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) { typeDecl.bits|= ASTNode.UndocumentedEmptyBlock; } typeDecl.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeClassHeader() { // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { typeDecl.bodyStart= this.scanner.currentPosition; } if (this.currentElement != null) { this.restartRecovery= true; // used to avoid branching back into the regular automaton } // flush the comments related to the class header this.scanner.commentPtr= -1; } protected void consumeClassHeaderExtends() { // ClassHeaderExtends ::= 'extends' ClassType //superclass TypeReference superClass= getTypeReference(0); // There is a class declaration on the top of stack TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; typeDecl.superclass= superClass; superClass.bits|= ASTNode.IsSuperType; typeDecl.bodyStart= typeDecl.superclass.sourceEnd + 1; // recovery if (this.currentElement != null) { this.lastCheckPoint= typeDecl.bodyStart; } } protected void consumeClassHeaderImplements() { // ClassHeaderImplements ::= 'implements' InterfaceTypeList int length= this.astLengthStack[this.astLengthPtr--]; //super interfaces this.astPtr-= length; // There is a class declaration on the top of stack TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; System.arraycopy( this.astStack, this.astPtr + 1, typeDecl.superInterfaces= new TypeReference[length], 0, length); for (int i= 0, max= typeDecl.superInterfaces.length; i < max; i++) { typeDecl.superInterfaces[i].bits|= ASTNode.IsSuperType; } typeDecl.bodyStart= typeDecl.superInterfaces[length - 1].sourceEnd + 1; this.listLength= 0; // reset after having read super-interfaces // recovery if (this.currentElement != null) { // is recovering this.lastCheckPoint= typeDecl.bodyStart; } } protected void consumeClassHeaderName1() { // ClassHeaderName1 ::= Modifiersopt 'class' 'Identifier' TypeDeclaration typeDecl= new TypeDeclaration(this.compilationUnit.compilationResult); if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { typeDecl.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types typeDecl.bits|= ASTNode.IsLocalType; markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; typeDecl.sourceEnd= (int)pos; typeDecl.sourceStart= (int)(pos >>> 32); typeDecl.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'class' and 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. typeDecl.declarationSourceStart= this.intStack[this.intPtr--]; this.intPtr--; // remove the end position of the class token typeDecl.modifiersSourceStart= this.intStack[this.intPtr--]; typeDecl.modifiers= this.intStack[this.intPtr--]; if (typeDecl.modifiersSourceStart >= 0) { typeDecl.declarationSourceStart= typeDecl.modifiersSourceStart; } // Store secondary info if ((typeDecl.bits & ASTNode.IsMemberType) == 0 && (typeDecl.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(typeDecl.name, this.compilationUnit.getMainTypeName())) { typeDecl.bits|= ASTNode.IsSecondaryType; } } // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, typeDecl.annotations= new Annotation[length], 0, length); } typeDecl.bodyStart= typeDecl.sourceEnd + 1; pushOnAstStack(typeDecl); this.listLength= 0; // will be updated when reading super-interfaces // recovery if (this.currentElement != null) { this.lastCheckPoint= typeDecl.bodyStart; this.currentElement= this.currentElement.add(typeDecl, 0); this.lastIgnoredToken= -1; } // javadoc typeDecl.javadoc= this.javadoc; this.javadoc= null; } protected void consumeClassInstanceCreationExpression() { // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt classInstanceCreation(false); } protected void consumeClassInstanceCreationExpressionName() { // ClassInstanceCreationExpressionName ::= Name '.' pushOnExpressionStack(getUnspecifiedReferenceOptimized()); } protected void consumeClassInstanceCreationExpressionQualified() { // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt classInstanceCreation(true); QualifiedAllocationExpression qae= (QualifiedAllocationExpression)this.expressionStack[this.expressionPtr]; if (qae.anonymousType == null) { this.expressionLengthPtr--; this.expressionPtr--; qae.enclosingInstance= this.expressionStack[this.expressionPtr]; this.expressionStack[this.expressionPtr]= qae; } qae.sourceStart= qae.enclosingInstance.sourceStart; } protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() { // ClassInstanceCreationExpression ::= Primary '.' 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt QualifiedAllocationExpression alloc; int length; if (((length= this.astLengthStack[this.astLengthPtr--]) == 1) && (this.astStack[this.astPtr] == null)) { //NO ClassBody this.astPtr--; alloc= new QualifiedAllocationExpression(); alloc.sourceEnd= this.endPosition; //the position has been stored explicitly if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, alloc.arguments= new Expression[length], 0, length); } alloc.type= getTypeReference(0); length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments= new TypeReference[length], 0, length); this.intPtr--; //the default constructor with the correct number of argument //will be created and added by the TC (see createsInternalConstructorWithBinding) alloc.sourceStart= this.intStack[this.intPtr--]; pushOnExpressionStack(alloc); } else { dispatchDeclarationInto(length); TypeDeclaration anonymousTypeDeclaration= (TypeDeclaration)this.astStack[this.astPtr]; anonymousTypeDeclaration.declarationSourceEnd= this.endStatementPosition; anonymousTypeDeclaration.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) { anonymousTypeDeclaration.bits|= ASTNode.UndocumentedEmptyBlock; } this.astPtr--; this.astLengthPtr--; QualifiedAllocationExpression allocationExpression= anonymousTypeDeclaration.allocation; if (allocationExpression != null) { allocationExpression.sourceEnd= this.endStatementPosition; // handle type arguments length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments= new TypeReference[length], 0, length); allocationExpression.sourceStart= this.intStack[this.intPtr--]; } } QualifiedAllocationExpression qae= (QualifiedAllocationExpression)this.expressionStack[this.expressionPtr]; if (qae.anonymousType == null) { this.expressionLengthPtr--; this.expressionPtr--; qae.enclosingInstance= this.expressionStack[this.expressionPtr]; this.expressionStack[this.expressionPtr]= qae; } qae.sourceStart= qae.enclosingInstance.sourceStart; } protected void consumeClassInstanceCreationExpressionWithTypeArguments() { // ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt AllocationExpression alloc; int length; if (((length= this.astLengthStack[this.astLengthPtr--]) == 1) && (this.astStack[this.astPtr] == null)) { //NO ClassBody this.astPtr--; alloc= new AllocationExpression(); alloc.sourceEnd= this.endPosition; //the position has been stored explicitly if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, alloc.arguments= new Expression[length], 0, length); } alloc.type= getTypeReference(0); length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments= new TypeReference[length], 0, length); this.intPtr--; //the default constructor with the correct number of argument //will be created and added by the TC (see createsInternalConstructorWithBinding) alloc.sourceStart= this.intStack[this.intPtr--]; pushOnExpressionStack(alloc); } else { dispatchDeclarationInto(length); TypeDeclaration anonymousTypeDeclaration= (TypeDeclaration)this.astStack[this.astPtr]; anonymousTypeDeclaration.declarationSourceEnd= this.endStatementPosition; anonymousTypeDeclaration.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) { anonymousTypeDeclaration.bits|= ASTNode.UndocumentedEmptyBlock; } this.astPtr--; this.astLengthPtr--; QualifiedAllocationExpression allocationExpression= anonymousTypeDeclaration.allocation; if (allocationExpression != null) { allocationExpression.sourceEnd= this.endStatementPosition; // handle type arguments length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments= new TypeReference[length], 0, length); allocationExpression.sourceStart= this.intStack[this.intPtr--]; } } } protected void consumeClassOrInterface() { this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr]+= this.identifierLengthStack[this.identifierLengthPtr]; pushOnGenericsLengthStack(0); // handle type arguments } protected void consumeClassOrInterfaceName() { pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); // handle type arguments } protected void consumeClassTypeElt() { // ClassTypeElt ::= ClassType pushOnAstStack(getTypeReference(0)); /* if incomplete thrown exception list, this.listLength counter will not have been reset, indicating that some items are available on the stack */ this.listLength++; } protected void consumeClassTypeList() { // ClassTypeList ::= ClassTypeList ',' ClassTypeElt optimizedConcatNodeLists(); } protected void consumeCompilationUnit() { // CompilationUnit ::= EnterCompilationUnit InternalCompilationUnit // do nothing by default } protected void consumeConditionalExpression(int op) { // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression //optimize the push/pop this.intPtr-= 2;//consume position of the question mark this.expressionPtr-= 2; this.expressionLengthPtr-= 2; this.expressionStack[this.expressionPtr]= new ConditionalExpression( this.expressionStack[this.expressionPtr], this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr + 2]); } /** * @param op */ protected void consumeConditionalExpressionWithName(int op) { // ConditionalExpression ::= Name '?' Expression ':' ConditionalExpression this.intPtr-= 2;//consume position of the question mark pushOnExpressionStack(getUnspecifiedReferenceOptimized()); this.expressionPtr-= 2; this.expressionLengthPtr-= 2; this.expressionStack[this.expressionPtr]= new ConditionalExpression( this.expressionStack[this.expressionPtr + 2], this.expressionStack[this.expressionPtr], this.expressionStack[this.expressionPtr + 1]); } protected void consumeConstructorBlockStatements() { // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}' concatNodeLists(); // explictly add the first statement into the list of statements } protected void consumeConstructorBody() { // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}' // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}' this.nestedMethod[this.nestedType]--; } protected void consumeConstructorDeclaration() { // ConstructorDeclaration ::= ConstructorHeader ConstructorBody /* this.astStack : MethodDeclaration statements this.identifierStack : name ==> this.astStack : MethodDeclaration this.identifierStack : */ //must provide a default constructor call when needed int length; // pop the position of the { (body of the method) pushed in block decl this.intPtr--; this.intPtr--; //statements this.realBlockPtr--; ExplicitConstructorCall constructorCall= null; Statement[] statements= null; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr-= length; if (!this.options.ignoreMethodBodies) { if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) { //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ? System.arraycopy( this.astStack, this.astPtr + 2, statements= new Statement[length - 1], 0, length - 1); constructorCall= (ExplicitConstructorCall)this.astStack[this.astPtr + 1]; } else { //need to add explicitly the super(); System.arraycopy( this.astStack, this.astPtr + 1, statements= new Statement[length], 0, length); constructorCall= SuperReference.implicitSuperConstructorCall(); } } } else { boolean insideFieldInitializer= false; if (this.diet) { for (int i= this.nestedType; i > 0; i--) { if (this.variablesCounter[i] > 0) { insideFieldInitializer= true; break; } } } if (!this.diet || insideFieldInitializer) { // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere. constructorCall= SuperReference.implicitSuperConstructorCall(); } } // now we know that the top of stack is a constructorDeclaration ConstructorDeclaration cd= (ConstructorDeclaration)this.astStack[this.astPtr]; cd.constructorCall= constructorCall; cd.statements= statements; //highlight of the implicit call on the method name if (constructorCall != null && cd.constructorCall.sourceEnd == 0) { cd.constructorCall.sourceEnd= cd.sourceEnd; cd.constructorCall.sourceStart= cd.sourceStart; } if (!(this.diet && this.dietInt == 0) && statements == null && (constructorCall == null || constructorCall.isImplicitSuper()) && !containsComment(cd.bodyStart, this.endPosition)) { cd.bits|= ASTNode.UndocumentedEmptyBlock; } //watch for } that could be given as a unicode ! ( u007D is '}' ) // store the this.endPosition (position just before the '}') in case there is // a trailing comment behind the end of the method cd.bodyEnd= this.endPosition; cd.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeConstructorHeader() { // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt AbstractMethodDeclaration method= (AbstractMethodDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { method.bodyStart= this.scanner.currentPosition; } // recovery if (this.currentElement != null) { if (this.currentToken == TokenNameSEMICOLON) { // for invalid constructors method.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; method.declarationSourceEnd= this.scanner.currentPosition - 1; method.bodyEnd= this.scanner.currentPosition - 1; if (this.currentElement.parseTree() == method && this.currentElement.parent != null) { this.currentElement= this.currentElement.parent; } } this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeConstructorHeaderName() { /* recovering - might be an empty message send */ if (this.currentElement != null) { if (this.lastIgnoredToken == TokenNamenew) { // was an allocation expression this.lastCheckPoint= this.scanner.startPosition; // force to restart at this exact position this.restartRecovery= true; return; } } // ConstructorHeaderName ::= Modifiersopt 'Identifier' '(' ConstructorDeclaration cd= new ConstructorDeclaration(this.compilationUnit.compilationResult); //name -- this is not really revelant but we do ..... cd.selector= this.identifierStack[this.identifierPtr]; long selectorSource= this.identifierPositionStack[this.identifierPtr--]; this.identifierLengthPtr--; //modifiers cd.declarationSourceStart= this.intStack[this.intPtr--]; cd.modifiers= this.intStack[this.intPtr--]; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, cd.annotations= new Annotation[length], 0, length); } // javadoc cd.javadoc= this.javadoc; this.javadoc= null; //highlight starts at the selector starts cd.sourceStart= (int)(selectorSource >>> 32); pushOnAstStack(cd); cd.sourceEnd= this.lParenPos; cd.bodyStart= this.lParenPos + 1; this.listLength= 0; // initialize this.listLength before reading parameters/throws // recovery if (this.currentElement != null) { this.lastCheckPoint= cd.bodyStart; if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT) || cd.modifiers != 0) { this.currentElement= this.currentElement.add(cd, 0); this.lastIgnoredToken= -1; } } } protected void consumeConstructorHeaderNameWithTypeParameters() { /* recovering - might be an empty message send */ if (this.currentElement != null) { if (this.lastIgnoredToken == TokenNamenew) { // was an allocation expression this.lastCheckPoint= this.scanner.startPosition; // force to restart at this exact position this.restartRecovery= true; return; } } // ConstructorHeaderName ::= Modifiersopt TypeParameters 'Identifier' '(' ConstructorDeclaration cd= new ConstructorDeclaration(this.compilationUnit.compilationResult); //name -- this is not really revelant but we do ..... cd.selector= this.identifierStack[this.identifierPtr]; long selectorSource= this.identifierPositionStack[this.identifierPtr--]; this.identifierLengthPtr--; // consume type parameters int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, cd.typeParameters= new TypeParameter[length], 0, length); //modifiers cd.declarationSourceStart= this.intStack[this.intPtr--]; cd.modifiers= this.intStack[this.intPtr--]; // consume annotations if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, cd.annotations= new Annotation[length], 0, length); } // javadoc cd.javadoc= this.javadoc; this.javadoc= null; //highlight starts at the selector starts cd.sourceStart= (int)(selectorSource >>> 32); pushOnAstStack(cd); cd.sourceEnd= this.lParenPos; cd.bodyStart= this.lParenPos + 1; this.listLength= 0; // initialize this.listLength before reading parameters/throws // recovery if (this.currentElement != null) { this.lastCheckPoint= cd.bodyStart; if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT) || cd.modifiers != 0) { this.currentElement= this.currentElement.add(cd, 0); this.lastIgnoredToken= -1; } } } protected void consumeCreateInitializer() { pushOnAstStack(new Initializer(null, 0)); } protected void consumeDefaultLabel() { // SwitchLabel ::= 'default' ':' CaseStatement defaultStatement= new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]); // Look for $fall-through$ tag in leading comment for case statement if (hasLeadingTagComment(FALL_THROUGH_TAG, defaultStatement.sourceStart)) { defaultStatement.bits|= ASTNode.DocumentedFallthrough; } pushOnAstStack(defaultStatement); } protected void consumeDefaultModifiers() { checkComment(); // might update modifiers with AccDeprecated pushOnIntStack(this.modifiers); // modifiers pushOnIntStack(this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition); resetModifiers(); pushOnExpressionStackLengthStack(0); // no annotation } protected void consumeDiet() { // Diet ::= $empty checkComment(); pushOnIntStack(this.modifiersSourceStart); // push the start position of a javadoc comment if there is one resetModifiers(); jumpOverMethodBody(); } protected void consumeDims() { // Dims ::= DimsLoop pushOnIntStack(this.dimensions); this.dimensions= 0; } protected void consumeDimWithOrWithOutExpr() { // DimWithOrWithOutExpr ::= '[' ']' pushOnExpressionStack(null); if (this.currentElement != null && this.currentToken == TokenNameLBRACE) { this.ignoreNextOpeningBrace= true; this.currentElement.bracketBalance++; } } protected void consumeDimWithOrWithOutExprs() { // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr concatExpressionLists(); } protected void consumeEmptyAnnotationTypeMemberDeclarationsopt() { // AnnotationTypeMemberDeclarationsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyArgumentListopt() { // ArgumentListopt ::= $empty pushOnExpressionStackLengthStack(0); } protected void consumeEmptyArguments() { // Argumentsopt ::= $empty final FieldDeclaration fieldDeclaration= (FieldDeclaration)this.astStack[this.astPtr]; pushOnIntStack(fieldDeclaration.sourceEnd); pushOnExpressionStackLengthStack(0); } protected void consumeEmptyArrayInitializer() { // ArrayInitializer ::= '{' ,opt '}' arrayInitializer(0); } protected void consumeEmptyArrayInitializeropt() { // ArrayInitializeropt ::= $empty pushOnExpressionStackLengthStack(0); } protected void consumeEmptyBlockStatementsopt() { // BlockStatementsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyCatchesopt() { // Catchesopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyClassBodyDeclarationsopt() { // ClassBodyDeclarationsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyDimsopt() { // Dimsopt ::= $empty pushOnIntStack(0); } protected void consumeEmptyEnumDeclarations() { // EnumBodyDeclarationsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyExpression() { // Expressionopt ::= $empty pushOnExpressionStackLengthStack(0); } protected void consumeEmptyForInitopt() { // ForInitopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyForUpdateopt() { // ForUpdateopt ::= $empty pushOnExpressionStackLengthStack(0); } protected void consumeEmptyInterfaceMemberDeclarationsopt() { // InterfaceMemberDeclarationsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyInternalCompilationUnit() { // InternalCompilationUnit ::= $empty // nothing to do by default if (this.compilationUnit.isPackageInfo()) { this.compilationUnit.types= new TypeDeclaration[1]; this.compilationUnit.createPackageInfoType(); } } protected void consumeEmptyMemberValueArrayInitializer() { // MemberValueArrayInitializer ::= '{' ',' '}' // MemberValueArrayInitializer ::= '{' '}' arrayInitializer(0); } protected void consumeEmptyMemberValuePairsopt() { // MemberValuePairsopt ::= $empty pushOnAstLengthStack(0); } protected void consumeEmptyMethodHeaderDefaultValue() { // DefaultValueopt ::= $empty AbstractMethodDeclaration method= (AbstractMethodDeclaration)this.astStack[this.astPtr]; if (method.isAnnotationMethod()) { //'method' can be a MethodDeclaration when recovery is started pushOnExpressionStackLengthStack(0); } this.recordStringLiterals= true; } protected void consumeEmptyStatement() { // EmptyStatement ::= ';' char[] source= this.scanner.source; if (source[this.endStatementPosition] == ';') { pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition)); } else { if (source.length > 5) { int c1= 0, c2= 0, c3= 0, c4= 0; int pos= this.endStatementPosition - 4; while (source[pos] == 'u') { pos--; } if (source[pos] == '\\' && !((c1= ScannerHelper.getNumericValue(source[this.endStatementPosition - 3])) > 15 || c1 < 0 || (c2= ScannerHelper.getNumericValue(source[this.endStatementPosition - 2])) > 15 || c2 < 0 || (c3= ScannerHelper.getNumericValue(source[this.endStatementPosition - 1])) > 15 || c3 < 0 || (c4= ScannerHelper.getNumericValue(source[this.endStatementPosition])) > 15 || c4 < 0) && ((char)(((c1 * 16 + c2) * 16 + c3) * 16 + c4)) == ';') { // we have a Unicode for the ';' (/u003B) pushOnAstStack(new EmptyStatement(pos, this.endStatementPosition)); return; } } pushOnAstStack(new EmptyStatement(this.endPosition + 1, this.endStatementPosition)); } } protected void consumeEmptySwitchBlock() { // SwitchBlock ::= '{' '}' pushOnAstLengthStack(0); } protected void consumeEmptyTypeDeclaration() { // ClassMemberDeclaration ::= ';' // InterfaceMemberDeclaration ::= ';' // TypeDeclaration ::= ';' pushOnAstLengthStack(0); if (!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition + 1, this.endStatementPosition); flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeEnhancedForStatement() { // EnhancedForStatement ::= EnhancedForStatementHeader Statement // EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf //statements this.astLengthPtr--; Statement statement= (Statement)this.astStack[this.astPtr--]; // foreach statement is on the ast stack ForeachStatement foreachStatement= (ForeachStatement)this.astStack[this.astPtr]; foreachStatement.action= statement; // remember useful empty statement if (statement instanceof EmptyStatement) statement.bits|= ASTNode.IsUsefulEmptyStatement; foreachStatement.sourceEnd= this.endStatementPosition; } protected void consumeEnhancedForStatementHeader() { // EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')' final ForeachStatement statement= (ForeachStatement)this.astStack[this.astPtr]; //updates are on the expression stack this.expressionLengthPtr--; final Expression collection= this.expressionStack[this.expressionPtr--]; statement.collection= collection; statement.sourceEnd= this.rParenPos; if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection); } } protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) { TypeReference type; char[] identifierName= this.identifierStack[this.identifierPtr]; long namePosition= this.identifierPositionStack[this.identifierPtr]; LocalDeclaration localDeclaration= createLocalDeclaration(identifierName, (int)(namePosition >>> 32), (int)namePosition); localDeclaration.declarationSourceEnd= localDeclaration.declarationEnd; int extraDims= this.intStack[this.intPtr--]; this.identifierPtr--; this.identifierLengthPtr--; // remove fake modifiers/modifiers start int declarationSourceStart= 0; int modifiersValue= 0; if (hasModifiers) { declarationSourceStart= this.intStack[this.intPtr--]; modifiersValue= this.intStack[this.intPtr--]; } else { this.intPtr-= 2; } type= getTypeReference(this.intStack[this.intPtr--] + extraDims); // type dimension // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, localDeclaration.annotations= new Annotation[length], 0, length); } if (hasModifiers) { localDeclaration.declarationSourceStart= declarationSourceStart; localDeclaration.modifiers= modifiersValue; } else { localDeclaration.declarationSourceStart= type.sourceStart; } localDeclaration.type= type; ForeachStatement iteratorForStatement= new ForeachStatement( localDeclaration, this.intStack[this.intPtr--]); pushOnAstStack(iteratorForStatement); iteratorForStatement.sourceEnd= localDeclaration.declarationSourceEnd; } protected void consumeEnterAnonymousClassBody(boolean qualified) { // EnterAnonymousClassBody ::= $empty TypeReference typeReference= getTypeReference(0); TypeDeclaration anonymousType= new TypeDeclaration(this.compilationUnit.compilationResult); anonymousType.name= CharOperation.NO_CHAR; anonymousType.bits|= (ASTNode.IsAnonymousType | ASTNode.IsLocalType); QualifiedAllocationExpression alloc= new QualifiedAllocationExpression(anonymousType); markEnclosingMemberWithLocalType(); pushOnAstStack(anonymousType); alloc.sourceEnd= this.rParenPos; //the position has been stored explicitly int argumentLength; if ((argumentLength= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= argumentLength; System.arraycopy( this.expressionStack, this.expressionPtr + 1, alloc.arguments= new Expression[argumentLength], 0, argumentLength); } if (qualified) { this.expressionLengthPtr--; alloc.enclosingInstance= this.expressionStack[this.expressionPtr--]; } alloc.type= typeReference; anonymousType.sourceEnd= alloc.sourceEnd; //position at the type while it impacts the anonymous declaration anonymousType.sourceStart= anonymousType.declarationSourceStart= alloc.type.sourceStart; alloc.sourceStart= this.intStack[this.intPtr--]; pushOnExpressionStack(alloc); anonymousType.bodyStart= this.scanner.currentPosition; this.listLength= 0; // will be updated when reading super-interfaces // flush the comments related to the anonymous this.scanner.commentPtr= -1; // recovery if (this.currentElement != null) { this.lastCheckPoint= anonymousType.bodyStart; this.currentElement= this.currentElement.add(anonymousType, 0); if (!(this.currentElement instanceof RecoveredAnnotation)) { this.currentToken= 0; // opening brace already taken into account } else { this.ignoreNextOpeningBrace= true; this.currentElement.bracketBalance++; } this.lastIgnoredToken= -1; } } protected void consumeEnterCompilationUnit() { // EnterCompilationUnit ::= $empty // do nothing by default } protected void consumeEnterMemberValue() { // EnterMemberValue ::= $empty if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { RecoveredAnnotation recoveredAnnotation= (RecoveredAnnotation)this.currentElement; recoveredAnnotation.hasPendingMemberValueName= true; } } protected void consumeEnterMemberValueArrayInitializer() { // EnterMemberValueArrayInitializer ::= $empty if (this.currentElement != null) { this.ignoreNextOpeningBrace= true; this.currentElement.bracketBalance++; } } protected void consumeEnterVariable() { // EnterVariable ::= $empty // do nothing by default char[] identifierName= this.identifierStack[this.identifierPtr]; long namePosition= this.identifierPositionStack[this.identifierPtr]; int extendedDimension= this.intStack[this.intPtr--]; AbstractVariableDeclaration declaration; // create the ast node boolean isLocalDeclaration= this.nestedMethod[this.nestedType] != 0; if (isLocalDeclaration) { // create the local variable declarations declaration= createLocalDeclaration(identifierName, (int)(namePosition >>> 32), (int)namePosition); } else { // create the field declaration declaration= createFieldDeclaration(identifierName, (int)(namePosition >>> 32), (int)namePosition); } this.identifierPtr--; this.identifierLengthPtr--; TypeReference type; int variableIndex= this.variablesCounter[this.nestedType]; int typeDim= 0; if (variableIndex == 0) { // first variable of the declaration (FieldDeclaration or LocalDeclaration) if (isLocalDeclaration) { declaration.declarationSourceStart= this.intStack[this.intPtr--]; declaration.modifiers= this.intStack[this.intPtr--]; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, declaration.annotations= new Annotation[length], 0, length); } type= getTypeReference(typeDim= this.intStack[this.intPtr--]); // type dimension if (declaration.declarationSourceStart == -1) { // this is true if there is no modifiers for the local variable declaration declaration.declarationSourceStart= type.sourceStart; } pushOnAstStack(type); } else { type= getTypeReference(typeDim= this.intStack[this.intPtr--]); // type dimension pushOnAstStack(type); declaration.declarationSourceStart= this.intStack[this.intPtr--]; declaration.modifiers= this.intStack[this.intPtr--]; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, declaration.annotations= new Annotation[length], 0, length); } // Store javadoc only on first declaration as it is the same for all ones FieldDeclaration fieldDeclaration= (FieldDeclaration)declaration; fieldDeclaration.javadoc= this.javadoc; } this.javadoc= null; } else { type= (TypeReference)this.astStack[this.astPtr - variableIndex]; typeDim= type.dimensions(); AbstractVariableDeclaration previousVariable= (AbstractVariableDeclaration)this.astStack[this.astPtr]; declaration.declarationSourceStart= previousVariable.declarationSourceStart; declaration.modifiers= previousVariable.modifiers; final Annotation[] annotations= previousVariable.annotations; if (annotations != null) { final int annotationsLength= annotations.length; System.arraycopy(annotations, 0, declaration.annotations= new Annotation[annotationsLength], 0, annotationsLength); } } if (extendedDimension == 0) { declaration.type= type; } else { int dimension= typeDim + extendedDimension; declaration.type= copyDims(type, dimension); } this.variablesCounter[this.nestedType]++; pushOnAstStack(declaration); // recovery if (this.currentElement != null) { if (!(this.currentElement instanceof RecoveredType) && (this.currentToken == TokenNameDOT //|| declaration.modifiers != 0 || (Util.getLineNumber(declaration.type.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr) != Util.getLineNumber((int)(namePosition >>> 32), this.scanner.lineEnds, 0, this.scanner.linePtr)))) { this.lastCheckPoint= (int)(namePosition >>> 32); this.restartRecovery= true; return; } if (isLocalDeclaration) { LocalDeclaration localDecl= (LocalDeclaration)this.astStack[this.astPtr]; this.lastCheckPoint= localDecl.sourceEnd + 1; this.currentElement= this.currentElement.add(localDecl, 0); } else { FieldDeclaration fieldDecl= (FieldDeclaration)this.astStack[this.astPtr]; this.lastCheckPoint= fieldDecl.sourceEnd + 1; this.currentElement= this.currentElement.add(fieldDecl, 0); } this.lastIgnoredToken= -1; } } protected void consumeEnumBodyNoConstants() { // nothing to do // The 0 on the astLengthStack has been pushed by EnumBodyDeclarationsopt } protected void consumeEnumBodyWithConstants() { // merge the constants values with the class body concatNodeLists(); } protected void consumeEnumConstantHeader() { FieldDeclaration enumConstant= (FieldDeclaration)this.astStack[this.astPtr]; boolean foundOpeningBrace= this.currentToken == TokenNameLBRACE; if (foundOpeningBrace) { // qualified allocation expression TypeDeclaration anonymousType= new TypeDeclaration(this.compilationUnit.compilationResult); anonymousType.name= CharOperation.NO_CHAR; anonymousType.bits|= (ASTNode.IsAnonymousType | ASTNode.IsLocalType); final int start= this.scanner.startPosition; anonymousType.declarationSourceStart= start; anonymousType.sourceStart= start; anonymousType.sourceEnd= start; // closing parenthesis anonymousType.modifiers= 0; anonymousType.bodyStart= this.scanner.currentPosition; markEnclosingMemberWithLocalType(); consumeNestedType(); this.variablesCounter[this.nestedType]++; pushOnAstStack(anonymousType); QualifiedAllocationExpression allocationExpression= new QualifiedAllocationExpression(anonymousType); allocationExpression.enumConstant= enumConstant; // fill arguments if needed int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, allocationExpression.arguments= new Expression[length], 0, length); } enumConstant.initialization= allocationExpression; } else { AllocationExpression allocationExpression= new AllocationExpression(); allocationExpression.enumConstant= enumConstant; // fill arguments if needed int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, allocationExpression.arguments= new Expression[length], 0, length); } enumConstant.initialization= allocationExpression; } // recovery if (this.currentElement != null) { if (foundOpeningBrace) { TypeDeclaration anonymousType= (TypeDeclaration)this.astStack[this.astPtr]; this.currentElement= this.currentElement.add(anonymousType, 0); this.lastCheckPoint= anonymousType.bodyStart; this.lastIgnoredToken= -1; this.currentToken= 0; // opening brace already taken into account } else { if (this.currentToken == TokenNameSEMICOLON) { RecoveredType currentType= currentRecoveryType(); if (currentType != null) { currentType.insideEnumConstantPart= false; } } this.lastCheckPoint= this.scanner.startPosition; // force to restart at this exact position this.lastIgnoredToken= -1; this.restartRecovery= true; } } } protected void consumeEnumConstantHeaderName() { if (this.currentElement != null) { if (!(this.currentElement instanceof RecoveredType || (this.currentElement instanceof RecoveredField && ((RecoveredField)this.currentElement).fieldDeclaration.type == null)) || (this.lastIgnoredToken == TokenNameDOT)) { this.lastCheckPoint= this.scanner.startPosition; this.restartRecovery= true; return; } } long namePosition= this.identifierPositionStack[this.identifierPtr]; char[] constantName= this.identifierStack[this.identifierPtr]; final int sourceEnd= (int)namePosition; FieldDeclaration enumConstant= createFieldDeclaration(constantName, (int)(namePosition >>> 32), sourceEnd); this.identifierPtr--; this.identifierLengthPtr--; enumConstant.modifiersSourceStart= this.intStack[this.intPtr--]; enumConstant.modifiers= this.intStack[this.intPtr--]; enumConstant.declarationSourceStart= enumConstant.modifiersSourceStart; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, enumConstant.annotations= new Annotation[length], 0, length); } pushOnAstStack(enumConstant); if (this.currentElement != null) { this.lastCheckPoint= enumConstant.sourceEnd + 1; this.currentElement= this.currentElement.add(enumConstant, 0); } // javadoc enumConstant.javadoc= this.javadoc; this.javadoc= null; } protected void consumeEnumConstantNoClassBody() { // set declarationEnd and declarationSourceEnd int endOfEnumConstant= this.intStack[this.intPtr--]; final FieldDeclaration fieldDeclaration= (FieldDeclaration)this.astStack[this.astPtr]; fieldDeclaration.declarationEnd= endOfEnumConstant; fieldDeclaration.declarationSourceEnd= endOfEnumConstant; } protected void consumeEnumConstants() { concatNodeLists(); } protected void consumeEnumConstantWithClassBody() { dispatchDeclarationInto(this.astLengthStack[this.astLengthPtr--]); TypeDeclaration anonymousType= (TypeDeclaration)this.astStack[this.astPtr--]; // pop type this.astLengthPtr--; anonymousType.bodyEnd= this.endPosition; anonymousType.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); final FieldDeclaration fieldDeclaration= ((FieldDeclaration)this.astStack[this.astPtr]); fieldDeclaration.declarationEnd= this.endStatementPosition; fieldDeclaration.declarationSourceEnd= anonymousType.declarationSourceEnd; this.intPtr--; // remove end position of the arguments this.variablesCounter[this.nestedType]= 0; this.nestedType--; } protected void consumeEnumDeclaration() { // EnumDeclaration ::= EnumHeader ClassHeaderImplementsopt EnumBody int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch according to the type of the declarations dispatchDeclarationIntoEnumDeclaration(length); } TypeDeclaration enumDeclaration= (TypeDeclaration)this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods boolean hasConstructor= enumDeclaration.checkConstructors(this); //add the default constructor when needed if (!hasConstructor) { boolean insideFieldInitializer= false; if (this.diet) { for (int i= this.nestedType; i > 0; i--) { if (this.variablesCounter[i] > 0) { insideFieldInitializer= true; break; } } } enumDeclaration.createDefaultConstructor(!this.diet || insideFieldInitializer, true); } //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { enumDeclaration.bits|= ASTNode.ContainsAssertion; } enumDeclaration.addClinit(); enumDeclaration.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(enumDeclaration.bodyStart, enumDeclaration.bodyEnd)) { enumDeclaration.bits|= ASTNode.UndocumentedEmptyBlock; } enumDeclaration.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeEnumDeclarations() { // Do nothing by default } protected void consumeEnumHeader() { TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { typeDecl.bodyStart= this.scanner.currentPosition; } if (this.currentElement != null) { this.restartRecovery= true; // used to avoid branching back into the regular automaton } // flush the comments related to the enum header this.scanner.commentPtr= -1; } protected void consumeEnumHeaderName() { // EnumHeaderName ::= Modifiersopt 'enum' Identifier TypeDeclaration enumDeclaration= new TypeDeclaration(this.compilationUnit.compilationResult); if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { enumDeclaration.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types // markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; enumDeclaration.sourceEnd= (int)pos; enumDeclaration.sourceStart= (int)(pos >>> 32); enumDeclaration.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'class' and 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. enumDeclaration.declarationSourceStart= this.intStack[this.intPtr--]; this.intPtr--; // remove the end position of the class token enumDeclaration.modifiersSourceStart= this.intStack[this.intPtr--]; enumDeclaration.modifiers= this.intStack[this.intPtr--] | ClassFileConstants.AccEnum; if (enumDeclaration.modifiersSourceStart >= 0) { enumDeclaration.declarationSourceStart= enumDeclaration.modifiersSourceStart; } // Store secondary info if ((enumDeclaration.bits & ASTNode.IsMemberType) == 0 && (enumDeclaration.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(enumDeclaration.name, this.compilationUnit.getMainTypeName())) { enumDeclaration.bits|= ASTNode.IsSecondaryType; } } // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, enumDeclaration.annotations= new Annotation[length], 0, length); } // if (this.currentToken == TokenNameLBRACE) { // enumDeclaration.bodyStart = this.scanner.currentPosition; // } enumDeclaration.bodyStart= enumDeclaration.sourceEnd + 1; pushOnAstStack(enumDeclaration); this.listLength= 0; // will be updated when reading super-interfaces if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { //TODO this code will be never run while 'enum' is an identifier in 1.3 scanner problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration); } // recovery if (this.currentElement != null) { this.lastCheckPoint= enumDeclaration.bodyStart; this.currentElement= this.currentElement.add(enumDeclaration, 0); this.lastIgnoredToken= -1; } // javadoc enumDeclaration.javadoc= this.javadoc; this.javadoc= null; } protected void consumeEnumHeaderNameWithTypeParameters() { // EnumHeaderNameWithTypeParameters ::= Modifiersopt 'enum' Identifier TypeParameters TypeDeclaration enumDeclaration= new TypeDeclaration(this.compilationUnit.compilationResult); // consume type parameters int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, enumDeclaration.typeParameters= new TypeParameter[length], 0, length); problemReporter().invalidUsageOfTypeParametersForEnumDeclaration(enumDeclaration); enumDeclaration.bodyStart= enumDeclaration.typeParameters[length - 1].declarationSourceEnd + 1; // enumDeclaration.typeParameters = null; this.listTypeParameterLength= 0; if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { enumDeclaration.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types // markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; enumDeclaration.sourceEnd= (int)pos; enumDeclaration.sourceStart= (int)(pos >>> 32); enumDeclaration.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'class' and 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. enumDeclaration.declarationSourceStart= this.intStack[this.intPtr--]; this.intPtr--; // remove the end position of the class token enumDeclaration.modifiersSourceStart= this.intStack[this.intPtr--]; enumDeclaration.modifiers= this.intStack[this.intPtr--] | ClassFileConstants.AccEnum; if (enumDeclaration.modifiersSourceStart >= 0) { enumDeclaration.declarationSourceStart= enumDeclaration.modifiersSourceStart; } // Store secondary info if ((enumDeclaration.bits & ASTNode.IsMemberType) == 0 && (enumDeclaration.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(enumDeclaration.name, this.compilationUnit.getMainTypeName())) { enumDeclaration.bits|= ASTNode.IsSecondaryType; } } // consume annotations if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, enumDeclaration.annotations= new Annotation[length], 0, length); } // if (this.currentToken == TokenNameLBRACE) { // enumDeclaration.bodyStart = this.scanner.currentPosition; // } enumDeclaration.bodyStart= enumDeclaration.sourceEnd + 1; pushOnAstStack(enumDeclaration); this.listLength= 0; // will be updated when reading super-interfaces if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { //TODO this code will be never run while 'enum' is an identifier in 1.3 scanner problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration); } // recovery if (this.currentElement != null) { this.lastCheckPoint= enumDeclaration.bodyStart; this.currentElement= this.currentElement.add(enumDeclaration, 0); this.lastIgnoredToken= -1; } // javadoc enumDeclaration.javadoc= this.javadoc; this.javadoc= null; } protected void consumeEqualityExpression(int op) { // EqualityExpression ::= EqualityExpression '==' RelationalExpression // EqualityExpression ::= EqualityExpression '!=' RelationalExpression //optimize the push/pop this.expressionPtr--; this.expressionLengthPtr--; this.expressionStack[this.expressionPtr]= new EqualExpression( this.expressionStack[this.expressionPtr], this.expressionStack[this.expressionPtr + 1], op); } /* * @param op */ protected void consumeEqualityExpressionWithName(int op) { // EqualityExpression ::= Name '==' RelationalExpression // EqualityExpression ::= Name '!=' RelationalExpression pushOnExpressionStack(getUnspecifiedReferenceOptimized()); this.expressionPtr--; this.expressionLengthPtr--; this.expressionStack[this.expressionPtr]= new EqualExpression( this.expressionStack[this.expressionPtr + 1], this.expressionStack[this.expressionPtr], op); } protected void consumeExitMemberValue() { // ExitMemberValue ::= $empty if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { RecoveredAnnotation recoveredAnnotation= (RecoveredAnnotation)this.currentElement; recoveredAnnotation.hasPendingMemberValueName= false; recoveredAnnotation.memberValuPairEqualEnd= -1; } } protected void consumeExitTryBlock() { //ExitTryBlock ::= $empty if (this.currentElement != null) { this.restartRecovery= true; } } protected void consumeExitVariableWithInitialization() { // ExitVariableWithInitialization ::= $empty // do nothing by default this.expressionLengthPtr--; AbstractVariableDeclaration variableDecl= (AbstractVariableDeclaration)this.astStack[this.astPtr]; variableDecl.initialization= this.expressionStack[this.expressionPtr--]; // we need to update the declarationSourceEnd of the local variable declaration to the // source end position of the initialization expression variableDecl.declarationSourceEnd= variableDecl.initialization.sourceEnd; variableDecl.declarationEnd= variableDecl.initialization.sourceEnd; recoveryExitFromVariable(); } protected void consumeExitVariableWithoutInitialization() { // ExitVariableWithoutInitialization ::= $empty // do nothing by default AbstractVariableDeclaration variableDecl= (AbstractVariableDeclaration)this.astStack[this.astPtr]; variableDecl.declarationSourceEnd= variableDecl.declarationEnd; if (this.currentElement != null && this.currentElement instanceof RecoveredField) { if (this.endStatementPosition > variableDecl.sourceEnd) { this.currentElement.updateSourceEndIfNecessary(this.endStatementPosition); } } recoveryExitFromVariable(); } protected void consumeExplicitConstructorInvocation(int flag, int recFlag) { /* flag allows to distinguish 3 cases : (0) : ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';' (1) : ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';' (2) : ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';' */ int startPosition= this.intStack[this.intPtr--]; ExplicitConstructorCall ecc= new ExplicitConstructorCall(recFlag); int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments= new Expression[length], 0, length); } switch (flag) { case 0: ecc.sourceStart= startPosition; break; case 1: this.expressionLengthPtr--; ecc.sourceStart= (ecc.qualification= this.expressionStack[this.expressionPtr--]).sourceStart; break; case 2: ecc.sourceStart= (ecc.qualification= getUnspecifiedReferenceOptimized()).sourceStart; break; } pushOnAstStack(ecc); ecc.sourceEnd= this.endStatementPosition; } protected void consumeExplicitConstructorInvocationWithTypeArguments(int flag, int recFlag) { /* flag allows to distinguish 3 cases : (0) : ExplicitConstructorInvocation ::= TypeArguments 'this' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= TypeArguments 'super' '(' ArgumentListopt ')' ';' (1) : ExplicitConstructorInvocation ::= Primary '.' TypeArguments 'super' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= Primary '.' TypeArguments 'this' '(' ArgumentListopt ')' ';' (2) : ExplicitConstructorInvocation ::= Name '.' TypeArguments 'super' '(' ArgumentListopt ')' ';' ExplicitConstructorInvocation ::= Name '.' TypeArguments 'this' '(' ArgumentListopt ')' ';' */ int startPosition= this.intStack[this.intPtr--]; ExplicitConstructorCall ecc= new ExplicitConstructorCall(recFlag); int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments= new Expression[length], 0, length); } length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, ecc.typeArguments= new TypeReference[length], 0, length); ecc.typeArgumentsSourceStart= this.intStack[this.intPtr--]; switch (flag) { case 0: ecc.sourceStart= startPosition; break; case 1: this.expressionLengthPtr--; ecc.sourceStart= (ecc.qualification= this.expressionStack[this.expressionPtr--]).sourceStart; break; case 2: ecc.sourceStart= (ecc.qualification= getUnspecifiedReferenceOptimized()).sourceStart; break; } pushOnAstStack(ecc); ecc.sourceEnd= this.endStatementPosition; } protected void consumeExpressionStatement() { // ExpressionStatement ::= StatementExpression ';' this.expressionLengthPtr--; Expression expression= this.expressionStack[this.expressionPtr--]; expression.statementEnd= this.endStatementPosition; pushOnAstStack(expression); } protected void consumeFieldAccess(boolean isSuperAccess) { // FieldAccess ::= Primary '.' 'Identifier' // FieldAccess ::= 'super' '.' 'Identifier' FieldReference fr= new FieldReference( this.identifierStack[this.identifierPtr], this.identifierPositionStack[this.identifierPtr--]); this.identifierLengthPtr--; if (isSuperAccess) { //considerates the fieldReference beginning at the 'super' .... fr.sourceStart= this.intStack[this.intPtr--]; fr.receiver= new SuperReference(fr.sourceStart, this.endPosition); pushOnExpressionStack(fr); } else { //optimize push/pop fr.receiver= this.expressionStack[this.expressionPtr]; //fieldreference begins at the receiver fr.sourceStart= fr.receiver.sourceStart; this.expressionStack[this.expressionPtr]= fr; } } protected void consumeFieldDeclaration() { // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' /* this.astStack : this.expressionStack: Expression Expression ...... Expression this.identifierStack : type identifier identifier ...... identifier this.intStack : typeDim dim dim dim ==> this.astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration this.expressionStack : this.identifierStack : this.intStack : */ int variableDeclaratorsCounter= this.astLengthStack[this.astLengthPtr]; for (int i= variableDeclaratorsCounter - 1; i >= 0; i--) { FieldDeclaration fieldDeclaration= (FieldDeclaration)this.astStack[this.astPtr - i]; fieldDeclaration.declarationSourceEnd= this.endStatementPosition; fieldDeclaration.declarationEnd= this.endStatementPosition; // semi-colon included } updateSourceDeclarationParts(variableDeclaratorsCounter); int endPos= flushCommentsDefinedPriorTo(this.endStatementPosition); if (endPos != this.endStatementPosition) { for (int i= 0; i < variableDeclaratorsCounter; i++) { FieldDeclaration fieldDeclaration= (FieldDeclaration)this.astStack[this.astPtr - i]; fieldDeclaration.declarationSourceEnd= endPos; } } // update the this.astStack, this.astPtr and this.astLengthStack int startIndex= this.astPtr - this.variablesCounter[this.nestedType] + 1; System.arraycopy( this.astStack, startIndex, this.astStack, startIndex - 1, variableDeclaratorsCounter); this.astPtr--; // remove the type reference this.astLengthStack[--this.astLengthPtr]= variableDeclaratorsCounter; // recovery if (this.currentElement != null) { this.lastCheckPoint= endPos + 1; if (this.currentElement.parent != null && this.currentElement instanceof RecoveredField) { if (!(this.currentElement instanceof RecoveredInitializer)) { this.currentElement= this.currentElement.parent; } } this.restartRecovery= true; } this.variablesCounter[this.nestedType]= 0; } protected void consumeForceNoDiet() { // ForceNoDiet ::= $empty this.dietInt++; } protected void consumeForInit() { // ForInit ::= StatementExpressionList pushOnAstLengthStack(-1); } protected void consumeFormalParameter(boolean isVarArgs) { // FormalParameter ::= Type VariableDeclaratorId ==> false // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true /* this.astStack : this.identifierStack : type identifier this.intStack : dim dim ==> this.astStack : Argument this.identifierStack : this.intStack : */ this.identifierLengthPtr--; char[] identifierName= this.identifierStack[this.identifierPtr]; long namePositions= this.identifierPositionStack[this.identifierPtr--]; int extendedDimensions= this.intStack[this.intPtr--]; int endOfEllipsis= 0; if (isVarArgs) { endOfEllipsis= this.intStack[this.intPtr--]; } int firstDimensions= this.intStack[this.intPtr--]; final int typeDimensions= firstDimensions + extendedDimensions; TypeReference type= getTypeReference(typeDimensions); if (isVarArgs) { type= copyDims(type, typeDimensions + 1); if (extendedDimensions == 0) { type.sourceEnd= endOfEllipsis; } type.bits|= ASTNode.IsVarArgs; // set isVarArgs } int modifierPositions= this.intStack[this.intPtr--]; this.intPtr--; Argument arg= new Argument( identifierName, namePositions, type, this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers arg.declarationSourceStart= modifierPositions; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, arg.annotations= new Annotation[length], 0, length); } pushOnAstStack(arg); /* if incomplete method header, this.listLength counter will not have been reset, indicating that some arguments are available on the stack */ this.listLength++; if (isVarArgs) { if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfVarargs(arg); } else if (!this.statementRecoveryActivated && extendedDimensions > 0) { problemReporter().illegalExtendedDimensions(arg); } } } protected void consumeFormalParameterList() { // FormalParameterList ::= FormalParameterList ',' FormalParameter optimizedConcatNodeLists(); } protected void consumeFormalParameterListopt() { // FormalParameterListopt ::= $empty pushOnAstLengthStack(0); } protected void consumeGenericType() { // nothing to do // Will be consume by a getTypeRefence call } protected void consumeGenericTypeArrayType() { // nothing to do // Will be consume by a getTypeRefence call } protected void consumeGenericTypeNameArrayType() { // nothing to do // Will be consume by a getTypeRefence call } protected void consumeImportDeclaration() { // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';' ImportReference impt= (ImportReference)this.astStack[this.astPtr]; // flush annotations defined prior to import statements impt.declarationEnd= this.endStatementPosition; impt.declarationSourceEnd= flushCommentsDefinedPriorTo(impt.declarationSourceEnd); // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.currentElement= this.currentElement.add(impt, 0); this.lastIgnoredToken= -1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeImportDeclarations() { // ImportDeclarations ::= ImportDeclarations ImportDeclaration optimizedConcatNodeLists(); } protected void consumeInsideCastExpression() { // InsideCastExpression ::= $empty } protected void consumeInsideCastExpressionLL1() { // InsideCastExpressionLL1 ::= $empty pushOnGenericsLengthStack(0); // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnExpressionStack(getTypeReference(0)); } protected void consumeInsideCastExpressionWithQualifiedGenerics() { // InsideCastExpressionWithQualifiedGenerics ::= $empty } protected void consumeInstanceOfExpression() { // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType //optimize the push/pop //by construction, no base type may be used in getTypeReference Expression exp; this.expressionStack[this.expressionPtr]= exp= new InstanceOfExpression( this.expressionStack[this.expressionPtr], getTypeReference(this.intStack[this.intPtr--])); if (exp.sourceEnd == 0) { //array on base type.... exp.sourceEnd= this.scanner.startPosition - 1; } //the scanner is on the next token already.... } protected void consumeInstanceOfExpressionWithName() { // RelationalExpression_NotName ::= Name instanceof ReferenceType //optimize the push/pop //by construction, no base type may be used in getTypeReference TypeReference reference= getTypeReference(this.intStack[this.intPtr--]); pushOnExpressionStack(getUnspecifiedReferenceOptimized()); Expression exp; this.expressionStack[this.expressionPtr]= exp= new InstanceOfExpression( this.expressionStack[this.expressionPtr], reference); if (exp.sourceEnd == 0) { //array on base type.... exp.sourceEnd= this.scanner.startPosition - 1; } //the scanner is on the next token already.... } protected void consumeInterfaceDeclaration() { // see consumeClassDeclaration in case of changes: duplicated code // InterfaceDeclaration ::= InterfaceHeader InterfaceBody int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { //there are length declarations //dispatch.....according to the type of the declarations dispatchDeclarationInto(length); } TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; //convert constructor that do not have the type's name into methods typeDecl.checkConstructors(this); //always add <clinit> (will be remove at code gen time if empty) if (this.scanner.containsAssertKeyword) { typeDecl.bits|= ASTNode.ContainsAssertion; } typeDecl.addClinit(); typeDecl.bodyEnd= this.endStatementPosition; if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) { typeDecl.bits|= ASTNode.UndocumentedEmptyBlock; } typeDecl.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeInterfaceHeader() { // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { typeDecl.bodyStart= this.scanner.currentPosition; } if (this.currentElement != null) { this.restartRecovery= true; // used to avoid branching back into the regular automaton } // flush the comments related to the interface header this.scanner.commentPtr= -1; } protected void consumeInterfaceHeaderExtends() { // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList int length= this.astLengthStack[this.astLengthPtr--]; //super interfaces this.astPtr-= length; TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; System.arraycopy( this.astStack, this.astPtr + 1, typeDecl.superInterfaces= new TypeReference[length], 0, length); for (int i= 0, max= typeDecl.superInterfaces.length; i < max; i++) { typeDecl.superInterfaces[i].bits|= ASTNode.IsSuperType; } typeDecl.bodyStart= typeDecl.superInterfaces[length - 1].sourceEnd + 1; this.listLength= 0; // reset after having read super-interfaces // recovery if (this.currentElement != null) { this.lastCheckPoint= typeDecl.bodyStart; } } protected void consumeInterfaceHeaderName1() { // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier' TypeDeclaration typeDecl= new TypeDeclaration(this.compilationUnit.compilationResult); if (this.nestedMethod[this.nestedType] == 0) { if (this.nestedType != 0) { typeDecl.bits|= ASTNode.IsMemberType; } } else { // Record that the block has a declaration for local types typeDecl.bits|= ASTNode.IsLocalType; markEnclosingMemberWithLocalType(); blockReal(); } //highlight the name of the type long pos= this.identifierPositionStack[this.identifierPtr]; typeDecl.sourceEnd= (int)pos; typeDecl.sourceStart= (int)(pos >>> 32); typeDecl.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; //compute the declaration source too // 'class' and 'interface' push two int positions: the beginning of the class token and its end. // we want to keep the beginning position but get rid of the end position // it is only used for the ClassLiteralAccess positions. typeDecl.declarationSourceStart= this.intStack[this.intPtr--]; this.intPtr--; // remove the end position of the class token typeDecl.modifiersSourceStart= this.intStack[this.intPtr--]; typeDecl.modifiers= this.intStack[this.intPtr--] | ClassFileConstants.AccInterface; if (typeDecl.modifiersSourceStart >= 0) { typeDecl.declarationSourceStart= typeDecl.modifiersSourceStart; } // Store secondary info if ((typeDecl.bits & ASTNode.IsMemberType) == 0 && (typeDecl.bits & ASTNode.IsLocalType) == 0) { if (this.compilationUnit != null && !CharOperation.equals(typeDecl.name, this.compilationUnit.getMainTypeName())) { typeDecl.bits|= ASTNode.IsSecondaryType; } } // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, typeDecl.annotations= new Annotation[length], 0, length); } typeDecl.bodyStart= typeDecl.sourceEnd + 1; pushOnAstStack(typeDecl); this.listLength= 0; // will be updated when reading super-interfaces // recovery if (this.currentElement != null) { // is recovering this.lastCheckPoint= typeDecl.bodyStart; this.currentElement= this.currentElement.add(typeDecl, 0); this.lastIgnoredToken= -1; } // javadoc typeDecl.javadoc= this.javadoc; this.javadoc= null; } protected void consumeInterfaceMemberDeclarations() { // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration concatNodeLists(); } protected void consumeInterfaceMemberDeclarationsopt() { // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations this.nestedType--; } protected void consumeInterfaceType() { // InterfaceType ::= ClassOrInterfaceType pushOnAstStack(getTypeReference(0)); /* if incomplete type header, this.listLength counter will not have been reset, indicating that some interfaces are available on the stack */ this.listLength++; } protected void consumeInterfaceTypeList() { // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType optimizedConcatNodeLists(); } protected void consumeInternalCompilationUnit() { // InternalCompilationUnit ::= PackageDeclaration // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports // InternalCompilationUnit ::= ImportDeclarations ReduceImports if (this.compilationUnit.isPackageInfo()) { this.compilationUnit.types= new TypeDeclaration[1]; this.compilationUnit.createPackageInfoType(); } } protected void consumeInternalCompilationUnitWithTypes() { // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations // InternalCompilationUnit ::= PackageDeclaration TypeDeclarations // InternalCompilationUnit ::= TypeDeclarations // InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations // consume type declarations int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { if (this.compilationUnit.isPackageInfo()) { this.compilationUnit.types= new TypeDeclaration[length + 1]; this.astPtr-= length; System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 1, length); this.compilationUnit.createPackageInfoType(); } else { this.compilationUnit.types= new TypeDeclaration[length]; this.astPtr-= length; System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length); } } } protected void consumeInvalidAnnotationTypeDeclaration() { // BlockStatement ::= AnnotationTypeDeclaration TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl); // remove the ast node created in interface header this.astPtr--; pushOnAstLengthStack(-1); concatNodeLists(); } protected void consumeInvalidConstructorDeclaration() { // ConstructorDeclaration ::= ConstructorHeader ';' // now we know that the top of stack is a constructorDeclaration ConstructorDeclaration cd= (ConstructorDeclaration)this.astStack[this.astPtr]; cd.bodyEnd= this.endPosition; // position just before the trailing semi-colon cd.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); // report the problem and continue the parsing - narrowing the problem onto the method cd.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; // remember semi-colon body } protected void consumeInvalidConstructorDeclaration(boolean hasBody) { // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false /* this.astStack : modifiers arguments throws statements this.identifierStack : name ==> this.astStack : MethodDeclaration this.identifierStack : */ if (hasBody) { // pop the position of the { (body of the method) pushed in block decl this.intPtr--; } //statements if (hasBody) { this.realBlockPtr--; } int length; if (hasBody && ((length= this.astLengthStack[this.astLengthPtr--]) != 0)) { this.astPtr-= length; } ConstructorDeclaration constructorDeclaration= (ConstructorDeclaration)this.astStack[this.astPtr]; constructorDeclaration.bodyEnd= this.endStatementPosition; constructorDeclaration.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); if (!hasBody) { constructorDeclaration.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; } } protected void consumeInvalidEnumDeclaration() { // BlockStatement ::= EnumDeclaration TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl); // remove the ast node created in interface header this.astPtr--; pushOnAstLengthStack(-1); concatNodeLists(); } protected void consumeInvalidInterfaceDeclaration() { // BlockStatement ::= InvalidInterfaceDeclaration //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl); // remove the ast node created in interface header this.astPtr--; pushOnAstLengthStack(-1); concatNodeLists(); } protected void consumeInvalidMethodDeclaration() { // InterfaceMemberDeclaration ::= InvalidMethodDeclaration /* this.astStack : modifiers arguments throws statements this.identifierStack : type name this.intStack : dim dim dim ==> this.astStack : MethodDeclaration this.identifierStack : this.intStack : */ // pop the position of the { (body of the method) pushed in block decl this.intPtr--; // retrieve end position of method declarator //statements this.realBlockPtr--; int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr-= length; } //watch for } that could be given as a unicode ! ( u007D is '}' ) MethodDeclaration md= (MethodDeclaration)this.astStack[this.astPtr]; md.bodyEnd= this.endPosition; md.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); // report the problem and continue the parsing - narrowing the problem onto the method if (!this.statementRecoveryActivated) problemReporter().abstractMethodNeedingNoBody(md); } protected void consumeLabel() { // Do nothing } protected void consumeLeftParen() { // PushLPAREN ::= '(' pushOnIntStack(this.lParenPos); } protected void consumeLocalVariableDeclaration() { // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';' /* this.astStack : this.expressionStack: Expression Expression ...... Expression this.identifierStack : type identifier identifier ...... identifier this.intStack : typeDim dim dim dim ==> this.astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration this.expressionStack : this.identifierStack : this.intStack : */ int variableDeclaratorsCounter= this.astLengthStack[this.astLengthPtr]; // update the this.astStack, this.astPtr and this.astLengthStack int startIndex= this.astPtr - this.variablesCounter[this.nestedType] + 1; System.arraycopy( this.astStack, startIndex, this.astStack, startIndex - 1, variableDeclaratorsCounter); this.astPtr--; // remove the type reference this.astLengthStack[--this.astLengthPtr]= variableDeclaratorsCounter; this.variablesCounter[this.nestedType]= 0; } protected void consumeLocalVariableDeclarationStatement() { // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';' // see blockReal in case of change: duplicated code // increment the amount of declared variables for this block this.realBlockStack[this.realBlockPtr]++; // update source end to include the semi-colon int variableDeclaratorsCounter= this.astLengthStack[this.astLengthPtr]; for (int i= variableDeclaratorsCounter - 1; i >= 0; i--) { LocalDeclaration localDeclaration= (LocalDeclaration)this.astStack[this.astPtr - i]; localDeclaration.declarationSourceEnd= this.endStatementPosition; localDeclaration.declarationEnd= this.endStatementPosition; // semi-colon included } } protected void consumeMarkerAnnotation() { // MarkerAnnotation ::= '@' Name MarkerAnnotation markerAnnotation= null; int oldIndex= this.identifierPtr; TypeReference typeReference= getAnnotationType(); markerAnnotation= new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]); markerAnnotation.declarationSourceEnd= markerAnnotation.sourceEnd; pushOnExpressionStack(markerAnnotation); if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfAnnotation(markerAnnotation); } this.recordStringLiterals= true; if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { this.currentElement= ((RecoveredAnnotation)this.currentElement).addAnnotation(markerAnnotation, oldIndex); } } protected void consumeMemberValueArrayInitializer() { // MemberValueArrayInitializer ::= '{' MemberValues ',' '}' // MemberValueArrayInitializer ::= '{' MemberValues '}' arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]); } protected void consumeMemberValueAsName() { pushOnExpressionStack(getUnspecifiedReferenceOptimized()); } protected void consumeMemberValuePair() { // MemberValuePair ::= SimpleName '=' MemberValue char[] simpleName= this.identifierStack[this.identifierPtr]; long position= this.identifierPositionStack[this.identifierPtr--]; this.identifierLengthPtr--; int end= (int)position; int start= (int)(position >>> 32); Expression value= this.expressionStack[this.expressionPtr--]; this.expressionLengthPtr--; MemberValuePair memberValuePair= new MemberValuePair(simpleName, start, end, value); pushOnAstStack(memberValuePair); if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { RecoveredAnnotation recoveredAnnotation= (RecoveredAnnotation)this.currentElement; recoveredAnnotation.setKind(RecoveredAnnotation.NORMAL); } } protected void consumeMemberValuePairs() { // MemberValuePairs ::= MemberValuePairs ',' MemberValuePair concatNodeLists(); } protected void consumeMemberValues() { // MemberValues ::= MemberValues ',' MemberValue concatExpressionLists(); } protected void consumeMethodBody() { // MethodBody ::= NestedMethod '{' BlockStatementsopt '}' this.nestedMethod[this.nestedType]--; } protected void consumeMethodDeclaration(boolean isNotAbstract) { // MethodDeclaration ::= MethodHeader MethodBody // AbstractMethodDeclaration ::= MethodHeader ';' /* this.astStack : modifiers arguments throws statements this.identifierStack : type name this.intStack : dim dim dim ==> this.astStack : MethodDeclaration this.identifierStack : this.intStack : */ int length; if (isNotAbstract) { // pop the position of the { (body of the method) pushed in block decl this.intPtr--; this.intPtr--; } int explicitDeclarations= 0; Statement[] statements= null; if (isNotAbstract) { //statements explicitDeclarations= this.realBlockStack[this.realBlockPtr--]; if (!this.options.ignoreMethodBodies) { if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { System.arraycopy( this.astStack, (this.astPtr-= length) + 1, statements= new Statement[length], 0, length); } } else { length= this.astLengthStack[this.astLengthPtr--]; this.astPtr-= length; } } // now we know that we have a method declaration at the top of the ast stack MethodDeclaration md= (MethodDeclaration)this.astStack[this.astPtr]; md.statements= statements; md.explicitDeclarations= explicitDeclarations; // cannot be done in consumeMethodHeader because we have no idea whether or not there // is a body when we reduce the method header if (!isNotAbstract) { //remember the fact that the method has a semicolon body md.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; } else if (!(this.diet && this.dietInt == 0) && statements == null && !containsComment(md.bodyStart, this.endPosition)) { md.bits|= ASTNode.UndocumentedEmptyBlock; } // store the this.endPosition (position just before the '}') in case there is // a trailing comment behind the end of the method md.bodyEnd= this.endPosition; md.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); } protected void consumeMethodHeader() { // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt // AnnotationMethodHeader ::= AnnotationMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt // RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt // RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims MethodHeaderThrowsClause // retrieve end position of method declarator AbstractMethodDeclaration method= (AbstractMethodDeclaration)this.astStack[this.astPtr]; if (this.currentToken == TokenNameLBRACE) { method.bodyStart= this.scanner.currentPosition; } // recovery if (this.currentElement != null) { // if(method.isAnnotationMethod()) { // method.modifiers |= AccSemicolonBody; // method.declarationSourceEnd = this.scanner.currentPosition-1; // method.bodyEnd = this.scanner.currentPosition-1; // this.currentElement = this.currentElement.parent; // } else if (this.currentToken == TokenNameSEMICOLON /*&& !method.isAnnotationMethod()*/) { method.modifiers|= ExtraCompilerModifiers.AccSemicolonBody; method.declarationSourceEnd= this.scanner.currentPosition - 1; method.bodyEnd= this.scanner.currentPosition - 1; if (this.currentElement.parseTree() == method && this.currentElement.parent != null) { this.currentElement= this.currentElement.parent; } } else if (this.currentToken == TokenNameLBRACE) { if (this.currentElement instanceof RecoveredMethod && ((RecoveredMethod)this.currentElement).methodDeclaration != method) { this.ignoreNextOpeningBrace= true; this.currentElement.bracketBalance++; } } this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeMethodHeaderDefaultValue() { // MethodHeaderDefaultValue ::= DefaultValue MethodDeclaration md= (MethodDeclaration)this.astStack[this.astPtr]; int length= this.expressionLengthStack[this.expressionLengthPtr--]; if (length == 1) { this.intPtr--; // we get rid of the position of the default keyword this.intPtr--; // we get rid of the position of the default keyword if (md.isAnnotationMethod()) { ((AnnotationMethodDeclaration)md).defaultValue= this.expressionStack[this.expressionPtr]; md.modifiers|= ClassFileConstants.AccAnnotationDefault; } this.expressionPtr--; this.recordStringLiterals= true; } if (this.currentElement != null) { if (md.isAnnotationMethod()) { this.currentElement.updateSourceEndIfNecessary(((AnnotationMethodDeclaration)md).defaultValue.sourceEnd); } } } protected void consumeMethodHeaderExtendedDims() { // MethodHeaderExtendedDims ::= Dimsopt // now we update the returnType of the method MethodDeclaration md= (MethodDeclaration)this.astStack[this.astPtr]; int extendedDims= this.intStack[this.intPtr--]; if (md.isAnnotationMethod()) { ((AnnotationMethodDeclaration)md).extendedDimensions= extendedDims; } if (extendedDims != 0) { TypeReference returnType= md.returnType; md.sourceEnd= this.endPosition; int dims= returnType.dimensions() + extendedDims; md.returnType= copyDims(returnType, dims); if (this.currentToken == TokenNameLBRACE) { md.bodyStart= this.endPosition + 1; } // recovery if (this.currentElement != null) { this.lastCheckPoint= md.bodyStart; } } } protected void consumeMethodHeaderName(boolean isAnnotationMethod) { // MethodHeaderName ::= Modifiersopt Type 'Identifier' '(' // AnnotationMethodHeaderName ::= Modifiersopt Type 'Identifier' '(' // RecoveryMethodHeaderName ::= Modifiersopt Type 'Identifier' '(' MethodDeclaration md= null; if (isAnnotationMethod) { md= new AnnotationMethodDeclaration(this.compilationUnit.compilationResult); this.recordStringLiterals= false; } else { md= new MethodDeclaration(this.compilationUnit.compilationResult); } //name md.selector= this.identifierStack[this.identifierPtr]; long selectorSource= this.identifierPositionStack[this.identifierPtr--]; this.identifierLengthPtr--; //type md.returnType= getTypeReference(this.intStack[this.intPtr--]); //modifiers md.declarationSourceStart= this.intStack[this.intPtr--]; md.modifiers= this.intStack[this.intPtr--]; // consume annotations int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, md.annotations= new Annotation[length], 0, length); } // javadoc md.javadoc= this.javadoc; this.javadoc= null; //highlight starts at selector start md.sourceStart= (int)(selectorSource >>> 32); pushOnAstStack(md); md.sourceEnd= this.lParenPos; md.bodyStart= this.lParenPos + 1; this.listLength= 0; // initialize this.listLength before reading parameters/throws // recovery if (this.currentElement != null) { if (this.currentElement instanceof RecoveredType //|| md.modifiers != 0 || (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr) == Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))) { this.lastCheckPoint= md.bodyStart; this.currentElement= this.currentElement.add(md, 0); this.lastIgnoredToken= -1; } else { this.lastCheckPoint= md.sourceStart; this.restartRecovery= true; } } } protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) { // MethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '(' // AnnotationMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '(' // RecoveryMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '(' MethodDeclaration md= null; if (isAnnotationMethod) { md= new AnnotationMethodDeclaration(this.compilationUnit.compilationResult); this.recordStringLiterals= false; } else { md= new MethodDeclaration(this.compilationUnit.compilationResult); } //name md.selector= this.identifierStack[this.identifierPtr]; long selectorSource= this.identifierPositionStack[this.identifierPtr--]; this.identifierLengthPtr--; //type md.returnType= getTypeReference(this.intStack[this.intPtr--]); // consume type parameters int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, md.typeParameters= new TypeParameter[length], 0, length); //modifiers md.declarationSourceStart= this.intStack[this.intPtr--]; md.modifiers= this.intStack[this.intPtr--]; // consume annotations if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, md.annotations= new Annotation[length], 0, length); } // javadoc md.javadoc= this.javadoc; this.javadoc= null; //highlight starts at selector start md.sourceStart= (int)(selectorSource >>> 32); pushOnAstStack(md); md.sourceEnd= this.lParenPos; md.bodyStart= this.lParenPos + 1; this.listLength= 0; // initialize this.listLength before reading parameters/throws // recovery if (this.currentElement != null) { boolean isType; if ((isType= this.currentElement instanceof RecoveredType) //|| md.modifiers != 0 || (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr) == Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))) { if (isType) { ((RecoveredType)this.currentElement).pendingTypeParameters= null; } this.lastCheckPoint= md.bodyStart; this.currentElement= this.currentElement.add(md, 0); this.lastIgnoredToken= -1; } else { this.lastCheckPoint= md.sourceStart; this.restartRecovery= true; } } } protected void consumeMethodHeaderRightParen() { // MethodHeaderParameters ::= FormalParameterListopt ')' int length= this.astLengthStack[this.astLengthPtr--]; this.astPtr-= length; AbstractMethodDeclaration md= (AbstractMethodDeclaration)this.astStack[this.astPtr]; md.sourceEnd= this.rParenPos; //arguments if (length != 0) { System.arraycopy( this.astStack, this.astPtr + 1, md.arguments= new Argument[length], 0, length); } md.bodyStart= this.rParenPos + 1; this.listLength= 0; // reset this.listLength after having read all parameters // recovery if (this.currentElement != null) { this.lastCheckPoint= md.bodyStart; if (this.currentElement.parseTree() == md) return; // might not have been attached yet - in some constructor scenarii if (md.isConstructor()) { if ((length != 0) || (this.currentToken == TokenNameLBRACE) || (this.currentToken == TokenNamethrows)) { this.currentElement= this.currentElement.add(md, 0); this.lastIgnoredToken= -1; } } } } protected void consumeMethodHeaderThrowsClause() { // MethodHeaderThrowsClause ::= 'throws' ClassTypeList int length= this.astLengthStack[this.astLengthPtr--]; this.astPtr-= length; AbstractMethodDeclaration md= (AbstractMethodDeclaration)this.astStack[this.astPtr]; System.arraycopy( this.astStack, this.astPtr + 1, md.thrownExceptions= new TypeReference[length], 0, length); md.sourceEnd= md.thrownExceptions[length - 1].sourceEnd; md.bodyStart= md.thrownExceptions[length - 1].sourceEnd + 1; this.listLength= 0; // reset this.listLength after having read all thrown exceptions // recovery if (this.currentElement != null) { this.lastCheckPoint= md.bodyStart; } } protected void consumeMethodInvocationName() { // MethodInvocation ::= Name '(' ArgumentListopt ')' // when the name is only an identifier...we have a message send to "this" (implicit) MessageSend m= newMessageSend(); m.sourceEnd= this.rParenPos; m.sourceStart= (int)((m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]) >>> 32); m.selector= this.identifierStack[this.identifierPtr--]; if (this.identifierLengthStack[this.identifierLengthPtr] == 1) { m.receiver= ThisReference.implicitThis(); this.identifierLengthPtr--; } else { this.identifierLengthStack[this.identifierLengthPtr]--; m.receiver= getUnspecifiedReference(); m.sourceStart= m.receiver.sourceStart; } pushOnExpressionStack(m); } protected void consumeMethodInvocationNameWithTypeArguments() { // MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')' // when the name is only an identifier...we have a message send to "this" (implicit) MessageSend m= newMessageSendWithTypeArguments(); m.sourceEnd= this.rParenPos; m.sourceStart= (int)((m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]) >>> 32); m.selector= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; // handle type arguments int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments= new TypeReference[length], 0, length); this.intPtr--; m.receiver= getUnspecifiedReference(); m.sourceStart= m.receiver.sourceStart; pushOnExpressionStack(m); } protected void consumeMethodInvocationPrimary() { //optimize the push/pop //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')' MessageSend m= newMessageSend(); m.sourceStart= (int)((m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]) >>> 32); m.selector= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; m.receiver= this.expressionStack[this.expressionPtr]; m.sourceStart= m.receiver.sourceStart; m.sourceEnd= this.rParenPos; this.expressionStack[this.expressionPtr]= m; } protected void consumeMethodInvocationPrimaryWithTypeArguments() { //optimize the push/pop //MethodInvocation ::= Primary '.' TypeArguments 'Identifier' '(' ArgumentListopt ')' MessageSend m= newMessageSendWithTypeArguments(); m.sourceStart= (int)((m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]) >>> 32); m.selector= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; // handle type arguments int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments= new TypeReference[length], 0, length); this.intPtr--; m.receiver= this.expressionStack[this.expressionPtr]; m.sourceStart= m.receiver.sourceStart; m.sourceEnd= this.rParenPos; this.expressionStack[this.expressionPtr]= m; } protected void consumeMethodInvocationSuper() { // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')' MessageSend m= newMessageSend(); m.sourceStart= this.intStack[this.intPtr--]; // start position of the super keyword m.sourceEnd= this.rParenPos; m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]; m.selector= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; m.receiver= new SuperReference(m.sourceStart, this.endPosition); pushOnExpressionStack(m); } protected void consumeMethodInvocationSuperWithTypeArguments() { // MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')' MessageSend m= newMessageSendWithTypeArguments(); this.intPtr--; // start position of the typeArguments m.sourceEnd= this.rParenPos; m.nameSourcePosition= this.identifierPositionStack[this.identifierPtr]; m.selector= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; // handle type arguments int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments= new TypeReference[length], 0, length); m.sourceStart= this.intStack[this.intPtr--]; // start position of the super keyword m.receiver= new SuperReference(m.sourceStart, this.endPosition); pushOnExpressionStack(m); } protected void consumeModifiers() { int savedModifiersSourceStart= this.modifiersSourceStart; checkComment(); // might update modifiers with AccDeprecated pushOnIntStack(this.modifiers); // modifiers if (this.modifiersSourceStart >= savedModifiersSourceStart) { this.modifiersSourceStart= savedModifiersSourceStart; } pushOnIntStack(this.modifiersSourceStart); resetModifiers(); } protected void consumeModifiers2() { this.expressionLengthStack[this.expressionLengthPtr - 1]+= this.expressionLengthStack[this.expressionLengthPtr--]; } protected void consumeNameArrayType() { pushOnGenericsLengthStack(0); // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); } protected void consumeNestedMethod() { // NestedMethod ::= $empty jumpOverMethodBody(); this.nestedMethod[this.nestedType]++; pushOnIntStack(this.scanner.currentPosition); consumeOpenBlock(); } protected void consumeNestedType() { // NestedType ::= $empty int length= this.nestedMethod.length; if (++this.nestedType >= length) { System.arraycopy( this.nestedMethod, 0, this.nestedMethod= new int[length + 30], 0, length); // increase the size of the variablesCounter as well. It has to be consistent with the size of the nestedMethod collection System.arraycopy( this.variablesCounter, 0, this.variablesCounter= new int[length + 30], 0, length); } this.nestedMethod[this.nestedType]= 0; this.variablesCounter[this.nestedType]= 0; } protected void consumeNormalAnnotation() { // NormalAnnotation ::= '@' Name '(' MemberValuePairsopt ')' NormalAnnotation normalAnnotation= null; int oldIndex= this.identifierPtr; TypeReference typeReference= getAnnotationType(); normalAnnotation= new NormalAnnotation(typeReference, this.intStack[this.intPtr--]); int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { System.arraycopy( this.astStack, (this.astPtr-= length) + 1, normalAnnotation.memberValuePairs= new MemberValuePair[length], 0, length); } normalAnnotation.declarationSourceEnd= this.rParenPos; pushOnExpressionStack(normalAnnotation); if (this.currentElement != null) { annotationRecoveryCheckPoint(normalAnnotation.sourceStart, normalAnnotation.declarationSourceEnd); if (this.currentElement instanceof RecoveredAnnotation) { this.currentElement= ((RecoveredAnnotation)this.currentElement).addAnnotation(normalAnnotation, oldIndex); } } if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfAnnotation(normalAnnotation); } this.recordStringLiterals= true; } protected void consumeOneDimLoop() { // OneDimLoop ::= '[' ']' this.dimensions++; } protected void consumeOnlySynchronized() { // OnlySynchronized ::= 'synchronized' pushOnIntStack(this.synchronizedBlockSourceStart); resetModifiers(); this.expressionLengthPtr--; } protected void consumeOnlyTypeArguments() { if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { int length= this.genericsLengthStack[this.genericsLengthPtr]; problemReporter().invalidUsageOfTypeArguments( (TypeReference)this.genericsStack[this.genericsPtr - length + 1], (TypeReference)this.genericsStack[this.genericsPtr]); } } protected void consumeOnlyTypeArgumentsForCastExpression() { // OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments } protected void consumeOpenBlock() { // OpenBlock ::= $empty pushOnIntStack(this.scanner.startPosition); int stackLength= this.realBlockStack.length; if (++this.realBlockPtr >= stackLength) { System.arraycopy( this.realBlockStack, 0, this.realBlockStack= new int[stackLength + StackIncrement], 0, stackLength); } this.realBlockStack[this.realBlockPtr]= 0; } protected void consumePackageComment() { // get possible comment for syntax since 1.5 if (this.options.sourceLevel >= ClassFileConstants.JDK1_5) { checkComment(); resetModifiers(); } } protected void consumePackageDeclaration() { // PackageDeclaration ::= 'package' Name ';' /* build an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt= this.compilationUnit.currentPackage; this.compilationUnit.javadoc= this.javadoc; this.javadoc= null; // flush comments defined prior to import statements impt.declarationEnd= this.endStatementPosition; impt.declarationSourceEnd= flushCommentsDefinedPriorTo(impt.declarationSourceEnd); } protected void consumePackageDeclarationName() { // PackageDeclarationName ::= 'package' Name /* build an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length); System.arraycopy( this.identifierPositionStack, this.identifierPtr--, positions, 0, length); impt= new ImportReference(tokens, positions, true, ClassFileConstants.AccDefault); this.compilationUnit.currentPackage= impt; if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; //this.endPosition is just before the ; impt.declarationSourceStart= this.intStack[this.intPtr--]; // get possible comment source start if (this.javadoc != null) { impt.declarationSourceStart= this.javadoc.sourceStart; } // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumePackageDeclarationNameWithModifiers() { // PackageDeclarationName ::= Modifiers 'package' Name /* build an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length); System.arraycopy( this.identifierPositionStack, this.identifierPtr--, positions, 0, length); int packageModifiersSourceStart= this.intStack[this.intPtr--]; // we don't need the modifiers start int packageModifiers= this.intStack[this.intPtr--]; impt= new ImportReference(tokens, positions, true, packageModifiers); this.compilationUnit.currentPackage= impt; // consume annotations if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { System.arraycopy( this.expressionStack, (this.expressionPtr-= length) + 1, impt.annotations= new Annotation[length], 0, length); impt.declarationSourceStart= packageModifiersSourceStart; this.intPtr--; // we don't need the position of the 'package keyword } else { impt.declarationSourceStart= this.intStack[this.intPtr--]; // get possible comment source start if (this.javadoc != null) { impt.declarationSourceStart= this.javadoc.sourceStart; } } if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumePostfixExpression() { // PostfixExpression ::= Name pushOnExpressionStack(getUnspecifiedReferenceOptimized()); } protected void consumePrimaryNoNewArray() { // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN final Expression parenthesizedExpression= this.expressionStack[this.expressionPtr]; updateSourcePosition(parenthesizedExpression); int numberOfParenthesis= (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; parenthesizedExpression.bits&= ~ASTNode.ParenthesizedMASK; parenthesizedExpression.bits|= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT; } protected void consumePrimaryNoNewArrayArrayType() { // PrimaryNoNewArray ::= Name Dims '.' 'class' this.intPtr--; // remove the class start position pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); pushOnExpressionStack(new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--]))); } protected void consumePrimaryNoNewArrayName() { // PrimaryNoNewArray ::= Name '.' 'class' this.intPtr--; // remove the class start position // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); TypeReference typeReference= getTypeReference(0); pushOnExpressionStack(new ClassLiteralAccess(this.intStack[this.intPtr--], typeReference)); } protected void consumePrimaryNoNewArrayNameSuper() { // PrimaryNoNewArray ::= Name '.' 'super' // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); TypeReference typeReference= getTypeReference(0); pushOnExpressionStack(new QualifiedSuperReference( typeReference, this.intStack[this.intPtr--], this.endPosition)); } protected void consumePrimaryNoNewArrayNameThis() { // PrimaryNoNewArray ::= Name '.' 'this' // handle type arguments pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]); pushOnGenericsLengthStack(0); // handle type arguments TypeReference typeReference= getTypeReference(0); pushOnExpressionStack(new QualifiedThisReference( typeReference, this.intStack[this.intPtr--], this.endPosition)); } protected void consumePrimaryNoNewArrayPrimitiveArrayType() { // PrimaryNoNewArray ::= PrimitiveType Dims '.' 'class' this.intPtr--; // remove the class start position pushOnExpressionStack(new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--]))); } protected void consumePrimaryNoNewArrayPrimitiveType() { // PrimaryNoNewArray ::= PrimitiveType '.' 'class' this.intPtr--; // remove the class start position pushOnExpressionStack(new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(0))); } protected void consumePrimaryNoNewArrayThis() { // PrimaryNoNewArray ::= 'this' pushOnExpressionStack(new ThisReference(this.intStack[this.intPtr--], this.endPosition)); } protected void consumePrimaryNoNewArrayWithName() { // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN pushOnExpressionStack(getUnspecifiedReferenceOptimized()); final Expression parenthesizedExpression= this.expressionStack[this.expressionPtr]; updateSourcePosition(parenthesizedExpression); int numberOfParenthesis= (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT; parenthesizedExpression.bits&= ~ASTNode.ParenthesizedMASK; parenthesizedExpression.bits|= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT; } protected void consumePrimitiveArrayType() { // nothing to do // Will be consume by a getTypeRefence call } protected void consumePrimitiveType() { // Type ::= PrimitiveType pushOnIntStack(0); } protected void consumePushLeftBrace() { pushOnIntStack(this.endPosition); // modifiers } protected void consumePushModifiers() { pushOnIntStack(this.modifiers); // modifiers pushOnIntStack(this.modifiersSourceStart); resetModifiers(); pushOnExpressionStackLengthStack(0); } protected void consumePushModifiersForHeader() { checkComment(); // might update modifiers with AccDeprecated pushOnIntStack(this.modifiers); // modifiers pushOnIntStack(this.modifiersSourceStart); resetModifiers(); pushOnExpressionStackLengthStack(0); } protected void consumePushPosition() { // for source managment purpose // PushPosition ::= $empty pushOnIntStack(this.endPosition); } protected void consumePushRealModifiers() { checkComment(); // might update modifiers with AccDeprecated pushOnIntStack(this.modifiers); // modifiers pushOnIntStack(this.modifiersSourceStart); resetModifiers(); } protected void consumeQualifiedName() { // QualifiedName ::= Name '.' SimpleName /*back from the recursive loop of QualifiedName. Updates identifier length into the length stack*/ this.identifierLengthStack[--this.identifierLengthPtr]++; } protected void consumeRecoveryMethodHeaderName() { // this method is call only inside recovery boolean isAnnotationMethod= false; if (this.currentElement instanceof RecoveredType) { isAnnotationMethod= (((RecoveredType)this.currentElement).typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0; } else { RecoveredType recoveredType= this.currentElement.enclosingType(); if (recoveredType != null) { isAnnotationMethod= (recoveredType.typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0; } } consumeMethodHeaderName(isAnnotationMethod); } protected void consumeRecoveryMethodHeaderNameWithTypeParameters() { // this method is call only inside recovery boolean isAnnotationMethod= false; if (this.currentElement instanceof RecoveredType) { isAnnotationMethod= (((RecoveredType)this.currentElement).typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0; } else { RecoveredType recoveredType= this.currentElement.enclosingType(); if (recoveredType != null) { isAnnotationMethod= (recoveredType.typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0; } } consumeMethodHeaderNameWithTypeParameters(isAnnotationMethod); } protected void consumeReduceImports() { // Consume imports int length; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr-= length; System.arraycopy( this.astStack, this.astPtr + 1, this.compilationUnit.imports= new ImportReference[length], 0, length); } } protected void consumeReferenceType() { pushOnIntStack(0); // handle array type } protected void consumeReferenceType1() { pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--])); } protected void consumeReferenceType2() { pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--])); } protected void consumeReferenceType3() { pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--])); } protected void consumeRestoreDiet() { // RestoreDiet ::= $empty this.dietInt--; } protected void consumeRightParen() { // PushRPAREN ::= ')' pushOnIntStack(this.rParenPos); } // This method is part of an automatic generation : do NOT edit-modify protected void consumeRule(int act) { switch (act) { case 30: if (DEBUG) { System.out.println("Type ::= PrimitiveType");} //$NON-NLS-1$ consumePrimitiveType(); break; case 44: if (DEBUG) { System.out.println("ReferenceType ::= ClassOrInterfaceType");} //$NON-NLS-1$ consumeReferenceType(); break; case 48: if (DEBUG) { System.out.println("ClassOrInterface ::= Name");} //$NON-NLS-1$ consumeClassOrInterfaceName(); break; case 49: if (DEBUG) { System.out.println("ClassOrInterface ::= GenericType DOT Name");} //$NON-NLS-1$ consumeClassOrInterface(); break; case 50: if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface TypeArguments");} //$NON-NLS-1$ consumeGenericType(); break; case 51: if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name");} //$NON-NLS-1$ consumeArrayTypeWithTypeArgumentsName(); break; case 52: if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims");} //$NON-NLS-1$ consumePrimitiveArrayType(); break; case 53: if (DEBUG) { System.out.println("ArrayType ::= Name Dims");} //$NON-NLS-1$ consumeNameArrayType(); break; case 54: if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims");} //$NON-NLS-1$ consumeGenericTypeNameArrayType(); break; case 55: if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims");} //$NON-NLS-1$ consumeGenericTypeArrayType(); break; case 60: if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName");} //$NON-NLS-1$ consumeQualifiedName(); break; case 61: if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit...");} //$NON-NLS-1$ consumeCompilationUnit(); break; case 62: if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration");} //$NON-NLS-1$ consumeInternalCompilationUnit(); break; case 63: if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration...");} //$NON-NLS-1$ consumeInternalCompilationUnit(); break; case 64: if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration...");} //$NON-NLS-1$ consumeInternalCompilationUnitWithTypes(); break; case 65: if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration...");} //$NON-NLS-1$ consumeInternalCompilationUnitWithTypes(); break; case 66: if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations...");} //$NON-NLS-1$ consumeInternalCompilationUnit(); break; case 67: if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations");} //$NON-NLS-1$ consumeInternalCompilationUnitWithTypes(); break; case 68: if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations...");} //$NON-NLS-1$ consumeInternalCompilationUnitWithTypes(); break; case 69: if (DEBUG) { System.out.println("InternalCompilationUnit ::=");} //$NON-NLS-1$ consumeEmptyInternalCompilationUnit(); break; case 70: if (DEBUG) { System.out.println("ReduceImports ::=");} //$NON-NLS-1$ consumeReduceImports(); break; case 71: if (DEBUG) { System.out.println("EnterCompilationUnit ::=");} //$NON-NLS-1$ consumeEnterCompilationUnit(); break; case 87: if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN...");} //$NON-NLS-1$ consumeCatchHeader(); break; case 89: if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations...");} //$NON-NLS-1$ consumeImportDeclarations(); break; case 91: if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");} //$NON-NLS-1$ consumeTypeDeclarations(); break; case 92: if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");} //$NON-NLS-1$ consumePackageDeclaration(); break; case 93: if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package...");} //$NON-NLS-1$ consumePackageDeclarationNameWithModifiers(); break; case 94: if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name");} //$NON-NLS-1$ consumePackageDeclarationName(); break; case 95: if (DEBUG) { System.out.println("PackageComment ::=");} //$NON-NLS-1$ consumePackageComment(); break; case 100: if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=...");} //$NON-NLS-1$ consumeImportDeclaration(); break; case 101: if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name");} //$NON-NLS-1$ consumeSingleTypeImportDeclarationName(); break; case 102: if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=...");} //$NON-NLS-1$ consumeImportDeclaration(); break; case 103: if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT...");} //$NON-NLS-1$ consumeTypeImportOnDemandDeclarationName(); break; case 106: if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON");} //$NON-NLS-1$ consumeEmptyTypeDeclaration(); break; case 110: if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier");} //$NON-NLS-1$ consumeModifiers2(); break; case 122: if (DEBUG) { System.out.println("Modifier ::= Annotation");} //$NON-NLS-1$ consumeAnnotationAsModifier(); break; case 123: if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody");} //$NON-NLS-1$ consumeClassDeclaration(); break; case 124: if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt...");} //$NON-NLS-1$ consumeClassHeader(); break; case 125: if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters");} //$NON-NLS-1$ consumeTypeHeaderNameWithTypeParameters(); break; case 127: if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier");} //$NON-NLS-1$ consumeClassHeaderName1(); break; case 128: if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType");} //$NON-NLS-1$ consumeClassHeaderExtends(); break; case 129: if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");} //$NON-NLS-1$ consumeClassHeaderImplements(); break; case 131: if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA...");} //$NON-NLS-1$ consumeInterfaceTypeList(); break; case 132: if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType");} //$NON-NLS-1$ consumeInterfaceType(); break; case 135: if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations...");} //$NON-NLS-1$ consumeClassBodyDeclarations(); break; case 139: if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod...");} //$NON-NLS-1$ consumeClassBodyDeclaration(); break; case 140: if (DEBUG) { System.out.println("Diet ::=");} //$NON-NLS-1$ consumeDiet(); break; case 141: if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer...");} //$NON-NLS-1$ consumeClassBodyDeclaration(); break; case 142: if (DEBUG) { System.out.println("CreateInitializer ::=");} //$NON-NLS-1$ consumeCreateInitializer(); break; case 149: if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON");} //$NON-NLS-1$ consumeEmptyTypeDeclaration(); break; case 152: if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type...");} //$NON-NLS-1$ consumeFieldDeclaration(); break; case 154: if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA...");} //$NON-NLS-1$ consumeVariableDeclarators(); break; case 157: if (DEBUG) { System.out.println("EnterVariable ::=");} //$NON-NLS-1$ consumeEnterVariable(); break; case 158: if (DEBUG) { System.out.println("ExitVariableWithInitialization ::=");} //$NON-NLS-1$ consumeExitVariableWithInitialization(); break; case 159: if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::=");} //$NON-NLS-1$ consumeExitVariableWithoutInitialization(); break; case 160: if (DEBUG) { System.out.println("ForceNoDiet ::=");} //$NON-NLS-1$ consumeForceNoDiet(); break; case 161: if (DEBUG) { System.out.println("RestoreDiet ::=");} //$NON-NLS-1$ consumeRestoreDiet(); break; case 166: if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody");} //$NON-NLS-1$ // set to true to consume a method with a body consumeMethodDeclaration(true); break; case 167: if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");} //$NON-NLS-1$ // set to false to consume a method without body consumeMethodDeclaration(false); break; case 168: if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt");} //$NON-NLS-1$ consumeMethodHeader(); break; case 169: if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type...");} //$NON-NLS-1$ consumeMethodHeaderNameWithTypeParameters(false); break; case 170: if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");} //$NON-NLS-1$ consumeMethodHeaderName(false); break; case 171: if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN");} //$NON-NLS-1$ consumeMethodHeaderRightParen(); break; case 172: if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt");} //$NON-NLS-1$ consumeMethodHeaderExtendedDims(); break; case 173: if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");} //$NON-NLS-1$ consumeMethodHeaderThrowsClause(); break; case 174: if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName...");} //$NON-NLS-1$ consumeConstructorHeader(); break; case 175: if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters...");} //$NON-NLS-1$ consumeConstructorHeaderNameWithTypeParameters(); break; case 176: if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");} //$NON-NLS-1$ consumeConstructorHeaderName(); break; case 178: if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA...");} //$NON-NLS-1$ consumeFormalParameterList(); break; case 179: if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type...");} //$NON-NLS-1$ consumeFormalParameter(false); break; case 180: if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS...");} //$NON-NLS-1$ consumeFormalParameter(true); break; case 182: if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");} //$NON-NLS-1$ consumeClassTypeList(); break; case 183: if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType");} //$NON-NLS-1$ consumeClassTypeElt(); break; case 184: if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt...");} //$NON-NLS-1$ consumeMethodBody(); break; case 185: if (DEBUG) { System.out.println("NestedMethod ::=");} //$NON-NLS-1$ consumeNestedMethod(); break; case 186: if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block");} //$NON-NLS-1$ consumeStaticInitializer(); break; case 187: if (DEBUG) { System.out.println("StaticOnly ::= static");} //$NON-NLS-1$ consumeStaticOnly(); break; case 188: if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody");} //$NON-NLS-1$ consumeConstructorDeclaration(); break; case 189: if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");} //$NON-NLS-1$ consumeInvalidConstructorDeclaration(); break; case 190: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN...");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(0, THIS_CALL); break; case 191: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(0, THIS_CALL); break; case 192: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN...");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(0, SUPER_CALL); break; case 193: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments...");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(0, SUPER_CALL); break; case 194: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super...");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(1, SUPER_CALL); break; case 195: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT...");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL); break; case 196: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(2, SUPER_CALL); break; case 197: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT...");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL); break; case 198: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this...");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(1, THIS_CALL); break; case 199: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT...");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL); break; case 200: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN");} //$NON-NLS-1$ consumeExplicitConstructorInvocation(2, THIS_CALL); break; case 201: if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT...");} //$NON-NLS-1$ consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL); break; case 202: if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");} //$NON-NLS-1$ consumeInterfaceDeclaration(); break; case 203: if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName...");} //$NON-NLS-1$ consumeInterfaceHeader(); break; case 204: if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1...");} //$NON-NLS-1$ consumeTypeHeaderNameWithTypeParameters(); break; case 206: if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface...");} //$NON-NLS-1$ consumeInterfaceHeaderName1(); break; case 207: if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");} //$NON-NLS-1$ consumeInterfaceHeaderExtends(); break; case 210: if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=...");} //$NON-NLS-1$ consumeInterfaceMemberDeclarations(); break; case 211: if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");} //$NON-NLS-1$ consumeEmptyTypeDeclaration(); break; case 213: if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody");} //$NON-NLS-1$ consumeInvalidMethodDeclaration(); break; case 214: if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader...");} //$NON-NLS-1$ consumeInvalidConstructorDeclaration(true); break; case 215: if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader...");} //$NON-NLS-1$ consumeInvalidConstructorDeclaration(false); break; case 223: if (DEBUG) { System.out.println("PushLeftBrace ::=");} //$NON-NLS-1$ consumePushLeftBrace(); break; case 224: if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE");} //$NON-NLS-1$ consumeEmptyArrayInitializer(); break; case 225: if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace...");} //$NON-NLS-1$ consumeArrayInitializer(); break; case 226: if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace...");} //$NON-NLS-1$ consumeArrayInitializer(); break; case 228: if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA...");} //$NON-NLS-1$ consumeVariableInitializers(); break; case 229: if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");} //$NON-NLS-1$ consumeBlock(); break; case 230: if (DEBUG) { System.out.println("OpenBlock ::=");} //$NON-NLS-1$ consumeOpenBlock(); break; case 232: if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement");} //$NON-NLS-1$ consumeBlockStatements(); break; case 236: if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration");} //$NON-NLS-1$ consumeInvalidInterfaceDeclaration(); break; case 237: if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration");} //$NON-NLS-1$ consumeInvalidAnnotationTypeDeclaration(); break; case 238: if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration");} //$NON-NLS-1$ consumeInvalidEnumDeclaration(); break; case 239: if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=...");} //$NON-NLS-1$ consumeLocalVariableDeclarationStatement(); break; case 240: if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers...");} //$NON-NLS-1$ consumeLocalVariableDeclaration(); break; case 241: if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type...");} //$NON-NLS-1$ consumeLocalVariableDeclaration(); break; case 242: if (DEBUG) { System.out.println("PushModifiers ::=");} //$NON-NLS-1$ consumePushModifiers(); break; case 243: if (DEBUG) { System.out.println("PushModifiersForHeader ::=");} //$NON-NLS-1$ consumePushModifiersForHeader(); break; case 244: if (DEBUG) { System.out.println("PushRealModifiers ::=");} //$NON-NLS-1$ consumePushRealModifiers(); break; case 270: if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON");} //$NON-NLS-1$ consumeEmptyStatement(); break; case 271: if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement");} //$NON-NLS-1$ consumeStatementLabel(); break; case 272: if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON...");} //$NON-NLS-1$ consumeStatementLabel(); break; case 273: if (DEBUG) { System.out.println("Label ::= Identifier");} //$NON-NLS-1$ consumeLabel(); break; case 274: if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");} //$NON-NLS-1$ consumeExpressionStatement(); break; case 283: if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN...");} //$NON-NLS-1$ consumeStatementIfNoElse(); break; case 284: if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN...");} //$NON-NLS-1$ consumeStatementIfWithElse(); break; case 285: if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression...");} //$NON-NLS-1$ consumeStatementIfWithElse(); break; case 286: if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN...");} //$NON-NLS-1$ consumeStatementSwitch(); break; case 287: if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE");} //$NON-NLS-1$ consumeEmptySwitchBlock(); break; case 290: if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements...");} //$NON-NLS-1$ consumeSwitchBlock(); break; case 292: if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements...");} //$NON-NLS-1$ consumeSwitchBlockStatements(); break; case 293: if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");} //$NON-NLS-1$ consumeSwitchBlockStatement(); break; case 295: if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");} //$NON-NLS-1$ consumeSwitchLabels(); break; case 296: if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON");} //$NON-NLS-1$ consumeCaseLabel(); break; case 297: if (DEBUG) { System.out.println("SwitchLabel ::= default COLON");} //$NON-NLS-1$ consumeDefaultLabel(); break; case 298: if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN...");} //$NON-NLS-1$ consumeStatementWhile(); break; case 299: if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression...");} //$NON-NLS-1$ consumeStatementWhile(); break; case 300: if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression...");} //$NON-NLS-1$ consumeStatementDo(); break; case 301: if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON...");} //$NON-NLS-1$ consumeStatementFor(); break; case 302: if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt...");} //$NON-NLS-1$ consumeStatementFor(); break; case 303: if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList");} //$NON-NLS-1$ consumeForInit(); break; case 307: if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList...");} //$NON-NLS-1$ consumeStatementExpressionList(); break; case 308: if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON");} //$NON-NLS-1$ consumeSimpleAssertStatement(); break; case 309: if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression");} //$NON-NLS-1$ consumeAssertStatement(); break; case 310: if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON");} //$NON-NLS-1$ consumeStatementBreak(); break; case 311: if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON");} //$NON-NLS-1$ consumeStatementBreakWithLabel(); break; case 312: if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON");} //$NON-NLS-1$ consumeStatementContinue(); break; case 313: if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");} //$NON-NLS-1$ consumeStatementContinueWithLabel(); break; case 314: if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");} //$NON-NLS-1$ consumeStatementReturn(); break; case 315: if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON");} //$NON-NLS-1$ consumeStatementThrow(); break; case 316: if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN...");} //$NON-NLS-1$ consumeStatementSynchronized(); break; case 317: if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized");} //$NON-NLS-1$ consumeOnlySynchronized(); break; case 318: if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches");} //$NON-NLS-1$ consumeStatementTry(false); break; case 319: if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally");} //$NON-NLS-1$ consumeStatementTry(true); break; case 321: if (DEBUG) { System.out.println("ExitTryBlock ::=");} //$NON-NLS-1$ consumeExitTryBlock(); break; case 323: if (DEBUG) { System.out.println("Catches ::= Catches CatchClause");} //$NON-NLS-1$ consumeCatches(); break; case 324: if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN...");} //$NON-NLS-1$ consumeStatementCatch(); break; case 326: if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN");} //$NON-NLS-1$ consumeLeftParen(); break; case 327: if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN");} //$NON-NLS-1$ consumeRightParen(); break; case 332: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this");} //$NON-NLS-1$ consumePrimaryNoNewArrayThis(); break; case 333: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName...");} //$NON-NLS-1$ consumePrimaryNoNewArray(); break; case 334: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN");} //$NON-NLS-1$ consumePrimaryNoNewArrayWithName(); break; case 337: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this");} //$NON-NLS-1$ consumePrimaryNoNewArrayNameThis(); break; case 338: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super");} //$NON-NLS-1$ consumePrimaryNoNewArrayNameSuper(); break; case 339: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class");} //$NON-NLS-1$ consumePrimaryNoNewArrayName(); break; case 340: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class");} //$NON-NLS-1$ consumePrimaryNoNewArrayArrayType(); break; case 341: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class");} //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveArrayType(); break; case 342: if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");} //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveType(); break; case 345: if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN...");} //$NON-NLS-1$ consumeAllocationHeader(); break; case 346: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new...");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionWithTypeArguments(); break; case 347: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN");} //$NON-NLS-1$ consumeClassInstanceCreationExpression(); break; case 348: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new...");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments(); break; case 349: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new...");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified(); break; case 350: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=...");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified(); break; case 351: if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=...");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments(); break; case 352: if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");} //$NON-NLS-1$ consumeClassInstanceCreationExpressionName(); break; case 353: if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::=");} //$NON-NLS-1$ consumeClassBodyopt(); break; case 355: if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::=");} //$NON-NLS-1$ consumeEnterAnonymousClassBody(false); break; case 356: if (DEBUG) { System.out.println("QualifiedClassBodyopt ::=");} //$NON-NLS-1$ consumeClassBodyopt(); break; case 358: if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::=");} //$NON-NLS-1$ consumeEnterAnonymousClassBody(true); break; case 360: if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression");} //$NON-NLS-1$ consumeArgumentList(); break; case 361: if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType...");} //$NON-NLS-1$ consumeArrayCreationHeader(); break; case 362: if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType...");} //$NON-NLS-1$ consumeArrayCreationHeader(); break; case 363: if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new...");} //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; case 364: if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType");} //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; case 365: if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new...");} //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; case 366: if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new...");} //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; case 368: if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs...");} //$NON-NLS-1$ consumeDimWithOrWithOutExprs(); break; case 370: if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");} //$NON-NLS-1$ consumeDimWithOrWithOutExpr(); break; case 371: if (DEBUG) { System.out.println("Dims ::= DimsLoop");} //$NON-NLS-1$ consumeDims(); break; case 374: if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET");} //$NON-NLS-1$ consumeOneDimLoop(); break; case 375: if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier");} //$NON-NLS-1$ consumeFieldAccess(false); break; case 376: if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier");} //$NON-NLS-1$ consumeFieldAccess(true); break; case 377: if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");} //$NON-NLS-1$ consumeMethodInvocationName(); break; case 378: if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments...");} //$NON-NLS-1$ consumeMethodInvocationNameWithTypeArguments(); break; case 379: if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments...");} //$NON-NLS-1$ consumeMethodInvocationPrimaryWithTypeArguments(); break; case 380: if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN...");} //$NON-NLS-1$ consumeMethodInvocationPrimary(); break; case 381: if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments...");} //$NON-NLS-1$ consumeMethodInvocationSuperWithTypeArguments(); break; case 382: if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN...");} //$NON-NLS-1$ consumeMethodInvocationSuper(); break; case 383: if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");} //$NON-NLS-1$ consumeArrayAccess(true); break; case 384: if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression...");} //$NON-NLS-1$ consumeArrayAccess(false); break; case 385: if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer...");} //$NON-NLS-1$ consumeArrayAccess(false); break; case 387: if (DEBUG) { System.out.println("PostfixExpression ::= Name");} //$NON-NLS-1$ consumePostfixExpression(); break; case 390: if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS, true); break; case 391: if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS, true); break; case 392: if (DEBUG) { System.out.println("PushPosition ::=");} //$NON-NLS-1$ consumePushPosition(); break; case 395: if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; case 396: if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; case 398: if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS, false); break; case 399: if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS, false); break; case 401: if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; case 402: if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; case 404: if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt...");} //$NON-NLS-1$ consumeCastExpressionWithPrimitiveType(); break; case 405: if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name...");} //$NON-NLS-1$ consumeCastExpressionWithGenericsArray(); break; case 406: if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name...");} //$NON-NLS-1$ consumeCastExpressionWithQualifiedGenericsArray(); break; case 407: if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN...");} //$NON-NLS-1$ consumeCastExpressionLL1(); break; case 408: if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN...");} //$NON-NLS-1$ consumeCastExpressionWithNameArray(); break; case 409: if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments");} //$NON-NLS-1$ consumeOnlyTypeArgumentsForCastExpression(); break; case 410: if (DEBUG) { System.out.println("InsideCastExpression ::=");} //$NON-NLS-1$ consumeInsideCastExpression(); break; case 411: if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::=");} //$NON-NLS-1$ consumeInsideCastExpressionLL1(); break; case 412: if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::=");} //$NON-NLS-1$ consumeInsideCastExpressionWithQualifiedGenerics(); break; case 414: if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; case 415: if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; case 416: if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; case 418: if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; case 419: if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; case 421: if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; case 422: if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; case 423: if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; case 425: if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; case 426: if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; case 427: if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; case 428: if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; case 430: if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof");} //$NON-NLS-1$ consumeInstanceOfExpression(); break; case 432: if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL...");} //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; case 433: if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL...");} //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; case 435: if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; case 437: if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; case 439: if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; case 441: if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; case 443: if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; case 445: if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression...");} //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON); break; case 448: if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator...");} //$NON-NLS-1$ consumeAssignment(); break; case 450: if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement");} //$NON-NLS-1$ ignoreExpressionAssignment(); break; case 451: if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(EQUAL); break; case 452: if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(MULTIPLY); break; case 453: if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(DIVIDE); break; case 454: if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(REMAINDER); break; case 455: if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(PLUS); break; case 456: if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(MINUS); break; case 457: if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(LEFT_SHIFT); break; case 458: if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(RIGHT_SHIFT); break; case 459: if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); break; case 460: if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(AND); break; case 461: if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(XOR); break; case 462: if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL");} //$NON-NLS-1$ consumeAssignmentOperator(OR); break; case 466: if (DEBUG) { System.out.println("Expressionopt ::=");} //$NON-NLS-1$ consumeEmptyExpression(); break; case 471: if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::=");} //$NON-NLS-1$ consumeEmptyClassBodyDeclarationsopt(); break; case 472: if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType...");} //$NON-NLS-1$ consumeClassBodyDeclarationsopt(); break; case 473: if (DEBUG) { System.out.println("Modifiersopt ::=");} //$NON-NLS-1$ consumeDefaultModifiers(); break; case 474: if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers");} //$NON-NLS-1$ consumeModifiers(); break; case 475: if (DEBUG) { System.out.println("BlockStatementsopt ::=");} //$NON-NLS-1$ consumeEmptyBlockStatementsopt(); break; case 477: if (DEBUG) { System.out.println("Dimsopt ::=");} //$NON-NLS-1$ consumeEmptyDimsopt(); break; case 479: if (DEBUG) { System.out.println("ArgumentListopt ::=");} //$NON-NLS-1$ consumeEmptyArgumentListopt(); break; case 483: if (DEBUG) { System.out.println("FormalParameterListopt ::=");} //$NON-NLS-1$ consumeFormalParameterListopt(); break; case 487: if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::=");} //$NON-NLS-1$ consumeEmptyInterfaceMemberDeclarationsopt(); break; case 488: if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType...");} //$NON-NLS-1$ consumeInterfaceMemberDeclarationsopt(); break; case 489: if (DEBUG) { System.out.println("NestedType ::=");} //$NON-NLS-1$ consumeNestedType(); break; case 490: if (DEBUG) { System.out.println("ForInitopt ::=");} //$NON-NLS-1$ consumeEmptyForInitopt(); break; case 492: if (DEBUG) { System.out.println("ForUpdateopt ::=");} //$NON-NLS-1$ consumeEmptyForUpdateopt(); break; case 496: if (DEBUG) { System.out.println("Catchesopt ::=");} //$NON-NLS-1$ consumeEmptyCatchesopt(); break; case 498: if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody");} //$NON-NLS-1$ consumeEnumDeclaration(); break; case 499: if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt");} //$NON-NLS-1$ consumeEnumHeader(); break; case 500: if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier");} //$NON-NLS-1$ consumeEnumHeaderName(); break; case 501: if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier...");} //$NON-NLS-1$ consumeEnumHeaderNameWithTypeParameters(); break; case 502: if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE");} //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; case 503: if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt...");} //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; case 504: if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA...");} //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; case 505: if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants...");} //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; case 507: if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant");} //$NON-NLS-1$ consumeEnumConstants(); break; case 508: if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier");} //$NON-NLS-1$ consumeEnumConstantHeaderName(); break; case 509: if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName...");} //$NON-NLS-1$ consumeEnumConstantHeader(); break; case 510: if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet...");} //$NON-NLS-1$ consumeEnumConstantWithClassBody(); break; case 511: if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader");} //$NON-NLS-1$ consumeEnumConstantNoClassBody(); break; case 512: if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN");} //$NON-NLS-1$ consumeArguments(); break; case 513: if (DEBUG) { System.out.println("Argumentsopt ::=");} //$NON-NLS-1$ consumeEmptyArguments(); break; case 515: if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt");} //$NON-NLS-1$ consumeEnumDeclarations(); break; case 516: if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::=");} //$NON-NLS-1$ consumeEmptyEnumDeclarations(); break; case 518: if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader...");} //$NON-NLS-1$ consumeEnhancedForStatement(); break; case 519: if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=...");} //$NON-NLS-1$ consumeEnhancedForStatement(); break; case 520: if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type...");} //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(false); break; case 521: if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers");} //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(true); break; case 522: if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=...");} //$NON-NLS-1$ consumeEnhancedForStatementHeader(); break; case 523: if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=...");} //$NON-NLS-1$ consumeImportDeclaration(); break; case 524: if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name");} //$NON-NLS-1$ consumeSingleStaticImportDeclarationName(); break; case 525: if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=...");} //$NON-NLS-1$ consumeImportDeclaration(); break; case 526: if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static...");} //$NON-NLS-1$ consumeStaticImportOnDemandDeclarationName(); break; case 527: if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1");} //$NON-NLS-1$ consumeTypeArguments(); break; case 528: if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1");} //$NON-NLS-1$ consumeOnlyTypeArguments(); break; case 530: if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA...");} //$NON-NLS-1$ consumeTypeArgumentList1(); break; case 532: if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument");} //$NON-NLS-1$ consumeTypeArgumentList(); break; case 533: if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType");} //$NON-NLS-1$ consumeTypeArgument(); break; case 537: if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER");} //$NON-NLS-1$ consumeReferenceType1(); break; case 538: if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS...");} //$NON-NLS-1$ consumeTypeArgumentReferenceType1(); break; case 540: if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA...");} //$NON-NLS-1$ consumeTypeArgumentList2(); break; case 543: if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT");} //$NON-NLS-1$ consumeReferenceType2(); break; case 544: if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS...");} //$NON-NLS-1$ consumeTypeArgumentReferenceType2(); break; case 546: if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA...");} //$NON-NLS-1$ consumeTypeArgumentList3(); break; case 549: if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT");} //$NON-NLS-1$ consumeReferenceType3(); break; case 550: if (DEBUG) { System.out.println("Wildcard ::= QUESTION");} //$NON-NLS-1$ consumeWildcard(); break; case 551: if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds");} //$NON-NLS-1$ consumeWildcardWithBounds(); break; case 552: if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType");} //$NON-NLS-1$ consumeWildcardBoundsExtends(); break; case 553: if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType");} //$NON-NLS-1$ consumeWildcardBoundsSuper(); break; case 554: if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER");} //$NON-NLS-1$ consumeWildcard1(); break; case 555: if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1");} //$NON-NLS-1$ consumeWildcard1WithBounds(); break; case 556: if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1");} //$NON-NLS-1$ consumeWildcardBounds1Extends(); break; case 557: if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1");} //$NON-NLS-1$ consumeWildcardBounds1Super(); break; case 558: if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT");} //$NON-NLS-1$ consumeWildcard2(); break; case 559: if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2");} //$NON-NLS-1$ consumeWildcard2WithBounds(); break; case 560: if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2");} //$NON-NLS-1$ consumeWildcardBounds2Extends(); break; case 561: if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2");} //$NON-NLS-1$ consumeWildcardBounds2Super(); break; case 562: if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT");} //$NON-NLS-1$ consumeWildcard3(); break; case 563: if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3");} //$NON-NLS-1$ consumeWildcard3WithBounds(); break; case 564: if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3");} //$NON-NLS-1$ consumeWildcardBounds3Extends(); break; case 565: if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3");} //$NON-NLS-1$ consumeWildcardBounds3Super(); break; case 566: if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier");} //$NON-NLS-1$ consumeTypeParameterHeader(); break; case 567: if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1");} //$NON-NLS-1$ consumeTypeParameters(); break; case 569: if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA...");} //$NON-NLS-1$ consumeTypeParameterList(); break; case 571: if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends...");} //$NON-NLS-1$ consumeTypeParameterWithExtends(); break; case 572: if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends...");} //$NON-NLS-1$ consumeTypeParameterWithExtendsAndBounds(); break; case 574: if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList...");} //$NON-NLS-1$ consumeAdditionalBoundList(); break; case 575: if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType");} //$NON-NLS-1$ consumeAdditionalBound(); break; case 577: if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA...");} //$NON-NLS-1$ consumeTypeParameterList1(); break; case 578: if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER");} //$NON-NLS-1$ consumeTypeParameter1(); break; case 579: if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends...");} //$NON-NLS-1$ consumeTypeParameter1WithExtends(); break; case 580: if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends...");} //$NON-NLS-1$ consumeTypeParameter1WithExtendsAndBounds(); break; case 582: if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList...");} //$NON-NLS-1$ consumeAdditionalBoundList1(); break; case 583: if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1");} //$NON-NLS-1$ consumeAdditionalBound1(); break; case 589: if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; case 590: if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; case 593: if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE...");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; case 594: if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition");} //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; case 597: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; case 598: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); break; case 599: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; case 600: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.DIVIDE); break; case 601: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; case 602: if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.REMAINDER); break; case 604: if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; case 605: if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.PLUS); break; case 606: if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; case 607: if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MINUS); break; case 609: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; case 610: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); break; case 611: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; case 612: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); break; case 613: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; case 614: if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; case 616: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; case 617: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS); break; case 618: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; case 619: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER); break; case 620: if (DEBUG) { System.out.println("RelationalExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; case 621: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); break; case 622: if (DEBUG) { System.out.println("RelationalExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; case 623: if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); break; case 625: if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof...");} //$NON-NLS-1$ consumeInstanceOfExpressionWithName(); break; case 626: if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=...");} //$NON-NLS-1$ consumeInstanceOfExpression(); break; case 628: if (DEBUG) { System.out.println("EqualityExpression_NotName ::=...");} //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; case 629: if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL...");} //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); break; case 630: if (DEBUG) { System.out.println("EqualityExpression_NotName ::=...");} //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; case 631: if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL...");} //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); break; case 633: if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; case 634: if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND); break; case 636: if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; case 637: if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.XOR); break; case 639: if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; case 640: if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR); break; case 642: if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; case 643: if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND_AND); break; case 645: if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=...");} //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; case 646: if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR...");} //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR_OR); break; case 648: if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=...");} //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON); break; case 649: if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION...");} //$NON-NLS-1$ consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON); break; case 653: if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT...");} //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName(); break; case 654: if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT...");} //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters(); break; case 655: if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT...");} //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters(); break; case 656: if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT...");} //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName(); break; case 657: if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=...");} //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeader(); break; case 658: if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=...");} //$NON-NLS-1$ consumeAnnotationTypeDeclaration(); break; case 660: if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::=");} //$NON-NLS-1$ consumeEmptyAnnotationTypeMemberDeclarationsopt(); break; case 661: if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType...");} //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarationsopt(); break; case 663: if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=...");} //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarations(); break; case 664: if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt...");} //$NON-NLS-1$ consumeMethodHeaderNameWithTypeParameters(true); break; case 665: if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type...");} //$NON-NLS-1$ consumeMethodHeaderName(true); break; case 666: if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::=");} //$NON-NLS-1$ consumeEmptyMethodHeaderDefaultValue(); break; case 667: if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue");} //$NON-NLS-1$ consumeMethodHeaderDefaultValue(); break; case 668: if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName...");} //$NON-NLS-1$ consumeMethodHeader(); break; case 669: if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=...");} //$NON-NLS-1$ consumeAnnotationTypeMemberDeclaration(); break; case 677: if (DEBUG) { System.out.println("AnnotationName ::= AT Name");} //$NON-NLS-1$ consumeAnnotationName(); break; case 678: if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN...");} //$NON-NLS-1$ consumeNormalAnnotation(); break; case 679: if (DEBUG) { System.out.println("MemberValuePairsopt ::=");} //$NON-NLS-1$ consumeEmptyMemberValuePairsopt(); break; case 682: if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA...");} //$NON-NLS-1$ consumeMemberValuePairs(); break; case 683: if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue...");} //$NON-NLS-1$ consumeMemberValuePair(); break; case 684: if (DEBUG) { System.out.println("EnterMemberValue ::=");} //$NON-NLS-1$ consumeEnterMemberValue(); break; case 685: if (DEBUG) { System.out.println("ExitMemberValue ::=");} //$NON-NLS-1$ consumeExitMemberValue(); break; case 687: if (DEBUG) { System.out.println("MemberValue ::= Name");} //$NON-NLS-1$ consumeMemberValueAsName(); break; case 690: if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=...");} //$NON-NLS-1$ consumeMemberValueArrayInitializer(); break; case 691: if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=...");} //$NON-NLS-1$ consumeMemberValueArrayInitializer(); break; case 692: if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=...");} //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer(); break; case 693: if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=...");} //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer(); break; case 694: if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::=");} //$NON-NLS-1$ consumeEnterMemberValueArrayInitializer(); break; case 696: if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue");} //$NON-NLS-1$ consumeMemberValues(); break; case 697: if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName");} //$NON-NLS-1$ consumeMarkerAnnotation(); break; case 698: if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue");} //$NON-NLS-1$ consumeSingleMemberAnnotationMemberValue(); break; case 699: if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN...");} //$NON-NLS-1$ consumeSingleMemberAnnotation(); break; case 700: if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters");} //$NON-NLS-1$ consumeRecoveryMethodHeaderNameWithTypeParameters(); break; case 701: if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type...");} //$NON-NLS-1$ consumeRecoveryMethodHeaderName(); break; case 702: if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName...");} //$NON-NLS-1$ consumeMethodHeader(); break; case 703: if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName...");} //$NON-NLS-1$ consumeMethodHeader(); break; } } protected void consumeSimpleAssertStatement() { // AssertStatement ::= 'assert' Expression ';' this.expressionLengthPtr--; pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--])); } protected void consumeSingleMemberAnnotation() { // SingleMemberAnnotation ::= '@' Name '(' MemberValue ')' SingleMemberAnnotation singleMemberAnnotation= null; int oldIndex= this.identifierPtr; TypeReference typeReference= getAnnotationType(); singleMemberAnnotation= new SingleMemberAnnotation(typeReference, this.intStack[this.intPtr--]); singleMemberAnnotation.memberValue= this.expressionStack[this.expressionPtr--]; this.expressionLengthPtr--; singleMemberAnnotation.declarationSourceEnd= this.rParenPos; pushOnExpressionStack(singleMemberAnnotation); if (this.currentElement != null) { annotationRecoveryCheckPoint(singleMemberAnnotation.sourceStart, singleMemberAnnotation.declarationSourceEnd); if (this.currentElement instanceof RecoveredAnnotation) { this.currentElement= ((RecoveredAnnotation)this.currentElement).addAnnotation(singleMemberAnnotation, oldIndex); } } if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { problemReporter().invalidUsageOfAnnotation(singleMemberAnnotation); } this.recordStringLiterals= true; } protected void consumeSingleMemberAnnotationMemberValue() { // this rule is used for syntax recovery only if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { RecoveredAnnotation recoveredAnnotation= (RecoveredAnnotation)this.currentElement; recoveredAnnotation.setKind(RecoveredAnnotation.SINGLE_MEMBER); } } protected void consumeSingleStaticImportDeclarationName() { // SingleTypeImportDeclarationName ::= 'import' 'static' Name /* push an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); pushOnAstStack(impt= new ImportReference(tokens, positions, false, ClassFileConstants.AccStatic)); this.modifiers= ClassFileConstants.AccDefault; this.modifiersSourceStart= -1; // <-- see comment into modifiersFlag(int) if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; //this.endPosition is just before the ; impt.declarationSourceStart= this.intStack[this.intPtr--]; if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { impt.modifiers= ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference problemReporter().invalidUsageOfStaticImports(impt); } // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.currentElement= this.currentElement.add(impt, 0); this.lastIgnoredToken= -1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeSingleTypeImportDeclarationName() { // SingleTypeImportDeclarationName ::= 'import' Name /* push an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); pushOnAstStack(impt= new ImportReference(tokens, positions, false, ClassFileConstants.AccDefault)); if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; //this.endPosition is just before the ; impt.declarationSourceStart= this.intStack[this.intPtr--]; // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.currentElement= this.currentElement.add(impt, 0); this.lastIgnoredToken= -1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeStatementBreak() { // BreakStatement ::= 'break' ';' // break pushs a position on this.intStack in case there is no label pushOnAstStack(new BreakStatement(null, this.intStack[this.intPtr--], this.endStatementPosition)); if (this.pendingRecoveredType != null) { // Used only in statements recovery. // This is not a real break statement but a placeholder for an existing local type. // The break statement must be replace by the local type. if (this.pendingRecoveredType.allocation == null && this.endPosition <= this.pendingRecoveredType.declarationSourceEnd) { this.astStack[this.astPtr]= this.pendingRecoveredType; this.pendingRecoveredType= null; return; } this.pendingRecoveredType= null; } } protected void consumeStatementBreakWithLabel() { // BreakStatement ::= 'break' Identifier ';' // break pushs a position on this.intStack in case there is no label pushOnAstStack(new BreakStatement( this.identifierStack[this.identifierPtr--], this.intStack[this.intPtr--], this.endStatementPosition)); this.identifierLengthPtr--; } protected void consumeStatementCatch() { // CatchClause ::= 'catch' '(' FormalParameter ')' Block //catch are stored directly into the Try //has they always comes two by two.... //we remove one entry from the astlengthPtr. //The construction of the try statement must //then fetch the catches using 2*i and 2*i + 1 this.astLengthPtr--; this.listLength= 0; // reset formalParameter counter (incremented for catch variable) } protected void consumeStatementContinue() { // ContinueStatement ::= 'continue' ';' // continue pushs a position on this.intStack in case there is no label pushOnAstStack(new ContinueStatement( null, this.intStack[this.intPtr--], this.endStatementPosition)); } protected void consumeStatementContinueWithLabel() { // ContinueStatement ::= 'continue' Identifier ';' // continue pushs a position on this.intStack in case there is no label pushOnAstStack(new ContinueStatement( this.identifierStack[this.identifierPtr--], this.intStack[this.intPtr--], this.endStatementPosition)); this.identifierLengthPtr--; } protected void consumeStatementDo() { // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';' //the 'while' pushes a value on this.intStack that we need to remove this.intPtr--; Statement statement= (Statement)this.astStack[this.astPtr]; this.expressionLengthPtr--; this.astStack[this.astPtr]= new DoStatement( this.expressionStack[this.expressionPtr--], statement, this.intStack[this.intPtr--], this.endStatementPosition); } protected void consumeStatementExpressionList() { // StatementExpressionList ::= StatementExpressionList ',' StatementExpression concatExpressionLists(); } protected void consumeStatementFor() { // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf int length; Expression cond= null; Statement[] inits, updates; boolean scope= true; //statements this.astLengthPtr--; Statement statement= (Statement)this.astStack[this.astPtr--]; //updates are on the expresion stack if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) == 0) { updates= null; } else { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, updates= new Statement[length], 0, length); } if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) cond= this.expressionStack[this.expressionPtr--]; //inits may be on two different stacks if ((length= this.astLengthStack[this.astLengthPtr--]) == 0) { inits= null; scope= false; } else { if (length == -1) { //on this.expressionStack scope= false; length= this.expressionLengthStack[this.expressionLengthPtr--]; this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, inits= new Statement[length], 0, length); } else { //on this.astStack this.astPtr-= length; System.arraycopy( this.astStack, this.astPtr + 1, inits= new Statement[length], 0, length); } } pushOnAstStack(new ForStatement( inits, cond, updates, statement, scope, this.intStack[this.intPtr--], this.endStatementPosition)); } protected void consumeStatementIfNoElse() { // IfThenStatement ::= 'if' '(' Expression ')' Statement //optimize the push/pop this.expressionLengthPtr--; Statement thenStatement= (Statement)this.astStack[this.astPtr]; this.astStack[this.astPtr]= new IfStatement( this.expressionStack[this.expressionPtr--], thenStatement, this.intStack[this.intPtr--], this.endStatementPosition); } protected void consumeStatementIfWithElse() { // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf this.expressionLengthPtr--; // optimized {..., Then, Else } ==> {..., If } this.astLengthPtr--; //optimize the push/pop this.astStack[--this.astPtr]= new IfStatement( this.expressionStack[this.expressionPtr--], (Statement)this.astStack[this.astPtr], (Statement)this.astStack[this.astPtr + 1], this.intStack[this.intPtr--], this.endStatementPosition); } protected void consumeStatementLabel() { // LabeledStatement ::= 'Identifier' ':' Statement // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf //optimize push/pop Statement statement= (Statement)this.astStack[this.astPtr]; this.astStack[this.astPtr]= new LabeledStatement( this.identifierStack[this.identifierPtr], statement, this.identifierPositionStack[this.identifierPtr--], this.endStatementPosition); this.identifierLengthPtr--; } protected void consumeStatementReturn() { // ReturnStatement ::= 'return' Expressionopt ';' // return pushs a position on this.intStack in case there is no expression if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) { pushOnAstStack(new ReturnStatement( this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--], this.endStatementPosition)); } else { pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endStatementPosition)); } } protected void consumeStatementSwitch() { // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock //OpenBlock just makes the semantic action blockStart() //the block is inlined but a scope need to be created //if some declaration occurs. int length; SwitchStatement switchStatement= new SwitchStatement(); this.expressionLengthPtr--; switchStatement.expression= this.expressionStack[this.expressionPtr--]; if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr-= length; System.arraycopy( this.astStack, this.astPtr + 1, switchStatement.statements= new Statement[length], 0, length); } switchStatement.explicitDeclarations= this.realBlockStack[this.realBlockPtr--]; pushOnAstStack(switchStatement); switchStatement.blockStart= this.intStack[this.intPtr--]; switchStatement.sourceStart= this.intStack[this.intPtr--]; switchStatement.sourceEnd= this.endStatementPosition; if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) { switchStatement.bits|= ASTNode.UndocumentedEmptyBlock; } } protected void consumeStatementSynchronized() { // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block //optimize the push/pop if (this.astLengthStack[this.astLengthPtr] == 0) { this.astLengthStack[this.astLengthPtr]= 1; this.expressionLengthPtr--; this.astStack[++this.astPtr]= new SynchronizedStatement( this.expressionStack[this.expressionPtr--], null, this.intStack[this.intPtr--], this.endStatementPosition); } else { this.expressionLengthPtr--; this.astStack[this.astPtr]= new SynchronizedStatement( this.expressionStack[this.expressionPtr--], (Block)this.astStack[this.astPtr], this.intStack[this.intPtr--], this.endStatementPosition); } resetModifiers(); } protected void consumeStatementThrow() { // ThrowStatement ::= 'throw' Expression ';' this.expressionLengthPtr--; pushOnAstStack(new ThrowStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--], this.endStatementPosition)); } protected void consumeStatementTry(boolean withFinally) { //TryStatement ::= 'try' Block Catches //TryStatement ::= 'try' Block Catchesopt Finally int length; TryStatement tryStmt= new TryStatement(); //finally if (withFinally) { this.astLengthPtr--; tryStmt.finallyBlock= (Block)this.astStack[this.astPtr--]; } //catches are handle by two <argument-block> [see statementCatch] if ((length= this.astLengthStack[this.astLengthPtr--]) != 0) { if (length == 1) { tryStmt.catchBlocks= new Block[] { (Block)this.astStack[this.astPtr--] }; tryStmt.catchArguments= new Argument[] { (Argument)this.astStack[this.astPtr--] }; } else { Block[] bks= (tryStmt.catchBlocks= new Block[length]); Argument[] args= (tryStmt.catchArguments= new Argument[length]); while (length-- > 0) { bks[length]= (Block)this.astStack[this.astPtr--]; args[length]= (Argument)this.astStack[this.astPtr--]; } } } //try this.astLengthPtr--; tryStmt.tryBlock= (Block)this.astStack[this.astPtr--]; //positions tryStmt.sourceEnd= this.endStatementPosition; tryStmt.sourceStart= this.intStack[this.intPtr--]; pushOnAstStack(tryStmt); } protected void consumeStatementWhile() { // WhileStatement ::= 'while' '(' Expression ')' Statement // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf this.expressionLengthPtr--; Statement statement= (Statement)this.astStack[this.astPtr]; this.astStack[this.astPtr]= new WhileStatement( this.expressionStack[this.expressionPtr--], statement, this.intStack[this.intPtr--], this.endStatementPosition); } protected void consumeStaticImportOnDemandDeclarationName() { // TypeImportOnDemandDeclarationName ::= 'import' 'static' Name '.' '*' /* push an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); pushOnAstStack(impt= new ImportReference(tokens, positions, true, ClassFileConstants.AccStatic)); this.modifiers= ClassFileConstants.AccDefault; this.modifiersSourceStart= -1; // <-- see comment into modifiersFlag(int) if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; //this.endPosition is just before the ; impt.declarationSourceStart= this.intStack[this.intPtr--]; if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { impt.modifiers= ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference problemReporter().invalidUsageOfStaticImports(impt); } // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.currentElement= this.currentElement.add(impt, 0); this.lastIgnoredToken= -1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeStaticInitializer() { // StaticInitializer ::= StaticOnly Block //push an Initializer //optimize the push/pop Block block= (Block)this.astStack[this.astPtr]; if (this.diet) block.bits&= ~ASTNode.UndocumentedEmptyBlock; // clear bit set since was diet Initializer initializer= new Initializer(block, ClassFileConstants.AccStatic); this.astStack[this.astPtr]= initializer; initializer.sourceEnd= this.endStatementPosition; initializer.declarationSourceEnd= flushCommentsDefinedPriorTo(this.endStatementPosition); this.nestedMethod[this.nestedType]--; initializer.declarationSourceStart= this.intStack[this.intPtr--]; initializer.bodyStart= this.intStack[this.intPtr--]; initializer.bodyEnd= this.endPosition; // doc comment initializer.javadoc= this.javadoc; this.javadoc= null; // recovery if (this.currentElement != null) { this.lastCheckPoint= initializer.declarationSourceEnd; this.currentElement= this.currentElement.add(initializer, 0); this.lastIgnoredToken= -1; } } protected void consumeStaticOnly() { // StaticOnly ::= 'static' int savedModifiersSourceStart= this.modifiersSourceStart; checkComment(); // might update declaration source start if (this.modifiersSourceStart >= savedModifiersSourceStart) { this.modifiersSourceStart= savedModifiersSourceStart; } pushOnIntStack(this.scanner.currentPosition); pushOnIntStack(this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition); jumpOverMethodBody(); this.nestedMethod[this.nestedType]++; resetModifiers(); this.expressionLengthPtr--; // remove the 0 pushed in consumeToken() for the static modifier // recovery if (this.currentElement != null) { this.recoveredStaticInitializerStart= this.intStack[this.intPtr]; // remember start position only for static initializers } } protected void consumeSwitchBlock() { // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' concatNodeLists(); } protected void consumeSwitchBlockStatement() { // SwitchBlockStatement ::= SwitchLabels BlockStatements concatNodeLists(); } protected void consumeSwitchBlockStatements() { // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement concatNodeLists(); } protected void consumeSwitchLabels() { // SwitchLabels ::= SwitchLabels SwitchLabel optimizedConcatNodeLists(); } protected void consumeToken(int type) { /* remember the last consumed value */ /* try to minimize the number of build values */ // // clear the commentPtr of the scanner in case we read something different from a modifier // switch(type) { // case TokenNameabstract : // case TokenNamestrictfp : // case TokenNamefinal : // case TokenNamenative : // case TokenNameprivate : // case TokenNameprotected : // case TokenNamepublic : // case TokenNametransient : // case TokenNamevolatile : // case TokenNamestatic : // case TokenNamesynchronized : // break; // default: // this.scanner.commentPtr = -1; // } //System.out.println(this.scanner.toStringAction(type)); switch (type) { case TokenNameIdentifier: pushIdentifier(); if (this.scanner.useAssertAsAnIndentifier && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { long positions= this.identifierPositionStack[this.identifierPtr]; if (!this.statementRecoveryActivated) problemReporter().useAssertAsAnIdentifier((int)(positions >>> 32), (int)positions); } if (this.scanner.useEnumAsAnIndentifier && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { long positions= this.identifierPositionStack[this.identifierPtr]; if (!this.statementRecoveryActivated) problemReporter().useEnumAsAnIdentifier((int)(positions >>> 32), (int)positions); } break; case TokenNameinterface: //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too.... pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNameabstract: checkAndSetModifiers(ClassFileConstants.AccAbstract); pushOnExpressionStackLengthStack(0); break; case TokenNamestrictfp: checkAndSetModifiers(ClassFileConstants.AccStrictfp); pushOnExpressionStackLengthStack(0); break; case TokenNamefinal: checkAndSetModifiers(ClassFileConstants.AccFinal); pushOnExpressionStackLengthStack(0); break; case TokenNamenative: checkAndSetModifiers(ClassFileConstants.AccNative); pushOnExpressionStackLengthStack(0); break; case TokenNameprivate: checkAndSetModifiers(ClassFileConstants.AccPrivate); pushOnExpressionStackLengthStack(0); break; case TokenNameprotected: checkAndSetModifiers(ClassFileConstants.AccProtected); pushOnExpressionStackLengthStack(0); break; case TokenNamepublic: checkAndSetModifiers(ClassFileConstants.AccPublic); pushOnExpressionStackLengthStack(0); break; case TokenNametransient: checkAndSetModifiers(ClassFileConstants.AccTransient); pushOnExpressionStackLengthStack(0); break; case TokenNamevolatile: checkAndSetModifiers(ClassFileConstants.AccVolatile); pushOnExpressionStackLengthStack(0); break; case TokenNamestatic: checkAndSetModifiers(ClassFileConstants.AccStatic); pushOnExpressionStackLengthStack(0); break; case TokenNamesynchronized: this.synchronizedBlockSourceStart= this.scanner.startPosition; checkAndSetModifiers(ClassFileConstants.AccSynchronized); pushOnExpressionStackLengthStack(0); break; //============================== case TokenNamevoid: pushIdentifier(-T_void); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; //push a default dimension while void is not part of the primitive //declaration baseType and so takes the place of a type without getting into //regular type parsing that generates a dimension on this.intStack case TokenNameboolean: pushIdentifier(-T_boolean); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamebyte: pushIdentifier(-T_byte); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamechar: pushIdentifier(-T_char); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamedouble: pushIdentifier(-T_double); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamefloat: pushIdentifier(-T_float); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNameint: pushIdentifier(-T_int); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamelong: pushIdentifier(-T_long); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNameshort: pushIdentifier(-T_short); pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; //============================== case TokenNameIntegerLiteral: pushOnExpressionStack(new IntLiteral( this.scanner.getCurrentTokenSource(), this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNameLongLiteral: pushOnExpressionStack(new LongLiteral( this.scanner.getCurrentTokenSource(), this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNameFloatingPointLiteral: pushOnExpressionStack(new FloatLiteral( this.scanner.getCurrentTokenSource(), this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNameDoubleLiteral: pushOnExpressionStack(new DoubleLiteral( this.scanner.getCurrentTokenSource(), this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNameCharacterLiteral: pushOnExpressionStack(new CharLiteral( this.scanner.getCurrentTokenSource(), this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNameStringLiteral: StringLiteral stringLiteral; if (this.recordStringLiterals && this.checkExternalizeStrings && this.lastPosistion < this.scanner.currentPosition && !this.statementRecoveryActivated) { stringLiteral= createStringLiteral( this.scanner.getCurrentTokenSourceString(), this.scanner.startPosition, this.scanner.currentPosition - 1, Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr)); this.compilationUnit.recordStringLiteral(stringLiteral, this.currentElement != null); } else { stringLiteral= createStringLiteral( this.scanner.getCurrentTokenSourceString(), this.scanner.startPosition, this.scanner.currentPosition - 1, 0); } pushOnExpressionStack(stringLiteral); break; case TokenNamefalse: pushOnExpressionStack(new FalseLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNametrue: pushOnExpressionStack(new TrueLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); break; case TokenNamenull: pushOnExpressionStack(new NullLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1)); break; //============================ case TokenNamesuper: case TokenNamethis: this.endPosition= this.scanner.currentPosition - 1; pushOnIntStack(this.scanner.startPosition); break; case TokenNameassert: case TokenNameimport: case TokenNamepackage: case TokenNamethrow: case TokenNamedo: case TokenNameif: case TokenNamefor: case TokenNameswitch: case TokenNametry: case TokenNamewhile: case TokenNamebreak: case TokenNamecontinue: case TokenNamereturn: case TokenNamecase: pushOnIntStack(this.scanner.startPosition); break; case TokenNamenew: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954 resetModifiers(); pushOnIntStack(this.scanner.startPosition); break; case TokenNameclass: pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNameenum: pushOnIntStack(this.scanner.currentPosition - 1); pushOnIntStack(this.scanner.startPosition); break; case TokenNamedefault: pushOnIntStack(this.scanner.startPosition); pushOnIntStack(this.scanner.currentPosition - 1); break; //let extra semantic action decide when to push case TokenNameRBRACKET: this.endPosition= this.scanner.startPosition; this.endStatementPosition= this.scanner.currentPosition - 1; break; case TokenNameLBRACE: this.endStatementPosition= this.scanner.currentPosition - 1; //$FALL-THROUGH$ case TokenNamePLUS: case TokenNameMINUS: case TokenNameNOT: case TokenNameTWIDDLE: this.endPosition= this.scanner.startPosition; break; case TokenNamePLUS_PLUS: case TokenNameMINUS_MINUS: this.endPosition= this.scanner.startPosition; this.endStatementPosition= this.scanner.currentPosition - 1; break; case TokenNameRBRACE: case TokenNameSEMICOLON: this.endStatementPosition= this.scanner.currentPosition - 1; this.endPosition= this.scanner.startPosition - 1; //the item is not part of the potential futur expression/statement break; case TokenNameRPAREN: // in order to handle ( expression) ////// (cast)expression///// foo(x) this.rParenPos= this.scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101 break; case TokenNameLPAREN: this.lParenPos= this.scanner.startPosition; break; case TokenNameAT: pushOnIntStack(this.scanner.startPosition); break; case TokenNameQUESTION: pushOnIntStack(this.scanner.startPosition); pushOnIntStack(this.scanner.currentPosition - 1); break; case TokenNameLESS: pushOnIntStack(this.scanner.startPosition); break; case TokenNameELLIPSIS: pushOnIntStack(this.scanner.currentPosition - 1); break; case TokenNameEQUAL: if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) { RecoveredAnnotation recoveredAnnotation= (RecoveredAnnotation)this.currentElement; if (recoveredAnnotation.memberValuPairEqualEnd == -1) { recoveredAnnotation.memberValuPairEqualEnd= this.scanner.currentPosition - 1; } } break; // case TokenNameCOMMA : // case TokenNameCOLON : // case TokenNameLBRACKET : // case TokenNameDOT : // case TokenNameERROR : // case TokenNameEOF : // case TokenNamecase : // case TokenNamecatch : // case TokenNameelse : // case TokenNameextends : // case TokenNamefinally : // case TokenNameimplements : // case TokenNamethrows : // case TokenNameinstanceof : // case TokenNameEQUAL_EQUAL : // case TokenNameLESS_EQUAL : // case TokenNameGREATER_EQUAL : // case TokenNameNOT_EQUAL : // case TokenNameLEFT_SHIFT : // case TokenNameRIGHT_SHIFT : // case TokenNameUNSIGNED_RIGHT_SHIFT : // case TokenNamePLUS_EQUAL : // case TokenNameMINUS_EQUAL : // case TokenNameMULTIPLY_EQUAL : // case TokenNameDIVIDE_EQUAL : // case TokenNameAND_EQUAL : // case TokenNameOR_EQUAL : // case TokenNameXOR_EQUAL : // case TokenNameREMAINDER_EQUAL : // case TokenNameLEFT_SHIFT_EQUAL : // case TokenNameRIGHT_SHIFT_EQUAL : // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // case TokenNameOR_OR : // case TokenNameAND_AND : // case TokenNameREMAINDER : // case TokenNameXOR : // case TokenNameAND : // case TokenNameMULTIPLY : // case TokenNameOR : // case TokenNameDIVIDE : // case TokenNameGREATER : } } protected void consumeTypeArgument() { pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--])); } protected void consumeTypeArgumentList() { concatGenericsLists(); } protected void consumeTypeArgumentList1() { concatGenericsLists(); } protected void consumeTypeArgumentList2() { concatGenericsLists(); } protected void consumeTypeArgumentList3() { concatGenericsLists(); } protected void consumeTypeArgumentReferenceType1() { concatGenericsLists(); pushOnGenericsStack(getTypeReference(0)); this.intPtr--; } protected void consumeTypeArgumentReferenceType2() { concatGenericsLists(); pushOnGenericsStack(getTypeReference(0)); this.intPtr--; } protected void consumeTypeArguments() { concatGenericsLists(); this.intPtr--; if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { int length= this.genericsLengthStack[this.genericsLengthPtr]; problemReporter().invalidUsageOfTypeArguments( (TypeReference)this.genericsStack[this.genericsPtr - length + 1], (TypeReference)this.genericsStack[this.genericsPtr]); } } protected void consumeTypeDeclarations() { // TypeDeclarations ::= TypeDeclarations TypeDeclaration concatNodeLists(); } protected void consumeTypeHeaderNameWithTypeParameters() { // ClassHeaderName ::= ClassHeaderName1 TypeParameters // InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; // consume type parameters int length= this.genericsLengthStack[this.genericsLengthPtr--]; this.genericsPtr-= length; System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeDecl.typeParameters= new TypeParameter[length], 0, length); typeDecl.bodyStart= typeDecl.typeParameters[length - 1].declarationSourceEnd + 1; this.listTypeParameterLength= 0; if (this.currentElement != null) { // is recovering if (this.currentElement instanceof RecoveredType) { RecoveredType recoveredType= (RecoveredType)this.currentElement; recoveredType.pendingTypeParameters= null; this.lastCheckPoint= typeDecl.bodyStart; } else { this.lastCheckPoint= typeDecl.bodyStart; this.currentElement= this.currentElement.add(typeDecl, 0); this.lastIgnoredToken= -1; } } } protected void consumeTypeImportOnDemandDeclarationName() { // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' /* push an ImportRef build from the last name stored in the identifier stack. */ ImportReference impt; int length; char[][] tokens= new char[length= this.identifierLengthStack[this.identifierLengthPtr--]][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); pushOnAstStack(impt= new ImportReference(tokens, positions, true, ClassFileConstants.AccDefault)); if (this.currentToken == TokenNameSEMICOLON) { impt.declarationSourceEnd= this.scanner.currentPosition - 1; } else { impt.declarationSourceEnd= impt.sourceEnd; } impt.declarationEnd= impt.declarationSourceEnd; //this.endPosition is just before the ; impt.declarationSourceStart= this.intStack[this.intPtr--]; // recovery if (this.currentElement != null) { this.lastCheckPoint= impt.declarationSourceEnd + 1; this.currentElement= this.currentElement.add(impt, 0); this.lastIgnoredToken= -1; this.restartRecovery= true; // used to avoid branching back into the regular automaton } } protected void consumeTypeParameter1() { // nothing to do } protected void consumeTypeParameter1WithExtends() { //TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType1 TypeReference superType= (TypeReference)this.genericsStack[this.genericsPtr--]; this.genericsLengthPtr--; TypeParameter typeParameter= (TypeParameter)this.genericsStack[this.genericsPtr]; typeParameter.declarationSourceEnd= superType.sourceEnd; typeParameter.type= superType; superType.bits|= ASTNode.IsSuperType; this.genericsStack[this.genericsPtr]= typeParameter; } protected void consumeTypeParameter1WithExtendsAndBounds() { //TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList1 int additionalBoundsLength= this.genericsLengthStack[this.genericsLengthPtr--]; TypeReference[] bounds= new TypeReference[additionalBoundsLength]; this.genericsPtr-= additionalBoundsLength; System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 0, additionalBoundsLength); TypeReference superType= getTypeReference(this.intStack[this.intPtr--]); TypeParameter typeParameter= (TypeParameter)this.genericsStack[this.genericsPtr]; typeParameter.declarationSourceEnd= bounds[additionalBoundsLength - 1].sourceEnd; typeParameter.type= superType; superType.bits|= ASTNode.IsSuperType; typeParameter.bounds= bounds; for (int i= 0, max= bounds.length; i < max; i++) { bounds[i].bits|= ASTNode.IsSuperType; } } protected void consumeTypeParameterHeader() { //TypeParameterHeader ::= Identifier TypeParameter typeParameter= new TypeParameter(); long pos= this.identifierPositionStack[this.identifierPtr]; final int end= (int)pos; typeParameter.declarationSourceEnd= end; typeParameter.sourceEnd= end; final int start= (int)(pos >>> 32); typeParameter.declarationSourceStart= start; typeParameter.sourceStart= start; typeParameter.name= this.identifierStack[this.identifierPtr--]; this.identifierLengthPtr--; pushOnGenericsStack(typeParameter); this.listTypeParameterLength++; } protected void consumeTypeParameterList() { //TypeParameterList ::= TypeParameterList ',' TypeParameter concatGenericsLists(); } protected void consumeTypeParameterList1() { //TypeParameterList1 ::= TypeParameterList ',' TypeParameter1 concatGenericsLists(); } protected void consumeTypeParameters() { int startPos= this.intStack[this.intPtr--]; if (this.currentElement != null) { if (this.currentElement instanceof RecoveredType) { RecoveredType recoveredType= (RecoveredType)this.currentElement; int length= this.genericsLengthStack[this.genericsLengthPtr]; TypeParameter[] typeParameters= new TypeParameter[length]; System.arraycopy(this.genericsStack, this.genericsPtr - length + 1, typeParameters, 0, length); recoveredType.add(typeParameters, startPos); } } if (!this.statementRecoveryActivated && this.options.sourceLevel < ClassFileConstants.JDK1_5 && this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) { int length= this.genericsLengthStack[this.genericsLengthPtr]; problemReporter().invalidUsageOfTypeParameters( (TypeParameter)this.genericsStack[this.genericsPtr - length + 1], (TypeParameter)this.genericsStack[this.genericsPtr]); } } protected void consumeTypeParameterWithExtends() { //TypeParameter ::= TypeParameterHeader 'extends' ReferenceType TypeReference superType= getTypeReference(this.intStack[this.intPtr--]); TypeParameter typeParameter= (TypeParameter)this.genericsStack[this.genericsPtr]; typeParameter.declarationSourceEnd= superType.sourceEnd; typeParameter.type= superType; superType.bits|= ASTNode.IsSuperType; } protected void consumeTypeParameterWithExtendsAndBounds() { //TypeParameter ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList int additionalBoundsLength= this.genericsLengthStack[this.genericsLengthPtr--]; TypeReference[] bounds= new TypeReference[additionalBoundsLength]; this.genericsPtr-= additionalBoundsLength; System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 0, additionalBoundsLength); TypeReference superType= getTypeReference(this.intStack[this.intPtr--]); TypeParameter typeParameter= (TypeParameter)this.genericsStack[this.genericsPtr]; typeParameter.type= superType; superType.bits|= ASTNode.IsSuperType; typeParameter.bounds= bounds; typeParameter.declarationSourceEnd= bounds[additionalBoundsLength - 1].sourceEnd; for (int i= 0, max= bounds.length; i < max; i++) { bounds[i].bits|= ASTNode.IsSuperType; } } protected void consumeUnaryExpression(int op) { // UnaryExpression ::= '+' PushPosition UnaryExpression // UnaryExpression ::= '-' PushPosition UnaryExpression // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression //optimize the push/pop //handle manually the -2147483648 while it is not a real //computation of an - and 2147483648 (notice that 2147483648 //is Integer.MAX_VALUE+1.....) //Same for -9223372036854775808L ............ //this.intStack have the position of the operator Expression r, exp= this.expressionStack[this.expressionPtr]; if (op == MINUS) { if ((exp instanceof IntLiteral) && (((IntLiteral)exp).mayRepresentMIN_VALUE())) { r= this.expressionStack[this.expressionPtr]= new IntLiteralMinValue(); } else { if ((exp instanceof LongLiteral) && (((LongLiteral)exp).mayRepresentMIN_VALUE())) { r= this.expressionStack[this.expressionPtr]= new LongLiteralMinValue(); } else { r= this.expressionStack[this.expressionPtr]= new UnaryExpression(exp, op); } } } else { r= this.expressionStack[this.expressionPtr]= new UnaryExpression(exp, op); } r.sourceStart= this.intStack[this.intPtr--]; r.sourceEnd= exp.sourceEnd; } protected void consumeUnaryExpression(int op, boolean post) { // PreIncrementExpression ::= '++' PushPosition UnaryExpression // PreDecrementExpression ::= '--' PushPosition UnaryExpression // ++ and -- operators //optimize the push/pop //this.intStack has the position of the operator when prefix Expression leftHandSide= this.expressionStack[this.expressionPtr]; if (leftHandSide instanceof Reference) { // ++foo()++ is unvalid if (post) { this.expressionStack[this.expressionPtr]= new PostfixExpression( leftHandSide, IntLiteral.One, op, this.endStatementPosition); } else { this.expressionStack[this.expressionPtr]= new PrefixExpression( leftHandSide, IntLiteral.One, op, this.intStack[this.intPtr--]); } } else { //the ++ or the -- is NOT taken into account if code gen proceeds if (!post) { this.intPtr--; } if (!this.statementRecoveryActivated) problemReporter().invalidUnaryExpression(leftHandSide); } } protected void consumeVariableDeclarators() { // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator optimizedConcatNodeLists(); } protected void consumeVariableInitializers() { // VariableInitializers ::= VariableInitializers ',' VariableInitializer concatExpressionLists(); } protected void consumeWildcard() { final Wildcard wildcard= new Wildcard(Wildcard.UNBOUND); wildcard.sourceEnd= this.intStack[this.intPtr--]; wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcard1() { final Wildcard wildcard= new Wildcard(Wildcard.UNBOUND); wildcard.sourceEnd= this.intStack[this.intPtr--]; wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcard1WithBounds() { // Nothing to do // The wildcard is created by the consumeWildcardBounds1Extends or by consumeWildcardBounds1Super } protected void consumeWildcard2() { final Wildcard wildcard= new Wildcard(Wildcard.UNBOUND); wildcard.sourceEnd= this.intStack[this.intPtr--]; wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcard2WithBounds() { // Nothing to do // The wildcard is created by the consumeWildcardBounds2Extends or by consumeWildcardBounds2Super } protected void consumeWildcard3() { final Wildcard wildcard= new Wildcard(Wildcard.UNBOUND); wildcard.sourceEnd= this.intStack[this.intPtr--]; wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcard3WithBounds() { // Nothing to do // The wildcard is created by the consumeWildcardBounds3Extends or by consumeWildcardBounds3Super } protected void consumeWildcardBounds1Extends() { Wildcard wildcard= new Wildcard(Wildcard.EXTENDS); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBounds1Super() { Wildcard wildcard= new Wildcard(Wildcard.SUPER); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; this.intPtr--; // remove the starting position of the super keyword wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBounds2Extends() { Wildcard wildcard= new Wildcard(Wildcard.EXTENDS); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBounds2Super() { Wildcard wildcard= new Wildcard(Wildcard.SUPER); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; this.intPtr--; // remove the starting position of the super keyword wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBounds3Extends() { Wildcard wildcard= new Wildcard(Wildcard.EXTENDS); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBounds3Super() { Wildcard wildcard= new Wildcard(Wildcard.SUPER); wildcard.bound= (TypeReference)this.genericsStack[this.genericsPtr]; this.intPtr--; // remove the starting position of the super keyword wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; this.genericsStack[this.genericsPtr]= wildcard; } protected void consumeWildcardBoundsExtends() { Wildcard wildcard= new Wildcard(Wildcard.EXTENDS); wildcard.bound= getTypeReference(this.intStack[this.intPtr--]); wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcardBoundsSuper() { Wildcard wildcard= new Wildcard(Wildcard.SUPER); wildcard.bound= getTypeReference(this.intStack[this.intPtr--]); this.intPtr--; // remove the starting position of the super keyword wildcard.sourceEnd= wildcard.bound.sourceEnd; this.intPtr--; // remove end position of the '?' wildcard.sourceStart= this.intStack[this.intPtr--]; pushOnGenericsStack(wildcard); } protected void consumeWildcardWithBounds() { // Nothing to do // The wildcard is created by the consumeWildcardBoundsExtends or by consumeWildcardBoundsSuper } /** * Given the current comment stack, answer whether some comment is available in a certain * exclusive range * * @param sourceStart int * @param sourceEnd int * @return boolean */ public boolean containsComment(int sourceStart, int sourceEnd) { int iComment= this.scanner.commentPtr; for (; iComment >= 0; iComment--) { int commentStart= this.scanner.commentStarts[iComment]; if (commentStart < 0) commentStart= -commentStart; // ignore comments before start if (commentStart < sourceStart) continue; // ignore comments after end if (commentStart > sourceEnd) continue; return true; } return false; } public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) { MethodDeclaration m= new MethodDeclaration(compilationResult); m.typeParameters= c.typeParameters; m.sourceStart= c.sourceStart; m.sourceEnd= c.sourceEnd; m.bodyStart= c.bodyStart; m.bodyEnd= c.bodyEnd; m.declarationSourceEnd= c.declarationSourceEnd; m.declarationSourceStart= c.declarationSourceStart; m.selector= c.selector; m.statements= c.statements; m.modifiers= c.modifiers; m.annotations= c.annotations; m.arguments= c.arguments; m.thrownExceptions= c.thrownExceptions; m.explicitDeclarations= c.explicitDeclarations; m.returnType= null; m.javadoc= c.javadoc; return m; } protected TypeReference copyDims(TypeReference typeRef, int dim) { return typeRef.copyDims(dim); } protected FieldDeclaration createFieldDeclaration(char[] fieldDeclarationName, int sourceStart, int sourceEnd) { return new FieldDeclaration(fieldDeclarationName, sourceStart, sourceEnd); } protected JavadocParser createJavadocParser() { return new JavadocParser(this); } protected LocalDeclaration createLocalDeclaration(char[] localDeclarationName, int sourceStart, int sourceEnd) { return new LocalDeclaration(localDeclarationName, sourceStart, sourceEnd); } protected StringLiteral createStringLiteral(char[] token, int start, int end, int lineNumber) { return new StringLiteral(token, start, end, lineNumber); } protected RecoveredType currentRecoveryType() { if (this.currentElement != null) { if (this.currentElement instanceof RecoveredType) { return (RecoveredType)this.currentElement; } else { return this.currentElement.enclosingType(); } } return null; } public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { CompilationUnitDeclaration parsedUnit; boolean old= this.diet; try { this.diet= true; parsedUnit= parse(sourceUnit, compilationResult); } finally { this.diet= old; } return parsedUnit; } protected void dispatchDeclarationInto(int length) { /* they are length on this.astStack that should go into methods fields constructors lists of the typeDecl Return if there is a constructor declaration in the methods declaration */ // Looks for the size of each array . if (length == 0) return; int[] flag= new int[length + 1]; //plus one -- see <HERE> int size1= 0, size2= 0, size3= 0; boolean hasAbstractMethods= false; for (int i= length - 1; i >= 0; i--) { ASTNode astNode= this.astStack[this.astPtr--]; if (astNode instanceof AbstractMethodDeclaration) { //methods and constructors have been regrouped into one single list flag[i]= 2; size2++; if (((AbstractMethodDeclaration)astNode).isAbstract()) { hasAbstractMethods= true; } } else if (astNode instanceof TypeDeclaration) { flag[i]= 3; size3++; } else { //field flag[i]= 1; size1++; } } //arrays creation TypeDeclaration typeDecl= (TypeDeclaration)this.astStack[this.astPtr]; if (size1 != 0) { typeDecl.fields= new FieldDeclaration[size1]; } if (size2 != 0) { typeDecl.methods= new AbstractMethodDeclaration[size2]; if (hasAbstractMethods) typeDecl.bits|= ASTNode.HasAbstractMethods; } if (size3 != 0) { typeDecl.memberTypes= new TypeDeclaration[size3]; } //arrays fill up size1= size2= size3= 0; int flagI= flag[0], start= 0; int length2; for (int end= 0; end <= length; end++) //<HERE> the plus one allows to { if (flagI != flag[end]) //treat the last element as a ended flag..... { //array copy switch (flagI) { case 1: size1+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, typeDecl.fields, size1 - length2, length2); break; case 2: size2+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, typeDecl.methods, size2 - length2, length2); break; case 3: size3+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, typeDecl.memberTypes, size3 - length2, length2); break; } flagI= flag[start= end]; } } if (typeDecl.memberTypes != null) { for (int i= typeDecl.memberTypes.length - 1; i >= 0; i--) { typeDecl.memberTypes[i].enclosingType= typeDecl; } } } protected void dispatchDeclarationIntoEnumDeclaration(int length) { if (length == 0) return; int[] flag= new int[length + 1]; //plus one -- see <HERE> int size1= 0, size2= 0, size3= 0; TypeDeclaration enumDeclaration= (TypeDeclaration)this.astStack[this.astPtr - length]; boolean hasAbstractMethods= false; for (int i= length - 1; i >= 0; i--) { ASTNode astNode= this.astStack[this.astPtr--]; if (astNode instanceof AbstractMethodDeclaration) { //methods and constructors have been regrouped into one single list flag[i]= 2; size2++; if (((AbstractMethodDeclaration)astNode).isAbstract()) { hasAbstractMethods= true; } } else if (astNode instanceof TypeDeclaration) { flag[i]= 3; size3++; } else if (astNode instanceof FieldDeclaration) { flag[i]= 1; size1++; // if(astNode instanceof EnumConstant) { // EnumConstant constant = (EnumConstant) astNode; // ((AllocationExpression)constant.initialization).type = new SingleTypeReference(enumDeclaration.name, // (((long) enumDeclaration.sourceStart) << 32) + enumDeclaration.sourceEnd); // } } } //arrays creation if (size1 != 0) { enumDeclaration.fields= new FieldDeclaration[size1]; } if (size2 != 0) { enumDeclaration.methods= new AbstractMethodDeclaration[size2]; if (hasAbstractMethods) enumDeclaration.bits|= ASTNode.HasAbstractMethods; } if (size3 != 0) { enumDeclaration.memberTypes= new TypeDeclaration[size3]; } //arrays fill up size1= size2= size3= 0; int flagI= flag[0], start= 0; int length2; for (int end= 0; end <= length; end++) //<HERE> the plus one allows to { if (flagI != flag[end]) //treat the last element as a ended flag..... { //array copy switch (flagI) { case 1: size1+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, enumDeclaration.fields, size1 - length2, length2); break; case 2: size2+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, enumDeclaration.methods, size2 - length2, length2); break; case 3: size3+= (length2= end - start); System.arraycopy( this.astStack, this.astPtr + start + 1, enumDeclaration.memberTypes, size3 - length2, length2); break; } flagI= flag[start= end]; } } if (enumDeclaration.memberTypes != null) { for (int i= enumDeclaration.memberTypes.length - 1; i >= 0; i--) { enumDeclaration.memberTypes[i].enclosingType= enumDeclaration; } } } protected CompilationUnitDeclaration endParse(int act) { this.lastAct= act; if (this.statementRecoveryActivated) { RecoveredElement recoveredElement= buildInitialRecoveryState(); if (recoveredElement != null) { recoveredElement.topElement().updateParseTree(); } if (this.hasError) resetStacks(); } else if (this.currentElement != null) { if (VERBOSE_RECOVERY) { System.out.print(Messages.parser_syntaxRecovery); System.out.println("--------------------------"); //$NON-NLS-1$ System.out.println(this.compilationUnit); System.out.println("----------------------------------"); //$NON-NLS-1$ } this.currentElement.topElement().updateParseTree(); } else { if (this.diet & VERBOSE_RECOVERY) { System.out.print(Messages.parser_regularParse); System.out.println("--------------------------"); //$NON-NLS-1$ System.out.println(this.compilationUnit); System.out.println("----------------------------------"); //$NON-NLS-1$ } } persistLineSeparatorPositions(); for (int i= 0; i < this.scanner.foundTaskCount; i++) { if (!this.statementRecoveryActivated) problemReporter().task( new String(this.scanner.foundTaskTags[i]), new String(this.scanner.foundTaskMessages[i]), this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]), this.scanner.foundTaskPositions[i][0], this.scanner.foundTaskPositions[i][1]); } return this.compilationUnit; } /* * Flush comments defined prior to a given positions. * * Note: comments are stacked in syntactical order * * Either answer given <position>, or the end position of a comment line * immediately following the <position> (same line) * * e.g. * void foo(){ * } // end of method foo */ public int flushCommentsDefinedPriorTo(int position) { int lastCommentIndex= this.scanner.commentPtr; if (lastCommentIndex < 0) return position; // no comment // compute the index of the first obsolete comment int index= lastCommentIndex; int validCount= 0; while (index >= 0) { int commentEnd= this.scanner.commentStops[index]; if (commentEnd < 0) commentEnd= -commentEnd; // negative end position for non-javadoc comments if (commentEnd <= position) { break; } index--; validCount++; } // if the source at <position> is immediately followed by a line comment, then // flush this comment and shift <position> to the comment end. if (validCount > 0) { int immediateCommentEnd= -this.scanner.commentStops[index + 1]; //non-javadoc comment end positions are negative if (immediateCommentEnd > 0) { // only tolerating non-javadoc comments // is there any line break until the end of the immediate comment ? (thus only tolerating line comment) immediateCommentEnd--; // comment end in one char too far if (Util.getLineNumber(position, this.scanner.lineEnds, 0, this.scanner.linePtr) == Util.getLineNumber(immediateCommentEnd, this.scanner.lineEnds, 0, this.scanner.linePtr)) { position= immediateCommentEnd; validCount--; // flush this comment index++; } } } if (index < 0) return position; // no obsolete comment switch (validCount) { case 0: // do nothing break; // move valid comment infos, overriding obsolete comment infos case 2: this.scanner.commentStarts[0]= this.scanner.commentStarts[index + 1]; this.scanner.commentStops[0]= this.scanner.commentStops[index + 1]; this.scanner.commentTagStarts[0]= this.scanner.commentTagStarts[index + 1]; this.scanner.commentStarts[1]= this.scanner.commentStarts[index + 2]; this.scanner.commentStops[1]= this.scanner.commentStops[index + 2]; this.scanner.commentTagStarts[1]= this.scanner.commentTagStarts[index + 2]; break; case 1: this.scanner.commentStarts[0]= this.scanner.commentStarts[index + 1]; this.scanner.commentStops[0]= this.scanner.commentStops[index + 1]; this.scanner.commentTagStarts[0]= this.scanner.commentTagStarts[index + 1]; break; default: System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount); System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount); System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount); } this.scanner.commentPtr= validCount - 1; return position; } protected TypeReference getAnnotationType() { int length= this.identifierLengthStack[this.identifierLengthPtr--]; if (length == 1) { return new SingleTypeReference( this.identifierStack[this.identifierPtr], this.identifierPositionStack[this.identifierPtr--]); } else { char[][] tokens= new char[length][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy( this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); return new QualifiedTypeReference(tokens, positions); } } public int getFirstToken() { // the first token is a virtual token that // allows the parser to parse several goals // even if they aren't LALR(1).... // Goal ::= '++' CompilationUnit // Goal ::= '--' MethodBody // Goal ::= '==' ConstructorBody // -- Initializer // Goal ::= '>>' StaticInitializer // Goal ::= '>>' Block // -- error recovery // Goal ::= '>>>' Headers // Goal ::= '*' BlockStatements // Goal ::= '*' MethodPushModifiersHeader // -- JDOM // Goal ::= '&&' FieldDeclaration // Goal ::= '||' ImportDeclaration // Goal ::= '?' PackageDeclaration // Goal ::= '+' TypeDeclaration // Goal ::= '/' GenericMethodDeclaration // Goal ::= '&' ClassBodyDeclaration // -- code snippet // Goal ::= '%' Expression // -- completion parser // Goal ::= '!' ConstructorBlockStatementsopt // Goal ::= '~' BlockStatementsopt return this.firstToken; } /* * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments. * The array is a flattened structure: 2*n entries with consecutives start and end positions. * * If no JavaDoc is available, then null is answered instead of an empty array. * * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 */ public int[] getJavaDocPositions() { int javadocCount= 0; int max= this.scanner.commentPtr; for (int i= 0; i <= max; i++) { // javadoc only (non javadoc comment have negative start and/or end positions.) if (this.scanner.commentStarts[i] >= 0 && this.scanner.commentStops[i] > 0) { javadocCount++; } } if (javadocCount == 0) return null; int[] positions= new int[2 * javadocCount]; int index= 0; for (int i= 0; i <= max; i++) { // javadoc only (non javadoc comment have negative start and/or end positions.) int commentStart= this.scanner.commentStarts[i]; if (commentStart >= 0) { int commentStop= this.scanner.commentStops[i]; if (commentStop > 0) { positions[index++]= commentStart; positions[index++]= commentStop - 1; //stop is one over } } } return positions; } public void getMethodBodies(CompilationUnitDeclaration unit) { //fill the methods bodies in order for the code to be generated if (unit == null) return; if (unit.ignoreMethodBodies) { unit.ignoreFurtherInvestigation= true; return; // if initial diet parse did not work, no need to dig into method bodies. } if ((unit.bits & ASTNode.HasAllMethodBodies) != 0) return; //work already done ... // save existing values to restore them at the end of the parsing process // see bug 47079 for more details int[] oldLineEnds= this.scanner.lineEnds; int oldLinePtr= this.scanner.linePtr; //real parse of the method.... CompilationResult compilationResult= unit.compilationResult; char[] contents= this.readManager != null ? this.readManager.getContents(compilationResult.compilationUnit) : compilationResult.compilationUnit.getContents(); this.scanner.setSource(contents, compilationResult); if (this.javadocParser != null && this.javadocParser.checkDocComment) { this.javadocParser.scanner.setSource(contents); } if (unit.types != null) { for (int i= 0, length= unit.types.length; i < length; i++) unit.types[i].parseMethods(this, unit); } // tag unit has having read bodies unit.bits|= ASTNode.HasAllMethodBodies; // this is done to prevent any side effects on the compilation unit result // line separator positions array. this.scanner.lineEnds= oldLineEnds; this.scanner.linePtr= oldLinePtr; } protected char getNextCharacter(char[] comment, int[] index) { char nextCharacter= comment[index[0]++]; switch (nextCharacter) { case '\\': int c1, c2, c3, c4; index[0]++; while (comment[index[0]] == 'u') index[0]++; if (!(((c1= ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c1 < 0) || ((c2= ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c2 < 0) || ((c3= ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c3 < 0) || ((c4= ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) { nextCharacter= (char)(((c1 * 16 + c2) * 16 + c3) * 16 + c4); } break; } return nextCharacter; } protected Expression getTypeReference(Expression exp) { exp.bits&= ~ASTNode.RestrictiveFlagMASK; exp.bits|= Binding.TYPE; return exp; } protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not This variable is a type reference and dim will be its dimensions*/ TypeReference ref; int length= this.identifierLengthStack[this.identifierLengthPtr--]; if (length < 0) { //flag for precompiled type reference on base types ref= TypeReference.baseTypeReference(-length, dim); ref.sourceStart= this.intStack[this.intPtr--]; if (dim == 0) { ref.sourceEnd= this.intStack[this.intPtr--]; } else { this.intPtr--; ref.sourceEnd= this.endPosition; } } else { int numberOfIdentifiers= this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--]; if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) { // generic type ref= getTypeReferenceForGenericType(dim, length, numberOfIdentifiers); } else if (length == 1) { // single variable reference this.genericsLengthPtr--; // pop the 0 if (dim == 0) { ref= new SingleTypeReference( this.identifierStack[this.identifierPtr], this.identifierPositionStack[this.identifierPtr--]); } else { ref= new ArrayTypeReference( this.identifierStack[this.identifierPtr], dim, this.identifierPositionStack[this.identifierPtr--]); ref.sourceEnd= this.endPosition; } } else { this.genericsLengthPtr--; //Qualified variable reference char[][] tokens= new char[length][]; this.identifierPtr-= length; long[] positions= new long[length]; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); System.arraycopy( this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); if (dim == 0) { ref= new QualifiedTypeReference(tokens, positions); } else { ref= new ArrayQualifiedTypeReference(tokens, dim, positions); ref.sourceEnd= this.endPosition; } } } return ref; } protected TypeReference getTypeReferenceForGenericType(int dim, int identifierLength, int numberOfIdentifiers) { if (identifierLength == 1 && numberOfIdentifiers == 1) { int currentTypeArgumentsLength= this.genericsLengthStack[this.genericsLengthPtr--]; TypeReference[] typeArguments= new TypeReference[currentTypeArgumentsLength]; this.genericsPtr-= currentTypeArgumentsLength; System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength); ParameterizedSingleTypeReference parameterizedSingleTypeReference= new ParameterizedSingleTypeReference(this.identifierStack[this.identifierPtr], typeArguments, dim, this.identifierPositionStack[this.identifierPtr--]); if (dim != 0) { parameterizedSingleTypeReference.sourceEnd= this.endStatementPosition; } return parameterizedSingleTypeReference; } else { TypeReference[][] typeArguments= new TypeReference[numberOfIdentifiers][]; char[][] tokens= new char[numberOfIdentifiers][]; long[] positions= new long[numberOfIdentifiers]; int index= numberOfIdentifiers; int currentIdentifiersLength= identifierLength; while (index > 0) { int currentTypeArgumentsLength= this.genericsLengthStack[this.genericsLengthPtr--]; if (currentTypeArgumentsLength != 0) { this.genericsPtr-= currentTypeArgumentsLength; System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1]= new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength); } switch (currentIdentifiersLength) { case 1: // we are in a case A<B>.C<D> or A<B>.C<D> tokens[index - 1]= this.identifierStack[this.identifierPtr]; positions[index - 1]= this.identifierPositionStack[this.identifierPtr--]; break; default: // we are in a case A.B.C<B>.C<D> or A.B.C<B>... this.identifierPtr-= currentIdentifiersLength; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, index - currentIdentifiersLength, currentIdentifiersLength); System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, index - currentIdentifiersLength, currentIdentifiersLength); } index-= currentIdentifiersLength; if (index > 0) { currentIdentifiersLength= this.identifierLengthStack[this.identifierLengthPtr--]; } } ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference= new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, positions); if (dim != 0) { parameterizedQualifiedTypeReference.sourceEnd= this.endStatementPosition; } return parameterizedQualifiedTypeReference; } } protected NameReference getUnspecifiedReference() { /* build a (unspecified) NameReference which may be qualified*/ int length; NameReference ref; if ((length= this.identifierLengthStack[this.identifierLengthPtr--]) == 1) // single variable reference ref= new SingleNameReference( this.identifierStack[this.identifierPtr], this.identifierPositionStack[this.identifierPtr--]); else //Qualified variable reference { char[][] tokens= new char[length][]; this.identifierPtr-= length; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); long[] positions= new long[length]; System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); ref= new QualifiedNameReference(tokens, positions, (int)(this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart (int)this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd } return ref; } protected NameReference getUnspecifiedReferenceOptimized() { /* build a (unspecified) NameReference which may be qualified The optimization occurs for qualified reference while we are certain in this case the last item of the qualified name is a field access. This optimization is IMPORTANT while it results that when a NameReference is build, the type checker should always look for that it is not a type reference */ int length; NameReference ref; if ((length= this.identifierLengthStack[this.identifierLengthPtr--]) == 1) { // single variable reference ref= new SingleNameReference( this.identifierStack[this.identifierPtr], this.identifierPositionStack[this.identifierPtr--]); ref.bits&= ~ASTNode.RestrictiveFlagMASK; ref.bits|= Binding.LOCAL | Binding.FIELD; return ref; } //Qualified-variable-reference //In fact it is variable-reference DOT field-ref , but it would result in a type //conflict tha can be only reduce by making a superclass (or inetrface ) between //nameReference and FiledReference or putting FieldReference under NameReference //or else..........This optimisation is not really relevant so just leave as it is char[][] tokens= new char[length][]; this.identifierPtr-= length; System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length); long[] positions= new long[length]; System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length); ref= new QualifiedNameReference( tokens, positions, (int)(this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart (int)this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd ref.bits&= ~ASTNode.RestrictiveFlagMASK; ref.bits|= Binding.LOCAL | Binding.FIELD; return ref; } public void goForBlockStatementsopt() { //tells the scanner to go for block statements opt parsing this.firstToken= TokenNameTWIDDLE; this.scanner.recordLineSeparator= false; } public void goForBlockStatementsOrCatchHeader() { //tells the scanner to go for block statements or method headers parsing this.firstToken= TokenNameMULTIPLY; this.scanner.recordLineSeparator= false; } public void goForClassBodyDeclarations() { //tells the scanner to go for any body declarations parsing this.firstToken= TokenNameAND; this.scanner.recordLineSeparator= true; } public void goForCompilationUnit() { //tells the scanner to go for compilation unit parsing this.firstToken= TokenNamePLUS_PLUS; this.scanner.foundTaskCount= 0; this.scanner.recordLineSeparator= true; } public void goForExpression() { //tells the scanner to go for an expression parsing this.firstToken= TokenNameREMAINDER; this.scanner.recordLineSeparator= true; // recovery goals must record line separators } public void goForFieldDeclaration() { //tells the scanner to go for field declaration parsing this.firstToken= TokenNameAND_AND; this.scanner.recordLineSeparator= true; } public void goForGenericMethodDeclaration() { //tells the scanner to go for generic method declarations parsing this.firstToken= TokenNameDIVIDE; this.scanner.recordLineSeparator= true; } public void goForHeaders() { //tells the scanner to go for headers only parsing RecoveredType currentType= currentRecoveryType(); if (currentType != null && currentType.insideEnumConstantPart) { this.firstToken= TokenNameNOT; } else { this.firstToken= TokenNameUNSIGNED_RIGHT_SHIFT; } this.scanner.recordLineSeparator= true; // recovery goals must record line separators } public void goForImportDeclaration() { //tells the scanner to go for import declaration parsing this.firstToken= TokenNameOR_OR; this.scanner.recordLineSeparator= true; } public void goForInitializer() { //tells the scanner to go for initializer parsing this.firstToken= TokenNameRIGHT_SHIFT; this.scanner.recordLineSeparator= false; } public void goForMemberValue() { //tells the scanner to go for a member value parsing this.firstToken= TokenNameOR_OR; this.scanner.recordLineSeparator= true; // recovery goals must record line separators } public void goForMethodBody() { //tells the scanner to go for method body parsing this.firstToken= TokenNameMINUS_MINUS; this.scanner.recordLineSeparator= false; } public void goForPackageDeclaration() { //tells the scanner to go for package declaration parsing this.firstToken= TokenNameQUESTION; this.scanner.recordLineSeparator= true; } public void goForTypeDeclaration() { //tells the scanner to go for type (interface or class) declaration parsing this.firstToken= TokenNamePLUS; this.scanner.recordLineSeparator= true; } /** * Look for a specific tag comment leading a given source range (comment located after any * statement in astStack) * * @param rangeEnd int * @return boolean */ public boolean hasLeadingTagComment(char[] commentPrefixTag, int rangeEnd) { int iComment= this.scanner.commentPtr; if (iComment < 0) return false; // no comment available int iStatement= this.astLengthPtr; if (iStatement < 0 || this.astLengthStack[iStatement] <= 1) return false; // no statement available // Fallthrough comment must be located after the previous statement ASTNode lastNode= this.astStack[this.astPtr]; int rangeStart= lastNode.sourceEnd; previousComment: for (; iComment >= 0; iComment--) { int commentStart= this.scanner.commentStarts[iComment]; if (commentStart < 0) commentStart= -commentStart; // line comments have negative start positions // ignore comments before start if (commentStart < rangeStart) return false; // no more comments in range // ignore comments after end if (commentStart > rangeEnd) continue previousComment; // found last comment in range - only check the last comment in range char[] source= this.scanner.source; int charPos= commentStart + 2; // skip // or /* // tag can be leaded by optional spaces for (; charPos < rangeEnd; charPos++) { char c= source[charPos]; if (c >= ScannerHelper.MAX_OBVIOUS || (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) == 0) { break; } } for (int iTag= 0, length= commentPrefixTag.length; iTag < length; iTag++, charPos++) { if (charPos >= rangeEnd) return false; // comment is too small to host tag if (source[charPos] != commentPrefixTag[iTag]) return false; } return true; } return false; } protected void ignoreExpressionAssignment() { // Assignment ::= InvalidArrayInitializerAssignement // encoded operator would be: this.intStack[this.intPtr] this.intPtr--; ArrayInitializer arrayInitializer= (ArrayInitializer)this.expressionStack[this.expressionPtr--]; this.expressionLengthPtr--; // report a syntax error and abort parsing if (!this.statementRecoveryActivated) problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd); } public void initialize() { this.initialize(false); } public void initialize(boolean initializeNLS) { //positionning the parser for a new compilation unit //avoiding stack reallocation and all that.... this.astPtr= -1; this.astLengthPtr= -1; this.expressionPtr= -1; this.expressionLengthPtr= -1; this.identifierPtr= -1; this.identifierLengthPtr= -1; this.intPtr= -1; this.nestedMethod[this.nestedType= 0]= 0; // need to reset for further reuse this.variablesCounter[this.nestedType]= 0; this.dimensions= 0; this.realBlockPtr= -1; this.compilationUnit= null; this.referenceContext= null; this.endStatementPosition= 0; //remove objects from stack too, while the same parser/compiler couple is //re-used between two compilations .... int astLength= this.astStack.length; if (this.noAstNodes.length < astLength) { this.noAstNodes= new ASTNode[astLength]; //System.out.println("Resized AST stacks : "+ astLength); } System.arraycopy(this.noAstNodes, 0, this.astStack, 0, astLength); int expressionLength= this.expressionStack.length; if (this.noExpressions.length < expressionLength) { this.noExpressions= new Expression[expressionLength]; //System.out.println("Resized EXPR stacks : "+ expressionLength); } System.arraycopy(this.noExpressions, 0, this.expressionStack, 0, expressionLength); // reset this.scanner state this.scanner.commentPtr= -1; this.scanner.foundTaskCount= 0; this.scanner.eofPosition= Integer.MAX_VALUE; this.recordStringLiterals= true; final boolean checkNLS= this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore; this.checkExternalizeStrings= checkNLS; this.scanner.checkNonExternalizedStringLiterals= initializeNLS && checkNLS; this.scanner.lastPosition= -1; resetModifiers(); // recovery this.lastCheckPoint= -1; this.currentElement= null; this.restartRecovery= false; this.hasReportedError= false; this.recoveredStaticInitializerStart= 0; this.lastIgnoredToken= -1; this.lastErrorEndPosition= -1; this.lastErrorEndPositionBeforeRecovery= -1; this.lastJavadocEnd= -1; this.listLength= 0; this.listTypeParameterLength= 0; this.lastPosistion= -1; this.rBraceStart= 0; this.rBraceEnd= 0; this.rBraceSuccessorStart= 0; this.genericsIdentifiersLengthPtr= -1; this.genericsLengthPtr= -1; this.genericsPtr= -1; } public void initializeScanner() { this.scanner= new Scanner( false /*comment*/, false /*whitespace*/, false, /* will be set in initialize(boolean) */ this.options.sourceLevel /*sourceLevel*/, this.options.complianceLevel /*complianceLevel*/, this.options.taskTags/*taskTags*/, this.options.taskPriorities/*taskPriorities*/, this.options.isTaskCaseSensitive/*taskCaseSensitive*/); } public void jumpOverMethodBody() { //on diet parsing.....do not buffer method statements //the scanner.diet is reinitialized to false //automatically by the scanner once it has jumped over //the statements if (this.diet && (this.dietInt == 0)) this.scanner.diet= true; } private void jumpOverType() { if (this.recoveredTypes != null && this.nextTypeStart > -1 && this.nextTypeStart < this.scanner.currentPosition) { if (DEBUG_AUTOMATON) { System.out.println("Jump -"); //$NON-NLS-1$ } TypeDeclaration typeDeclaration= this.recoveredTypes[this.recoveredTypePtr]; boolean isAnonymous= typeDeclaration.allocation != null; this.scanner.startPosition= typeDeclaration.declarationSourceEnd + 1; this.scanner.currentPosition= typeDeclaration.declarationSourceEnd + 1; this.scanner.diet= false; // quit jumping over method bodies if (!isAnonymous) { ((RecoveryScanner)this.scanner).setPendingTokens(new int[] { TokenNameSEMICOLON, TokenNamebreak }); } else { ((RecoveryScanner)this.scanner).setPendingTokens(new int[] { TokenNameIdentifier, TokenNameEQUAL, TokenNameIdentifier }); } this.pendingRecoveredType= typeDeclaration; try { this.currentToken= this.scanner.getNextToken(); } catch (InvalidInputException e) { // it's impossible because we added pending tokens before } if (++this.recoveredTypePtr < this.recoveredTypes.length) { TypeDeclaration nextTypeDeclaration= this.recoveredTypes[this.recoveredTypePtr]; this.nextTypeStart= nextTypeDeclaration.allocation == null ? nextTypeDeclaration.declarationSourceStart : nextTypeDeclaration.allocation.sourceStart; } else { this.nextTypeStart= Integer.MAX_VALUE; } } } protected void markEnclosingMemberWithLocalType() { if (this.currentElement != null) return; // this is already done in the recovery code for (int i= this.astPtr; i >= 0; i--) { ASTNode node= this.astStack[i]; if (node instanceof AbstractMethodDeclaration || node instanceof FieldDeclaration || (node instanceof TypeDeclaration // mark type for now: all initializers will be marked when added to this type // and enclosing type must not be closed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=147485) && ((TypeDeclaration)node).declarationSourceEnd == 0)) { node.bits|= ASTNode.HasLocalType; return; } } // default to reference context (case of parse method body) if (this.referenceContext instanceof AbstractMethodDeclaration || this.referenceContext instanceof TypeDeclaration) { ((ASTNode)this.referenceContext).bits|= ASTNode.HasLocalType; } } /* * Move checkpoint location (current implementation is moving it by one token) * * Answers true if successfully moved checkpoint (in other words, it did not attempt to move it * beyond end of file). */ protected boolean moveRecoveryCheckpoint() { int pos= this.lastCheckPoint; /* reset this.scanner, and move checkpoint by one token */ this.scanner.startPosition= pos; this.scanner.currentPosition= pos; this.scanner.diet= false; // quit jumping over method bodies /* if about to restart, then no need to shift token */ if (this.restartRecovery) { this.lastIgnoredToken= -1; this.scanner.insideRecovery= true; return true; } /* protect against shifting on an invalid token */ this.lastIgnoredToken= this.nextIgnoredToken; this.nextIgnoredToken= -1; do { try { this.nextIgnoredToken= this.scanner.getNextToken(); if (this.scanner.currentPosition == this.scanner.startPosition) { this.scanner.currentPosition++; // on fake completion identifier this.nextIgnoredToken= -1; } } catch (InvalidInputException e) { pos= this.scanner.currentPosition; } } while (this.nextIgnoredToken < 0); if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF return false; } } this.lastCheckPoint= this.scanner.currentPosition; /* reset this.scanner again to previous checkpoint location*/ this.scanner.startPosition= pos; this.scanner.currentPosition= pos; this.scanner.commentPtr= -1; this.scanner.foundTaskCount= 0; return true; /* The following implementation moves the checkpoint location by one line: int pos = this.lastCheckPoint; // reset this.scanner, and move checkpoint by one token this.scanner.startPosition = pos; this.scanner.currentPosition = pos; this.scanner.diet = false; // quit jumping over method bodies // if about to restart, then no need to shift token if (this.restartRecovery){ this.lastIgnoredToken = -1; return true; } // protect against shifting on an invalid token this.lastIgnoredToken = this.nextIgnoredToken; this.nextIgnoredToken = -1; boolean wasTokenizingWhiteSpace = this.scanner.tokenizeWhiteSpace; this.scanner.tokenizeWhiteSpace = true; checkpointMove: do { try { this.nextIgnoredToken = this.scanner.getNextToken(); switch(this.nextIgnoredToken){ case Scanner.TokenNameWHITESPACE : if(this.scanner.getLineNumber(this.scanner.startPosition) == this.scanner.getLineNumber(this.scanner.currentPosition)){ this.nextIgnoredToken = -1; } break; case TokenNameSEMICOLON : case TokenNameLBRACE : case TokenNameRBRACE : break; case TokenNameIdentifier : if(this.scanner.currentPosition == this.scanner.startPosition){ this.scanner.currentPosition++; // on fake completion identifier } default: this.nextIgnoredToken = -1; break; case TokenNameEOF : break checkpointMove; } } catch(InvalidInputException e){ pos = this.scanner.currentPosition; } } while (this.nextIgnoredToken < 0); this.scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace; if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF return false; } } this.lastCheckPoint = this.scanner.currentPosition; // reset this.scanner again to previous checkpoint location this.scanner.startPosition = pos; this.scanner.currentPosition = pos; this.scanner.commentPtr = -1; return true; */ } protected MessageSend newMessageSend() { // '(' ArgumentListopt ')' // the arguments are on the expression stack MessageSend m= new MessageSend(); int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, m.arguments= new Expression[length], 0, length); } return m; } protected MessageSend newMessageSendWithTypeArguments() { MessageSend m= new MessageSend(); int length; if ((length= this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { this.expressionPtr-= length; System.arraycopy( this.expressionStack, this.expressionPtr + 1, m.arguments= new Expression[length], 0, length); } return m; } protected void optimizedConcatNodeLists() { /*back from a recursive loop. Virtualy group the astNode into an array using this.astLengthStack*/ /* * This is a case where you have two sublists into the this.astStack that you want * to merge in one list. There is no action required on the this.astStack. The only * thing you need to do is merge the two lengths specified on the astStackLength. * The top two length are for example: * ... p n * and you want to result in a list like: * ... n+p * This means that the p could be equals to 0 in case there is no astNode pushed * on the this.astStack. * Look at the InterfaceMemberDeclarations for an example. * This case optimizes the fact that p == 1. */ this.astLengthStack[--this.astLengthPtr]++; } /*main loop of the automat When a rule is reduced, the method consumeRule(int) is called with the number of the consumed rule. When a terminal is consumed, the method consumeToken(int) is called in order to remember (when needed) the consumed token */ // (int)asr[asi(act)] // name[symbol_index[currentKind]] protected void parse() { if (DEBUG) System.out.println("-- ENTER INSIDE PARSE METHOD --"); //$NON-NLS-1$ if (DEBUG_AUTOMATON) { System.out.println("- Start --------------------------------"); //$NON-NLS-1$ } boolean isDietParse= this.diet; int oldFirstToken= getFirstToken(); this.hasError= false; this.hasReportedError= false; int act= START_STATE; this.stateStackTop= -1; this.currentToken= getFirstToken(); ProcessTerminals: for (;;) { int stackLength= this.stack.length; if (++this.stateStackTop >= stackLength) { System.arraycopy( this.stack, 0, this.stack= new int[stackLength + StackIncrement], 0, stackLength); } this.stack[this.stateStackTop]= act; act= tAction(act, this.currentToken); if (act == ERROR_ACTION || this.restartRecovery) { if (DEBUG_AUTOMATON) { if (this.restartRecovery) { System.out.println("Restart - "); //$NON-NLS-1$ } else { System.out.println("Error - "); //$NON-NLS-1$ } } int errorPos= this.scanner.currentPosition - 1; if (!this.hasReportedError) { this.hasError= true; } int previousToken= this.currentToken; if (resumeOnSyntaxError()) { if (act == ERROR_ACTION && previousToken != 0) this.lastErrorEndPosition= errorPos; act= START_STATE; this.stateStackTop= -1; this.currentToken= getFirstToken(); continue ProcessTerminals; } act= ERROR_ACTION; break ProcessTerminals; } if (act <= NUM_RULES) { this.stateStackTop--; if (DEBUG_AUTOMATON) { System.out.print("Reduce - "); //$NON-NLS-1$ } } else if (act > ERROR_ACTION) { /* shift-reduce */ consumeToken(this.currentToken); if (this.currentElement != null) { boolean oldValue= this.recordStringLiterals; this.recordStringLiterals= false; recoveryTokenCheck(); this.recordStringLiterals= oldValue; } try { this.currentToken= this.scanner.getNextToken(); } catch (InvalidInputException e) { if (!this.hasReportedError) { problemReporter().scannerError(this, e.getMessage()); this.hasReportedError= true; } this.lastCheckPoint= this.scanner.currentPosition; this.currentToken= 0; this.restartRecovery= true; } if (this.statementRecoveryActivated) { jumpOverType(); } act-= ERROR_ACTION; if (DEBUG_AUTOMATON) { System.out.print("Shift/Reduce - (" + name[terminal_index[this.currentToken]] + ") "); //$NON-NLS-1$ //$NON-NLS-2$ } } else { if (act < ACCEPT_ACTION) { /* shift */ consumeToken(this.currentToken); if (this.currentElement != null) { boolean oldValue= this.recordStringLiterals; this.recordStringLiterals= false; recoveryTokenCheck(); this.recordStringLiterals= oldValue; } try { this.currentToken= this.scanner.getNextToken(); } catch (InvalidInputException e) { if (!this.hasReportedError) { problemReporter().scannerError(this, e.getMessage()); this.hasReportedError= true; } this.lastCheckPoint= this.scanner.currentPosition; this.currentToken= 0; this.restartRecovery= true; } if (this.statementRecoveryActivated) { jumpOverType(); } if (DEBUG_AUTOMATON) { System.out.println("Shift - (" + name[terminal_index[this.currentToken]] + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } continue ProcessTerminals; } break ProcessTerminals; } // ProcessNonTerminals : do { /* reduce */ if (DEBUG_AUTOMATON) { System.out.println(name[non_terminal_index[lhs[act]]]); } consumeRule(act); this.stateStackTop-= (rhs[act] - 1); act= ntAction(this.stack[this.stateStackTop], lhs[act]); if (DEBUG_AUTOMATON) { if (act <= NUM_RULES) { System.out.print(" - "); //$NON-NLS-1$ } } } while (act <= NUM_RULES); if (DEBUG_AUTOMATON) { System.out.println("----------------------------------------"); //$NON-NLS-1$ } } if (DEBUG_AUTOMATON) { System.out.println("- End ----------------------------------"); //$NON-NLS-1$ } endParse(act); // record all nls tags in the corresponding compilation unit final NLSTag[] tags= this.scanner.getNLSTags(); if (tags != null) { this.compilationUnit.nlsTags= tags; } this.scanner.checkNonExternalizedStringLiterals= false; if (this.reportSyntaxErrorIsRequired && this.hasError && !this.statementRecoveryActivated) { if (!this.options.performStatementsRecovery) { reportSyntaxErrors(isDietParse, oldFirstToken); } else { RecoveryScannerData data= this.referenceContext.compilationResult().recoveryScannerData; if (this.recoveryScanner == null) { this.recoveryScanner= new RecoveryScanner(this.scanner, data); } else { this.recoveryScanner.setData(data); } this.recoveryScanner.setSource(this.scanner.source); this.recoveryScanner.lineEnds= this.scanner.lineEnds; this.recoveryScanner.linePtr= this.scanner.linePtr; reportSyntaxErrors(isDietParse, oldFirstToken); if (data == null) { this.referenceContext.compilationResult().recoveryScannerData= this.recoveryScanner.getData(); } if (this.methodRecoveryActivated && this.options.performStatementsRecovery) { this.methodRecoveryActivated= false; recoverStatements(); this.methodRecoveryActivated= true; this.lastAct= ERROR_ACTION; } } } if (DEBUG) System.out.println("-- EXIT FROM PARSE METHOD --"); //$NON-NLS-1$ } public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit, boolean recordLineSeparator) { //only parse the method body of cd //fill out its statements //convert bugs into parse error boolean oldMethodRecoveryActivated= this.methodRecoveryActivated; if (this.options.performMethodsFullRecovery) { this.methodRecoveryActivated= true; } initialize(); goForBlockStatementsopt(); if (recordLineSeparator) { this.scanner.recordLineSeparator= true; } this.nestedMethod[this.nestedType]++; pushOnRealBlockStack(0); this.referenceContext= cd; this.compilationUnit= unit; this.scanner.resetTo(cd.bodyStart, cd.bodyEnd); try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; if (this.options.performStatementsRecovery) { this.methodRecoveryActivated= oldMethodRecoveryActivated; } } checkNonNLSAfterBodyEnd(cd.declarationSourceEnd); if (this.lastAct == ERROR_ACTION) { cd.bits|= ASTNode.HasSyntaxErrors; initialize(); return; } //statements cd.explicitDeclarations= this.realBlockStack[this.realBlockPtr--]; int length; if (this.astLengthPtr > -1 && (length= this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr-= length; if (!this.options.ignoreMethodBodies) { if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ? { System.arraycopy( this.astStack, this.astPtr + 2, cd.statements= new Statement[length - 1], 0, length - 1); cd.constructorCall= (ExplicitConstructorCall)this.astStack[this.astPtr + 1]; } else { //need to add explicitly the super(); System.arraycopy( this.astStack, this.astPtr + 1, cd.statements= new Statement[length], 0, length); cd.constructorCall= SuperReference.implicitSuperConstructorCall(); } } } else { if (!this.options.ignoreMethodBodies) { cd.constructorCall= SuperReference.implicitSuperConstructorCall(); } if (!containsComment(cd.bodyStart, cd.bodyEnd)) { cd.bits|= ASTNode.UndocumentedEmptyBlock; } } ExplicitConstructorCall explicitConstructorCall= cd.constructorCall; if (explicitConstructorCall != null && explicitConstructorCall.sourceEnd == 0) { explicitConstructorCall.sourceEnd= cd.sourceEnd; explicitConstructorCall.sourceStart= cd.sourceStart; } } // A P I public void parse( FieldDeclaration field, TypeDeclaration type, CompilationUnitDeclaration unit, char[] initializationSource) { //only parse the initializationSource of the given field //convert bugs into parse error initialize(); goForExpression(); this.nestedMethod[this.nestedType]++; this.referenceContext= type; this.compilationUnit= unit; this.scanner.setSource(initializationSource); this.scanner.resetTo(0, initializationSource.length - 1); try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; } if (this.lastAct == ERROR_ACTION) { field.bits|= ASTNode.HasSyntaxErrors; return; } field.initialization= this.expressionStack[this.expressionPtr]; // mark field with local type if one was found during parsing if ((type.bits & ASTNode.HasLocalType) != 0) { field.bits|= ASTNode.HasLocalType; } } // A P I public CompilationUnitDeclaration parse( ICompilationUnit sourceUnit, CompilationResult compilationResult) { // parses a compilation unit and manages error handling (even bugs....) return parse(sourceUnit, compilationResult, -1, -1/*parse without reseting the scanner*/); } // A P I public CompilationUnitDeclaration parse( ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) { // parses a compilation unit and manages error handling (even bugs....) CompilationUnitDeclaration unit; try { /* automaton initialization */ initialize(true); goForCompilationUnit(); /* unit creation */ this.referenceContext= this.compilationUnit= new CompilationUnitDeclaration( this.problemReporter, compilationResult, 0); /* scanners initialization */ char[] contents; try { contents= this.readManager != null ? this.readManager.getContents(sourceUnit) : sourceUnit.getContents(); } catch (AbortCompilationUnit abortException) { problemReporter().cannotReadSource(this.compilationUnit, abortException, this.options.verbose); contents= CharOperation.NO_CHAR; // pretend empty from thereon } this.scanner.setSource(contents); this.compilationUnit.sourceEnd= this.scanner.source.length - 1; if (end != -1) this.scanner.resetTo(start, end); if (this.javadocParser != null && this.javadocParser.checkDocComment) { this.javadocParser.scanner.setSource(contents); if (end != -1) { this.javadocParser.scanner.resetTo(start, end); } } /* run automaton */ parse(); } finally { unit= this.compilationUnit; this.compilationUnit= null; // reset parser // tag unit has having read bodies if (!this.diet) unit.bits|= ASTNode.HasAllMethodBodies; } return unit; } // A P I public void parse( Initializer initializer, TypeDeclaration type, CompilationUnitDeclaration unit) { //only parse the method body of md //fill out method statements //convert bugs into parse error boolean oldMethodRecoveryActivated= this.methodRecoveryActivated; if (this.options.performMethodsFullRecovery) { this.methodRecoveryActivated= true; } initialize(); goForBlockStatementsopt(); this.nestedMethod[this.nestedType]++; pushOnRealBlockStack(0); this.referenceContext= type; this.compilationUnit= unit; this.scanner.resetTo(initializer.bodyStart, initializer.bodyEnd); // just on the beginning { try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; if (this.options.performStatementsRecovery) { this.methodRecoveryActivated= oldMethodRecoveryActivated; } } checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd); if (this.lastAct == ERROR_ACTION) { initializer.bits|= ASTNode.HasSyntaxErrors; return; } //refill statements initializer.block.explicitDeclarations= this.realBlockStack[this.realBlockPtr--]; int length; if (this.astLengthPtr > -1 && (length= this.astLengthStack[this.astLengthPtr--]) > 0) { System.arraycopy(this.astStack, (this.astPtr-= length) + 1, initializer.block.statements= new Statement[length], 0, length); } else { // check whether this block at least contains some comment in it if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) { initializer.block.bits|= ASTNode.UndocumentedEmptyBlock; } } // mark initializer with local type if one was found during parsing if ((type.bits & ASTNode.HasLocalType) != 0) { initializer.bits|= ASTNode.HasLocalType; } } // A P I public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) { //only parse the method body of md //fill out method statements //convert bugs into parse error if (md.isAbstract()) return; if (md.isNative()) return; if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) return; boolean oldMethodRecoveryActivated= this.methodRecoveryActivated; if (this.options.performMethodsFullRecovery) { this.methodRecoveryActivated= true; this.rParenPos= md.sourceEnd; } initialize(); goForBlockStatementsopt(); this.nestedMethod[this.nestedType]++; pushOnRealBlockStack(0); this.referenceContext= md; this.compilationUnit= unit; this.scanner.resetTo(md.bodyStart, md.bodyEnd); // reset the scanner to parser from { down to } try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; if (this.options.performStatementsRecovery) { this.methodRecoveryActivated= oldMethodRecoveryActivated; } } checkNonNLSAfterBodyEnd(md.declarationSourceEnd); if (this.lastAct == ERROR_ACTION) { md.bits|= ASTNode.HasSyntaxErrors; return; } //refill statements md.explicitDeclarations= this.realBlockStack[this.realBlockPtr--]; int length; if (this.astLengthPtr > -1 && (length= this.astLengthStack[this.astLengthPtr--]) != 0) { if (this.options.ignoreMethodBodies) { // ignore statements this.astPtr-= length; } else { System.arraycopy( this.astStack, (this.astPtr-= length) + 1, md.statements= new Statement[length], 0, length); } } else { if (!containsComment(md.bodyStart, md.bodyEnd)) { md.bits|= ASTNode.UndocumentedEmptyBlock; } } } public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int length, CompilationUnitDeclaration unit) { boolean oldDiet= this.diet; /* automaton initialization */ initialize(); goForClassBodyDeclarations(); /* scanner initialization */ this.scanner.setSource(source); this.scanner.resetTo(offset, offset + length - 1); if (this.javadocParser != null && this.javadocParser.checkDocComment) { this.javadocParser.scanner.setSource(source); this.javadocParser.scanner.resetTo(offset, offset + length - 1); } /* type declaration should be parsed as member type declaration */ this.nestedType= 1; /* unit creation */ TypeDeclaration referenceContextTypeDeclaration= new TypeDeclaration(unit.compilationResult); referenceContextTypeDeclaration.name= Util.EMPTY_STRING.toCharArray(); referenceContextTypeDeclaration.fields= new FieldDeclaration[0]; this.compilationUnit= unit; unit.types= new TypeDeclaration[1]; unit.types[0]= referenceContextTypeDeclaration; this.referenceContext= unit; /* run automaton */ try { this.diet= true; parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.diet= oldDiet; } ASTNode[] result= null; if (this.lastAct == ERROR_ACTION) { if (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery) { return null; } // collect all body declaration inside the compilation unit except the default constructor final List bodyDeclarations= new ArrayList(); ASTVisitor visitor= new ASTVisitor() { public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { if (!methodDeclaration.isDefaultConstructor()) { bodyDeclarations.add(methodDeclaration); } return false; } public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) { bodyDeclarations.add(fieldDeclaration); return false; } public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) { bodyDeclarations.add(memberTypeDeclaration); return false; } }; unit.ignoreFurtherInvestigation= false; unit.traverse(visitor, unit.scope); unit.ignoreFurtherInvestigation= true; result= (ASTNode[])bodyDeclarations.toArray(new ASTNode[bodyDeclarations.size()]); } else { int astLength; if (this.astLengthPtr > -1 && (astLength= this.astLengthStack[this.astLengthPtr--]) != 0) { result= new ASTNode[astLength]; this.astPtr-= astLength; System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength); } else { // empty class body declaration (like ';' see https://bugs.eclipse.org/bugs/show_bug.cgi?id=280079). result= new ASTNode[0]; } } boolean containsInitializers= false; TypeDeclaration typeDeclaration= null; for (int i= 0, max= result.length; i < max; i++) { // parse each class body declaration ASTNode node= result[i]; if (node instanceof TypeDeclaration) { ((TypeDeclaration)node).parseMethods(this, unit); } else if (node instanceof AbstractMethodDeclaration) { ((AbstractMethodDeclaration)node).parseStatements(this, unit); } else if (node instanceof FieldDeclaration) { FieldDeclaration fieldDeclaration= (FieldDeclaration)node; switch (fieldDeclaration.getKind()) { case AbstractVariableDeclaration.INITIALIZER: containsInitializers= true; if (typeDeclaration == null) { typeDeclaration= referenceContextTypeDeclaration; } if (typeDeclaration.fields == null) { typeDeclaration.fields= new FieldDeclaration[1]; typeDeclaration.fields[0]= fieldDeclaration; } else { int length2= typeDeclaration.fields.length; FieldDeclaration[] temp= new FieldDeclaration[length2 + 1]; System.arraycopy(typeDeclaration.fields, 0, temp, 0, length2); temp[length2]= fieldDeclaration; typeDeclaration.fields= temp; } break; } } if (((node.bits & ASTNode.HasSyntaxErrors) != 0) && (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery)) { return null; } } if (containsInitializers) { FieldDeclaration[] fieldDeclarations= typeDeclaration.fields; for (int i= 0, max= fieldDeclarations.length; i < max; i++) { Initializer initializer= (Initializer)fieldDeclarations[i]; initializer.parseStatements(this, typeDeclaration, unit); if (((initializer.bits & ASTNode.HasSyntaxErrors) != 0) && (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery)) { return null; } } } return result; } public Expression parseExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit) { initialize(); goForExpression(); this.nestedMethod[this.nestedType]++; this.referenceContext= unit; this.compilationUnit= unit; this.scanner.setSource(source); this.scanner.resetTo(offset, offset + length - 1); try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; } if (this.lastAct == ERROR_ACTION) { return null; } return this.expressionStack[this.expressionPtr]; } public Expression parseMemberValue(char[] source, int offset, int length, CompilationUnitDeclaration unit) { initialize(); goForMemberValue(); this.nestedMethod[this.nestedType]++; this.referenceContext= unit; this.compilationUnit= unit; this.scanner.setSource(source); this.scanner.resetTo(offset, offset + length - 1); try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; } if (this.lastAct == ERROR_ACTION) { return null; } return this.expressionStack[this.expressionPtr]; } public void parseStatements(ReferenceContext rc, int start, int end, TypeDeclaration[] types, CompilationUnitDeclaration unit) { boolean oldStatementRecoveryEnabled= this.statementRecoveryActivated; this.statementRecoveryActivated= true; initialize(); goForBlockStatementsopt(); this.nestedMethod[this.nestedType]++; pushOnRealBlockStack(0); pushOnAstLengthStack(0); this.referenceContext= rc; this.compilationUnit= unit; this.pendingRecoveredType= null; if (types != null && types.length > 0) { this.recoveredTypes= types; this.recoveredTypePtr= 0; this.nextTypeStart= this.recoveredTypes[0].allocation == null ? this.recoveredTypes[0].declarationSourceStart : this.recoveredTypes[0].allocation.sourceStart; } else { this.recoveredTypes= null; this.recoveredTypePtr= -1; this.nextTypeStart= -1; } this.scanner.resetTo(start, end); // reset the scanner to parser from { down to } this.lastCheckPoint= this.scanner.initialPosition; this.stateStackTop= -1; try { parse(); } catch (AbortCompilation ex) { this.lastAct= ERROR_ACTION; } finally { this.nestedMethod[this.nestedType]--; this.recoveredTypes= null; this.statementRecoveryActivated= oldStatementRecoveryEnabled; } checkNonNLSAfterBodyEnd(end); } public void persistLineSeparatorPositions() { if (this.scanner.recordLineSeparator) { this.compilationUnit.compilationResult.lineSeparatorPositions= this.scanner.getLineEnds(); } } /* * Prepares the state of the parser to go for BlockStatements. */ protected void prepareForBlockStatements() { this.nestedMethod[this.nestedType= 0]= 1; this.variablesCounter[this.nestedType]= 0; this.realBlockStack[this.realBlockPtr= 1]= 0; } /** * Returns this parser's problem reporter initialized with its reference context. Also it is * assumed that a problem is going to be reported, so initializes the compilation result's line * positions. * * @return ProblemReporter */ public ProblemReporter problemReporter() { if (this.scanner.recordLineSeparator) { this.compilationUnit.compilationResult.lineSeparatorPositions= this.scanner.getLineEnds(); } this.problemReporter.referenceContext= this.referenceContext; return this.problemReporter; } protected void pushIdentifier() { /*push the consumeToken on the identifier stack. Increase the total number of identifier in the stack. identifierPtr points on the next top */ int stackLength= this.identifierStack.length; if (++this.identifierPtr >= stackLength) { System.arraycopy( this.identifierStack, 0, this.identifierStack= new char[stackLength + 20][], 0, stackLength); System.arraycopy( this.identifierPositionStack, 0, this.identifierPositionStack= new long[stackLength + 20], 0, stackLength); } this.identifierStack[this.identifierPtr]= this.scanner.getCurrentIdentifierSource(); this.identifierPositionStack[this.identifierPtr]= (((long)this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1); stackLength= this.identifierLengthStack.length; if (++this.identifierLengthPtr >= stackLength) { System.arraycopy( this.identifierLengthStack, 0, this.identifierLengthStack= new int[stackLength + 10], 0, stackLength); } this.identifierLengthStack[this.identifierLengthPtr]= 1; } protected void pushIdentifier(int flag) { /*push a special flag on the stack : -zero stands for optional Name -negative number for direct ref to base types. identifierLengthPtr points on the top */ int stackLength= this.identifierLengthStack.length; if (++this.identifierLengthPtr >= stackLength) { System.arraycopy( this.identifierLengthStack, 0, this.identifierLengthStack= new int[stackLength + 10], 0, stackLength); } this.identifierLengthStack[this.identifierLengthPtr]= flag; } protected void pushOnAstLengthStack(int pos) { int stackLength= this.astLengthStack.length; if (++this.astLengthPtr >= stackLength) { System.arraycopy( this.astLengthStack, 0, this.astLengthStack= new int[stackLength + StackIncrement], 0, stackLength); } this.astLengthStack[this.astLengthPtr]= pos; } protected void pushOnAstStack(ASTNode node) { /*add a new obj on top of the ast stack astPtr points on the top*/ int stackLength= this.astStack.length; if (++this.astPtr >= stackLength) { System.arraycopy( this.astStack, 0, this.astStack= new ASTNode[stackLength + AstStackIncrement], 0, stackLength); this.astPtr= stackLength; } this.astStack[this.astPtr]= node; stackLength= this.astLengthStack.length; if (++this.astLengthPtr >= stackLength) { System.arraycopy( this.astLengthStack, 0, this.astLengthStack= new int[stackLength + AstStackIncrement], 0, stackLength); } this.astLengthStack[this.astLengthPtr]= 1; } protected void pushOnExpressionStack(Expression expr) { int stackLength= this.expressionStack.length; if (++this.expressionPtr >= stackLength) { System.arraycopy( this.expressionStack, 0, this.expressionStack= new Expression[stackLength + ExpressionStackIncrement], 0, stackLength); } this.expressionStack[this.expressionPtr]= expr; stackLength= this.expressionLengthStack.length; if (++this.expressionLengthPtr >= stackLength) { System.arraycopy( this.expressionLengthStack, 0, this.expressionLengthStack= new int[stackLength + ExpressionStackIncrement], 0, stackLength); } this.expressionLengthStack[this.expressionLengthPtr]= 1; } protected void pushOnExpressionStackLengthStack(int pos) { int stackLength= this.expressionLengthStack.length; if (++this.expressionLengthPtr >= stackLength) { System.arraycopy( this.expressionLengthStack, 0, this.expressionLengthStack= new int[stackLength + StackIncrement], 0, stackLength); } this.expressionLengthStack[this.expressionLengthPtr]= pos; } protected void pushOnGenericsIdentifiersLengthStack(int pos) { int stackLength= this.genericsIdentifiersLengthStack.length; if (++this.genericsIdentifiersLengthPtr >= stackLength) { System.arraycopy( this.genericsIdentifiersLengthStack, 0, this.genericsIdentifiersLengthStack= new int[stackLength + GenericsStackIncrement], 0, stackLength); } this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr]= pos; } protected void pushOnGenericsLengthStack(int pos) { int stackLength= this.genericsLengthStack.length; if (++this.genericsLengthPtr >= stackLength) { System.arraycopy( this.genericsLengthStack, 0, this.genericsLengthStack= new int[stackLength + GenericsStackIncrement], 0, stackLength); } this.genericsLengthStack[this.genericsLengthPtr]= pos; } protected void pushOnGenericsStack(ASTNode node) { /*add a new obj on top of the generics stack genericsPtr points on the top*/ int stackLength= this.genericsStack.length; if (++this.genericsPtr >= stackLength) { System.arraycopy( this.genericsStack, 0, this.genericsStack= new ASTNode[stackLength + GenericsStackIncrement], 0, stackLength); } this.genericsStack[this.genericsPtr]= node; stackLength= this.genericsLengthStack.length; if (++this.genericsLengthPtr >= stackLength) { System.arraycopy( this.genericsLengthStack, 0, this.genericsLengthStack= new int[stackLength + GenericsStackIncrement], 0, stackLength); } this.genericsLengthStack[this.genericsLengthPtr]= 1; } protected void pushOnIntStack(int pos) { int stackLength= this.intStack.length; if (++this.intPtr >= stackLength) { System.arraycopy( this.intStack, 0, this.intStack= new int[stackLength + StackIncrement], 0, stackLength); } this.intStack[this.intPtr]= pos; } protected void pushOnRealBlockStack(int i) { int stackLength= this.realBlockStack.length; if (++this.realBlockPtr >= stackLength) { System.arraycopy( this.realBlockStack, 0, this.realBlockStack= new int[stackLength + StackIncrement], 0, stackLength); } this.realBlockStack[this.realBlockPtr]= i; } protected void recoverStatements() { class MethodVisitor extends ASTVisitor { public ASTVisitor typeVisitor; TypeDeclaration enclosingType; // used only for initializer TypeDeclaration[] types= new TypeDeclaration[0]; int typePtr= -1; public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { endVisitMethod(constructorDeclaration, scope); } public void endVisit(Initializer initializer, MethodScope scope) { if (initializer.block == null) return; TypeDeclaration[] foundTypes= null; int length= 0; if (this.typePtr > -1) { length= this.typePtr + 1; foundTypes= new TypeDeclaration[length]; System.arraycopy(this.types, 0, foundTypes, 0, length); } ReferenceContext oldContext= Parser.this.referenceContext; Parser.this.recoveryScanner.resetTo(initializer.bodyStart, initializer.bodyEnd); Scanner oldScanner= Parser.this.scanner; Parser.this.scanner= Parser.this.recoveryScanner; parseStatements( this.enclosingType, initializer.bodyStart, initializer.bodyEnd, foundTypes, Parser.this.compilationUnit); Parser.this.scanner= oldScanner; Parser.this.referenceContext= oldContext; for (int i= 0; i < length; i++) { foundTypes[i].traverse(this.typeVisitor, scope); } } public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) { endVisitMethod(methodDeclaration, scope); } private void endVisitMethod(AbstractMethodDeclaration methodDeclaration, ClassScope scope) { TypeDeclaration[] foundTypes= null; int length= 0; if (this.typePtr > -1) { length= this.typePtr + 1; foundTypes= new TypeDeclaration[length]; System.arraycopy(this.types, 0, foundTypes, 0, length); } ReferenceContext oldContext= Parser.this.referenceContext; Parser.this.recoveryScanner.resetTo(methodDeclaration.bodyStart, methodDeclaration.bodyEnd); Scanner oldScanner= Parser.this.scanner; Parser.this.scanner= Parser.this.recoveryScanner; parseStatements( methodDeclaration, methodDeclaration.bodyStart, methodDeclaration.bodyEnd, foundTypes, Parser.this.compilationUnit); Parser.this.scanner= oldScanner; Parser.this.referenceContext= oldContext; for (int i= 0; i < length; i++) { foundTypes[i].traverse(this.typeVisitor, scope); } } public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { this.typePtr= -1; return true; } public boolean visit(Initializer initializer, MethodScope scope) { this.typePtr= -1; if (initializer.block == null) return false; return true; } public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { this.typePtr= -1; return true; } private boolean visit(TypeDeclaration typeDeclaration) { if (this.types.length <= ++this.typePtr) { int length= this.typePtr; System.arraycopy(this.types, 0, this.types= new TypeDeclaration[length * 2 + 1], 0, length); } this.types[this.typePtr]= typeDeclaration; return false; } public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) { return this.visit(typeDeclaration); } public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) { return this.visit(typeDeclaration); } } class TypeVisitor extends ASTVisitor { public MethodVisitor methodVisitor; TypeDeclaration[] types= new TypeDeclaration[0]; int typePtr= -1; public void endVisit(TypeDeclaration typeDeclaration, BlockScope scope) { endVisitType(); } public void endVisit(TypeDeclaration typeDeclaration, ClassScope scope) { endVisitType(); } private void endVisitType() { this.typePtr--; } public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { if (constructorDeclaration.isDefaultConstructor()) return false; constructorDeclaration.traverse(this.methodVisitor, scope); return false; } public boolean visit(Initializer initializer, MethodScope scope) { if (initializer.block == null) return false; this.methodVisitor.enclosingType= this.types[this.typePtr]; initializer.traverse(this.methodVisitor, scope); return false; } public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { methodDeclaration.traverse(this.methodVisitor, scope); return false; } private boolean visit(TypeDeclaration typeDeclaration) { if (this.types.length <= ++this.typePtr) { int length= this.typePtr; System.arraycopy(this.types, 0, this.types= new TypeDeclaration[length * 2 + 1], 0, length); } this.types[this.typePtr]= typeDeclaration; return true; } public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) { return this.visit(typeDeclaration); } public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) { return this.visit(typeDeclaration); } } MethodVisitor methodVisitor= new MethodVisitor(); TypeVisitor typeVisitor= new TypeVisitor(); methodVisitor.typeVisitor= typeVisitor; typeVisitor.methodVisitor= methodVisitor; if (this.referenceContext instanceof AbstractMethodDeclaration) { ((AbstractMethodDeclaration)this.referenceContext).traverse(methodVisitor, (ClassScope)null); } else if (this.referenceContext instanceof TypeDeclaration) { TypeDeclaration typeContext= (TypeDeclaration)this.referenceContext; int length= typeContext.fields.length; for (int i= 0; i < length; i++) { final FieldDeclaration fieldDeclaration= typeContext.fields[i]; switch (fieldDeclaration.getKind()) { case AbstractVariableDeclaration.INITIALIZER: Initializer initializer= (Initializer)fieldDeclaration; if (initializer.block == null) break; methodVisitor.enclosingType= typeContext; initializer.traverse(methodVisitor, (MethodScope)null); break; } } } } public void recoveryExitFromVariable() { if (this.currentElement != null && this.currentElement.parent != null) { if (this.currentElement instanceof RecoveredLocalVariable) { int end= ((RecoveredLocalVariable)this.currentElement).localDeclaration.sourceEnd; this.currentElement.updateSourceEndIfNecessary(end); this.currentElement= this.currentElement.parent; } else if (this.currentElement instanceof RecoveredField && !(this.currentElement instanceof RecoveredInitializer)) { // Do not move focus to parent if we are still inside an array initializer // https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 if (this.currentElement.bracketBalance <= 0) { int end= ((RecoveredField)this.currentElement).fieldDeclaration.sourceEnd; this.currentElement.updateSourceEndIfNecessary(end); this.currentElement= this.currentElement.parent; } } } } /* Token check performed on every token shift once having entered * recovery mode. */ public void recoveryTokenCheck() { switch (this.currentToken) { case TokenNameStringLiteral: if (this.recordStringLiterals && this.checkExternalizeStrings && this.lastPosistion < this.scanner.currentPosition && !this.statementRecoveryActivated) { StringLiteral stringLiteral= createStringLiteral( this.scanner.getCurrentTokenSourceString(), this.scanner.startPosition, this.scanner.currentPosition - 1, Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr)); this.compilationUnit.recordStringLiteral(stringLiteral, this.currentElement != null); } break; case TokenNameLBRACE: RecoveredElement newElement= null; if (!this.ignoreNextOpeningBrace) { newElement= this.currentElement.updateOnOpeningBrace(this.scanner.startPosition - 1, this.scanner.currentPosition - 1); } this.lastCheckPoint= this.scanner.currentPosition; if (newElement != null) { // null means nothing happened this.restartRecovery= true; // opening brace detected this.currentElement= newElement; } break; case TokenNameRBRACE: this.rBraceStart= this.scanner.startPosition - 1; this.rBraceEnd= this.scanner.currentPosition - 1; this.endPosition= flushCommentsDefinedPriorTo(this.rBraceEnd); newElement= this.currentElement.updateOnClosingBrace(this.scanner.startPosition, this.rBraceEnd); this.lastCheckPoint= this.scanner.currentPosition; if (newElement != this.currentElement) { this.currentElement= newElement; // if (newElement instanceof RecoveredField && this.dietInt <= 0) { // if (((RecoveredField)newElement).fieldDeclaration.type == null) { // enum constant // this.isInsideEnumConstantPart = true; // restore status // } // } } break; case TokenNameSEMICOLON: this.endStatementPosition= this.scanner.currentPosition - 1; this.endPosition= this.scanner.startPosition - 1; RecoveredType currentType= currentRecoveryType(); if (currentType != null) { currentType.insideEnumConstantPart= false; } //$FALL-THROUGH$ default: { if (this.rBraceEnd > this.rBraceSuccessorStart && this.scanner.currentPosition != this.scanner.startPosition) { this.rBraceSuccessorStart= this.scanner.startPosition; } break; } } this.ignoreNextOpeningBrace= false; } // A P I protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) { if (this.referenceContext instanceof MethodDeclaration) { MethodDeclaration methodDeclaration= (MethodDeclaration)this.referenceContext; if ((methodDeclaration.bits & ASTNode.ErrorInSignature) != 0) { return; } } this.compilationUnit.compilationResult.lineSeparatorPositions= this.scanner.getLineEnds(); this.scanner.recordLineSeparator= false; int start= this.scanner.initialPosition; int end= this.scanner.eofPosition == Integer.MAX_VALUE ? this.scanner.eofPosition : this.scanner.eofPosition - 1; if (isDietParse) { TypeDeclaration[] types= this.compilationUnit.types; int[][] intervalToSkip= org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types); DiagnoseParser diagnoseParser= new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2], this.options); diagnoseParser.diagnoseParse(false); reportSyntaxErrorsForSkippedMethod(types); this.scanner.resetTo(start, end); } else { DiagnoseParser diagnoseParser= new DiagnoseParser(this, oldFirstToken, start, end, this.options); diagnoseParser.diagnoseParse(this.options.performStatementsRecovery); } } private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types) { if (types != null) { for (int i= 0; i < types.length; i++) { TypeDeclaration[] memberTypes= types[i].memberTypes; if (memberTypes != null) { reportSyntaxErrorsForSkippedMethod(memberTypes); } AbstractMethodDeclaration[] methods= types[i].methods; if (methods != null) { for (int j= 0; j < methods.length; j++) { AbstractMethodDeclaration method= methods[j]; if ((method.bits & ASTNode.ErrorInSignature) != 0) { if (method.isAnnotationMethod()) { DiagnoseParser diagnoseParser= new DiagnoseParser(this, TokenNameQUESTION, method.declarationSourceStart, method.declarationSourceEnd, this.options); diagnoseParser.diagnoseParse(this.options.performStatementsRecovery); } else { DiagnoseParser diagnoseParser= new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd, this.options); diagnoseParser.diagnoseParse(this.options.performStatementsRecovery); } } } } FieldDeclaration[] fields= types[i].fields; if (fields != null) { int length= fields.length; for (int j= 0; j < length; j++) { if (fields[j] instanceof Initializer) { Initializer initializer= (Initializer)fields[j]; if ((initializer.bits & ASTNode.ErrorInSignature) != 0) { DiagnoseParser diagnoseParser= new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd, this.options); diagnoseParser.diagnoseParse(this.options.performStatementsRecovery); } } } } } } } protected void resetModifiers() { this.modifiers= ClassFileConstants.AccDefault; this.modifiersSourceStart= -1; // <-- see comment into modifiersFlag(int) this.scanner.commentPtr= -1; } /* * Reset context so as to resume to regular parse loop */ protected void resetStacks() { this.astPtr= -1; this.astLengthPtr= -1; this.expressionPtr= -1; this.expressionLengthPtr= -1; this.identifierPtr= -1; this.identifierLengthPtr= -1; this.intPtr= -1; this.nestedMethod[this.nestedType= 0]= 0; // need to reset for further reuse this.variablesCounter[this.nestedType]= 0; this.dimensions= 0; this.realBlockStack[this.realBlockPtr= 0]= 0; this.recoveredStaticInitializerStart= 0; this.listLength= 0; this.listTypeParameterLength= 0; this.genericsIdentifiersLengthPtr= -1; this.genericsLengthPtr= -1; this.genericsPtr= -1; } /* * Reset context so as to resume to regular parse loop * If unable to reset for resuming, answers false. * * Move checkpoint location, reset internal stacks and * decide which grammar goal is activated. */ protected boolean resumeAfterRecovery() { if (!this.methodRecoveryActivated && !this.statementRecoveryActivated) { // reset internal stacks resetStacks(); resetModifiers(); /* attempt to move checkpoint location */ if (!moveRecoveryCheckpoint()) { return false; } // only look for headers if (this.referenceContext instanceof CompilationUnitDeclaration) { goForHeaders(); this.diet= true; // passed this point, will not consider method bodies return true; } // does not know how to restart return false; } else if (!this.statementRecoveryActivated) { // reset internal stacks resetStacks(); resetModifiers(); /* attempt to move checkpoint location */ if (!moveRecoveryCheckpoint()) { return false; } // only look for headers goForHeaders(); return true; } else { return false; } } protected boolean resumeOnSyntaxError() { /* request recovery initialization */ if (this.currentElement == null) { // Reset javadoc before restart parsing after recovery this.javadoc= null; // do not investigate deeper in statement recovery if (this.statementRecoveryActivated) return false; // build some recovered elements this.currentElement= buildInitialRecoveryState(); } /* do not investigate deeper in recovery when no recovered element */ if (this.currentElement == null) return false; /* manual forced recovery restart - after headers */ if (this.restartRecovery) { this.restartRecovery= false; } /* update recovery state with current error state of the parser */ updateRecoveryState(); if (getFirstToken() == TokenNameAND) { if (this.referenceContext instanceof CompilationUnitDeclaration) { TypeDeclaration typeDeclaration= new TypeDeclaration(this.referenceContext.compilationResult()); typeDeclaration.name= Util.EMPTY_STRING.toCharArray(); this.currentElement= this.currentElement.add(typeDeclaration, 0); } } if (this.lastPosistion < this.scanner.currentPosition) { this.lastPosistion= this.scanner.currentPosition; this.scanner.lastPosition= this.scanner.currentPosition; } /* attempt to reset state in order to resume to parse loop */ return resumeAfterRecovery(); } public void setMethodsFullRecovery(boolean enabled) { this.options.performMethodsFullRecovery= enabled; } public void setStatementsRecovery(boolean enabled) { if (enabled) this.options.performMethodsFullRecovery= true; this.options.performStatementsRecovery= enabled; } public String toString() { String s= "lastCheckpoint : int = " + String.valueOf(this.lastCheckPoint) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ s= s + "identifierStack : char[" + (this.identifierPtr + 1) + "][] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.identifierPtr; i++) { s= s + "\"" + String.valueOf(this.identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "identifierLengthStack : int[" + (this.identifierLengthPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.identifierLengthPtr; i++) { s= s + this.identifierLengthStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "astLengthStack : int[" + (this.astLengthPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.astLengthPtr; i++) { s= s + this.astLengthStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "astPtr : int = " + String.valueOf(this.astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ s= s + "intStack : int[" + (this.intPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.intPtr; i++) { s= s + this.intStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "expressionLengthStack : int[" + (this.expressionLengthPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.expressionLengthPtr; i++) { s= s + this.expressionLengthStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "expressionPtr : int = " + String.valueOf(this.expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ s= s + "genericsIdentifiersLengthStack : int[" + (this.genericsIdentifiersLengthPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.genericsIdentifiersLengthPtr; i++) { s= s + this.genericsIdentifiersLengthStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "genericsLengthStack : int[" + (this.genericsLengthPtr + 1) + "] = {"; //$NON-NLS-1$ //$NON-NLS-2$ for (int i= 0; i <= this.genericsLengthPtr; i++) { s= s + this.genericsLengthStack[i] + ","; //$NON-NLS-1$ } s= s + "}\n"; //$NON-NLS-1$ s= s + "genericsPtr : int = " + String.valueOf(this.genericsPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ s= s + "\n\n\n----------------Scanner--------------\n" + this.scanner.toString(); //$NON-NLS-1$ return s; } /* * Update recovery state based on current parser/scanner state */ protected void updateRecoveryState() { /* expose parser state to recovery state */ this.currentElement.updateFromParserState(); /* check and update recovered state based on current token, this action is also performed when shifting token after recovery got activated once. */ recoveryTokenCheck(); } protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) { //fields is a definition of fields that are grouped together like in //public int[] a, b[], c //which results into 3 fields. FieldDeclaration field; int endTypeDeclarationPosition= -1 + this.astStack[this.astPtr - variableDeclaratorsCounter + 1].sourceStart; for (int i= 0; i < variableDeclaratorsCounter - 1; i++) { //last one is special(see below) field= (FieldDeclaration)this.astStack[this.astPtr - i - 1]; field.endPart1Position= endTypeDeclarationPosition; field.endPart2Position= -1 + this.astStack[this.astPtr - i].sourceStart; } //last one (field= (FieldDeclaration)this.astStack[this.astPtr]).endPart1Position= endTypeDeclarationPosition; field.endPart2Position= field.declarationSourceEnd; } protected void updateSourcePosition(Expression exp) { //update the source Position of the expression //this.intStack : int int //--> //this.intStack : exp.sourceEnd= this.intStack[this.intPtr--]; exp.sourceStart= this.intStack[this.intPtr--]; } }