View | Details | Raw Unified | Return to bug 245257 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java (-19 / +19 lines)
Lines 27-60 Link Here
27
	public final static int Bit2 = 0x2;					// return type (operator) | name reference kind (name ref) | has local type (type, method, field decl)
27
	public final static int Bit2 = 0x2;					// return type (operator) | name reference kind (name ref) | has local type (type, method, field decl)
28
	public final static int Bit3 = 0x4;					// return type (operator) | name reference kind (name ref) | implicit this (this ref)
28
	public final static int Bit3 = 0x4;					// return type (operator) | name reference kind (name ref) | implicit this (this ref)
29
	public final static int Bit4 = 0x8;					// return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
29
	public final static int Bit4 = 0x8;					// return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
30
	public final static int Bit5 = 0x10;				// value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
30
	public final static int Bit5 = 0x10;					// value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
31
	public final static int Bit6 = 0x20;				// depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference)
31
	public final static int Bit6 = 0x20;					// depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference)
32
	public final static int Bit7 = 0x40;				// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
32
	public final static int Bit7 = 0x40;					// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
33
	public final static int Bit8 = 0x80;				// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration)
33
	public final static int Bit8 = 0x80;					// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration)
34
	public final static int Bit9 = 0x100;				// depth (name ref, msg) | operator (operator) | is local type (type decl)
34
	public final static int Bit9 = 0x100;				// depth (name ref, msg) | operator (operator) | is local type (type decl)
35
	public final static int Bit10= 0x200;				// depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
35
	public final static int Bit10= 0x200;				// depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
36
	public final static int Bit11 = 0x400;				// depth (name ref, msg) | operator (operator) | is member type (type decl)
36
	public final static int Bit11 = 0x400;				// depth (name ref, msg) | operator (operator) | is member type (type decl)
37
	public final static int Bit12 = 0x800;				// depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
37
	public final static int Bit12 = 0x800;				// depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
38
	public final static int Bit13 = 0x1000;				// depth (name ref, msg) | is secondary type (type decl)
38
	public final static int Bit13 = 0x1000;			// depth (name ref, msg) | is secondary type (type decl)
39
	public final static int Bit14 = 0x2000;				// strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
39
	public final static int Bit14 = 0x2000;			// strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
40
	public final static int Bit15 = 0x4000;				// is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) | superAccess (javadoc allocation expression/javadoc message send/javadoc return statement)
40
	public final static int Bit15 = 0x4000;			// is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) | superAccess (javadoc allocation expression/javadoc message send/javadoc return statement)
41
	public final static int Bit16 = 0x8000;				// in javadoc comment (name ref, type ref, msg)
41
	public final static int Bit16 = 0x8000;			// in javadoc comment (name ref, type ref, msg)
42
	public final static int Bit17 = 0x10000;			// compound assigned (reference lhs)
42
	public final static int Bit17 = 0x10000;			// compound assigned (reference lhs)
43
	public final static int Bit18 = 0x20000;			// non null (expression) | onDemand (import reference)
43
	public final static int Bit18 = 0x20000;			// non null (expression) | onDemand (import reference)
44
	public final static int Bit19 = 0x40000;			// didResolve (parameterized qualified type ref/parameterized single type ref)  | empty (javadoc return statement)
44
	public final static int Bit19 = 0x40000;			// didResolve (parameterized qualified type ref/parameterized single type ref)  | empty (javadoc return statement)
45
	public final static int Bit20 = 0x80000;
45
	public final static int Bit20 = 0x80000;
46
	public final static int Bit21 = 0x100000;
46
	public final static int Bit21 = 0x100000;
47
	public final static int Bit22 = 0x200000;			// parenthesis count (expression) | used (import reference)
47
	public final static int Bit22 = 0x200000;		// parenthesis count (expression) | used (import reference)
48
	public final static int Bit23 = 0x400000;			// parenthesis count (expression)
48
	public final static int Bit23 = 0x400000;		// parenthesis count (expression)
49
	public final static int Bit24 = 0x800000;			// parenthesis count (expression)
49
	public final static int Bit24 = 0x800000;		// parenthesis count (expression)
50
	public final static int Bit25 = 0x1000000;			// parenthesis count (expression)
50
	public final static int Bit25 = 0x1000000;		// parenthesis count (expression)
51
	public final static int Bit26 = 0x2000000;			// parenthesis count (expression)
51
	public final static int Bit26 = 0x2000000;		// parenthesis count (expression)
52
	public final static int Bit27 = 0x4000000;			// parenthesis count (expression)
52
	public final static int Bit27 = 0x4000000;		// parenthesis count (expression)
53
	public final static int Bit28 = 0x8000000;			// parenthesis count (expression)
53
	public final static int Bit28 = 0x8000000;		// parenthesis count (expression)
54
	public final static int Bit29 = 0x10000000;			// parenthesis count (expression)
54
	public final static int Bit29 = 0x10000000;	// parenthesis count (expression)
55
	public final static int Bit30 = 0x20000000;			// elseif (if statement) | try block exit (try statement) | fall-through (case statement) | ignore no effect assign (expression ref) | needScope (for statement) | isAnySubRoutineEscaping (return statement) | blockExit (synchronized statement)
55
	public final static int Bit30 = 0x20000000;	// elseif (if statement) | try block exit (try statement) | fall-through (case statement) | ignore no effect assign (expression ref) | needScope (for statement) | isAnySubRoutineEscaping (return statement) | blockExit (synchronized statement)
56
	public final static int Bit31 = 0x40000000;			// local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) | isSynchronized (return statement) | thenExit (if statement)
56
	public final static int Bit31 = 0x40000000;	// local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) | isSynchronized (return statement) | thenExit (if statement)
57
	public final static int Bit32 = 0x80000000;			// reachable (statement)
57
	public final static int Bit32 = 0x80000000;	// reachable (statement)
58
58
59
	public final static long Bit32L = 0x80000000L;
59
	public final static long Bit32L = 0x80000000L;
60
	public final static long Bit33L = 0x100000000L;
60
	public final static long Bit33L = 0x100000000L;
(-)compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java (-1048 / +1097 lines)
Lines 45-53 Link Here
45
import org.eclipse.jdt.internal.compiler.util.Util;
45
import org.eclipse.jdt.internal.compiler.util.Util;
46
46
47
public class Parser implements  ParserBasicInformation, TerminalTokens, OperatorIds, TypeIds {
47
public class Parser implements  ParserBasicInformation, TerminalTokens, OperatorIds, TypeIds {
48
	
48
	protected static final int THIS_CALL = ExplicitConstructorCall.This;
49
	protected static final int THIS_CALL = ExplicitConstructorCall.This;
49
	protected static final int SUPER_CALL = ExplicitConstructorCall.Super;
50
	protected static final int SUPER_CALL = ExplicitConstructorCall.Super;
50
51
	protected static final char[] FALL_THROUGH_TAG = "$FALL-THROUGH$".toCharArray(); //$NON-NLS-1$
52
	
51
	public static char asb[] = null;
53
	public static char asb[] = null;
52
	public static char asr[] = null;
54
	public static char asr[] = null;
53
	//ast stack
55
	//ast stack
Lines 113-219 Link Here
113
	private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
115
	private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
114
	public static boolean VERBOSE_RECOVERY = false;
116
	public static boolean VERBOSE_RECOVERY = false;
115
117
116
117
118
	protected int astLengthPtr;
119
	protected int[] astLengthStack;
120
	protected int astPtr;
121
	protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
122
	public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
123
	protected RecoveredElement currentElement;
124
	public int currentToken;
125
	protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
126
	protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
127
	protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
128
	protected int endStatementPosition;
129
	protected int expressionLengthPtr;
130
	protected int[] expressionLengthStack;
131
	protected int expressionPtr;
132
	protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
133
	public int firstToken ; // handle for multiple parsing goals
134
135
	// generics management
136
	protected int genericsIdentifiersLengthPtr;
137
	protected int[] genericsIdentifiersLengthStack = new int[GenericsStackIncrement];
138
	protected int genericsLengthPtr;
139
	protected int[] genericsLengthStack = new int[GenericsStackIncrement];
140
	protected int genericsPtr;
141
	protected ASTNode[] genericsStack = new ASTNode[GenericsStackIncrement];
142
143
	protected boolean hasError;
144
	protected boolean hasReportedError;
145
146
	//identifiers stacks
147
	protected int identifierLengthPtr;
148
	protected int[] identifierLengthStack;
149
	protected long[] identifierPositionStack;
150
	protected int identifierPtr;
151
	protected char[][] identifierStack;
152
153
	protected boolean ignoreNextOpeningBrace;
154
	//positions , dimensions , .... (int stacks)
155
	protected int intPtr;
156
	protected int[] intStack;
157
	public int lastAct ; //handle for multiple parsing goals
158
159
	//error recovery management
160
	protected int lastCheckPoint;
161
	protected int lastErrorEndPosition;
162
	protected int lastErrorEndPositionBeforeRecovery = -1;
163
	protected int lastIgnoredToken, nextIgnoredToken;
164
	protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
165
	protected int listTypeParameterLength; // for recovering some incomplete list (type parameters)
166
	protected int lParenPos,rParenPos; //accurate only when used !
167
	protected int modifiers;
168
	protected int modifiersSourceStart;
169
	protected int[] nestedMethod; //the ptr is nestedType
170
	protected int nestedType, dimensions;
171
	ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
172
	Expression [] noExpressions = new Expression[ExpressionStackIncrement];
173
	//modifiers dimensions nestedType etc.......
174
	protected boolean optimizeStringLiterals =true;
175
	protected CompilerOptions options;
176
	protected ProblemReporter problemReporter;
177
	protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
178
	protected int realBlockPtr;
179
	protected int[] realBlockStack;
180
	protected int recoveredStaticInitializerStart;
181
	public ReferenceContext referenceContext;
182
	public boolean reportOnlyOneSyntaxError = false;
183
	public boolean reportSyntaxErrorIsRequired = true;
184
	protected boolean restartRecovery;
185
	protected boolean annotationRecoveryActivated = true;
186
187
	protected int lastPosistion;
188
189
	// statement recovery
190
	public boolean methodRecoveryActivated = false;
191
	protected boolean statementRecoveryActivated = false;
192
	protected TypeDeclaration[] recoveredTypes;
193
	protected int recoveredTypePtr;
194
	protected int nextTypeStart;
195
	protected TypeDeclaration pendingRecoveredType;
196
197
	public RecoveryScanner recoveryScanner;
198
199
	//scanner token
200
	public Scanner scanner;
201
	protected int[] stack = new int[StackIncrement];
202
	protected int stateStackTop;
203
	protected int synchronizedBlockSourceStart;
204
	protected int[] variablesCounter;
205
206
	protected boolean checkExternalizeStrings;
207
	protected boolean recordStringLiterals;
208
209
	// javadoc
210
	public Javadoc javadoc;
211
	public JavadocParser javadocParser;
212
	// used for recovery
213
	protected int lastJavadocEnd;
214
215
	public org.eclipse.jdt.internal.compiler.ReadManager readManager;
216
217
	static {
118
	static {
218
		try{
119
		try{
219
			initTables();
120
			initTables();
Lines 221-874 Link Here
221
			throw new ExceptionInInitializerError(ex.getMessage());
122
			throw new ExceptionInInitializerError(ex.getMessage());
222
		}
123
		}
223
	}
124
	}
224
public static int asi(int state) {
125
	public static int asi(int state) {
225
126
	
226
	return asb[original_state(state)];
127
		return asb[original_state(state)];
227
}
128
	}
228
public final static short base_check(int i) {
129
	public final static short base_check(int i) {
229
	return check_table[i - (NUM_RULES + 1)];
130
		return check_table[i - (NUM_RULES + 1)];
230
}
131
	}
231
private final static void buildFile(String filename, List listToDump) {
132
	private final static void buildFile(String filename, List listToDump) {
232
	BufferedWriter writer = null;
133
		BufferedWriter writer = null;
233
	try {
134
		try {
234
		writer = new BufferedWriter(new FileWriter(filename));
135
			writer = new BufferedWriter(new FileWriter(filename));
235
    	for (Iterator iterator = listToDump.iterator(); iterator.hasNext(); ) {
136
	    	for (Iterator iterator = listToDump.iterator(); iterator.hasNext(); ) {
236
    		writer.write(String.valueOf(iterator.next()));
137
	    		writer.write(String.valueOf(iterator.next()));
237
    	}
138
	    	}
238
    	writer.flush();
139
	    	writer.flush();
239
	} catch(IOException e) {
140
		} catch(IOException e) {
240
		// ignore
141
			// ignore
241
	} finally {
142
		} finally {
242
		if (writer != null) {
143
			if (writer != null) {
243
        	try {
144
	        	try {
244
				writer.close();
145
					writer.close();
245
			} catch (IOException e1) {
146
				} catch (IOException e1) {
246
				// ignore
147
					// ignore
148
				}
247
			}
149
			}
248
		}
150
		}
151
		System.out.println(filename + " creation complete"); //$NON-NLS-1$
249
	}
152
	}
250
	System.out.println(filename + " creation complete"); //$NON-NLS-1$
153
	private static void buildFileForCompliance(
251
}
154
			String file,
252
private final static String[] buildFileForName(String filename, String contents) {
155
			int length,
253
	String[] result = new String[contents.length()];
156
			String[] tokens) {
254
	result[0] = null;
157
	
255
	int resultCount = 1;
158
			byte[] result = new byte[length * 8];
256
159
	
257
	StringBuffer buffer = new StringBuffer();
160
			for (int i = 0; i < tokens.length; i = i + 3) {
258
161
				if("2".equals(tokens[i])) { //$NON-NLS-1$
259
	int start = contents.indexOf("name[]"); //$NON-NLS-1$
162
					int index = Integer.parseInt(tokens[i + 1]);
260
	start = contents.indexOf('\"', start);
163
					String token = tokens[i + 2].trim();
261
	int end = contents.indexOf("};", start); //$NON-NLS-1$
164
					long compliance = 0;
262
165
					if("1.4".equals(token)) { //$NON-NLS-1$
263
	contents = contents.substring(start, end);
166
						compliance = ClassFileConstants.JDK1_4;
264
167
					} else if("1.5".equals(token)) { //$NON-NLS-1$
265
	boolean addLineSeparator = false;
168
						compliance = ClassFileConstants.JDK1_5;
266
	int tokenStart = -1;
169
					} else if("recovery".equals(token)) { //$NON-NLS-1$
267
	StringBuffer currentToken = new StringBuffer();
170
						compliance = ClassFileConstants.JDK_DEFERRED;
268
	for (int i = 0; i < contents.length(); i++) {
171
					}
269
		char c = contents.charAt(i);
172
	
270
		if(c == '\"') {
173
					int j = index * 8;
271
			if(tokenStart == -1) {
174
					result[j] = 	(byte)(compliance >>> 56);
272
				tokenStart = i + 1;
175
					result[j + 1] = (byte)(compliance >>> 48);
273
			} else {
176
					result[j + 2] = (byte)(compliance >>> 40);
274
				if(addLineSeparator) {
177
					result[j + 3] = (byte)(compliance >>> 32);
275
					buffer.append('\n');
178
					result[j + 4] = (byte)(compliance >>> 24);
276
					result[resultCount++] = currentToken.toString();
179
					result[j + 5] = (byte)(compliance >>> 16);
277
					currentToken = new StringBuffer();
180
					result[j + 6] = (byte)(compliance >>> 8);
181
					result[j + 7] = (byte)(compliance);
278
				}
182
				}
279
				String token = contents.substring(tokenStart, i);
183
			}
280
				if(token.equals(ERROR_TOKEN)){
184
	
281
					token = INVALID_CHARACTER;
185
			buildFileForTable(file, result);
282
				} else if(token.equals(EOF_TOKEN)) {
186
		}
283
					token = UNEXPECTED_EOF;
187
	private final static String[] buildFileForName(String filename, String contents) {
188
		String[] result = new String[contents.length()];
189
		result[0] = null;
190
		int resultCount = 1;
191
	
192
		StringBuffer buffer = new StringBuffer();
193
	
194
		int start = contents.indexOf("name[]"); //$NON-NLS-1$
195
		start = contents.indexOf('\"', start);
196
		int end = contents.indexOf("};", start); //$NON-NLS-1$
197
	
198
		contents = contents.substring(start, end);
199
	
200
		boolean addLineSeparator = false;
201
		int tokenStart = -1;
202
		StringBuffer currentToken = new StringBuffer();
203
		for (int i = 0; i < contents.length(); i++) {
204
			char c = contents.charAt(i);
205
			if(c == '\"') {
206
				if(tokenStart == -1) {
207
					tokenStart = i + 1;
208
				} else {
209
					if(addLineSeparator) {
210
						buffer.append('\n');
211
						result[resultCount++] = currentToken.toString();
212
						currentToken = new StringBuffer();
213
					}
214
					String token = contents.substring(tokenStart, i);
215
					if(token.equals(ERROR_TOKEN)){
216
						token = INVALID_CHARACTER;
217
					} else if(token.equals(EOF_TOKEN)) {
218
						token = UNEXPECTED_EOF;
219
					}
220
					buffer.append(token);
221
					currentToken.append(token);
222
					addLineSeparator = true;
223
					tokenStart = -1;
284
				}
224
				}
285
				buffer.append(token);
225
			}
286
				currentToken.append(token);
226
			if(tokenStart == -1 && c == '+'){
287
				addLineSeparator = true;
227
				addLineSeparator = false;
288
				tokenStart = -1;
289
			}
228
			}
290
		}
229
		}
291
		if(tokenStart == -1 && c == '+'){
230
		if(currentToken.length() > 0) {
292
			addLineSeparator = false;
231
			result[resultCount++] = currentToken.toString();
293
		}
232
		}
233
	
234
		buildFileForTable(filename, buffer.toString().toCharArray());
235
	
236
		System.arraycopy(result, 0, result = new String[resultCount], 0, resultCount);
237
		return result;
294
	}
238
	}
295
	if(currentToken.length() > 0) {
239
	private static void buildFileForReadableName(
296
		result[resultCount++] = currentToken.toString();
240
		String file,
297
	}
241
		char[] newLhs,
298
242
		char[] newNonTerminalIndex,
299
	buildFileForTable(filename, buffer.toString().toCharArray());
243
		String[] newName,
300
244
		String[] tokens) {
301
	System.arraycopy(result, 0, result = new String[resultCount], 0, resultCount);
245
	
302
	return result;
246
		ArrayList entries = new ArrayList();
303
}
247
	
304
private static void buildFileForReadableName(
248
		boolean[] alreadyAdded = new boolean[newName.length];
305
	String file,
249
	
306
	char[] newLhs,
250
		for (int i = 0; i < tokens.length; i = i + 3) {
307
	char[] newNonTerminalIndex,
251
			if("1".equals(tokens[i])) { //$NON-NLS-1$
308
	String[] newName,
252
				int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i + 1])]];
309
	String[] tokens) {
253
				StringBuffer buffer = new StringBuffer();
310
254
				if(!alreadyAdded[index]) {
311
	ArrayList entries = new ArrayList();
255
					alreadyAdded[index] = true;
312
256
					buffer.append(newName[index]);
313
	boolean[] alreadyAdded = new boolean[newName.length];
257
					buffer.append('=');
314
258
					buffer.append(tokens[i+2].trim());
315
	for (int i = 0; i < tokens.length; i = i + 3) {
259
					buffer.append('\n');
316
		if("1".equals(tokens[i])) { //$NON-NLS-1$
260
					entries.add(String.valueOf(buffer));
317
			int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i + 1])]];
261
				}
318
			StringBuffer buffer = new StringBuffer();
319
			if(!alreadyAdded[index]) {
320
				alreadyAdded[index] = true;
321
				buffer.append(newName[index]);
322
				buffer.append('=');
323
				buffer.append(tokens[i+2].trim());
324
				buffer.append('\n');
325
				entries.add(String.valueOf(buffer));
326
			}
262
			}
327
		}
263
		}
328
	}
264
		int i = 1;
329
	int i = 1;
265
		while(!INVALID_CHARACTER.equals(newName[i])) i++;
330
	while(!INVALID_CHARACTER.equals(newName[i])) i++;
266
		i++;
331
	i++;
267
		for (; i < alreadyAdded.length; i++) {
332
	for (; i < alreadyAdded.length; i++) {
268
			if(!alreadyAdded[i]) {
333
		if(!alreadyAdded[i]) {
269
				System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
334
			System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
270
			}
335
		}
271
		}
272
		Collections.sort(entries);
273
		buildFile(file, entries);
336
	}
274
	}
337
	Collections.sort(entries);
275
	private final static void buildFileForTable(String filename, byte[] bytes) {
338
	buildFile(file, entries);
276
		java.io.FileOutputStream stream = null;
339
}
277
		try {
340
private static void buildFilesForRecoveryTemplates(
278
			stream = new java.io.FileOutputStream(filename);
341
	String indexFilename,
279
			stream.write(bytes);
342
	String templatesFilename,
280
		} catch(IOException e) {
343
	char[] newTerminalIndex,
281
			// ignore
344
	char[] newNonTerminalIndex,
282
		} finally {
345
	String[] newName,
283
			if (stream != null) {
346
	char[] newLhs,
284
				try {
347
	String[] tokens) {
285
					stream.close();
348
286
				} catch (IOException e) {
349
	int[] newReverse = computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName);
287
					// ignore
350
288
				}
351
	char[] newRecoveyTemplatesIndex = new char[newNonTerminalIndex.length];
352
	char[] newRecoveyTemplates = new char[newNonTerminalIndex.length];
353
	int newRecoveyTemplatesPtr = 0;
354
355
	for (int i = 0; i < tokens.length; i = i + 3) {
356
		if("3".equals(tokens[i])) { //$NON-NLS-1$
357
			int length = newRecoveyTemplates.length;
358
			if(length == newRecoveyTemplatesPtr + 1) {
359
				System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
360
			}
361
			newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
362
363
			int index = newLhs[Integer.parseInt(tokens[i + 1])];
364
365
			newRecoveyTemplatesIndex[index] = (char)newRecoveyTemplatesPtr;
366
367
			String token = tokens[i + 2].trim();
368
			java.util.StringTokenizer st = new java.util.StringTokenizer(new String(token), " ");  //$NON-NLS-1$
369
			String[] terminalNames = new String[st.countTokens()];
370
			int t = 0;
371
			while (st.hasMoreTokens()) {
372
				terminalNames[t++] = st.nextToken();
373
			}
289
			}
374
290
		}
375
			for (int j = 0; j < terminalNames.length; j++) {
291
		System.out.println(filename + " creation complete"); //$NON-NLS-1$
376
				int symbol = getSymbol(terminalNames[j], newName, newReverse);
292
	}
377
				if(symbol > -1) {
293
	private final static void buildFileForTable(String filename, char[] chars) {
378
					length = newRecoveyTemplates.length;
294
		byte[] bytes = new byte[chars.length * 2];
379
					if(length == newRecoveyTemplatesPtr + 1) {
295
		for (int i = 0; i < chars.length; i++) {
380
						System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
296
			bytes[2 * i] = (byte) (chars[i] >>> 8);
381
					}
297
			bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
382
					newRecoveyTemplates[newRecoveyTemplatesPtr++] = (char)symbol;
298
		}
299
	
300
		java.io.FileOutputStream stream = null;
301
		try {
302
			stream = new java.io.FileOutputStream(filename);
303
			stream.write(bytes);
304
		} catch(IOException e) {
305
			// ignore
306
		} finally {
307
			if (stream != null) {
308
				try {
309
					stream.close();
310
				} catch (IOException e) {
311
					// ignore
383
				}
312
				}
384
			}
313
			}
385
		}
314
		}
315
		System.out.println(filename + " creation complete"); //$NON-NLS-1$
386
	}
316
	}
387
	newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
317
	private final static byte[] buildFileOfByteFor(String filename, String tag, String[] tokens) {
388
	System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr);
318
	
389
319
		//transform the String tokens into chars before dumping then into file
390
	buildFileForTable(indexFilename, newRecoveyTemplatesIndex);
320
	
391
	buildFileForTable(templatesFilename, newRecoveyTemplates);
321
		int i = 0;
392
}
322
		//read upto the tag
393
private static void buildFilesForStatementsRecoveryFilter(
323
		while (!tokens[i++].equals(tag)){/*empty*/}
394
		String filename,
324
		//read upto the }
325
	
326
		byte[] bytes = new byte[tokens.length]; //can't be bigger
327
		int ic = 0;
328
		String token;
329
		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
330
			int c = Integer.parseInt(token);
331
			bytes[ic++] = (byte) c;
332
		}
333
	
334
		//resize
335
		System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
336
	
337
		buildFileForTable(filename, bytes);
338
		return bytes;
339
	}
340
	private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) {
341
	
342
		//transform the String tokens into chars before dumping then into file
343
	
344
		int i = 0;
345
		//read upto the tag
346
		while (!tokens[i++].equals(tag)){/*empty*/}
347
		//read upto the }
348
	
349
		char[] chars = new char[tokens.length]; //can't be bigger
350
		int ic = 0;
351
		String token;
352
		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
353
			int c = Integer.parseInt(token);
354
			chars[ic++] = (char) c;
355
		}
356
	
357
		//resize
358
		System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
359
	
360
		buildFileForTable(filename, chars);
361
		return chars;
362
	}
363
	private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) {
364
	
365
		//transform the String tokens into chars before dumping then into file
366
	
367
		int i = 0;
368
		//read upto the tag
369
		while (!tokens[i++].equals(tag)){/*empty*/}
370
		//read upto the }
371
	
372
		char[] chars = new char[tokens.length]; //can't be bigger
373
		int ic = 0;
374
		String token;
375
		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
376
			int c = Integer.parseInt(token);
377
			chars[ic++] = (char) (c + 32768);
378
		}
379
	
380
		//resize
381
		System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
382
	
383
		buildFileForTable(filename, chars);
384
	}
385
	private static void buildFilesForRecoveryTemplates(
386
		String indexFilename,
387
		String templatesFilename,
388
		char[] newTerminalIndex,
395
		char[] newNonTerminalIndex,
389
		char[] newNonTerminalIndex,
390
		String[] newName,
396
		char[] newLhs,
391
		char[] newLhs,
397
		String[] tokens) {
392
		String[] tokens) {
398
393
	
399
		char[] newStatementsRecoveryFilter = new char[newNonTerminalIndex.length];
394
		int[] newReverse = computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName);
400
395
	
396
		char[] newRecoveyTemplatesIndex = new char[newNonTerminalIndex.length];
397
		char[] newRecoveyTemplates = new char[newNonTerminalIndex.length];
398
		int newRecoveyTemplatesPtr = 0;
399
	
401
		for (int i = 0; i < tokens.length; i = i + 3) {
400
		for (int i = 0; i < tokens.length; i = i + 3) {
402
			if("4".equals(tokens[i])) { //$NON-NLS-1$
401
			if("3".equals(tokens[i])) { //$NON-NLS-1$
402
				int length = newRecoveyTemplates.length;
403
				if(length == newRecoveyTemplatesPtr + 1) {
404
					System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
405
				}
406
				newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
407
	
403
				int index = newLhs[Integer.parseInt(tokens[i + 1])];
408
				int index = newLhs[Integer.parseInt(tokens[i + 1])];
404
409
	
405
				newStatementsRecoveryFilter[index] = 1;
410
				newRecoveyTemplatesIndex[index] = (char)newRecoveyTemplatesPtr;
411
	
412
				String token = tokens[i + 2].trim();
413
				java.util.StringTokenizer st = new java.util.StringTokenizer(new String(token), " ");  //$NON-NLS-1$
414
				String[] terminalNames = new String[st.countTokens()];
415
				int t = 0;
416
				while (st.hasMoreTokens()) {
417
					terminalNames[t++] = st.nextToken();
418
				}
419
	
420
				for (int j = 0; j < terminalNames.length; j++) {
421
					int symbol = getSymbol(terminalNames[j], newName, newReverse);
422
					if(symbol > -1) {
423
						length = newRecoveyTemplates.length;
424
						if(length == newRecoveyTemplatesPtr + 1) {
425
							System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
426
						}
427
						newRecoveyTemplates[newRecoveyTemplatesPtr++] = (char)symbol;
428
					}
429
				}
406
			}
430
			}
407
		}
431
		}
408
		buildFileForTable(filename, newStatementsRecoveryFilter);
432
		newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
409
	}
433
		System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr);
410
private static void buildFileForCompliance(
434
	
411
		String file,
435
		buildFileForTable(indexFilename, newRecoveyTemplatesIndex);
412
		int length,
436
		buildFileForTable(templatesFilename, newRecoveyTemplates);
413
		String[] tokens) {
437
	}
414
438
	private static void buildFilesForStatementsRecoveryFilter(
415
		byte[] result = new byte[length * 8];
439
			String filename,
416
440
			char[] newNonTerminalIndex,
417
		for (int i = 0; i < tokens.length; i = i + 3) {
441
			char[] newLhs,
418
			if("2".equals(tokens[i])) { //$NON-NLS-1$
442
			String[] tokens) {
419
				int index = Integer.parseInt(tokens[i + 1]);
443
	
420
				String token = tokens[i + 2].trim();
444
			char[] newStatementsRecoveryFilter = new char[newNonTerminalIndex.length];
421
				long compliance = 0;
445
	
422
				if("1.4".equals(token)) { //$NON-NLS-1$
446
			for (int i = 0; i < tokens.length; i = i + 3) {
423
					compliance = ClassFileConstants.JDK1_4;
447
				if("4".equals(tokens[i])) { //$NON-NLS-1$
424
				} else if("1.5".equals(token)) { //$NON-NLS-1$
448
					int index = newLhs[Integer.parseInt(tokens[i + 1])];
425
					compliance = ClassFileConstants.JDK1_5;
449
	
426
				} else if("recovery".equals(token)) { //$NON-NLS-1$
450
					newStatementsRecoveryFilter[index] = 1;
427
					compliance = ClassFileConstants.JDK_DEFERRED;
428
				}
451
				}
429
430
				int j = index * 8;
431
				result[j] = 	(byte)(compliance >>> 56);
432
				result[j + 1] = (byte)(compliance >>> 48);
433
				result[j + 2] = (byte)(compliance >>> 40);
434
				result[j + 3] = (byte)(compliance >>> 32);
435
				result[j + 4] = (byte)(compliance >>> 24);
436
				result[j + 5] = (byte)(compliance >>> 16);
437
				result[j + 6] = (byte)(compliance >>> 8);
438
				result[j + 7] = (byte)(compliance);
439
			}
452
			}
453
			buildFileForTable(filename, newStatementsRecoveryFilter);
440
		}
454
		}
441
455
	public final static void buildFilesFromLPG(String dataFilename, String dataFilename2) {
442
		buildFileForTable(file, result);
456
	
457
		//RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
458
	
459
		//build from the lpg javadcl.java files that represents the parser tables
460
		//lhs check_table asb asr symbol_index
461
	
462
		//[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
463
		char[] contents = CharOperation.NO_CHAR;
464
		try {
465
			contents = Util.getFileCharContent(new File(dataFilename), null);
466
		} catch (IOException ex) {
467
			System.out.println(Messages.parser_incorrectPath);
468
			return;
469
		}
470
		java.util.StringTokenizer st =
471
			new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;");  //$NON-NLS-1$
472
		String[] tokens = new String[st.countTokens()];
473
		int j = 0;
474
		while (st.hasMoreTokens()) {
475
			tokens[j++] = st.nextToken();
476
		}
477
		final String prefix = FILEPREFIX;
478
		int i = 0;
479
	
480
		char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
481
		buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
482
		buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
483
		buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
484
		buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
485
		buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
486
		char[] newTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
487
		char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
488
		buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
489
	
490
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
491
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
492
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
493
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
494
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
495
		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
496
		buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
497
	
498
		byte[] newRhs = buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
499
		buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
500
		buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
501
	
502
		String[] newName = buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$
503
	
504
		contents = CharOperation.NO_CHAR;
505
		try {
506
			contents = Util.getFileCharContent(new File(dataFilename2), null);
507
		} catch (IOException ex) {
508
			System.out.println(Messages.parser_incorrectPath);
509
			return;
510
		}
511
		st = new java.util.StringTokenizer(new String(contents), "\t\n\r#");  //$NON-NLS-1$
512
		tokens = new String[st.countTokens()];
513
		j = 0;
514
		while (st.hasMoreTokens()) {
515
			tokens[j++] = st.nextToken();
516
		}
517
	
518
		buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
519
		buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
520
	
521
		buildFilesForRecoveryTemplates(
522
				prefix + (++i) + ".rsc", //$NON-NLS-1$
523
				prefix + (++i) + ".rsc", //$NON-NLS-1$
524
				newTerminalIndex,
525
				newNonTerminalIndex,
526
				newName,
527
				newLhs,
528
				tokens);
529
	
530
		buildFilesForStatementsRecoveryFilter(
531
				prefix + (++i) + ".rsc", //$NON-NLS-1$
532
				newNonTerminalIndex,
533
				newLhs,
534
				tokens);
535
	
536
	
537
		System.out.println(Messages.parser_moveFiles);
538
	}
539
	protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName) {
540
		int[] newReverseTable = new int[newName.length];
541
		for (int j = 0; j < newName.length; j++) {
542
			found : {
543
				for (int k = 0; k < newTerminalIndex.length; k++) {
544
					if(newTerminalIndex[k] == j) {
545
						newReverseTable[j] = k;
546
						break found;
547
					}
548
				}
549
				for (int k = 0; k < newNonTerminalIndex.length; k++) {
550
					if(newNonTerminalIndex[k] == j) {
551
						newReverseTable[j] = -k;
552
						break found;
553
					}
554
				}
555
			}
556
		}
557
		return newReverseTable;
443
	}
558
	}
444
private final static void buildFileForTable(String filename, byte[] bytes) {
559
445
	java.io.FileOutputStream stream = null;
560
	private static int getSymbol(String terminalName, String[] newName, int[] newReverse) {
446
	try {
561
		for (int j = 0; j < newName.length; j++) {
447
		stream = new java.io.FileOutputStream(filename);
562
			if(terminalName.equals(newName[j])) {
448
		stream.write(bytes);
563
				return newReverse[j];
449
	} catch(IOException e) {
564
			}
450
		// ignore
565
		}
451
	} finally {
566
		return -1;
452
		if (stream != null) {
567
	}
568
	public static int in_symbol(int state) {
569
		return in_symb[original_state(state)];
570
	}
571
	public final static void initTables() throws java.io.IOException {
572
	
573
		final String prefix = FILEPREFIX;
574
		int i = 0;
575
		lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
576
		char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
577
		check_table = new short[chars.length];
578
		for (int c = chars.length; c-- > 0;) {
579
			check_table[c] = (short) (chars[c] - 32768);
580
		}
581
		asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
582
		asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
583
		nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
584
		nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
585
		terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
586
		non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
587
		term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
588
	
589
		scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
590
		scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
591
		scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
592
		scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
593
		scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
594
		scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
595
		in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
596
	
597
		rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
598
		term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
599
		scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
600
	
601
		name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
602
	
603
		rules_compliance = readLongTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
604
	
605
		readableName = readReadableNameTable(READABLE_NAMES_FILE_NAME);
606
	
607
		reverse_index = computeReverseTable(terminal_index, non_terminal_index, name);
608
	
609
		recovery_templates_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
610
		recovery_templates = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
611
	
612
		statements_recovery_filter = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
613
	
614
		base_action = lhs;
615
	}
616
	public static int nasi(int state) {
617
		return nasb[original_state(state)];
618
	}
619
	public static int ntAction(int state, int sym) {
620
		return base_action[state + sym];
621
	}
622
	protected static int original_state(int state) {
623
		return -base_check(state);
624
	}
625
626
	protected static byte[] readByteTable(String filename) throws java.io.IOException {
627
	
628
		//files are located at Parser.class directory
629
	
630
		InputStream stream = Parser.class.getResourceAsStream(filename);
631
		if (stream == null) {
632
			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
633
		}
634
		byte[] bytes = null;
635
		try {
636
			stream = new BufferedInputStream(stream);
637
			bytes = Util.getInputStreamAsByteArray(stream, -1);
638
		} finally {
453
			try {
639
			try {
454
				stream.close();
640
				stream.close();
455
			} catch (IOException e) {
641
			} catch (IOException e) {
456
				// ignore
642
				// ignore
457
			}
643
			}
458
		}
644
		}
645
		return bytes;
459
	}
646
	}
460
	System.out.println(filename + " creation complete"); //$NON-NLS-1$
647
	protected static long[] readLongTable(String filename) throws java.io.IOException {
461
}
648
	
462
private final static void buildFileForTable(String filename, char[] chars) {
649
		//files are located at Parser.class directory
463
	byte[] bytes = new byte[chars.length * 2];
650
	
464
	for (int i = 0; i < chars.length; i++) {
651
		InputStream stream = Parser.class.getResourceAsStream(filename);
465
		bytes[2 * i] = (byte) (chars[i] >>> 8);
652
		if (stream == null) {
466
		bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
653
			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
467
	}
654
		}
468
655
		byte[] bytes = null;
469
	java.io.FileOutputStream stream = null;
656
		try {
470
	try {
657
			stream = new BufferedInputStream(stream);
471
		stream = new java.io.FileOutputStream(filename);
658
			bytes = Util.getInputStreamAsByteArray(stream, -1);
472
		stream.write(bytes);
659
		} finally {
473
	} catch(IOException e) {
474
		// ignore
475
	} finally {
476
		if (stream != null) {
477
			try {
660
			try {
478
				stream.close();
661
				stream.close();
479
			} catch (IOException e) {
662
			} catch (IOException e) {
480
				// ignore
663
				// ignore
481
			}
664
			}
482
		}
665
		}
666
	
667
		//minimal integrity check (even size expected)
668
		int length = bytes.length;
669
		if (length % 8 != 0)
670
			throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
671
	
672
		// convert bytes into longs
673
		long[] longs = new long[length / 8];
674
		int i = 0;
675
		int longIndex = 0;
676
	
677
		while (true) {
678
			longs[longIndex++] =
679
			  (((long) (bytes[i++] & 0xFF)) << 56)
680
			+ (((long) (bytes[i++] & 0xFF)) << 48)
681
			+ (((long) (bytes[i++] & 0xFF)) << 40)
682
			+ (((long) (bytes[i++] & 0xFF)) << 32)
683
			+ (((long) (bytes[i++] & 0xFF)) << 24)
684
			+ (((long) (bytes[i++] & 0xFF)) << 16)
685
			+ (((long) (bytes[i++] & 0xFF)) << 8)
686
			+ (bytes[i++] & 0xFF);
687
	
688
			if (i == length)
689
				break;
690
		}
691
		return longs;
692
	}
693
694
	protected static String[] readNameTable(String filename) throws java.io.IOException {
695
		char[] contents = readTable(filename);
696
		char[][] nameAsChar = CharOperation.splitOn('\n', contents);
697
	
698
		String[] result = new String[nameAsChar.length + 1];
699
		result[0] = null;
700
		for (int i = 0; i < nameAsChar.length; i++) {
701
			result[i + 1] = new String(nameAsChar[i]);
702
		}
703
	
704
		return result;
483
	}
705
	}
484
	System.out.println(filename + " creation complete"); //$NON-NLS-1$
706
	protected static String[] readReadableNameTable(String filename) {
485
}
707
		String[] result = new String[name.length];
486
private final static byte[] buildFileOfByteFor(String filename, String tag, String[] tokens) {
708
	
487
709
		ResourceBundle bundle;
488
	//transform the String tokens into chars before dumping then into file
710
		try {
489
711
			bundle = ResourceBundle.getBundle(filename, Locale.getDefault());
490
	int i = 0;
712
		} catch(MissingResourceException e) {
491
	//read upto the tag
713
			System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
492
	while (!tokens[i++].equals(tag)){/*empty*/}
714
			throw e;
493
	//read upto the }
715
		}
494
716
		for (int i = 0; i < NT_OFFSET + 1; i++) {
495
	byte[] bytes = new byte[tokens.length]; //can't be bigger
717
			result[i] = name[i];
496
	int ic = 0;
718
		}
497
	String token;
719
		for (int i = NT_OFFSET; i < name.length; i++) {
498
	while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
720
			try {
499
		int c = Integer.parseInt(token);
721
				String n = bundle.getString(name[i]);
500
		bytes[ic++] = (byte) c;
722
				if(n != null && n.length() > 0) {
501
	}
723
					result[i] = n;
502
724
				} else {
503
	//resize
725
					result[i] = name[i];
504
	System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
505
506
	buildFileForTable(filename, bytes);
507
	return bytes;
508
}
509
private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) {
510
511
	//transform the String tokens into chars before dumping then into file
512
513
	int i = 0;
514
	//read upto the tag
515
	while (!tokens[i++].equals(tag)){/*empty*/}
516
	//read upto the }
517
518
	char[] chars = new char[tokens.length]; //can't be bigger
519
	int ic = 0;
520
	String token;
521
	while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
522
		int c = Integer.parseInt(token);
523
		chars[ic++] = (char) c;
524
	}
525
526
	//resize
527
	System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
528
529
	buildFileForTable(filename, chars);
530
	return chars;
531
}
532
private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) {
533
534
	//transform the String tokens into chars before dumping then into file
535
536
	int i = 0;
537
	//read upto the tag
538
	while (!tokens[i++].equals(tag)){/*empty*/}
539
	//read upto the }
540
541
	char[] chars = new char[tokens.length]; //can't be bigger
542
	int ic = 0;
543
	String token;
544
	while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
545
		int c = Integer.parseInt(token);
546
		chars[ic++] = (char) (c + 32768);
547
	}
548
549
	//resize
550
	System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
551
552
	buildFileForTable(filename, chars);
553
}
554
public final static void buildFilesFromLPG(String dataFilename, String dataFilename2) {
555
556
	//RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
557
558
	//build from the lpg javadcl.java files that represents the parser tables
559
	//lhs check_table asb asr symbol_index
560
561
	//[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
562
	char[] contents = CharOperation.NO_CHAR;
563
	try {
564
		contents = Util.getFileCharContent(new File(dataFilename), null);
565
	} catch (IOException ex) {
566
		System.out.println(Messages.parser_incorrectPath);
567
		return;
568
	}
569
	java.util.StringTokenizer st =
570
		new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;");  //$NON-NLS-1$
571
	String[] tokens = new String[st.countTokens()];
572
	int j = 0;
573
	while (st.hasMoreTokens()) {
574
		tokens[j++] = st.nextToken();
575
	}
576
	final String prefix = FILEPREFIX;
577
	int i = 0;
578
579
	char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
580
	buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
581
	buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
582
	buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
583
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
584
	buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
585
	char[] newTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
586
	char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
587
	buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
588
589
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
590
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
591
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
592
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
593
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
594
	buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
595
	buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
596
597
	byte[] newRhs = buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
598
	buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
599
	buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
600
601
	String[] newName = buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$
602
603
	contents = CharOperation.NO_CHAR;
604
	try {
605
		contents = Util.getFileCharContent(new File(dataFilename2), null);
606
	} catch (IOException ex) {
607
		System.out.println(Messages.parser_incorrectPath);
608
		return;
609
	}
610
	st = new java.util.StringTokenizer(new String(contents), "\t\n\r#");  //$NON-NLS-1$
611
	tokens = new String[st.countTokens()];
612
	j = 0;
613
	while (st.hasMoreTokens()) {
614
		tokens[j++] = st.nextToken();
615
	}
616
617
	buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
618
	buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
619
620
	buildFilesForRecoveryTemplates(
621
			prefix + (++i) + ".rsc", //$NON-NLS-1$
622
			prefix + (++i) + ".rsc", //$NON-NLS-1$
623
			newTerminalIndex,
624
			newNonTerminalIndex,
625
			newName,
626
			newLhs,
627
			tokens);
628
629
	buildFilesForStatementsRecoveryFilter(
630
			prefix + (++i) + ".rsc", //$NON-NLS-1$
631
			newNonTerminalIndex,
632
			newLhs,
633
			tokens);
634
635
636
	System.out.println(Messages.parser_moveFiles);
637
}
638
public static int in_symbol(int state) {
639
	return in_symb[original_state(state)];
640
}
641
public final static void initTables() throws java.io.IOException {
642
643
	final String prefix = FILEPREFIX;
644
	int i = 0;
645
	lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
646
	char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
647
	check_table = new short[chars.length];
648
	for (int c = chars.length; c-- > 0;) {
649
		check_table[c] = (short) (chars[c] - 32768);
650
	}
651
	asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
652
	asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
653
	nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
654
	nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
655
	terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
656
	non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
657
	term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
658
659
	scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
660
	scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
661
	scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
662
	scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
663
	scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
664
	scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
665
	in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
666
667
	rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
668
	term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
669
	scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
670
671
	name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
672
673
	rules_compliance = readLongTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
674
675
	readableName = readReadableNameTable(READABLE_NAMES_FILE_NAME);
676
677
	reverse_index = computeReverseTable(terminal_index, non_terminal_index, name);
678
679
	recovery_templates_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
680
	recovery_templates = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
681
682
	statements_recovery_filter = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
683
684
	base_action = lhs;
685
}
686
public static int nasi(int state) {
687
	return nasb[original_state(state)];
688
}
689
public static int ntAction(int state, int sym) {
690
	return base_action[state + sym];
691
}
692
protected static int original_state(int state) {
693
	return -base_check(state);
694
}
695
protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName) {
696
	int[] newReverseTable = new int[newName.length];
697
	for (int j = 0; j < newName.length; j++) {
698
		found : {
699
			for (int k = 0; k < newTerminalIndex.length; k++) {
700
				if(newTerminalIndex[k] == j) {
701
					newReverseTable[j] = k;
702
					break found;
703
				}
704
			}
705
			for (int k = 0; k < newNonTerminalIndex.length; k++) {
706
				if(newNonTerminalIndex[k] == j) {
707
					newReverseTable[j] = -k;
708
					break found;
709
				}
726
				}
727
			} catch(MissingResourceException e) {
728
				result[i] = name[i];
710
			}
729
			}
711
		}
730
		}
731
		return result;
712
	}
732
	}
713
	return newReverseTable;
733
	protected static char[] readTable(String filename) throws java.io.IOException {
714
}
734
	
715
735
		//files are located at Parser.class directory
716
private static int getSymbol(String terminalName, String[] newName, int[] newReverse) {
736
	
717
	for (int j = 0; j < newName.length; j++) {
737
		InputStream stream = Parser.class.getResourceAsStream(filename);
718
		if(terminalName.equals(newName[j])) {
738
		if (stream == null) {
719
			return newReverse[j];
739
			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
720
		}
740
		}
721
	}
741
		byte[] bytes = null;
722
	return -1;
723
}
724
725
protected static byte[] readByteTable(String filename) throws java.io.IOException {
726
727
	//files are located at Parser.class directory
728
729
	InputStream stream = Parser.class.getResourceAsStream(filename);
730
	if (stream == null) {
731
		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
732
	}
733
	byte[] bytes = null;
734
	try {
735
		stream = new BufferedInputStream(stream);
736
		bytes = Util.getInputStreamAsByteArray(stream, -1);
737
	} finally {
738
		try {
742
		try {
739
			stream.close();
743
			stream = new BufferedInputStream(stream);
740
		} catch (IOException e) {
744
			bytes = Util.getInputStreamAsByteArray(stream, -1);
741
			// ignore
745
		} finally {
746
			try {
747
				stream.close();
748
			} catch (IOException e) {
749
				// ignore
750
			}
742
		}
751
		}
752
	
753
		//minimal integrity check (even size expected)
754
		int length = bytes.length;
755
		if ((length & 1) != 0)
756
			throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
757
	
758
		// convert bytes into chars
759
		char[] chars = new char[length / 2];
760
		int i = 0;
761
		int charIndex = 0;
762
	
763
		while (true) {
764
			chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
765
			if (i == length)
766
				break;
767
		}
768
		return chars;
743
	}
769
	}
744
	return bytes;
770
	public static int tAction(int state, int sym) {
745
}
771
		return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
746
747
protected static String[] readNameTable(String filename) throws java.io.IOException {
748
	char[] contents = readTable(filename);
749
	char[][] nameAsChar = CharOperation.splitOn('\n', contents);
750
751
	String[] result = new String[nameAsChar.length + 1];
752
	result[0] = null;
753
	for (int i = 0; i < nameAsChar.length; i++) {
754
		result[i + 1] = new String(nameAsChar[i]);
755
	}
772
	}
773
	protected int astLengthPtr;
756
774
757
	return result;
775
	protected int[] astLengthStack;
758
}
776
	protected int astPtr;
759
protected static String[] readReadableNameTable(String filename) {
777
	protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
760
	String[] result = new String[name.length];
778
	public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
761
762
	ResourceBundle bundle;
763
	try {
764
		bundle = ResourceBundle.getBundle(filename, Locale.getDefault());
765
	} catch(MissingResourceException e) {
766
		System.out.println("Missing resource : " + filename.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
767
		throw e;
768
	}
769
	for (int i = 0; i < NT_OFFSET + 1; i++) {
770
		result[i] = name[i];
771
	}
772
	for (int i = NT_OFFSET; i < name.length; i++) {
773
		try {
774
			String n = bundle.getString(name[i]);
775
			if(n != null && n.length() > 0) {
776
				result[i] = n;
777
			} else {
778
				result[i] = name[i];
779
			}
780
		} catch(MissingResourceException e) {
781
			result[i] = name[i];
782
		}
783
	}
784
	return result;
785
}
786
protected static char[] readTable(String filename) throws java.io.IOException {
787
779
788
	//files are located at Parser.class directory
780
	protected RecoveredElement currentElement;
781
	public int currentToken;
782
	protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
783
	protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
784
	protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
785
	protected int endStatementPosition;
786
	protected int expressionLengthPtr;
787
	protected int[] expressionLengthStack;
788
	protected int expressionPtr;
789
	protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
790
	public int firstToken ; // handle for multiple parsing goals
791
	// generics management
792
	protected int genericsIdentifiersLengthPtr;
793
	protected int[] genericsIdentifiersLengthStack = new int[GenericsStackIncrement];
794
	protected int genericsLengthPtr;
795
	protected int[] genericsLengthStack = new int[GenericsStackIncrement];
796
	protected int genericsPtr;
797
	protected ASTNode[] genericsStack = new ASTNode[GenericsStackIncrement];
798
	protected boolean hasError;
799
	protected boolean hasReportedError;
800
	//identifiers stacks
801
	protected int identifierLengthPtr;
802
	protected int[] identifierLengthStack;
803
	protected long[] identifierPositionStack;
804
	protected int identifierPtr;
805
	protected char[][] identifierStack;
806
	protected boolean ignoreNextOpeningBrace;
789
807
790
	InputStream stream = Parser.class.getResourceAsStream(filename);
808
	//positions , dimensions , .... (int stacks)
791
	if (stream == null) {
809
	protected int intPtr;
792
		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
793
	}
794
	byte[] bytes = null;
795
	try {
796
		stream = new BufferedInputStream(stream);
797
		bytes = Util.getInputStreamAsByteArray(stream, -1);
798
	} finally {
799
		try {
800
			stream.close();
801
		} catch (IOException e) {
802
			// ignore
803
		}
804
	}
805
810
806
	//minimal integrity check (even size expected)
811
	protected int[] intStack;
807
	int length = bytes.length;
812
	public int lastAct ; //handle for multiple parsing goals
808
	if ((length & 1) != 0)
813
	//error recovery management
809
		throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
814
	protected int lastCheckPoint;
815
	protected int lastErrorEndPosition;
816
	protected int lastErrorEndPositionBeforeRecovery = -1;
817
	protected int lastIgnoredToken, nextIgnoredToken;
810
818
811
	// convert bytes into chars
819
	protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
812
	char[] chars = new char[length / 2];
813
	int i = 0;
814
	int charIndex = 0;
815
820
816
	while (true) {
821
	protected int listTypeParameterLength; // for recovering some incomplete list (type parameters)
817
		chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
822
	protected int lParenPos,rParenPos; //accurate only when used !
818
		if (i == length)
823
	protected int modifiers;
819
			break;
824
	protected int modifiersSourceStart;
820
	}
825
	protected int[] nestedMethod; //the ptr is nestedType
821
	return chars;
822
}
823
protected static long[] readLongTable(String filename) throws java.io.IOException {
824
826
825
	//files are located at Parser.class directory
827
	protected int nestedType, dimensions;
828
	ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
826
829
827
	InputStream stream = Parser.class.getResourceAsStream(filename);
830
	Expression [] noExpressions = new Expression[ExpressionStackIncrement];
828
	if (stream == null) {
831
	//modifiers dimensions nestedType etc.......
829
		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
832
	protected boolean optimizeStringLiterals =true;
830
	}
833
	protected CompilerOptions options;
831
	byte[] bytes = null;
832
	try {
833
		stream = new BufferedInputStream(stream);
834
		bytes = Util.getInputStreamAsByteArray(stream, -1);
835
	} finally {
836
		try {
837
			stream.close();
838
		} catch (IOException e) {
839
			// ignore
840
		}
841
	}
842
834
843
	//minimal integrity check (even size expected)
835
	protected ProblemReporter problemReporter;
844
	int length = bytes.length;
845
	if (length % 8 != 0)
846
		throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
847
848
	// convert bytes into longs
849
	long[] longs = new long[length / 8];
850
	int i = 0;
851
	int longIndex = 0;
852
853
	while (true) {
854
		longs[longIndex++] =
855
		  (((long) (bytes[i++] & 0xFF)) << 56)
856
		+ (((long) (bytes[i++] & 0xFF)) << 48)
857
		+ (((long) (bytes[i++] & 0xFF)) << 40)
858
		+ (((long) (bytes[i++] & 0xFF)) << 32)
859
		+ (((long) (bytes[i++] & 0xFF)) << 24)
860
		+ (((long) (bytes[i++] & 0xFF)) << 16)
861
		+ (((long) (bytes[i++] & 0xFF)) << 8)
862
		+ (bytes[i++] & 0xFF);
863
836
864
		if (i == length)
837
	protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
865
			break;
838
protected int realBlockPtr;
866
	}
839
protected int[] realBlockStack;
867
	return longs;
840
protected int recoveredStaticInitializerStart;
868
}
841
public ReferenceContext referenceContext;
869
public static int tAction(int state, int sym) {
842
public boolean reportOnlyOneSyntaxError = false;
870
	return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
843
public boolean reportSyntaxErrorIsRequired = true;
871
}
844
protected boolean restartRecovery;
845
protected boolean annotationRecoveryActivated = true;
846
protected int lastPosistion;
847
// statement recovery
848
public boolean methodRecoveryActivated = false;
849
protected boolean statementRecoveryActivated = false;
850
protected TypeDeclaration[] recoveredTypes;
851
protected int recoveredTypePtr;
852
protected int nextTypeStart;
853
protected TypeDeclaration pendingRecoveredType;
854
public RecoveryScanner recoveryScanner;
855
//scanner token
856
public Scanner scanner;
857
protected int[] stack = new int[StackIncrement];
858
protected int stateStackTop;
859
protected int synchronizedBlockSourceStart;
860
861
protected int[] variablesCounter;
862
863
protected boolean checkExternalizeStrings;
864
865
protected boolean recordStringLiterals;
866
// javadoc
867
public Javadoc javadoc;
868
public JavadocParser javadocParser;
869
// used for recovery
870
protected int lastJavadocEnd;
871
public org.eclipse.jdt.internal.compiler.ReadManager readManager;
872
872
873
public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
873
public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
874
874
Lines 1193-1198 Link Here
1193
		this.astLengthPtr--;
1193
		this.astLengthPtr--;
1194
	}
1194
	}
1195
}
1195
}
1196
protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim) {
1197
	int nameSize = this.identifierLengthStack[this.identifierLengthPtr];
1198
	int tokensSize = nameSize;
1199
	if (rightSide instanceof ParameterizedSingleTypeReference) {
1200
		tokensSize ++;
1201
	} else if (rightSide instanceof SingleTypeReference) {
1202
		tokensSize ++;
1203
	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
1204
		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
1205
	} else if (rightSide instanceof QualifiedTypeReference) {
1206
		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
1207
	}
1208
	TypeReference[][] typeArguments = new TypeReference[tokensSize][];
1209
	char[][] tokens = new char[tokensSize][];
1210
	long[] positions = new long[tokensSize];
1211
	if (rightSide instanceof ParameterizedSingleTypeReference) {
1212
		ParameterizedSingleTypeReference singleParameterizedTypeReference = (ParameterizedSingleTypeReference) rightSide;
1213
		tokens[nameSize] = singleParameterizedTypeReference.token;
1214
		positions[nameSize] = (((long) singleParameterizedTypeReference.sourceStart) << 32) + singleParameterizedTypeReference.sourceEnd;
1215
		typeArguments[nameSize] = singleParameterizedTypeReference.typeArguments;
1216
	} else if (rightSide instanceof SingleTypeReference) {
1217
		SingleTypeReference singleTypeReference = (SingleTypeReference) rightSide;
1218
		tokens[nameSize] = singleTypeReference.token;
1219
		positions[nameSize] = (((long) singleTypeReference.sourceStart) << 32) + singleTypeReference.sourceEnd;
1220
	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
1221
		ParameterizedQualifiedTypeReference parameterizedTypeReference = (ParameterizedQualifiedTypeReference) rightSide;
1222
		TypeReference[][] rightSideTypeArguments = parameterizedTypeReference.typeArguments;
1223
		System.arraycopy(rightSideTypeArguments, 0, typeArguments, nameSize, rightSideTypeArguments.length);
1224
		char[][] rightSideTokens = parameterizedTypeReference.tokens;
1225
		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
1226
		long[] rightSidePositions = parameterizedTypeReference.sourcePositions;
1227
		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
1228
	} else if (rightSide instanceof QualifiedTypeReference) {
1229
		QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) rightSide;
1230
		char[][] rightSideTokens = qualifiedTypeReference.tokens;
1231
		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
1232
		long[] rightSidePositions = qualifiedTypeReference.sourcePositions;
1233
		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
1234
	}
1235
1236
	int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
1237
	TypeReference[] currentTypeArguments = new TypeReference[currentTypeArgumentsLength];
1238
	this.genericsPtr -= currentTypeArgumentsLength;
1239
	System.arraycopy(this.genericsStack, this.genericsPtr + 1, currentTypeArguments, 0, currentTypeArgumentsLength);
1240
1241
	if (nameSize == 1) {
1242
		tokens[0] = this.identifierStack[this.identifierPtr];
1243
		positions[0] = this.identifierPositionStack[this.identifierPtr--];
1244
		typeArguments[0] = currentTypeArguments;
1245
	} else {
1246
		this.identifierPtr -= nameSize;
1247
		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, nameSize);
1248
		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, nameSize);
1249
		typeArguments[nameSize - 1] = currentTypeArguments;
1250
	}
1251
	this.identifierLengthPtr--;
1252
	return new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, positions);
1253
}
1196
protected void concatExpressionLists() {
1254
protected void concatExpressionLists() {
1197
	this.expressionLengthStack[--this.expressionLengthPtr]++;
1255
	this.expressionLengthStack[--this.expressionLengthPtr]++;
1198
}
1256
}
Lines 1484-1489 Link Here
1484
	// AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration
1542
	// AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration
1485
	concatNodeLists();
1543
	concatNodeLists();
1486
}
1544
}
1545
protected void consumeAnnotationTypeMemberDeclarationsopt() {
1546
	this.nestedType-- ;
1547
}
1487
protected void consumeArgumentList() {
1548
protected void consumeArgumentList() {
1488
	// ArgumentList ::= ArgumentList ',' Expression
1549
	// ArgumentList ::= ArgumentList ',' Expression
1489
	concatExpressionLists();
1550
	concatExpressionLists();
Lines 1944-1950 Link Here
1944
	// SwitchLabel ::= 'case' ConstantExpression ':'
2005
	// SwitchLabel ::= 'case' ConstantExpression ':'
1945
	this.expressionLengthPtr--;
2006
	this.expressionLengthPtr--;
1946
	Expression expression = this.expressionStack[this.expressionPtr--];
2007
	Expression expression = this.expressionStack[this.expressionPtr--];
1947
	pushOnAstStack(new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]));
2008
	CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]);
2009
	// Look for $fall-through$ tag in leading comment for case statement
2010
	if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) {
2011
		caseStatement.bits |= ASTNode.DocumentedFallthrough;
2012
	}
2013
	pushOnAstStack(caseStatement);
1948
}
2014
}
1949
protected void consumeCastExpressionLL1() {
2015
protected void consumeCastExpressionLL1() {
1950
	//CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
2016
	//CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
Lines 1976-2068 Link Here
1976
	castType.sourceEnd = end - 1;
2042
	castType.sourceEnd = end - 1;
1977
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
2043
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1978
	cast.sourceEnd = exp.sourceEnd;
2044
	cast.sourceEnd = exp.sourceEnd;
1979
}
2045
}
1980
protected void consumeCastExpressionWithNameArray() {
2046
protected void consumeCastExpressionWithNameArray() {
1981
	// CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
2047
	// CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
1982
1983
	Expression exp, cast, castType;
1984
	int end = this.intStack[this.intPtr--];
1985
1986
	// handle type arguments
1987
	pushOnGenericsLengthStack(0);
1988
	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
1989
1990
	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
1991
	castType.sourceEnd = end - 1;
1992
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
1993
	cast.sourceEnd = exp.sourceEnd;
1994
}
1995
protected void consumeCastExpressionWithPrimitiveType() {
1996
	// CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression
1997
1998
	//this.intStack : posOfLeftParen dim posOfRightParen
1999
2000
	//optimize the push/pop
2001
2002
	Expression exp, cast, castType;
2003
	int end = this.intStack[this.intPtr--];
2004
	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
2005
	castType.sourceEnd = end - 1;
2006
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
2007
	cast.sourceEnd = exp.sourceEnd;
2008
}
2009
protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim) {
2010
	int nameSize = this.identifierLengthStack[this.identifierLengthPtr];
2011
	int tokensSize = nameSize;
2012
	if (rightSide instanceof ParameterizedSingleTypeReference) {
2013
		tokensSize ++;
2014
	} else if (rightSide instanceof SingleTypeReference) {
2015
		tokensSize ++;
2016
	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
2017
		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
2018
	} else if (rightSide instanceof QualifiedTypeReference) {
2019
		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
2020
	}
2021
	TypeReference[][] typeArguments = new TypeReference[tokensSize][];
2022
	char[][] tokens = new char[tokensSize][];
2023
	long[] positions = new long[tokensSize];
2024
	if (rightSide instanceof ParameterizedSingleTypeReference) {
2025
		ParameterizedSingleTypeReference singleParameterizedTypeReference = (ParameterizedSingleTypeReference) rightSide;
2026
		tokens[nameSize] = singleParameterizedTypeReference.token;
2027
		positions[nameSize] = (((long) singleParameterizedTypeReference.sourceStart) << 32) + singleParameterizedTypeReference.sourceEnd;
2028
		typeArguments[nameSize] = singleParameterizedTypeReference.typeArguments;
2029
	} else if (rightSide instanceof SingleTypeReference) {
2030
		SingleTypeReference singleTypeReference = (SingleTypeReference) rightSide;
2031
		tokens[nameSize] = singleTypeReference.token;
2032
		positions[nameSize] = (((long) singleTypeReference.sourceStart) << 32) + singleTypeReference.sourceEnd;
2033
	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
2034
		ParameterizedQualifiedTypeReference parameterizedTypeReference = (ParameterizedQualifiedTypeReference) rightSide;
2035
		TypeReference[][] rightSideTypeArguments = parameterizedTypeReference.typeArguments;
2036
		System.arraycopy(rightSideTypeArguments, 0, typeArguments, nameSize, rightSideTypeArguments.length);
2037
		char[][] rightSideTokens = parameterizedTypeReference.tokens;
2038
		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
2039
		long[] rightSidePositions = parameterizedTypeReference.sourcePositions;
2040
		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
2041
	} else if (rightSide instanceof QualifiedTypeReference) {
2042
		QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) rightSide;
2043
		char[][] rightSideTokens = qualifiedTypeReference.tokens;
2044
		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
2045
		long[] rightSidePositions = qualifiedTypeReference.sourcePositions;
2046
		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
2047
	}
2048
2048
2049
	int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
2049
	Expression exp, cast, castType;
2050
	TypeReference[] currentTypeArguments = new TypeReference[currentTypeArgumentsLength];
2050
	int end = this.intStack[this.intPtr--];
2051
	this.genericsPtr -= currentTypeArgumentsLength;
2052
	System.arraycopy(this.genericsStack, this.genericsPtr + 1, currentTypeArguments, 0, currentTypeArgumentsLength);
2053
2051
2054
	if (nameSize == 1) {
2052
	// handle type arguments
2055
		tokens[0] = this.identifierStack[this.identifierPtr];
2053
	pushOnGenericsLengthStack(0);
2056
		positions[0] = this.identifierPositionStack[this.identifierPtr--];
2054
	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
2057
		typeArguments[0] = currentTypeArguments;
2055
2058
	} else {
2056
	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
2059
		this.identifierPtr -= nameSize;
2057
	castType.sourceEnd = end - 1;
2060
		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, nameSize);
2058
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
2061
		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, nameSize);
2059
	cast.sourceEnd = exp.sourceEnd;
2062
		typeArguments[nameSize - 1] = currentTypeArguments;
2060
}
2063
	}
2061
protected void consumeCastExpressionWithPrimitiveType() {
2064
	this.identifierLengthPtr--;
2062
	// CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN InsideCastExpression UnaryExpression
2065
	return new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, positions);
2063
2064
	//this.intStack : posOfLeftParen dim posOfRightParen
2065
2066
	//optimize the push/pop
2067
2068
	Expression exp, cast, castType;
2069
	int end = this.intStack[this.intPtr--];
2070
	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
2071
	castType.sourceEnd = end - 1;
2072
	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
2073
	cast.sourceEnd = exp.sourceEnd;
2066
}
2074
}
2067
protected void consumeCastExpressionWithQualifiedGenericsArray() {
2075
protected void consumeCastExpressionWithQualifiedGenericsArray() {
2068
	// CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
2076
	// CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
Lines 2144-2152 Link Here
2144
	// ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
2152
	// ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
2145
	this.nestedType-- ;
2153
	this.nestedType-- ;
2146
}
2154
}
2147
protected void consumeAnnotationTypeMemberDeclarationsopt() {
2148
	this.nestedType-- ;
2149
}
2150
protected void consumeClassBodyopt() {
2155
protected void consumeClassBodyopt() {
2151
	// ClassBodyopt ::= $empty
2156
	// ClassBodyopt ::= $empty
2152
	pushOnAstStack(null);
2157
	pushOnAstStack(null);
Lines 2311-2337 Link Here
2311
	typeDecl.javadoc = this.javadoc;
2316
	typeDecl.javadoc = this.javadoc;
2312
	this.javadoc = null;
2317
	this.javadoc = null;
2313
}
2318
}
2314
protected void consumeTypeHeaderNameWithTypeParameters() {
2315
	// ClassHeaderName ::= ClassHeaderName1 TypeParameters
2316
	// InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters
2317
	TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
2318
2319
	// consume type parameters
2320
	int length = this.genericsLengthStack[this.genericsLengthPtr--];
2321
	this.genericsPtr -= length;
2322
	System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
2323
2324
	typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
2325
2326
	this.listTypeParameterLength = 0;
2327
2328
	if (this.currentElement != null) { // is recovering
2329
		RecoveredType recoveredType = (RecoveredType) this.currentElement;
2330
		recoveredType.pendingTypeParameters = null;
2331
2332
		this.lastCheckPoint = typeDecl.bodyStart;
2333
	}
2334
}
2335
protected void consumeClassInstanceCreationExpression() {
2319
protected void consumeClassInstanceCreationExpression() {
2336
	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
2320
	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
2337
	classInstanceCreation(false);
2321
	classInstanceCreation(false);
Lines 2740-2752 Link Here
2740
		}
2724
		}
2741
	}
2725
	}
2742
}
2726
}
2743
protected void consumeDefaultLabel() {
2744
	// SwitchLabel ::= 'default' ':'
2745
	pushOnAstStack(new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]));
2746
}
2747
protected void consumeCreateInitializer() {
2727
protected void consumeCreateInitializer() {
2748
	pushOnAstStack(new Initializer(null, 0));
2728
	pushOnAstStack(new Initializer(null, 0));
2749
}
2729
}
2730
protected void consumeDefaultLabel() {
2731
	// SwitchLabel ::= 'default' ':'
2732
	CaseStatement defaultStatement = new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]);
2733
	// Look for $fall-through$ tag in leading comment for case statement
2734
	if (hasLeadingTagComment(FALL_THROUGH_TAG, defaultStatement.sourceStart)) {
2735
		defaultStatement.bits |= ASTNode.DocumentedFallthrough;
2736
	}	
2737
	pushOnAstStack(defaultStatement);
2738
}
2750
protected void consumeDefaultModifiers() {
2739
protected void consumeDefaultModifiers() {
2751
	checkComment(); // might update modifiers with AccDeprecated
2740
	checkComment(); // might update modifiers with AccDeprecated
2752
	pushOnIntStack(this.modifiers); // modifiers
2741
	pushOnIntStack(this.modifiers); // modifiers
Lines 2814-2827 Link Here
2814
	// ClassBodyDeclarationsopt ::= $empty
2803
	// ClassBodyDeclarationsopt ::= $empty
2815
	pushOnAstLengthStack(0);
2804
	pushOnAstLengthStack(0);
2816
}
2805
}
2817
protected void consumeEmptyMethodHeaderDefaultValue() {
2818
	// DefaultValueopt ::= $empty
2819
	AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2820
	if(method.isAnnotationMethod()) { //'method' can be a MethodDeclaration when recovery is started
2821
		pushOnExpressionStackLengthStack(0);
2822
	}
2823
	this.recordStringLiterals = true;
2824
}
2825
protected void consumeEmptyDimsopt() {
2806
protected void consumeEmptyDimsopt() {
2826
	// Dimsopt ::= $empty
2807
	// Dimsopt ::= $empty
2827
	pushOnIntStack(0);
2808
	pushOnIntStack(0);
Lines 2859-2873 Link Here
2859
		declaration.javadoc = this.compilationUnit.javadoc;
2840
		declaration.javadoc = this.compilationUnit.javadoc;
2860
	}
2841
	}
2861
}
2842
}
2862
protected void consumeEmptyMemberValuePairsopt() {
2863
	// MemberValuePairsopt ::= $empty
2864
	pushOnAstLengthStack(0);
2865
}
2866
protected void consumeEmptyMemberValueArrayInitializer() {
2843
protected void consumeEmptyMemberValueArrayInitializer() {
2867
	// MemberValueArrayInitializer ::= '{' ',' '}'
2844
	// MemberValueArrayInitializer ::= '{' ',' '}'
2868
	// MemberValueArrayInitializer ::= '{' '}'
2845
	// MemberValueArrayInitializer ::= '{' '}'
2869
	arrayInitializer(0);
2846
	arrayInitializer(0);
2870
}
2847
}
2848
protected void consumeEmptyMemberValuePairsopt() {
2849
	// MemberValuePairsopt ::= $empty
2850
	pushOnAstLengthStack(0);
2851
}
2852
protected void consumeEmptyMethodHeaderDefaultValue() {
2853
	// DefaultValueopt ::= $empty
2854
	AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
2855
	if(method.isAnnotationMethod()) { //'method' can be a MethodDeclaration when recovery is started
2856
		pushOnExpressionStackLengthStack(0);
2857
	}
2858
	this.recordStringLiterals = true;
2859
}
2871
protected void consumeEmptyStatement() {
2860
protected void consumeEmptyStatement() {
2872
	// EmptyStatement ::= ';'
2861
	// EmptyStatement ::= ';'
2873
	char[] source = this.scanner.source;
2862
	char[] source = this.scanner.source;
Lines 2910-2915 Link Here
2910
	if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2899
	if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
2911
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2900
	flushCommentsDefinedPriorTo(this.endStatementPosition);
2912
}
2901
}
2902
protected void consumeEnhancedForStatement() {
2903
	// EnhancedForStatement ::= EnhancedForStatementHeader Statement
2904
	// EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf
2905
2906
	//statements
2907
	this.astLengthPtr--;
2908
	Statement statement = (Statement) this.astStack[this.astPtr--];
2909
2910
	// foreach statement is on the ast stack
2911
	ForeachStatement foreachStatement = (ForeachStatement) this.astStack[this.astPtr];
2912
	foreachStatement.action = statement;
2913
	// remember useful empty statement
2914
	if (statement instanceof EmptyStatement) statement.bits |= ASTNode.IsUsefulEmptyStatement;
2915
2916
	foreachStatement.sourceEnd = this.endStatementPosition;
2917
}
2918
protected void consumeEnhancedForStatementHeader(){
2919
	// EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
2920
	final ForeachStatement statement = (ForeachStatement) this.astStack[this.astPtr];
2921
	//updates are on the expression stack
2922
	this.expressionLengthPtr--;
2923
	final Expression collection = this.expressionStack[this.expressionPtr--];
2924
	statement.collection = collection;
2925
	statement.sourceEnd = this.rParenPos;
2926
2927
	if(!this.statementRecoveryActivated &&
2928
			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
2929
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2930
		problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
2931
	}
2932
}
2913
protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
2933
protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
2914
	TypeReference type;
2934
	TypeReference type;
2915
2935
Lines 2960-2996 Link Here
2960
2980
2961
	iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
2981
	iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
2962
}
2982
}
2963
protected void consumeEnhancedForStatementHeader(){
2964
	// EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
2965
	final ForeachStatement statement = (ForeachStatement) this.astStack[this.astPtr];
2966
	//updates are on the expression stack
2967
	this.expressionLengthPtr--;
2968
	final Expression collection = this.expressionStack[this.expressionPtr--];
2969
	statement.collection = collection;
2970
	statement.sourceEnd = this.rParenPos;
2971
2972
	if(!this.statementRecoveryActivated &&
2973
			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
2974
			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
2975
		problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
2976
	}
2977
}
2978
protected void consumeEnhancedForStatement() {
2979
	// EnhancedForStatement ::= EnhancedForStatementHeader Statement
2980
	// EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf
2981
2982
	//statements
2983
	this.astLengthPtr--;
2984
	Statement statement = (Statement) this.astStack[this.astPtr--];
2985
2986
	// foreach statement is on the ast stack
2987
	ForeachStatement foreachStatement = (ForeachStatement) this.astStack[this.astPtr];
2988
	foreachStatement.action = statement;
2989
	// remember useful empty statement
2990
	if (statement instanceof EmptyStatement) statement.bits |= ASTNode.IsUsefulEmptyStatement;
2991
2992
	foreachStatement.sourceEnd = this.endStatementPosition;
2993
}
2994
protected void consumeEnterAnonymousClassBody() {
2983
protected void consumeEnterAnonymousClassBody() {
2995
	// EnterAnonymousClassBody ::= $empty
2984
	// EnterAnonymousClassBody ::= $empty
2996
	TypeReference typeReference = getTypeReference(0);
2985
	TypeReference typeReference = getTypeReference(0);
Lines 3177-3228 Link Here
3177
	// merge the constants values with the class body
3166
	// merge the constants values with the class body
3178
	concatNodeLists();
3167
	concatNodeLists();
3179
}
3168
}
3180
protected void consumeEnumConstantHeaderName() {
3181
	if (this.currentElement != null) {
3182
		if (!(this.currentElement instanceof RecoveredType
3183
					|| (this.currentElement instanceof RecoveredField && ((RecoveredField)this.currentElement).fieldDeclaration.type == null))
3184
				|| (this.lastIgnoredToken == TokenNameDOT)) {
3185
			this.lastCheckPoint = this.scanner.startPosition;
3186
			this.restartRecovery = true;
3187
			return;
3188
		}
3189
	}
3190
   long namePosition = this.identifierPositionStack[this.identifierPtr];
3191
   char[] constantName = this.identifierStack[this.identifierPtr];
3192
   final int sourceEnd = (int) namePosition;
3193
   FieldDeclaration enumConstant = createFieldDeclaration(constantName, (int) (namePosition >>> 32), sourceEnd);
3194
   this.identifierPtr--;
3195
   this.identifierLengthPtr--;
3196
   enumConstant.modifiersSourceStart = this.intStack[this.intPtr--];
3197
   enumConstant.modifiers = this.intStack[this.intPtr--];
3198
   enumConstant.declarationSourceStart = enumConstant.modifiersSourceStart;
3199
3200
	// Store secondary info
3201
	if ((enumConstant.bits & ASTNode.IsMemberType) == 0 && (enumConstant.bits & ASTNode.IsLocalType) == 0) {
3202
		if (this.compilationUnit != null && !CharOperation.equals(enumConstant.name, this.compilationUnit.getMainTypeName())) {
3203
			enumConstant.bits |= ASTNode.IsSecondaryType;
3204
		}
3205
	}
3206
3207
	// consume annotations
3208
   int length;
3209
   if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3210
      System.arraycopy(
3211
         this.expressionStack,
3212
         (this.expressionPtr -= length) + 1,
3213
         enumConstant.annotations = new Annotation[length],
3214
         0,
3215
         length);
3216
   }
3217
   pushOnAstStack(enumConstant);
3218
	if (this.currentElement != null){
3219
		this.lastCheckPoint = enumConstant.sourceEnd + 1;
3220
		this.currentElement = this.currentElement.add(enumConstant, 0);
3221
	}
3222
	// javadoc
3223
	enumConstant.javadoc = this.javadoc;
3224
	this.javadoc = null;
3225
}
3226
protected void consumeEnumConstantHeader() {
3169
protected void consumeEnumConstantHeader() {
3227
   FieldDeclaration enumConstant = (FieldDeclaration) this.astStack[this.astPtr];
3170
   FieldDeclaration enumConstant = (FieldDeclaration) this.astStack[this.astPtr];
3228
   boolean foundOpeningBrace = this.currentToken == TokenNameLBRACE;
3171
   boolean foundOpeningBrace = this.currentToken == TokenNameLBRACE;
Lines 3292-3297 Link Here
3292
	  }
3235
	  }
3293
   }
3236
   }
3294
}
3237
}
3238
protected void consumeEnumConstantHeaderName() {
3239
	if (this.currentElement != null) {
3240
		if (!(this.currentElement instanceof RecoveredType
3241
					|| (this.currentElement instanceof RecoveredField && ((RecoveredField)this.currentElement).fieldDeclaration.type == null))
3242
				|| (this.lastIgnoredToken == TokenNameDOT)) {
3243
			this.lastCheckPoint = this.scanner.startPosition;
3244
			this.restartRecovery = true;
3245
			return;
3246
		}
3247
	}
3248
   long namePosition = this.identifierPositionStack[this.identifierPtr];
3249
   char[] constantName = this.identifierStack[this.identifierPtr];
3250
   final int sourceEnd = (int) namePosition;
3251
   FieldDeclaration enumConstant = createFieldDeclaration(constantName, (int) (namePosition >>> 32), sourceEnd);
3252
   this.identifierPtr--;
3253
   this.identifierLengthPtr--;
3254
   enumConstant.modifiersSourceStart = this.intStack[this.intPtr--];
3255
   enumConstant.modifiers = this.intStack[this.intPtr--];
3256
   enumConstant.declarationSourceStart = enumConstant.modifiersSourceStart;
3257
3258
	// Store secondary info
3259
	if ((enumConstant.bits & ASTNode.IsMemberType) == 0 && (enumConstant.bits & ASTNode.IsLocalType) == 0) {
3260
		if (this.compilationUnit != null && !CharOperation.equals(enumConstant.name, this.compilationUnit.getMainTypeName())) {
3261
			enumConstant.bits |= ASTNode.IsSecondaryType;
3262
		}
3263
	}
3264
3265
	// consume annotations
3266
   int length;
3267
   if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
3268
      System.arraycopy(
3269
         this.expressionStack,
3270
         (this.expressionPtr -= length) + 1,
3271
         enumConstant.annotations = new Annotation[length],
3272
         0,
3273
         length);
3274
   }
3275
   pushOnAstStack(enumConstant);
3276
	if (this.currentElement != null){
3277
		this.lastCheckPoint = enumConstant.sourceEnd + 1;
3278
		this.currentElement = this.currentElement.add(enumConstant, 0);
3279
	}
3280
	// javadoc
3281
	enumConstant.javadoc = this.javadoc;
3282
	this.javadoc = null;
3283
}
3295
protected void consumeEnumConstantNoClassBody() {
3284
protected void consumeEnumConstantNoClassBody() {
3296
	// set declarationEnd and declarationSourceEnd
3285
	// set declarationEnd and declarationSourceEnd
3297
	int endOfEnumConstant = this.intStack[this.intPtr--];
3286
	int endOfEnumConstant = this.intStack[this.intPtr--];
Lines 4137-4145 Link Here
4137
		constructorDeclaration.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
4126
		constructorDeclaration.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
4138
	}
4127
	}
4139
}
4128
}
4140
protected void consumeInvalidInterfaceDeclaration() {
4129
protected void consumeInvalidEnumDeclaration() {
4141
	// BlockStatement ::= InvalidInterfaceDeclaration
4130
	// BlockStatement ::= EnumDeclaration
4142
	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
4143
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4131
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4144
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
4132
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
4145
	// remove the ast node created in interface header
4133
	// remove the ast node created in interface header
Lines 4147-4154 Link Here
4147
	pushOnAstLengthStack(-1);
4135
	pushOnAstLengthStack(-1);
4148
	concatNodeLists();
4136
	concatNodeLists();
4149
}
4137
}
4150
protected void consumeInvalidEnumDeclaration() {
4138
protected void consumeInvalidInterfaceDeclaration() {
4151
	// BlockStatement ::= EnumDeclaration
4139
	// BlockStatement ::= InvalidInterfaceDeclaration
4140
	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
4152
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4141
	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
4153
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
4142
	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
4154
	// remove the ast node created in interface header
4143
	// remove the ast node created in interface header
Lines 5041-5052 Link Here
5041
protected void consumePushLeftBrace() {
5030
protected void consumePushLeftBrace() {
5042
	pushOnIntStack(this.endPosition); // modifiers
5031
	pushOnIntStack(this.endPosition); // modifiers
5043
}
5032
}
5044
protected void consumePushRealModifiers() {
5045
	checkComment(); // might update modifiers with AccDeprecated
5046
	pushOnIntStack(this.modifiers); // modifiers
5047
	pushOnIntStack(this.modifiersSourceStart);
5048
	resetModifiers();
5049
}
5050
protected void consumePushModifiers() {
5033
protected void consumePushModifiers() {
5051
	pushOnIntStack(this.modifiers); // modifiers
5034
	pushOnIntStack(this.modifiers); // modifiers
5052
	pushOnIntStack(this.modifiersSourceStart);
5035
	pushOnIntStack(this.modifiersSourceStart);
Lines 5065-5070 Link Here
5065
	// PushPosition ::= $empty
5048
	// PushPosition ::= $empty
5066
	pushOnIntStack(this.endPosition);
5049
	pushOnIntStack(this.endPosition);
5067
}
5050
}
5051
protected void consumePushRealModifiers() {
5052
	checkComment(); // might update modifiers with AccDeprecated
5053
	pushOnIntStack(this.modifiers); // modifiers
5054
	pushOnIntStack(this.modifiersSourceStart);
5055
	resetModifiers();
5056
}
5068
protected void consumeQualifiedName() {
5057
protected void consumeQualifiedName() {
5069
	// QualifiedName ::= Name '.' SimpleName
5058
	// QualifiedName ::= Name '.' SimpleName
5070
	/*back from the recursive loop of QualifiedName.
5059
	/*back from the recursive loop of QualifiedName.
Lines 6840-6846 Link Here
6840
	}
6829
	}
6841
	this.recordStringLiterals = true;
6830
	this.recordStringLiterals = true;
6842
}
6831
}
6843
6844
protected void consumeSingleMemberAnnotationMemberValue() {
6832
protected void consumeSingleMemberAnnotationMemberValue() {
6845
	// this rule is used for syntax recovery only
6833
	// this rule is used for syntax recovery only
6846
	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
6834
	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
Lines 6850-6855 Link Here
6850
	}
6838
	}
6851
6839
6852
}
6840
}
6841
6853
protected void consumeSingleStaticImportDeclarationName() {
6842
protected void consumeSingleStaticImportDeclarationName() {
6854
	// SingleTypeImportDeclarationName ::= 'import' 'static' Name
6843
	// SingleTypeImportDeclarationName ::= 'import' 'static' Name
6855
	/* push an ImportRef build from the last name
6844
	/* push an ImportRef build from the last name
Lines 7714-7719 Link Here
7714
	// TypeDeclarations ::= TypeDeclarations TypeDeclaration
7703
	// TypeDeclarations ::= TypeDeclarations TypeDeclaration
7715
	concatNodeLists();
7704
	concatNodeLists();
7716
}
7705
}
7706
protected void consumeTypeHeaderNameWithTypeParameters() {
7707
	// ClassHeaderName ::= ClassHeaderName1 TypeParameters
7708
	// InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters
7709
	TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
7710
7711
	// consume type parameters
7712
	int length = this.genericsLengthStack[this.genericsLengthPtr--];
7713
	this.genericsPtr -= length;
7714
	System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
7715
7716
	typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
7717
7718
	this.listTypeParameterLength = 0;
7719
7720
	if (this.currentElement != null) { // is recovering
7721
		RecoveredType recoveredType = (RecoveredType) this.currentElement;
7722
		recoveredType.pendingTypeParameters = null;
7723
7724
		this.lastCheckPoint = typeDecl.bodyStart;
7725
	}
7726
}
7717
protected void consumeTypeImportOnDemandDeclarationName() {
7727
protected void consumeTypeImportOnDemandDeclarationName() {
7718
	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
7728
	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
7719
	/* push an ImportRef build from the last name
7729
	/* push an ImportRef build from the last name
Lines 7745-7766 Link Here
7745
		this.restartRecovery = true; // used to avoid branching back into the regular automaton
7755
		this.restartRecovery = true; // used to avoid branching back into the regular automaton
7746
	}
7756
	}
7747
}
7757
}
7748
protected void consumeTypeParameterHeader() {
7749
	//TypeParameterHeader ::= Identifier
7750
	TypeParameter typeParameter = new TypeParameter();
7751
	long pos = this.identifierPositionStack[this.identifierPtr];
7752
	final int end = (int) pos;
7753
	typeParameter.declarationSourceEnd = end;
7754
	typeParameter.sourceEnd = end;
7755
	final int start = (int) (pos >>> 32);
7756
	typeParameter.declarationSourceStart = start;
7757
	typeParameter.sourceStart = start;
7758
	typeParameter.name = this.identifierStack[this.identifierPtr--];
7759
	this.identifierLengthPtr--;
7760
	pushOnGenericsStack(typeParameter);
7761
7762
	this.listTypeParameterLength++;
7763
}
7764
protected void consumeTypeParameter1() {
7758
protected void consumeTypeParameter1() {
7765
	// nothing to do
7759
	// nothing to do
7766
}
7760
}
Lines 7790-7795 Link Here
7790
		bounds[i].bits |= ASTNode.IsSuperType;
7784
		bounds[i].bits |= ASTNode.IsSuperType;
7791
	}
7785
	}
7792
}
7786
}
7787
protected void consumeTypeParameterHeader() {
7788
	//TypeParameterHeader ::= Identifier
7789
	TypeParameter typeParameter = new TypeParameter();
7790
	long pos = this.identifierPositionStack[this.identifierPtr];
7791
	final int end = (int) pos;
7792
	typeParameter.declarationSourceEnd = end;
7793
	typeParameter.sourceEnd = end;
7794
	final int start = (int) (pos >>> 32);
7795
	typeParameter.declarationSourceStart = start;
7796
	typeParameter.sourceStart = start;
7797
	typeParameter.name = this.identifierStack[this.identifierPtr--];
7798
	this.identifierLengthPtr--;
7799
	pushOnGenericsStack(typeParameter);
7800
7801
	this.listTypeParameterLength++;
7802
}
7793
protected void consumeTypeParameterList() {
7803
protected void consumeTypeParameterList() {
7794
	//TypeParameterList ::= TypeParameterList ',' TypeParameter
7804
	//TypeParameterList ::= TypeParameterList ',' TypeParameter
7795
	concatGenericsLists();
7805
	concatGenericsLists();
Lines 8048-8053 Link Here
8048
	}
8058
	}
8049
	return false;
8059
	return false;
8050
}
8060
}
8061
8051
public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
8062
public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
8052
	MethodDeclaration m = new MethodDeclaration(compilationResult);
8063
	MethodDeclaration m = new MethodDeclaration(compilationResult);
8053
	m.typeParameters = c.typeParameters;
8064
	m.typeParameters = c.typeParameters;
Lines 8068-8073 Link Here
8068
	m.javadoc = c.javadoc;
8079
	m.javadoc = c.javadoc;
8069
	return m;
8080
	return m;
8070
}
8081
}
8082
8071
protected TypeReference copyDims(TypeReference typeRef, int dim) {
8083
protected TypeReference copyDims(TypeReference typeRef, int dim) {
8072
	return typeRef.copyDims(dim);
8084
	return typeRef.copyDims(dim);
8073
}
8085
}
Lines 8338-8344 Link Here
8338
 * void foo(){
8350
 * void foo(){
8339
 * } // end of method foo
8351
 * } // end of method foo
8340
 */
8352
 */
8341
8342
public int flushCommentsDefinedPriorTo(int position) {
8353
public int flushCommentsDefinedPriorTo(int position) {
8343
8354
8344
	int lastCommentIndex = this.scanner.commentPtr;
8355
	int lastCommentIndex = this.scanner.commentPtr;
Lines 8400-8405 Link Here
8400
	this.scanner.commentPtr = validCount - 1;
8411
	this.scanner.commentPtr = validCount - 1;
8401
	return position;
8412
	return position;
8402
}
8413
}
8414
8403
protected TypeReference getAnnotationType() {
8415
protected TypeReference getAnnotationType() {
8404
	int length = this.identifierLengthStack[this.identifierLengthPtr--];
8416
	int length = this.identifierLengthStack[this.identifierLengthPtr--];
8405
	if (length == 1) {
8417
	if (length == 1) {
Lines 8479-8544 Link Here
8479
	}
8491
	}
8480
	return positions;
8492
	return positions;
8481
}
8493
}
8482
	public void getMethodBodies(CompilationUnitDeclaration unit) {
8494
public void getMethodBodies(CompilationUnitDeclaration unit) {
8483
		//fill the methods bodies in order for the code to be generated
8495
	//fill the methods bodies in order for the code to be generated
8484
8496
8485
		if (unit == null) return;
8497
	if (unit == null) return;
8486
8498
8487
		if (unit.ignoreMethodBodies) {
8499
	if (unit.ignoreMethodBodies) {
8488
			unit.ignoreFurtherInvestigation = true;
8500
		unit.ignoreFurtherInvestigation = true;
8489
			return;
8501
		return;
8490
			// if initial diet parse did not work, no need to dig into method bodies.
8502
		// if initial diet parse did not work, no need to dig into method bodies.
8491
		}
8503
	}
8492
8504
8493
		if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
8505
	if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
8494
			return; //work already done ...
8506
		return; //work already done ...
8495
8507
8496
		// save existing values to restore them at the end of the parsing process
8508
	// save existing values to restore them at the end of the parsing process
8497
		// see bug 47079 for more details
8509
	// see bug 47079 for more details
8498
		int[] oldLineEnds = this.scanner.lineEnds;
8510
	int[] oldLineEnds = this.scanner.lineEnds;
8499
		int oldLinePtr = this.scanner.linePtr;
8511
	int oldLinePtr = this.scanner.linePtr;
8500
8512
8501
		//real parse of the method....
8513
	//real parse of the method....
8502
		CompilationResult compilationResult = unit.compilationResult;
8514
	CompilationResult compilationResult = unit.compilationResult;
8503
		char[] contents = this.readManager != null
8515
	char[] contents = this.readManager != null
8504
			? this.readManager.getContents(compilationResult.compilationUnit)
8516
		? this.readManager.getContents(compilationResult.compilationUnit)
8505
			: compilationResult.compilationUnit.getContents();
8517
		: compilationResult.compilationUnit.getContents();
8506
		this.scanner.setSource(contents, compilationResult);
8518
	this.scanner.setSource(contents, compilationResult);
8507
8519
8508
		if (this.javadocParser != null && this.javadocParser.checkDocComment) {
8520
	if (this.javadocParser != null && this.javadocParser.checkDocComment) {
8509
			this.javadocParser.scanner.setSource(contents);
8521
		this.javadocParser.scanner.setSource(contents);
8510
		}
8522
	}
8511
		if (unit.types != null) {
8523
	if (unit.types != null) {
8512
			for (int i = 0, length = unit.types.length; i < length; i++)
8524
		for (int i = 0, length = unit.types.length; i < length; i++)
8513
				unit.types[i].parseMethods(this, unit);
8525
			unit.types[i].parseMethods(this, unit);
8526
	}
8527
8528
	// tag unit has having read bodies
8529
	unit.bits |= ASTNode.HasAllMethodBodies;
8530
8531
	// this is done to prevent any side effects on the compilation unit result
8532
	// line separator positions array.
8533
	this.scanner.lineEnds = oldLineEnds;
8534
	this.scanner.linePtr = oldLinePtr;
8535
}
8536
	protected char getNextCharacter(char[] comment, int[] index) {
8537
		char nextCharacter = comment[index[0]++];
8538
		switch(nextCharacter) {
8539
			case '\\' :
8540
				int c1, c2, c3, c4;
8541
				index[0]++;
8542
				while (comment[index[0]] == 'u') index[0]++;
8543
				if (!(((c1 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15
8544
					|| c1 < 0)
8545
					|| ((c2 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c2 < 0)
8546
					|| ((c3 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c3 < 0)
8547
					|| ((c4 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) {
8548
						nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
8549
				}
8550
				break;
8514
		}
8551
		}
8515
8552
		return nextCharacter;
8516
		// tag unit has having read bodies
8517
		unit.bits |= ASTNode.HasAllMethodBodies;
8518
8519
		// this is done to prevent any side effects on the compilation unit result
8520
		// line separator positions array.
8521
		this.scanner.lineEnds = oldLineEnds;
8522
		this.scanner.linePtr = oldLinePtr;
8523
	}
8524
protected char getNextCharacter(char[] comment, int[] index) {
8525
	char nextCharacter = comment[index[0]++];
8526
	switch(nextCharacter) {
8527
		case '\\' :
8528
			int c1, c2, c3, c4;
8529
			index[0]++;
8530
			while (comment[index[0]] == 'u') index[0]++;
8531
			if (!(((c1 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15
8532
				|| c1 < 0)
8533
				|| ((c2 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c2 < 0)
8534
				|| ((c3 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c3 < 0)
8535
				|| ((c4 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) {
8536
					nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
8537
			}
8538
			break;
8539
	}
8553
	}
8540
	return nextCharacter;
8541
}
8542
protected Expression getTypeReference(Expression exp) {
8554
protected Expression getTypeReference(Expression exp) {
8543
8555
8544
	exp.bits &= ~ASTNode.RestrictiveFlagMASK;
8556
	exp.bits &= ~ASTNode.RestrictiveFlagMASK;
Lines 8808-8813 Link Here
8808
	this.firstToken = TokenNamePLUS;
8820
	this.firstToken = TokenNamePLUS;
8809
	this.scanner.recordLineSeparator = true;
8821
	this.scanner.recordLineSeparator = true;
8810
}
8822
}
8823
/**
8824
 * Look for a specific tag comment leading a given source range (comment located after any statement in astStack)
8825
 * @param rangeEnd int
8826
 * @return boolean
8827
 */
8828
public boolean hasLeadingTagComment(char[] commentPrefixTag, int rangeEnd) {
8829
	int iComment = this.scanner.commentPtr;
8830
	if (iComment < 0) return false; // no comment available
8831
	int iStatement = this.astLengthPtr;
8832
	if (iStatement < 0 || this.astLengthStack[iStatement] <= 1) return false; // no statement available
8833
	// Fallthrough comment must be located after the previous statement
8834
	ASTNode lastNode = this.astStack[this.astPtr];
8835
	int rangeStart = lastNode.sourceEnd;
8836
	previousComment: for (; iComment >= 0; iComment--) {
8837
		int commentStart = this.scanner.commentStarts[iComment];
8838
		// ignore comments before start
8839
		if (commentStart < rangeStart) return false; // no more comments in range
8840
		// ignore comments after end
8841
		if (commentStart > rangeEnd) continue previousComment;
8842
		// found last comment in range - only check the last comment in range
8843
		char[] source = this.scanner.source;
8844
		int charPos = commentStart+2; // skip // or /*
8845
		// tag can be leaded by optional spaces
8846
		for (; charPos < rangeEnd; charPos++) {
8847
			char c = source[charPos];
8848
			if (c >= ScannerHelper.MAX_OBVIOUS || (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) == 0) {
8849
				break;
8850
			}
8851
		}
8852
		for (int iTag = 0, length = commentPrefixTag.length; iTag < length; iTag++, charPos++) {
8853
			if (charPos >= rangeEnd) return false; // comment is too small to host tag
8854
			if (source[charPos] != commentPrefixTag[iTag]) return false;
8855
		}
8856
		return true;
8857
	}
8858
	return false;
8859
}
8811
protected void ignoreExpressionAssignment() {
8860
protected void ignoreExpressionAssignment() {
8812
	// Assignment ::= InvalidArrayInitializerAssignement
8861
	// Assignment ::= InvalidArrayInitializerAssignement
8813
	// encoded operator would be: this.intStack[this.intPtr]
8862
	// encoded operator would be: this.intStack[this.intPtr]
Lines 9901-9906 Link Here
9901
	}
9950
	}
9902
	this.expressionLengthStack[this.expressionLengthPtr] = pos;
9951
	this.expressionLengthStack[this.expressionLengthPtr] = pos;
9903
}
9952
}
9953
protected void pushOnGenericsIdentifiersLengthStack(int pos) {
9954
	int stackLength = this.genericsIdentifiersLengthStack.length;
9955
	if (++this.genericsIdentifiersLengthPtr >= stackLength) {
9956
		System.arraycopy(
9957
			this.genericsIdentifiersLengthStack, 0,
9958
			this.genericsIdentifiersLengthStack = new int[stackLength + GenericsStackIncrement], 0,
9959
			stackLength);
9960
	}
9961
	this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] = pos;
9962
}
9963
protected void pushOnGenericsLengthStack(int pos) {
9964
	int stackLength = this.genericsLengthStack.length;
9965
	if (++this.genericsLengthPtr >= stackLength) {
9966
		System.arraycopy(
9967
			this.genericsLengthStack, 0,
9968
			this.genericsLengthStack = new int[stackLength + GenericsStackIncrement], 0,
9969
			stackLength);
9970
	}
9971
	this.genericsLengthStack[this.genericsLengthPtr] = pos;
9972
}
9904
protected void pushOnGenericsStack(ASTNode node) {
9973
protected void pushOnGenericsStack(ASTNode node) {
9905
	/*add a new obj on top of the generics stack
9974
	/*add a new obj on top of the generics stack
9906
	genericsPtr points on the top*/
9975
	genericsPtr points on the top*/
Lines 9923-9948 Link Here
9923
	}
9992
	}
9924
	this.genericsLengthStack[this.genericsLengthPtr] = 1;
9993
	this.genericsLengthStack[this.genericsLengthPtr] = 1;
9925
}
9994
}
9926
protected void pushOnGenericsIdentifiersLengthStack(int pos) {
9927
	int stackLength = this.genericsIdentifiersLengthStack.length;
9928
	if (++this.genericsIdentifiersLengthPtr >= stackLength) {
9929
		System.arraycopy(
9930
			this.genericsIdentifiersLengthStack, 0,
9931
			this.genericsIdentifiersLengthStack = new int[stackLength + GenericsStackIncrement], 0,
9932
			stackLength);
9933
	}
9934
	this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] = pos;
9935
}
9936
protected void pushOnGenericsLengthStack(int pos) {
9937
	int stackLength = this.genericsLengthStack.length;
9938
	if (++this.genericsLengthPtr >= stackLength) {
9939
		System.arraycopy(
9940
			this.genericsLengthStack, 0,
9941
			this.genericsLengthStack = new int[stackLength + GenericsStackIncrement], 0,
9942
			stackLength);
9943
	}
9944
	this.genericsLengthStack[this.genericsLengthPtr] = pos;
9945
}
9946
protected void pushOnIntStack(int pos) {
9995
protected void pushOnIntStack(int pos) {
9947
9996
9948
	int stackLength = this.intStack.length;
9997
	int stackLength = this.intStack.length;
Lines 9973-10012 Link Here
9973
10022
9974
		TypeDeclaration[] types = new TypeDeclaration[0];
10023
		TypeDeclaration[] types = new TypeDeclaration[0];
9975
		int typePtr = -1;
10024
		int typePtr = -1;
9976
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
9977
			this.typePtr = -1;
9978
			return true;
9979
		}
9980
		public boolean visit(Initializer initializer, MethodScope scope) {
9981
			this.typePtr = -1;
9982
			if (initializer.block == null) return false;
9983
			return true;
9984
		}
9985
		public boolean visit(MethodDeclaration methodDeclaration,ClassScope scope) {
9986
			this.typePtr = -1;
9987
			return true;
9988
		}
9989
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
9990
			return this.visit(typeDeclaration);
9991
		}
9992
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
9993
			return this.visit(typeDeclaration);
9994
		}
9995
		private boolean visit(TypeDeclaration typeDeclaration) {
9996
			if(this.types.length <= ++this.typePtr) {
9997
				int length = this.typePtr;
9998
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
9999
			}
10000
			this.types[this.typePtr] = typeDeclaration;
10001
			return false;
10002
		}
10003
		public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
10025
		public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
10004
			endVisitMethod(constructorDeclaration, scope);
10026
			endVisitMethod(constructorDeclaration, scope);
10005
		}
10027
		}
10006
		public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
10028
		public void endVisit(Initializer initializer, MethodScope scope) {
10007
			endVisitMethod(methodDeclaration, scope);
10029
			if (initializer.block == null) return;
10008
		}
10009
		private void endVisitMethod(AbstractMethodDeclaration methodDeclaration, ClassScope scope) {
10010
			TypeDeclaration[] foundTypes = null;
10030
			TypeDeclaration[] foundTypes = null;
10011
			int length = 0;
10031
			int length = 0;
10012
			if(this.typePtr > -1) {
10032
			if(this.typePtr > -1) {
Lines 10015-10027 Link Here
10015
				System.arraycopy(this.types, 0, foundTypes, 0, length);
10035
				System.arraycopy(this.types, 0, foundTypes, 0, length);
10016
			}
10036
			}
10017
			ReferenceContext oldContext = Parser.this.referenceContext;
10037
			ReferenceContext oldContext = Parser.this.referenceContext;
10018
			Parser.this.recoveryScanner.resetTo(methodDeclaration.bodyStart, methodDeclaration.bodyEnd);
10038
			Parser.this.recoveryScanner.resetTo(initializer.bodyStart, initializer.bodyEnd);
10019
			Scanner oldScanner = Parser.this.scanner;
10039
			Scanner oldScanner = Parser.this.scanner;
10020
			Parser.this.scanner = Parser.this.recoveryScanner;
10040
			Parser.this.scanner = Parser.this.recoveryScanner;
10021
			parseStatements(
10041
			parseStatements(
10022
					methodDeclaration,
10042
					this.enclosingType,
10023
					methodDeclaration.bodyStart,
10043
					initializer.bodyStart,
10024
					methodDeclaration.bodyEnd,
10044
					initializer.bodyEnd,
10025
					foundTypes,
10045
					foundTypes,
10026
					Parser.this.compilationUnit);
10046
					Parser.this.compilationUnit);
10027
			Parser.this.scanner = oldScanner;
10047
			Parser.this.scanner = oldScanner;
Lines 10031-10038 Link Here
10031
				foundTypes[i].traverse(this.typeVisitor, scope);
10051
				foundTypes[i].traverse(this.typeVisitor, scope);
10032
			}
10052
			}
10033
		}
10053
		}
10034
		public void endVisit(Initializer initializer, MethodScope scope) {
10054
		public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
10035
			if (initializer.block == null) return;
10055
			endVisitMethod(methodDeclaration, scope);
10056
		}
10057
		private void endVisitMethod(AbstractMethodDeclaration methodDeclaration, ClassScope scope) {
10036
			TypeDeclaration[] foundTypes = null;
10058
			TypeDeclaration[] foundTypes = null;
10037
			int length = 0;
10059
			int length = 0;
10038
			if(this.typePtr > -1) {
10060
			if(this.typePtr > -1) {
Lines 10041-10053 Link Here
10041
				System.arraycopy(this.types, 0, foundTypes, 0, length);
10063
				System.arraycopy(this.types, 0, foundTypes, 0, length);
10042
			}
10064
			}
10043
			ReferenceContext oldContext = Parser.this.referenceContext;
10065
			ReferenceContext oldContext = Parser.this.referenceContext;
10044
			Parser.this.recoveryScanner.resetTo(initializer.bodyStart, initializer.bodyEnd);
10066
			Parser.this.recoveryScanner.resetTo(methodDeclaration.bodyStart, methodDeclaration.bodyEnd);
10045
			Scanner oldScanner = Parser.this.scanner;
10067
			Scanner oldScanner = Parser.this.scanner;
10046
			Parser.this.scanner = Parser.this.recoveryScanner;
10068
			Parser.this.scanner = Parser.this.recoveryScanner;
10047
			parseStatements(
10069
			parseStatements(
10048
					this.enclosingType,
10070
					methodDeclaration,
10049
					initializer.bodyStart,
10071
					methodDeclaration.bodyStart,
10050
					initializer.bodyEnd,
10072
					methodDeclaration.bodyEnd,
10051
					foundTypes,
10073
					foundTypes,
10052
					Parser.this.compilationUnit);
10074
					Parser.this.compilationUnit);
10053
			Parser.this.scanner = oldScanner;
10075
			Parser.this.scanner = oldScanner;
Lines 10057-10062 Link Here
10057
				foundTypes[i].traverse(this.typeVisitor, scope);
10079
				foundTypes[i].traverse(this.typeVisitor, scope);
10058
			}
10080
			}
10059
		}
10081
		}
10082
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
10083
			this.typePtr = -1;
10084
			return true;
10085
		}
10086
		public boolean visit(Initializer initializer, MethodScope scope) {
10087
			this.typePtr = -1;
10088
			if (initializer.block == null) return false;
10089
			return true;
10090
		}
10091
		public boolean visit(MethodDeclaration methodDeclaration,ClassScope scope) {
10092
			this.typePtr = -1;
10093
			return true;
10094
		}
10095
		private boolean visit(TypeDeclaration typeDeclaration) {
10096
			if(this.types.length <= ++this.typePtr) {
10097
				int length = this.typePtr;
10098
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
10099
			}
10100
			this.types[this.typePtr] = typeDeclaration;
10101
			return false;
10102
		}
10103
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
10104
			return this.visit(typeDeclaration);
10105
		}
10106
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
10107
			return this.visit(typeDeclaration);
10108
		}
10060
	}
10109
	}
10061
	class TypeVisitor extends ASTVisitor {
10110
	class TypeVisitor extends ASTVisitor {
10062
		public MethodVisitor methodVisitor;
10111
		public MethodVisitor methodVisitor;
Lines 10073-10092 Link Here
10073
		private void endVisitType() {
10122
		private void endVisitType() {
10074
			this.typePtr--;
10123
			this.typePtr--;
10075
		}
10124
		}
10076
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
10077
			return this.visit(typeDeclaration);
10078
		}
10079
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
10080
			return this.visit(typeDeclaration);
10081
		}
10082
		private boolean visit(TypeDeclaration typeDeclaration) {
10083
			if(this.types.length <= ++this.typePtr) {
10084
				int length = this.typePtr;
10085
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
10086
			}
10087
			this.types[this.typePtr] = typeDeclaration;
10088
			return true;
10089
		}
10090
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
10125
		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
10091
			if(constructorDeclaration.isDefaultConstructor()) return false;
10126
			if(constructorDeclaration.isDefaultConstructor()) return false;
10092
10127
Lines 10103-10108 Link Here
10103
			methodDeclaration.traverse(this.methodVisitor, scope);
10138
			methodDeclaration.traverse(this.methodVisitor, scope);
10104
			return false;
10139
			return false;
10105
		}
10140
		}
10141
		private boolean visit(TypeDeclaration typeDeclaration) {
10142
			if(this.types.length <= ++this.typePtr) {
10143
				int length = this.typePtr;
10144
				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
10145
			}
10146
			this.types[this.typePtr] = typeDeclaration;
10147
			return true;
10148
		}
10149
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
10150
			return this.visit(typeDeclaration);
10151
		}
10152
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
10153
			return this.visit(typeDeclaration);
10154
		}
10106
	}
10155
	}
10107
10156
10108
	MethodVisitor methodVisitor = new MethodVisitor();
10157
	MethodVisitor methodVisitor = new MethodVisitor();
(-)src/org/eclipse/jdt/core/tests/compiler/regression/SwitchTest.java (+116 lines)
Lines 11-16 Link Here
11
package org.eclipse.jdt.core.tests.compiler.regression;
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
12
13
import java.io.File;
13
import java.io.File;
14
import java.util.Map;
14
15
15
import junit.framework.Test;
16
import junit.framework.Test;
16
17
Lines 561-566 Link Here
561
		assertEquals("Wrong contents", expectedOutput, result);
562
		assertEquals("Wrong contents", expectedOutput, result);
562
	}
563
	}
563
}
564
}
565
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=245257
566
public void testONLY_014() {
567
	Map options = getCompilerOptions();
568
	options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
569
	this.runNegativeTest(new String[] {
570
		"X.java",
571
		"public class X {\n" + 
572
		"	void foo1(int i) {\n" + 
573
		"		switch (i) {\n" + 
574
		"			case 0://OK\n" + 
575
		"			case 1://OK\n" + 
576
		"				System.out.println();\n" + 
577
		"				//$FALL-THROUGH$\n" + 
578
		"			case 2://OK\n" + 
579
		"				System.out.println(); //$FALL-THROUGH$\n" + 
580
		"			case 3://OK\n" + 
581
		"				System.out.println();\n" + 
582
		"				//$FALL-THROUGH$ - some allowed explanation\n" + 
583
		"			case 4://OK\n" + 
584
		"			case 5://OK\n" + 
585
		"				System.out.println();\n" + 
586
		"				//$FALL-THROUGH$ - not last comment, thus inoperant\n" + 
587
		"				// last comment is not fall-through explanation\n" + 
588
		"			case 6://WRONG\n" + 
589
		"				//$FALL-THROUGH$ - useless since not leading the case\n" + 
590
		"				System.out.println();\n" + 
591
		"				/*$FALL-THROUGH$ - block comment, is also allowed */\n" + 
592
		"			case 7://OK\n" + 
593
		"				System.out.println(\"aa\"); //$NON-NLS-1$\n" + 
594
		"		}\n" + 
595
		"	}\n" + 
596
		"}\n",
597
	},
598
	"----------\n" + 
599
	"1. ERROR in X.java (at line 18)\n" + 
600
	"	case 6://WRONG\n" + 
601
	"	^^^^^^\n" + 
602
	"Switch case may be entered by falling through previous case\n" + 
603
	"----------\n",
604
	null,
605
	true,
606
	options);
607
}
608
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=245257 - variation
609
public void testONLY_015() {
610
	Map options = getCompilerOptions();
611
	options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
612
	this.runNegativeTest(new String[] {
613
		"X.java",
614
		"public class X {\n" + 
615
		"	void foo1(int i) {\n" + 
616
		"		switch (i) {\n" + 
617
		"			case 0://OK\n" + 
618
		"			case 1://OK\n" + 
619
		"				System.out.println();\n" + 
620
		"				//	  $FALL-THROUGH$\n" + 
621
		"			case 2://OK\n" + 
622
		"				System.out.println(); // 	 $FALL-THROUGH$\n" + 
623
		"			case 3://OK\n" + 
624
		"				System.out.println();\n" + 
625
		"				//	$FALL-THROUGH$ - some allowed explanation\n" + 
626
		"			case 4://OK\n" + 
627
		"			case 5://OK\n" + 
628
		"				System.out.println();\n" + 
629
		"				// $FALL-THROUGH$ - not last comment, thus inoperant\n" + 
630
		"				// last comment is not fall-through explanation\n" + 
631
		"			case 6://WRONG\n" + 
632
		"				// $FALL-THROUGH$ - useless since not leading the case\n" + 
633
		"				System.out.println();\n" + 
634
		"				/* $FALL-THROUGH$ - block comment, is also allowed */\n" + 
635
		"			case 7://OK\n" + 
636
		"				System.out.println(\"aa\"); //$NON-NLS-1$\n" + 
637
		"		}\n" + 
638
		"	}\n" + 
639
		"}\n",
640
	},
641
	"----------\n" + 
642
	"1. ERROR in X.java (at line 18)\n" + 
643
	"	case 6://WRONG\n" + 
644
	"	^^^^^^\n" + 
645
	"Switch case may be entered by falling through previous case\n" + 
646
	"----------\n",
647
	null,
648
	true,
649
	options);
650
}
651
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=245257 - variation
652
public void testONLY_016() {
653
	Map options = getCompilerOptions();
654
	options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.ERROR);
655
	this.runNegativeTest(new String[] {
656
		"X.java",
657
		"public class X {\n" + 
658
		"	void foo1(int i) {\n" + 
659
		"		switch (i) {\n" + 
660
		"			case 0://OK\n" + 
661
		"			case 1://OK\n" + 
662
		"				System.out.println();\n" + 
663
		"				//	  $FALL-THROUGH - missing trailing $ in tag\n" + 
664
		"			case 2://WRONG\n" + 
665
		"				System.out.println();\n" + 
666
		"		}\n" + 
667
		"	}\n" + 
668
		"}\n",
669
	},
670
	"----------\n" + 
671
	"1. ERROR in X.java (at line 8)\n" + 
672
	"	case 2://WRONG\n" + 
673
	"	^^^^^^\n" + 
674
	"Switch case may be entered by falling through previous case\n" + 
675
	"----------\n",
676
	null,
677
	true,
678
	options);
679
}
564
public static Class testClass() {
680
public static Class testClass() {
565
	return SwitchTest.class;
681
	return SwitchTest.class;
566
}
682
}

Return to bug 245257